diff options
author | phk <phk@FreeBSD.org> | 1997-09-15 19:11:07 +0000 |
---|---|---|
committer | phk <phk@FreeBSD.org> | 1997-09-15 19:11:07 +0000 |
commit | 869c60f487eb0d9eb86e84eac1870b40462f99e3 (patch) | |
tree | 3069519ae06fd5fb5f9112d54def3320e7143166 /sys | |
parent | e9ff6fa415854fb287567c0f9830f46ca52e7ddf (diff) | |
download | FreeBSD-src-869c60f487eb0d9eb86e84eac1870b40462f99e3.zip FreeBSD-src-869c60f487eb0d9eb86e84eac1870b40462f99e3.tar.gz |
Solve race-condition, return path in normal order.
A couple of stylistic nits from Bruce.
If your libc contains version 1.11 or 1.12 of getcwd.c, (ie: if
you recompiled libc one of the last couple of days):
>>> Recompile LIBC before you boot a new kernel <<<
A new libc will deal with both old and new kernels.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/kern/vfs_extattr.c | 55 | ||||
-rw-r--r-- | sys/kern/vfs_syscalls.c | 55 |
2 files changed, 58 insertions, 52 deletions
diff --git a/sys/kern/vfs_extattr.c b/sys/kern/vfs_extattr.c index 01b980d..a2f1382 100644 --- a/sys/kern/vfs_extattr.c +++ b/sys/kern/vfs_extattr.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)vfs_syscalls.c 8.13 (Berkeley) 4/15/94 - * $Id: vfs_syscalls.c,v 1.68 1997/09/14 16:51:15 phk Exp $ + * $Id: vfs_syscalls.c,v 1.69 1997/09/15 08:25:43 phk Exp $ */ /* @@ -2765,52 +2765,55 @@ getvnode(fdp, fd, fpp) } #ifndef _SYS_SYSPROTO_H_ struct __getcwd_args { - u_char * buf; - u_int buflen; + u_char *buf; + u_int buflen; }; #endif -/* ARGSUSED */ int __getcwd(p, uap, retval) struct proc *p; - register struct __getcwd_args *uap; + struct __getcwd_args *uap; register_t *retval; { - struct filedesc *fdp = p->p_fd; + struct filedesc *fdp; struct vnode *vp; struct namecache *ncp; - int i,j=0; + char *buf, *bp; + int i, j = 0, error = 0; + fdp = p->p_fd; + if (uap->buflen > PATH_MAX+1) + uap->buflen = PATH_MAX+1; + buf = bp = (char *)malloc(uap->buflen, M_TEMP, M_WAITOK); + bp += uap->buflen - 1; + *bp = '\0'; for (vp = fdp->fd_cdir; vp != fdp->fd_rdir && vp != rootvnode;) { if (vp->v_dd->v_id != vp->v_ddid) - return(ENOTDIR); + return (ENOTDIR); ncp = TAILQ_FIRST(&vp->v_cache_dst); if (!ncp) - return(ENOENT); + return (ENOENT); if (ncp->nc_dvp != vp->v_dd) - return(EBADF); - for (i=ncp->nc_nlen-1; i >= 0; i--) { - if (uap->buflen-- < 2) - return(ENOMEM); - subyte(uap->buf, ncp->nc_name[i]); - uap->buf++; + return (EBADF); + for (i=ncp->nc_nlen - 1; i >= 0; i--) { + if (bp <= buf) + return (ENOMEM); + *--bp = ncp->nc_name[i]; } - if (uap->buflen-- < 2) - return(ENOMEM); - subyte(uap->buf, '/' ); - uap->buf++; + if (bp <= buf) + return (ENOMEM); + *--bp = '/'; j++; vp = vp->v_dd; if (vp->v_flag & VROOT) vp = vp->v_mount->mnt_vnodecovered; } if (!j) { - if (uap->buflen-- < 2) - return(ENOMEM); - subyte(uap->buf, '/' ); - uap->buf++; + if (bp <= buf) + return (ENOMEM); + *--bp = '/'; } - subyte(uap->buf, '\0' ); - uap->buf++; - return (0); + error = copyout(bp, uap->buf, strlen(bp) + 1); + free(buf, M_TEMP); + return (error); } diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 01b980d..a2f1382 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)vfs_syscalls.c 8.13 (Berkeley) 4/15/94 - * $Id: vfs_syscalls.c,v 1.68 1997/09/14 16:51:15 phk Exp $ + * $Id: vfs_syscalls.c,v 1.69 1997/09/15 08:25:43 phk Exp $ */ /* @@ -2765,52 +2765,55 @@ getvnode(fdp, fd, fpp) } #ifndef _SYS_SYSPROTO_H_ struct __getcwd_args { - u_char * buf; - u_int buflen; + u_char *buf; + u_int buflen; }; #endif -/* ARGSUSED */ int __getcwd(p, uap, retval) struct proc *p; - register struct __getcwd_args *uap; + struct __getcwd_args *uap; register_t *retval; { - struct filedesc *fdp = p->p_fd; + struct filedesc *fdp; struct vnode *vp; struct namecache *ncp; - int i,j=0; + char *buf, *bp; + int i, j = 0, error = 0; + fdp = p->p_fd; + if (uap->buflen > PATH_MAX+1) + uap->buflen = PATH_MAX+1; + buf = bp = (char *)malloc(uap->buflen, M_TEMP, M_WAITOK); + bp += uap->buflen - 1; + *bp = '\0'; for (vp = fdp->fd_cdir; vp != fdp->fd_rdir && vp != rootvnode;) { if (vp->v_dd->v_id != vp->v_ddid) - return(ENOTDIR); + return (ENOTDIR); ncp = TAILQ_FIRST(&vp->v_cache_dst); if (!ncp) - return(ENOENT); + return (ENOENT); if (ncp->nc_dvp != vp->v_dd) - return(EBADF); - for (i=ncp->nc_nlen-1; i >= 0; i--) { - if (uap->buflen-- < 2) - return(ENOMEM); - subyte(uap->buf, ncp->nc_name[i]); - uap->buf++; + return (EBADF); + for (i=ncp->nc_nlen - 1; i >= 0; i--) { + if (bp <= buf) + return (ENOMEM); + *--bp = ncp->nc_name[i]; } - if (uap->buflen-- < 2) - return(ENOMEM); - subyte(uap->buf, '/' ); - uap->buf++; + if (bp <= buf) + return (ENOMEM); + *--bp = '/'; j++; vp = vp->v_dd; if (vp->v_flag & VROOT) vp = vp->v_mount->mnt_vnodecovered; } if (!j) { - if (uap->buflen-- < 2) - return(ENOMEM); - subyte(uap->buf, '/' ); - uap->buf++; + if (bp <= buf) + return (ENOMEM); + *--bp = '/'; } - subyte(uap->buf, '\0' ); - uap->buf++; - return (0); + error = copyout(bp, uap->buf, strlen(bp) + 1); + free(buf, M_TEMP); + return (error); } |