summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_sysctl.c
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>2001-08-29 11:47:53 +0000
committerpeter <peter@FreeBSD.org>2001-08-29 11:47:53 +0000
commit701291bbfe7ed3214779d9767acfe38948cd000a (patch)
tree1ddf4252b9d5874d61477b972fa4898ce3d7815b /sys/kern/kern_sysctl.c
parent170a9793204b83be92235c069e25cb0c612bcbf4 (diff)
downloadFreeBSD-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.c22
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));
OpenPOWER on IntegriCloud