From 7874d7a3bbf1c437cb066cc45bd152d33663ddc5 Mon Sep 17 00:00:00 2001 From: Poul-Henning Kamp Date: Mon, 15 Sep 1997 19:11:07 +0000 Subject: [PATCH] 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. --- sys/kern/vfs_extattr.c | 55 ++++++++++++++++++++++------------------- 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 01b980d6a2d..a2f1382b4d8 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 01b980d6a2d..a2f1382b4d8 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); }