diff options
author | peter <peter@FreeBSD.org> | 2001-08-29 11:47:53 +0000 |
---|---|---|
committer | peter <peter@FreeBSD.org> | 2001-08-29 11:47:53 +0000 |
commit | 701291bbfe7ed3214779d9767acfe38948cd000a (patch) | |
tree | 1ddf4252b9d5874d61477b972fa4898ce3d7815b /sys/kern/kern_sysctl.c | |
parent | 170a9793204b83be92235c069e25cb0c612bcbf4 (diff) | |
download | FreeBSD-src-701291bbfe7ed3214779d9767acfe38948cd000a.zip FreeBSD-src-701291bbfe7ed3214779d9767acfe38948cd000a.tar.gz |
Fix the ogetkerninfo() syscall handling of sizes for
KINFO_BSDI_SYSINFO. This supposedly fixes Netscape 3.0.4 (bsdi binary)
on -current. (and is also applicable to RELENG_4)
PR: 25476
Submitted by: Philipp Mergenthaler <un1i@rz.uni-karlsruhe.de>
Diffstat (limited to 'sys/kern/kern_sysctl.c')
-rw-r--r-- | sys/kern/kern_sysctl.c | 22 |
1 files changed, 12 insertions, 10 deletions
diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c index c165bb3..6397893 100644 --- a/sys/kern/kern_sysctl.c +++ b/sys/kern/kern_sysctl.c @@ -1237,6 +1237,7 @@ ogetkerninfo(struct proc *p, struct getkerninfo_args *uap) { int error, name[6]; size_t size; + u_int needed = 0; switch (uap->op & 0xff00) { @@ -1300,16 +1301,15 @@ ogetkerninfo(struct proc *p, struct getkerninfo_args *uap) * this is pretty crude, but it's just enough for uname() * from BSDI's 1.x libc to work. * - * In particular, it doesn't return the same results when - * the supplied buffer is too small. BSDI's version apparently - * will return the amount copied, and set the *size to how - * much was needed. The emulation framework here isn't capable - * of that, so we just set both to the amount copied. - * BSDI's 2.x product apparently fails with ENOMEM in this - * scenario. + * *size gives the size of the buffer before the call, and + * the amount of data copied after a successful call. + * If successful, the return value is the amount of data + * available, which can be larger than *size. + * + * BSDI's 2.x product apparently fails with ENOMEM if *size + * is too small. */ - u_int needed; u_int left; char *s; @@ -1332,13 +1332,15 @@ ogetkerninfo(struct proc *p, struct getkerninfo_args *uap) needed = sizeof(bsdi_si) + (s - bsdi_strings); - if (uap->where == NULL) { + if ((uap->where == NULL) || (uap->size == NULL)) { /* process is asking how much buffer to supply.. */ size = needed; error = 0; break; } + if ((error = copyin(uap->size, &size, sizeof(size))) != 0) + break; /* if too much buffer supplied, trim it down */ if (size > needed) @@ -1364,7 +1366,7 @@ ogetkerninfo(struct proc *p, struct getkerninfo_args *uap) } if (error) return (error); - p->p_retval[0] = size; + p->p_retval[0] = needed ? needed : size; if (uap->size) error = copyout((caddr_t)&size, (caddr_t)uap->size, sizeof(size)); |