1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-10-19 02:29:40 +00:00

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.
This commit is contained in:
Poul-Henning Kamp 1997-09-15 19:11:07 +00:00
parent 36dff60096
commit 7874d7a3bb
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=29477
2 changed files with 58 additions and 52 deletions

View File

@ -36,7 +36,7 @@
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* @(#)vfs_syscalls.c 8.13 (Berkeley) 4/15/94 * @(#)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_ #ifndef _SYS_SYSPROTO_H_
struct __getcwd_args { struct __getcwd_args {
u_char * buf; u_char *buf;
u_int buflen; u_int buflen;
}; };
#endif #endif
/* ARGSUSED */
int int
__getcwd(p, uap, retval) __getcwd(p, uap, retval)
struct proc *p; struct proc *p;
register struct __getcwd_args *uap; struct __getcwd_args *uap;
register_t *retval; register_t *retval;
{ {
struct filedesc *fdp = p->p_fd; struct filedesc *fdp;
struct vnode *vp; struct vnode *vp;
struct namecache *ncp; 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;) { for (vp = fdp->fd_cdir; vp != fdp->fd_rdir && vp != rootvnode;) {
if (vp->v_dd->v_id != vp->v_ddid) if (vp->v_dd->v_id != vp->v_ddid)
return(ENOTDIR); return (ENOTDIR);
ncp = TAILQ_FIRST(&vp->v_cache_dst); ncp = TAILQ_FIRST(&vp->v_cache_dst);
if (!ncp) if (!ncp)
return(ENOENT); return (ENOENT);
if (ncp->nc_dvp != vp->v_dd) if (ncp->nc_dvp != vp->v_dd)
return(EBADF); return (EBADF);
for (i=ncp->nc_nlen-1; i >= 0; i--) { for (i=ncp->nc_nlen - 1; i >= 0; i--) {
if (uap->buflen-- < 2) if (bp <= buf)
return(ENOMEM); return (ENOMEM);
subyte(uap->buf, ncp->nc_name[i]); *--bp = ncp->nc_name[i];
uap->buf++;
} }
if (uap->buflen-- < 2) if (bp <= buf)
return(ENOMEM); return (ENOMEM);
subyte(uap->buf, '/' ); *--bp = '/';
uap->buf++;
j++; j++;
vp = vp->v_dd; vp = vp->v_dd;
if (vp->v_flag & VROOT) if (vp->v_flag & VROOT)
vp = vp->v_mount->mnt_vnodecovered; vp = vp->v_mount->mnt_vnodecovered;
} }
if (!j) { if (!j) {
if (uap->buflen-- < 2) if (bp <= buf)
return(ENOMEM); return (ENOMEM);
subyte(uap->buf, '/' ); *--bp = '/';
uap->buf++;
} }
subyte(uap->buf, '\0' ); error = copyout(bp, uap->buf, strlen(bp) + 1);
uap->buf++; free(buf, M_TEMP);
return (0); return (error);
} }

View File

@ -36,7 +36,7 @@
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* @(#)vfs_syscalls.c 8.13 (Berkeley) 4/15/94 * @(#)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_ #ifndef _SYS_SYSPROTO_H_
struct __getcwd_args { struct __getcwd_args {
u_char * buf; u_char *buf;
u_int buflen; u_int buflen;
}; };
#endif #endif
/* ARGSUSED */
int int
__getcwd(p, uap, retval) __getcwd(p, uap, retval)
struct proc *p; struct proc *p;
register struct __getcwd_args *uap; struct __getcwd_args *uap;
register_t *retval; register_t *retval;
{ {
struct filedesc *fdp = p->p_fd; struct filedesc *fdp;
struct vnode *vp; struct vnode *vp;
struct namecache *ncp; 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;) { for (vp = fdp->fd_cdir; vp != fdp->fd_rdir && vp != rootvnode;) {
if (vp->v_dd->v_id != vp->v_ddid) if (vp->v_dd->v_id != vp->v_ddid)
return(ENOTDIR); return (ENOTDIR);
ncp = TAILQ_FIRST(&vp->v_cache_dst); ncp = TAILQ_FIRST(&vp->v_cache_dst);
if (!ncp) if (!ncp)
return(ENOENT); return (ENOENT);
if (ncp->nc_dvp != vp->v_dd) if (ncp->nc_dvp != vp->v_dd)
return(EBADF); return (EBADF);
for (i=ncp->nc_nlen-1; i >= 0; i--) { for (i=ncp->nc_nlen - 1; i >= 0; i--) {
if (uap->buflen-- < 2) if (bp <= buf)
return(ENOMEM); return (ENOMEM);
subyte(uap->buf, ncp->nc_name[i]); *--bp = ncp->nc_name[i];
uap->buf++;
} }
if (uap->buflen-- < 2) if (bp <= buf)
return(ENOMEM); return (ENOMEM);
subyte(uap->buf, '/' ); *--bp = '/';
uap->buf++;
j++; j++;
vp = vp->v_dd; vp = vp->v_dd;
if (vp->v_flag & VROOT) if (vp->v_flag & VROOT)
vp = vp->v_mount->mnt_vnodecovered; vp = vp->v_mount->mnt_vnodecovered;
} }
if (!j) { if (!j) {
if (uap->buflen-- < 2) if (bp <= buf)
return(ENOMEM); return (ENOMEM);
subyte(uap->buf, '/' ); *--bp = '/';
uap->buf++;
} }
subyte(uap->buf, '\0' ); error = copyout(bp, uap->buf, strlen(bp) + 1);
uap->buf++; free(buf, M_TEMP);
return (0); return (error);
} }