From owner-svn-src-stable-7@FreeBSD.ORG Thu Oct 30 13:14:45 2008 Return-Path: Delivered-To: svn-src-stable-7@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id D7AE21065672; Thu, 30 Oct 2008 13:14:45 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id C32798FC16; Thu, 30 Oct 2008 13:14:45 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id m9UDEjwP052286; Thu, 30 Oct 2008 13:14:45 GMT (envelope-from jhb@svn.freebsd.org) Received: (from jhb@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id m9UDEjMp052282; Thu, 30 Oct 2008 13:14:45 GMT (envelope-from jhb@svn.freebsd.org) Message-Id: <200810301314.m9UDEjMp052282@svn.freebsd.org> From: John Baldwin Date: Thu, 30 Oct 2008 13:14:45 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org X-SVN-Group: stable-7 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r184469 - in stable/7/sys: . compat/freebsd32 kern sys X-BeenThere: svn-src-stable-7@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for only the 7-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 30 Oct 2008 13:14:46 -0000 Author: jhb Date: Thu Oct 30 13:14:45 2008 New Revision: 184469 URL: http://svn.freebsd.org/changeset/base/184469 Log: MFC: Split most of getdirentries() out into a kern_getdirentries() and add a freebsd32 frontend to fix a data corruption bug with 32-bit binaries. Approved by: re (kib) Modified: stable/7/sys/ (props changed) stable/7/sys/compat/freebsd32/freebsd32_misc.c stable/7/sys/compat/freebsd32/syscalls.master stable/7/sys/kern/vfs_syscalls.c stable/7/sys/sys/syscallsubr.h Modified: stable/7/sys/compat/freebsd32/freebsd32_misc.c ============================================================================== --- stable/7/sys/compat/freebsd32/freebsd32_misc.c Thu Oct 30 13:10:33 2008 (r184468) +++ stable/7/sys/compat/freebsd32/freebsd32_misc.c Thu Oct 30 13:14:45 2008 (r184469) @@ -1724,6 +1724,24 @@ freebsd32_ftruncate(struct thread *td, s return (ftruncate(td, &ap)); } +int +freebsd32_getdirentries(struct thread *td, + struct freebsd32_getdirentries_args *uap) +{ + long base; + int32_t base32; + int error; + + error = kern_getdirentries(td, uap->fd, uap->buf, uap->count, &base); + if (error) + return (error); + if (uap->basep != NULL) { + base32 = base; + error = copyout(&base32, uap->basep, sizeof(int32_t)); + } + return (error); +} + #ifdef COMPAT_FREEBSD6 /* versions with the 'int pad' argument */ int Modified: stable/7/sys/compat/freebsd32/syscalls.master ============================================================================== --- stable/7/sys/compat/freebsd32/syscalls.master Thu Oct 30 13:10:33 2008 (r184468) +++ stable/7/sys/compat/freebsd32/syscalls.master Thu Oct 30 13:14:45 2008 (r184469) @@ -350,8 +350,8 @@ 195 AUE_SETRLIMIT NOPROTO { int setrlimit(u_int which, \ struct rlimit *rlp); } setrlimit \ __setrlimit_args int -196 AUE_GETDIRENTRIES NOPROTO { int getdirentries(int fd, char *buf, \ - u_int count, long *basep); } +196 AUE_GETDIRENTRIES STD { int freebsd32_getdirentries(int fd, \ + char *buf, u_int count, int32_t *basep); } 197 AUE_MMAP COMPAT6 { caddr_t freebsd32_mmap(caddr_t addr, \ size_t len, int prot, int flags, int fd, \ int pad, u_int32_t poslo, \ Modified: stable/7/sys/kern/vfs_syscalls.c ============================================================================== --- stable/7/sys/kern/vfs_syscalls.c Thu Oct 30 13:10:33 2008 (r184468) +++ stable/7/sys/kern/vfs_syscalls.c Thu Oct 30 13:14:45 2008 (r184469) @@ -3761,6 +3761,21 @@ getdirentries(td, uap) long *basep; } */ *uap; { + long base; + int error; + + error = kern_getdirentries(td, uap->fd, uap->buf, uap->count, &base); + if (error) + return (error); + if (uap->basep != NULL) + error = copyout(&base, uap->basep, sizeof(long)); + return (error); +} + +int +kern_getdirentries(struct thread *td, int fd, char *buf, u_int count, + long *basep) +{ struct vnode *vp; struct file *fp; struct uio auio; @@ -3769,8 +3784,8 @@ getdirentries(td, uap) long loff; int error, eofflag; - AUDIT_ARG(fd, uap->fd); - if ((error = getvnode(td->td_proc->p_fd, uap->fd, &fp)) != 0) + AUDIT_ARG(fd, fd); + if ((error = getvnode(td->td_proc->p_fd, fd, &fp)) != 0) return (error); if ((fp->f_flag & FREAD) == 0) { fdrop(fp, td); @@ -3784,14 +3799,14 @@ unionread: error = EINVAL; goto fail; } - aiov.iov_base = uap->buf; - aiov.iov_len = uap->count; + aiov.iov_base = buf; + aiov.iov_len = count; auio.uio_iov = &aiov; auio.uio_iovcnt = 1; auio.uio_rw = UIO_READ; auio.uio_segflg = UIO_USERSPACE; auio.uio_td = td; - auio.uio_resid = uap->count; + auio.uio_resid = count; /* vn_lock(vp, LK_SHARED | LK_RETRY, td); */ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); AUDIT_ARG(vnode, vp, ARG_VNODE1); @@ -3808,7 +3823,7 @@ unionread: VFS_UNLOCK_GIANT(vfslocked); goto fail; } - if (uap->count == auio.uio_resid && + if (count == auio.uio_resid && (vp->v_vflag & VV_ROOT) && (vp->v_mount->mnt_flag & MNT_UNION)) { struct vnode *tvp = vp; @@ -3823,10 +3838,8 @@ unionread: } VOP_UNLOCK(vp, 0, td); VFS_UNLOCK_GIANT(vfslocked); - if (uap->basep != NULL) { - error = copyout(&loff, uap->basep, sizeof(long)); - } - td->td_retval[0] = uap->count - auio.uio_resid; + *basep = loff; + td->td_retval[0] = count - auio.uio_resid; fail: fdrop(fp, td); return (error); Modified: stable/7/sys/sys/syscallsubr.h ============================================================================== --- stable/7/sys/sys/syscallsubr.h Thu Oct 30 13:10:33 2008 (r184468) +++ stable/7/sys/sys/syscallsubr.h Thu Oct 30 13:14:45 2008 (r184469) @@ -84,6 +84,8 @@ int kern_fstat(struct thread *td, int fd int kern_fstatfs(struct thread *td, int fd, struct statfs *buf); int kern_futimes(struct thread *td, int fd, struct timeval *tptr, enum uio_seg tptrseg); +int kern_getdirentries(struct thread *td, int fd, char *buf, u_int count, + long *basep); int kern_getfsstat(struct thread *td, struct statfs **buf, size_t bufsize, enum uio_seg bufseg, int flags); int kern_getgroups(struct thread *td, u_int *ngrp, gid_t *groups);