svn commit: r187537 - in stable/6/sys: . compat/freebsd32 kern sys
John Baldwin
jhb at FreeBSD.org
Wed Jan 21 09:03:56 PST 2009
Author: jhb
Date: Wed Jan 21 17:03:55 2009
New Revision: 187537
URL: http://svn.freebsd.org/changeset/base/187537
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.
Modified:
stable/6/sys/ (props changed)
stable/6/sys/compat/freebsd32/freebsd32_misc.c
stable/6/sys/compat/freebsd32/syscalls.master
stable/6/sys/kern/vfs_syscalls.c
stable/6/sys/sys/syscallsubr.h
Modified: stable/6/sys/compat/freebsd32/freebsd32_misc.c
==============================================================================
--- stable/6/sys/compat/freebsd32/freebsd32_misc.c Wed Jan 21 16:28:15 2009 (r187536)
+++ stable/6/sys/compat/freebsd32/freebsd32_misc.c Wed Jan 21 17:03:55 2009 (r187537)
@@ -1702,6 +1702,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);
+}
+
struct sf_hdtr32 {
uint32_t headers;
int hdr_cnt;
Modified: stable/6/sys/compat/freebsd32/syscalls.master
==============================================================================
--- stable/6/sys/compat/freebsd32/syscalls.master Wed Jan 21 16:28:15 2009 (r187536)
+++ stable/6/sys/compat/freebsd32/syscalls.master Wed Jan 21 17:03:55 2009 (r187537)
@@ -355,8 +355,8 @@
195 AUE_SETRLIMIT MNOPROTO { int setrlimit(u_int which, \
struct rlimit *rlp); } setrlimit \
__setrlimit_args int
-196 AUE_GETDIRENTRIES MNOPROTO { int getdirentries(int fd, char *buf, \
- u_int count, long *basep); }
+196 AUE_GETDIRENTRIES MSTD { int freebsd32_getdirentries(int fd, \
+ char *buf, u_int count, int32_t *basep); }
197 AUE_MMAP MSTD { caddr_t freebsd32_mmap(caddr_t addr, \
size_t len, int prot, int flags, int fd, \
int pad, u_int32_t poslo, \
Modified: stable/6/sys/kern/vfs_syscalls.c
==============================================================================
--- stable/6/sys/kern/vfs_syscalls.c Wed Jan 21 16:28:15 2009 (r187536)
+++ stable/6/sys/kern/vfs_syscalls.c Wed Jan 21 17:03:55 2009 (r187537)
@@ -3688,6 +3688,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;
@@ -3696,10 +3711,10 @@ getdirentries(td, uap)
long loff;
int error, eofflag;
- AUDIT_ARG(fd, uap->fd);
+ AUDIT_ARG(fd, fd);
if (uap->count > INT_MAX)
return (EINVAL);
- if ((error = getvnode(td->td_proc->p_fd, uap->fd, &fp)) != 0)
+ if ((error = getvnode(td->td_proc->p_fd, fd, &fp)) != 0)
return (error);
if ((fp->f_flag & FREAD) == 0) {
fdrop(fp, td);
@@ -3713,14 +3728,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);
@@ -3737,7 +3752,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;
@@ -3752,10 +3767,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/6/sys/sys/syscallsubr.h
==============================================================================
--- stable/6/sys/sys/syscallsubr.h Wed Jan 21 16:28:15 2009 (r187536)
+++ stable/6/sys/sys/syscallsubr.h Wed Jan 21 17:03:55 2009 (r187537)
@@ -79,6 +79,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_getitimer(struct thread *, u_int, struct itimerval *);
More information about the svn-src-stable-6
mailing list