From 327ae6eb3a1a8aa10419a446a94f60c35996d868 Mon Sep 17 00:00:00 2001 From: jhb Date: Wed, 22 Oct 2008 21:55:48 +0000 Subject: Split the copyout of *base at the end of getdirentries() out leaving the rest in kern_getdirentries(). Use kern_getdirentries() to implement freebsd32_getdirentries(). This fixes a bug where calls to getdirentries() in 32-bit binaries would trash the 4 bytes after the 'long base' in userland. Submitted by: ups MFC after: 1 week --- sys/compat/freebsd32/freebsd32_misc.c | 18 ++++++++++++++++++ sys/compat/freebsd32/syscalls.master | 4 ++-- 2 files changed, 20 insertions(+), 2 deletions(-) (limited to 'sys/compat') diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c index 4c89d74..f75c9af 100644 --- a/sys/compat/freebsd32/freebsd32_misc.c +++ b/sys/compat/freebsd32/freebsd32_misc.c @@ -1762,6 +1762,24 @@ freebsd32_ftruncate(struct thread *td, struct freebsd32_ftruncate_args *uap) 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 diff --git a/sys/compat/freebsd32/syscalls.master b/sys/compat/freebsd32/syscalls.master index 0e70981..fa9cbd2 100644 --- a/sys/compat/freebsd32/syscalls.master +++ b/sys/compat/freebsd32/syscalls.master @@ -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, \ -- cgit v1.1