From 203937456ec0987abdb711ede637e467750f5a83 Mon Sep 17 00:00:00 2001 From: Thomas Veerman Date: Mon, 12 Sep 2011 09:00:24 +0000 Subject: [PATCH] Fix off-by-one errors and increase PATH_MAX to 1024 In some places it was assumed that PATH_MAX does not include a terminating null character. Increases PATH_MAX to 1024 to get in sync with NetBSD. Required some rewriting in AVFS to keep memory usage low (the stack in use by a thread is very small). --- common/include/minix/limits.h | 2 +- nbsd_include/stdio.h | 2 +- servers/avfs/exec.c | 6 +-- servers/avfs/fscall.c | 2 +- servers/avfs/link.c | 29 +++++------ servers/avfs/mount.c | 10 ++-- servers/avfs/open.c | 14 +++--- servers/avfs/path.c | 93 +++++++++++++++-------------------- servers/avfs/protect.c | 6 +-- servers/avfs/proto.h | 3 +- servers/avfs/request.c | 2 +- servers/avfs/stadir.c | 8 +-- servers/avfs/time.c | 2 +- servers/avfs/utility.c | 2 +- servers/mfs/glo.h | 2 +- servers/vfs/fscall.c | 2 +- servers/vfs/glo.h | 2 +- servers/vfs/link.c | 7 +-- servers/vfs/path.c | 28 ++++++----- servers/vfs/utility.c | 4 +- 20 files changed, 108 insertions(+), 118 deletions(-) diff --git a/common/include/minix/limits.h b/common/include/minix/limits.h index c5d5576af..ee1012a95 100644 --- a/common/include/minix/limits.h +++ b/common/include/minix/limits.h @@ -7,6 +7,6 @@ #define _MINIX_LIMITS_H #define __MINIX_OPEN_MAX 255 /* a process may have 255 files open */ -#define __MINIX_PATH_MAX 255 /* a pathname may contain 255 chars */ +#define __MINIX_PATH_MAX 1024/* a pathname may contain 1023 chars (+ '\0')*/ #endif /* _MINIX_LIMITS_H */ diff --git a/nbsd_include/stdio.h b/nbsd_include/stdio.h index 0f977a21a..341de8b5d 100644 --- a/nbsd_include/stdio.h +++ b/nbsd_include/stdio.h @@ -185,7 +185,7 @@ __END_DECLS */ /* must be == _POSIX_STREAM_MAX */ #define FOPEN_MAX 20 /* must be <= OPEN_MAX */ -#define FILENAME_MAX 1024 /* must be <= PATH_MAX */ +#define FILENAME_MAX 255 /* must be <= PATH_MAX */ /* System V/ANSI C; this is the wrong way to do this, do *not* use these. */ #if defined(_XOPEN_SOURCE) || defined(_NETBSD_SOURCE) diff --git a/servers/avfs/exec.c b/servers/avfs/exec.c index dc29c6875..eb91fc96b 100644 --- a/servers/avfs/exec.c +++ b/servers/avfs/exec.c @@ -46,7 +46,7 @@ FORWARD _PROTOTYPE( int exec_newmem, (int proc_e, vir_bytes text_addr, vir_bytes int *allow_setuidp) ); FORWARD _PROTOTYPE( int is_script, (const char *exec_hdr, size_t exec_len)); FORWARD _PROTOTYPE( int patch_stack, (struct vnode *vp, char stack[ARG_MAX], - vir_bytes *stk_bytes, char path[PATH_MAX+1]) ); + vir_bytes *stk_bytes, char path[PATH_MAX]) ); FORWARD _PROTOTYPE( int insert_arg, (char stack[ARG_MAX], vir_bytes *stk_bytes, char *arg, int replace) ); FORWARD _PROTOTYPE( void patch_ptr, (char stack[ARG_MAX], vir_bytes base)); @@ -127,7 +127,7 @@ PUBLIC int pm_exec(int proc_e, char *path, vir_bytes path_len, char *frame, static char mbuf[ARG_MAX]; /* buffer for stack and zeroes */ struct exec_info execi; int i; - char fullpath[PATH_MAX+1]; + char fullpath[PATH_MAX]; struct lookup resolve; lock_exec(); @@ -435,7 +435,7 @@ PRIVATE int patch_stack(vp, stack, stk_bytes, path) struct vnode *vp; /* pointer for open script file */ char stack[ARG_MAX]; /* pointer to stack image within VFS */ vir_bytes *stk_bytes; /* size of initial stack */ -char path[PATH_MAX+1]; /* path to script file */ +char path[PATH_MAX]; /* path to script file */ { /* Patch the argument vector to include the path name of the script to be * interpreted, and all strings on the #! line. Returns the path name of diff --git a/servers/avfs/fscall.c b/servers/avfs/fscall.c index 2ef4f62d7..6098af822 100644 --- a/servers/avfs/fscall.c +++ b/servers/avfs/fscall.c @@ -27,7 +27,7 @@ PRIVATE struct { int g_who_p; /* slot number of caller process */ int g_call_nr; /* call number */ int g_super_user; /* is the caller root? */ - char g_user_fullpath[PATH_MAX+1]; /* path to look up */ + char g_user_fullpath[PATH_MAX]; /* path to look up */ } globals[MAX_DEPTH]; PRIVATE int depth = 0; /* current globals stack level */ diff --git a/servers/avfs/link.c b/servers/avfs/link.c index d0e1c762f..a4efae564 100644 --- a/servers/avfs/link.c +++ b/servers/avfs/link.c @@ -34,7 +34,7 @@ PUBLIC int do_link() int r = OK; struct vnode *vp = NULL, *dirp = NULL; struct vmnt *vmp1 = NULL, *vmp2 = NULL; - char fullpath[PATH_MAX+1]; + char fullpath[PATH_MAX]; struct lookup resolve; lookup_init(&resolve, fullpath, PATH_NOFLAGS, &vmp1, &vp); @@ -94,7 +94,7 @@ PUBLIC int do_unlink() struct vnode *dirp, *vp; struct vmnt *vmp, *vmp2; int r; - char fullpath[PATH_MAX+1]; + char fullpath[PATH_MAX]; struct lookup resolve; lookup_init(&resolve, fullpath, PATH_NOFLAGS, &vmp, &dirp); @@ -170,8 +170,8 @@ PUBLIC int do_rename() int r = OK, r1; struct vnode *old_dirp, *new_dirp = NULL, *vp; struct vmnt *oldvmp, *newvmp, *vmp2; - char old_name[PATH_MAX+1]; - char fullpath[PATH_MAX+1]; + char old_name[PATH_MAX]; + char fullpath[PATH_MAX]; struct lookup resolve; lookup_init(&resolve, fullpath, PATH_NOFLAGS, &oldvmp, &old_dirp); @@ -273,7 +273,7 @@ PUBLIC int do_truncate() struct vnode *vp; struct vmnt *vmp; int r; - char fullpath[PATH_MAX+1]; + char fullpath[PATH_MAX]; struct lookup resolve; lookup_init(&resolve, fullpath, PATH_NOFLAGS, &vmp, &vp); @@ -348,7 +348,7 @@ PUBLIC int do_slink() int r; struct vnode *vp; struct vmnt *vmp; - char fullpath[PATH_MAX+1]; + char fullpath[PATH_MAX]; struct lookup resolve; lookup_init(&resolve, fullpath, PATH_NOFLAGS, &vmp, &vp); @@ -382,30 +382,31 @@ PUBLIC int do_slink() *===========================================================================*/ PUBLIC int rdlink_direct(orig_path, link_path, rfp) char *orig_path; -char *link_path; /* should have length PATH_MAX+1 */ +char link_path[PATH_MAX]; /* should have length PATH_MAX */ struct fproc *rfp; { /* Perform a readlink()-like call from within the VFS */ int r; struct vnode *vp; struct vmnt *vmp; - char fullpath[PATH_MAX+1]; struct lookup resolve; - lookup_init(&resolve, fullpath, PATH_RET_SYMLINK, &vmp, &vp); + lookup_init(&resolve, link_path, PATH_RET_SYMLINK, &vmp, &vp); resolve.l_vmnt_lock = VMNT_READ; resolve.l_vnode_lock = VNODE_READ; - /* Temporarily open the file containing the symbolic link */ - strncpy(fullpath, orig_path, PATH_MAX); + /* Temporarily open the file containing the symbolic link. Use link_path + * for temporary storage to keep orig_path untouched. */ + strncpy(link_path, orig_path, PATH_MAX); /* PATH_MAX includes '\0' */ + link_path[PATH_MAX - 1] = '\0'; if ((vp = eat_path(&resolve, rfp)) == NULL) return(err_code); /* Make sure this is a symbolic link */ if ((vp->v_mode & I_TYPE) != I_SYMBOLIC_LINK) r = EINVAL; else - r = req_rdlink(vp->v_fs_e, vp->v_inode_nr, (endpoint_t) 0, - link_path, PATH_MAX+1, 1); + r = req_rdlink(vp->v_fs_e, vp->v_inode_nr, NONE, link_path, + PATH_MAX - 1, 1); if (r > 0) link_path[r] = '\0'; /* Terminate string when succesful */ @@ -425,7 +426,7 @@ PUBLIC int do_rdlink() int r, copylen; struct vnode *vp; struct vmnt *vmp; - char fullpath[PATH_MAX+1]; + char fullpath[PATH_MAX]; struct lookup resolve; lookup_init(&resolve, fullpath, PATH_RET_SYMLINK, &vmp, &vp); diff --git a/servers/avfs/mount.c b/servers/avfs/mount.c index a0096e6a8..151e63a7d 100644 --- a/servers/avfs/mount.c +++ b/servers/avfs/mount.c @@ -42,7 +42,7 @@ PRIVATE bitchunk_t nonedev[BITMAP_CHUNKS(NR_NONEDEVS)] = { 0 }; #define free_nonedev(dev) UNSET_BIT(nonedev, minor(dev) - 1) FORWARD _PROTOTYPE( dev_t name_to_dev, (int allow_mountpt, - char path[PATH_MAX+1]) ); + char path[PATH_MAX]) ); FORWARD _PROTOTYPE( dev_t find_free_nonedev, (void) ); FORWARD _PROTOTYPE( void update_bspec, (dev_t dev, endpoint_t fs_e, int send_drv_e) ); @@ -103,7 +103,7 @@ PUBLIC int do_mount() /* Perform the mount(name, mfile, mount_flags) system call. */ endpoint_t fs_e; int r, slot, rdonly, nodev; - char fullpath[PATH_MAX+1]; + char fullpath[PATH_MAX]; char mount_label[LABEL_MAX]; dev_t dev; @@ -161,7 +161,7 @@ PUBLIC int do_mount() *===========================================================================*/ PUBLIC int mount_fs( dev_t dev, -char mountpoint[PATH_MAX+1], +char mountpoint[PATH_MAX], endpoint_t fs_e, int rdonly, char mount_label[LABEL_MAX] ) @@ -397,7 +397,7 @@ PUBLIC int do_umount(void) char label[LABEL_MAX]; dev_t dev; int r; - char fullpath[PATH_MAX+1]; + char fullpath[PATH_MAX]; /* Only the super-user may do umount. */ if (!super_user) return(EPERM); @@ -529,7 +529,7 @@ PUBLIC void unmount_all(void) /*===========================================================================* * name_to_dev * *===========================================================================*/ -PRIVATE dev_t name_to_dev(int allow_mountpt, char path[PATH_MAX+1]) +PRIVATE dev_t name_to_dev(int allow_mountpt, char path[PATH_MAX]) { /* Convert the block special file in 'user_fullpath' to a device number. * If the given path is not a block special file, but 'allow_mountpt' is set diff --git a/servers/avfs/open.c b/servers/avfs/open.c index 23e8cfb5f..1655fd2f6 100644 --- a/servers/avfs/open.c +++ b/servers/avfs/open.c @@ -33,7 +33,7 @@ PRIVATE char mode_map[] = {R_BIT, W_BIT, R_BIT|W_BIT, 0}; -FORWARD _PROTOTYPE( int common_open, (char path[PATH_MAX+1], int oflags, +FORWARD _PROTOTYPE( int common_open, (char path[PATH_MAX], int oflags, mode_t omode) ); FORWARD _PROTOTYPE( struct vnode *new_node, (struct lookup *resolve, int oflags, mode_t bits) ); @@ -48,7 +48,7 @@ PUBLIC int do_creat() { /* Perform the creat(name, mode) system call. */ int r; - char fullpath[PATH_MAX+1]; + char fullpath[PATH_MAX]; if (fetch_name(m_in.name, m_in.name_length, M3, fullpath) != OK) return(err_code); @@ -65,7 +65,7 @@ PUBLIC int do_open() /* Perform the open(name, flags,...) system call. */ int create_mode = 0; /* is really mode_t but this gives problems */ int r; - char fullpath[PATH_MAX+1]; + char fullpath[PATH_MAX]; /* If O_CREAT is set, open has three parameters, otherwise two. */ if (m_in.mode & O_CREAT) { @@ -84,7 +84,7 @@ PUBLIC int do_open() /*===========================================================================* * common_open * *===========================================================================*/ -PRIVATE int common_open(char path[PATH_MAX+1], int oflags, mode_t omode) +PRIVATE int common_open(char path[PATH_MAX], int oflags, mode_t omode) { /* Common code from do_creat and do_open. */ int b, r, exist = TRUE, major_dev; @@ -369,7 +369,7 @@ printf("XXX: dangling symlink needs re-resolving\n"); slp->v_inode_nr, VFS_PROC_NR, path, - PATH_MAX, 0); + PATH_MAX - 1, 0); if (r < 0) { /* Failed to read link */ unlock_vnode(slp); @@ -500,7 +500,7 @@ PUBLIC int do_mknod() int r; struct vnode *vp; struct vmnt *vmp; - char fullpath[PATH_MAX+1]; + char fullpath[PATH_MAX]; struct lookup resolve; lookup_init(&resolve, fullpath, PATH_NOFLAGS, &vmp, &vp); @@ -544,7 +544,7 @@ PUBLIC int do_mkdir() int r; struct vnode *vp; struct vmnt *vmp; - char fullpath[PATH_MAX+1]; + char fullpath[PATH_MAX]; struct lookup resolve; lookup_init(&resolve, fullpath, PATH_NOFLAGS, &vmp, &vp); diff --git a/servers/avfs/path.c b/servers/avfs/path.c index d5afaaf38..9ed1540f8 100644 --- a/servers/avfs/path.c +++ b/servers/avfs/path.c @@ -167,7 +167,7 @@ struct fproc *rfp; size_t len; char *cp; - char dir_entry[PATH_MAX+1]; + char dir_entry[NAME_MAX+1]; struct vnode *start_dir, *res; int r; @@ -215,8 +215,9 @@ struct fproc *rfp; strcpy(dir_entry, "."); } else { /* A path name for the directory and a directory entry */ - strcpy(dir_entry, cp+1); + strncpy(dir_entry, cp+1, NAME_MAX); cp[1] = '\0'; + dir_entry[NAME_MAX] = '\0'; } /* Remove trailing slashes */ @@ -230,7 +231,7 @@ struct fproc *rfp; if (res == NULL) return(NULL); /* Copy the directory entry back to user_fullpath */ - strncpy(resolve->l_path, dir_entry, PATH_MAX); + strncpy(resolve->l_path, dir_entry, NAME_MAX + 1); return(res); } @@ -490,23 +491,24 @@ char ename[NAME_MAX + 1]; /*===========================================================================* * canonical_path * *===========================================================================*/ -PUBLIC int canonical_path(orig_path, canon_path, rfp) -char *orig_path; -char canon_path[PATH_MAX+1]; /* should have length PATH_MAX+1 */ +PUBLIC int canonical_path(orig_path, rfp) +char orig_path[PATH_MAX]; struct fproc *rfp; { +/* Find canonical path of a given path */ int len = 0; int r, symloop = 0; struct vnode *dir_vp, *parent_dir; struct vmnt *dir_vmp, *parent_vmp; - char component[NAME_MAX+1]; - char link_path[PATH_MAX+1]; - char temp_path[PATH_MAX+1]; + char component[NAME_MAX+1]; /* NAME_MAX does /not/ include '\0' */ + char temp_path[PATH_MAX]; struct lookup resolve; dir_vp = NULL; strncpy(temp_path, orig_path, PATH_MAX); + temp_path[PATH_MAX - 1] = '\0'; + /* First resolve path to the last directory holding the file */ do { if (dir_vp) { unlock_vnode(dir_vp); @@ -514,7 +516,6 @@ struct fproc *rfp; put_vnode(dir_vp); } - /* Resolve to the last directory holding the file */ lookup_init(&resolve, temp_path, PATH_NOFLAGS, &dir_vmp, &dir_vp); resolve.l_vmnt_lock = VMNT_READ; resolve.l_vnode_lock = VNODE_READ; @@ -523,18 +524,16 @@ struct fproc *rfp; /* dir_vp points to dir and resolve path now contains only the * filename. */ - strcpy(canon_path, resolve.l_path); /* Store file name */ + strncpy(orig_path, temp_path, NAME_MAX); /* Store file name */ /* check if the file is a symlink, if so resolve it */ - r = rdlink_direct(canon_path, link_path, rfp); - if (r <= 0) { - strcpy(temp_path, canon_path); + r = rdlink_direct(orig_path, temp_path, rfp); + + if (r <= 0) break; - } /* encountered a symlink -- loop again */ - strcpy(temp_path, link_path); - + strncpy(orig_path, temp_path, PATH_MAX - 1); symloop++; } while (symloop < SYMLOOP_MAX); @@ -547,7 +546,9 @@ struct fproc *rfp; return(ELOOP); } - while(dir_vp != rfp->fp_rd) { + /* We've got the filename and the actual directory holding the file. From + * here we start building up the canonical path by climbing up the tree */ + while (dir_vp != rfp->fp_rd) { strcpy(temp_path, ".."); @@ -587,8 +588,8 @@ struct fproc *rfp; } len += strlen(component) + 1; - if (len > PATH_MAX) { - /* adding the component to canon_path would exceed PATH_MAX */ + if (len >= PATH_MAX) { + /* adding the component to orig_path would exceed PATH_MAX */ unlock_vnode(parent_dir); unlock_vmnt(parent_vmp); unlock_vnode(dir_vp); @@ -598,19 +599,16 @@ struct fproc *rfp; return(ENOMEM); } - /* store result of component in canon_path */ - - /* first make space by moving the contents of canon_path to - * the right. Move strlen + 1 bytes to include the terminating '\0'. + /* Store result of component in orig_path. First make space by moving + * the contents of orig_path to the right. Move strlen + 1 bytes to + * include the terminating '\0'. Move to strlen + 1 bytes to reserve + * space for the slash. */ - memmove(canon_path+strlen(component)+1, canon_path, - strlen(canon_path) + 1); - + memmove(orig_path+strlen(component)+1, orig_path, strlen(orig_path)+1); /* Copy component into canon_path */ - memmove(canon_path, component, strlen(component)); - + memmove(orig_path, component, strlen(component)); /* Put slash into place */ - canon_path[strlen(component)] = '/'; + orig_path[strlen(component)] = '/'; /* Store parent_dir result, and continue the loop once more */ unlock_vnode(dir_vp); @@ -625,9 +623,9 @@ struct fproc *rfp; put_vnode(dir_vp); /* add the leading slash */ - if (strlen(canon_path) >= PATH_MAX) return(ENAMETOOLONG); - memmove(canon_path+1, canon_path, strlen(canon_path)); - canon_path[0] = '/'; + if (strlen(orig_path) >= PATH_MAX) return(ENAMETOOLONG); + memmove(orig_path+1, orig_path, strlen(orig_path)); + orig_path[0] = '/'; return(OK); } @@ -644,44 +642,33 @@ size_t pathlen; struct vnode *vp; struct vmnt *vmp; struct fproc *rfp; - char orig_path[PATH_MAX+1]; - char canon_path[PATH_MAX+1]; - char temp_path[PATH_MAX+1]; + char canon_path[PATH_MAX]; struct lookup resolve; if (isokendpt(ep, &slot) != OK) return(EINVAL); - if (pathlen < UNIX_PATH_MAX || pathlen > PATH_MAX) return(EINVAL); + if (pathlen < UNIX_PATH_MAX || pathlen >= PATH_MAX) return(EINVAL); rfp = &(fproc[slot]); - memset(canon_path, '\0', PATH_MAX+1); - r = sys_safecopyfrom(PFS_PROC_NR, io_gr, (vir_bytes) 0, - (vir_bytes) temp_path, pathlen, D); + (vir_bytes) canon_path, pathlen, D); if (r != OK) return(r); + canon_path[pathlen] = '\0'; - temp_path[pathlen] = '\0'; - - /* save path from pfs before permissions checking modifies it */ - memcpy(orig_path, temp_path, PATH_MAX+1); - - /* get the canonical path to the socket file */ - if ((r = canonical_path(orig_path, canon_path, rfp)) != OK) + /* Turn path into canonical path to the socket file */ + if ((r = canonical_path(canon_path, rfp)) != OK) return(r); if (strlen(canon_path) >= pathlen) return(ENAMETOOLONG); /* copy canon_path back to PFS */ r = sys_safecopyto(PFS_PROC_NR, (cp_grant_id_t) io_gr, (vir_bytes) 0, - (vir_bytes) canon_path, strlen(canon_path)+1, - D); + (vir_bytes) canon_path, pathlen, D); if (r != OK) return(r); - /* reload user_fullpath for permissions checking */ - memcpy(temp_path, orig_path, PATH_MAX+1); - lookup_init(&resolve, temp_path, PATH_NOFLAGS, &vmp, &vp); + /* Now do permissions checking */ + lookup_init(&resolve, canon_path, PATH_NOFLAGS, &vmp, &vp); resolve.l_vmnt_lock = VMNT_READ; resolve.l_vnode_lock = VNODE_READ; - if ((vp = eat_path(&resolve, rfp)) == NULL) return(err_code); /* check permissions */ diff --git a/servers/avfs/protect.c b/servers/avfs/protect.c index 3f8c3838e..45df97349 100644 --- a/servers/avfs/protect.c +++ b/servers/avfs/protect.c @@ -31,7 +31,7 @@ PUBLIC int do_chmod() struct vmnt *vmp; int r; mode_t new_mode; - char fullpath[PATH_MAX+1]; + char fullpath[PATH_MAX]; struct lookup resolve; flp = NULL; @@ -98,7 +98,7 @@ PUBLIC int do_chown() uid_t uid; gid_t gid; mode_t new_mode; - char fullpath[PATH_MAX+1]; + char fullpath[PATH_MAX]; struct lookup resolve; flp = NULL; @@ -182,7 +182,7 @@ PUBLIC int do_access() int r; struct vnode *vp; struct vmnt *vmp; - char fullpath[PATH_MAX+1]; + char fullpath[PATH_MAX]; struct lookup resolve; lookup_init(&resolve, fullpath, PATH_NOFLAGS, &vmp, &vp); diff --git a/servers/avfs/proto.h b/servers/avfs/proto.h index 54eb107a3..d0c51b14a 100644 --- a/servers/avfs/proto.h +++ b/servers/avfs/proto.h @@ -174,8 +174,7 @@ _PROTOTYPE( void lookup_init, (struct lookup *resolve, char *path, int flags, struct vmnt **vmp, struct vnode **vp) ); _PROTOTYPE( int get_name, (struct vnode *dirp, struct vnode *entry, char *_name) ); -_PROTOTYPE( int canonical_path, (char *orig_path, char *canon_path, - struct fproc *rfp) ); +_PROTOTYPE( int canonical_path, (char *orig_path, struct fproc *rfp) ); _PROTOTYPE( int do_check_perms, (void) ); /* pipe.c */ diff --git a/servers/avfs/request.c b/servers/avfs/request.c index 233601777..25e309213 100644 --- a/servers/avfs/request.c +++ b/servers/avfs/request.c @@ -389,7 +389,7 @@ PUBLIC int req_lookup( vfs_ucred_t credentials; int flags; - grant_id = cpf_grant_direct(fs_e, (vir_bytes) resolve->l_path, PATH_MAX+1, + grant_id = cpf_grant_direct(fs_e, (vir_bytes) resolve->l_path, PATH_MAX, CPF_READ | CPF_WRITE); if(grant_id == -1) panic("req_lookup: cpf_grant_direct failed"); diff --git a/servers/avfs/stadir.c b/servers/avfs/stadir.c index fbc8fa088..ec8920b71 100644 --- a/servers/avfs/stadir.c +++ b/servers/avfs/stadir.c @@ -78,7 +78,7 @@ int len; /* length of the directory name string */ /* Do the actual work for chdir() and chroot(). */ struct vnode *vp; struct vmnt *vmp; - char fullpath[PATH_MAX+1]; + char fullpath[PATH_MAX]; struct lookup resolve; int r; @@ -130,7 +130,7 @@ PUBLIC int do_stat() int r; struct vnode *vp; struct vmnt *vmp; - char fullpath[PATH_MAX+1]; + char fullpath[PATH_MAX]; struct lookup resolve; int old_stat = 0; @@ -215,7 +215,7 @@ PUBLIC int do_statvfs() int r; struct vnode *vp; struct vmnt *vmp; - char fullpath[PATH_MAX+1]; + char fullpath[PATH_MAX]; struct lookup resolve; lookup_init(&resolve, fullpath, PATH_NOFLAGS, &vmp, &vp); @@ -263,7 +263,7 @@ PUBLIC int do_lstat() struct vnode *vp; struct vmnt *vmp; int r; - char fullpath[PATH_MAX+1]; + char fullpath[PATH_MAX]; struct lookup resolve; int old_stat = 0; diff --git a/servers/avfs/time.c b/servers/avfs/time.c index 315fc4b78..77892808d 100644 --- a/servers/avfs/time.c +++ b/servers/avfs/time.c @@ -26,7 +26,7 @@ PUBLIC int do_utime() time_t actime, modtime; struct vnode *vp; struct vmnt *vmp; - char fullpath[PATH_MAX+1]; + char fullpath[PATH_MAX]; struct lookup resolve; lookup_init(&resolve, fullpath, PATH_NOFLAGS, &vmp, &vp); diff --git a/servers/avfs/utility.c b/servers/avfs/utility.c index 5ff6fd134..71922d84a 100644 --- a/servers/avfs/utility.c +++ b/servers/avfs/utility.c @@ -38,7 +38,7 @@ char *dest; /* pointer to where path is to be stored */ register char *rpu, *rpm; int r, count; - if (len > PATH_MAX) { + if (len > PATH_MAX) { /* 'len' includes terminating-nul */ err_code = ENAMETOOLONG; return(EGENERIC); } diff --git a/servers/mfs/glo.h b/servers/mfs/glo.h index 1cfb0355f..8b381b21f 100644 --- a/servers/mfs/glo.h +++ b/servers/mfs/glo.h @@ -31,7 +31,7 @@ EXTERN int req_nr; EXTERN endpoint_t SELF_E; -EXTERN char user_path[PATH_MAX+1]; /* pathname to be processed */ +EXTERN char user_path[PATH_MAX]; /* pathname to be processed */ EXTERN dev_t fs_dev; /* The device that is handled by this FS proc. */ diff --git a/servers/vfs/fscall.c b/servers/vfs/fscall.c index 249c41efc..dc758f555 100644 --- a/servers/vfs/fscall.c +++ b/servers/vfs/fscall.c @@ -27,7 +27,7 @@ PRIVATE struct { int g_who_p; /* slot number of caller process */ int g_call_nr; /* call number */ int g_super_user; /* is the caller root? */ - char g_user_fullpath[PATH_MAX+1]; /* path to look up */ + char g_user_fullpath[PATH_MAX]; /* path to look up */ } globals[MAX_DEPTH]; PRIVATE int depth = 0; /* current globals stack level */ diff --git a/servers/vfs/glo.h b/servers/vfs/glo.h index 852218295..8df434d5d 100644 --- a/servers/vfs/glo.h +++ b/servers/vfs/glo.h @@ -24,7 +24,7 @@ EXTERN int call_nr; /* system call number */ EXTERN message mount_m_in; /* the input message for a mount request */ EXTERN char mount_label[LABEL_MAX]; /* label of file system to mount */ -EXTERN char user_fullpath[PATH_MAX+1]; /* storage for user path name */ +EXTERN char user_fullpath[PATH_MAX]; /* storage for user path name */ /* The following variables are used for returning results to the caller. */ EXTERN int err_code; /* temporary storage for error number */ diff --git a/servers/vfs/link.c b/servers/vfs/link.c index 9be281c36..4000097e8 100644 --- a/servers/vfs/link.c +++ b/servers/vfs/link.c @@ -125,7 +125,7 @@ PUBLIC int do_rename() /* Perform the rename(name1, name2) system call. */ int r = OK, r1; struct vnode *old_dirp, *new_dirp = NULL, *vp; - char old_name[PATH_MAX+1]; + char old_name[PATH_MAX]; /* See if 'name1' (existing file) exists. Get dir and file inodes. */ if(fetch_name(m_in.name1, m_in.name1_length, M1) != OK) return(err_code); @@ -276,7 +276,7 @@ PUBLIC int do_slink() *===========================================================================*/ PUBLIC int rdlink_direct(orig_path, link_path, rfp) char *orig_path; -char *link_path; /* should have length PATH_MAX+1 */ +char *link_path; /* should have length PATH_MAX */ struct fproc *rfp; { /* Perform a readlink()-like call from within the VFS */ @@ -284,6 +284,7 @@ struct fproc *rfp; struct vnode *vp; /* Temporarily open the file containing the symbolic link */ + orig_path[PATH_MAX - 1] = '\0'; strncpy(user_fullpath, orig_path, PATH_MAX); if ((vp = eat_path(PATH_RET_SYMLINK, rfp)) == NULL) return(err_code); @@ -292,7 +293,7 @@ struct fproc *rfp; r = EINVAL; else r = req_rdlink(vp->v_fs_e, vp->v_inode_nr, (endpoint_t) 0, - link_path, PATH_MAX+1, 1); + link_path, PATH_MAX - 1, 1); if (r > 0) link_path[r] = '\0'; put_vnode(vp); diff --git a/servers/vfs/path.c b/servers/vfs/path.c index c0ddceb44..a58fd0b08 100644 --- a/servers/vfs/path.c +++ b/servers/vfs/path.c @@ -119,7 +119,7 @@ struct fproc *rfp; size_t len; char *cp; - char dir_entry[PATH_MAX+1]; + char dir_entry[NAME_MAX+1]; struct vnode *vp, *res; /* Is the path absolute or relative? Initialize 'vp' accordingly. */ @@ -151,8 +151,9 @@ struct fproc *rfp; strcpy(dir_entry, "."); } else { /* A path name for the directory and a directory entry */ - strcpy(dir_entry, cp+1); + strncpy(dir_entry, cp+1, NAME_MAX); cp[1]= '\0'; + dir_entry[NAME_MAX] = '\0'; } /* Remove trailing slashes */ @@ -165,7 +166,7 @@ struct fproc *rfp; if (res == NULL) return(NULL); /* Copy the directory entry back to user_fullpath */ - strcpy(user_fullpath, dir_entry); + strncpy(user_fullpath, dir_entry, NAME_MAX); return(res); } @@ -362,16 +363,17 @@ char ename[NAME_MAX + 1]; *===========================================================================*/ PUBLIC int canonical_path(orig_path, canon_path, rfp) char *orig_path; -char *canon_path; /* should have length PATH_MAX+1 */ +char *canon_path; /* should have length PATH_MAX */ struct fproc *rfp; { int len = 0; int r, symloop = 0; struct vnode *dir_vp, *parent_dir; char component[NAME_MAX+1]; - char link_path[PATH_MAX+1]; + char link_path[PATH_MAX]; dir_vp = NULL; + orig_path[PATH_MAX - 1] = '\0'; strncpy(user_fullpath, orig_path, PATH_MAX); do { @@ -429,7 +431,7 @@ struct fproc *rfp; } len += strlen(component) + 1; - if (len > PATH_MAX) { + if (len >= PATH_MAX) { /* adding the component to canon_path would exceed PATH_MAX */ put_vnode(dir_vp); put_vnode(parent_dir); @@ -476,16 +478,16 @@ int pathlen; int r, i; struct vnode *vp; struct fproc *rfp; - char orig_path[PATH_MAX+1]; - char canon_path[PATH_MAX+1]; + char orig_path[PATH_MAX]; + char canon_path[PATH_MAX]; i = _ENDPOINT_P(ep); - if (pathlen < UNIX_PATH_MAX || pathlen > PATH_MAX || i < 0 || i >= NR_PROCS) { + if (pathlen < UNIX_PATH_MAX || pathlen >= PATH_MAX || i < 0 || i >= NR_PROCS) return EINVAL; - } + rfp = &(fproc[i]); - memset(canon_path, '\0', PATH_MAX+1); + memset(canon_path, '\0', PATH_MAX); r = sys_safecopyfrom(PFS_PROC_NR, io_gr, (vir_bytes) 0, (vir_bytes) &user_fullpath, pathlen, D); @@ -495,7 +497,7 @@ int pathlen; user_fullpath[pathlen] = '\0'; /* save path from pfs before permissions checking modifies it */ - memcpy(orig_path, user_fullpath, PATH_MAX+1); + memcpy(orig_path, user_fullpath, PATH_MAX); /* get the canonical path to the socket file */ r = canonical_path(orig_path, canon_path, rfp); @@ -516,7 +518,7 @@ int pathlen; } /* reload user_fullpath for permissions checking */ - memcpy(user_fullpath, orig_path, PATH_MAX+1); + memcpy(user_fullpath, orig_path, PATH_MAX); if ((vp = eat_path(PATH_NOFLAGS, rfp)) == NULL) { return(err_code); } diff --git a/servers/vfs/utility.c b/servers/vfs/utility.c index eb91d011e..79227fb52 100644 --- a/servers/vfs/utility.c +++ b/servers/vfs/utility.c @@ -37,12 +37,12 @@ int flag; /* M3 means path may be in message */ register char *rpu, *rpm; int r, count; - if (len > PATH_MAX) { + if (len > PATH_MAX) { /* 'len' includes terminating-nul */ err_code = ENAMETOOLONG; return(EGENERIC); } - if(len >= sizeof(user_fullpath)) + if (len > sizeof(user_fullpath)) panic("fetch_name: len too much for user_fullpath: %d", len); /* Check name length for validity. */ -- 2.44.0