Date: Thu, 1 Mar 2001 16:09:41 +0100 (CET) From: un1i@rz.uni-karlsruhe.de To: FreeBSD-gnats-submit@freebsd.org Subject: kern/25476: [PATCH] The syscall oldgetkerninfo can return bogus values. Message-ID: <200103011509.f21F9fl01218@i609.hadiko.de>
next in thread | raw e-mail | index | archive | help
>Number: 25476 >Category: kern >Synopsis: [PATCH] The syscall oldgetkerninfo can return bogus values. >Confidential: no >Severity: serious >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Thu Mar 01 07:20:01 PST 2001 >Closed-Date: >Last-Modified: >Originator: Philipp Mergenthaler >Release: FreeBSD 5.0-CURRENT i386 >Organization: University of Karlsruhe, Germany >Environment: System: FreeBSD i609.hadiko.de 5.0-CURRENT FreeBSD 5.0-CURRENT #340: Thu Mar 1 15:04:58 CET 2001 p@i609.hadiko.de:/neu/obj/usr/src/sys/I609 i386 (The bug has been there since this code's introduction in 1995. The patch also applies to RELENG_4, Revision 1.92.2.4 ) >Description: In src/sys/kern/kern_sysctl: ogetkerninfo(), in "case KINFO_BSDI_SYSINFO:", the variable size is used without being initialized. Depending on what value it happens to have, the parameter *size may be set to a bogus value. On my system, this causes Netscape-3.04 to crash. Second, the return value shouldn't be the amount of information copied, but the amount available (which canbe larger). See the BSDI man page, e.g.: http://www.neosoft.com/neosoft/man/getkerninfo.2.html >How-To-Repeat: (I can give my kernel configuration file, if wanted. But whether this variable happens to have a value that causes Netscape to crash, or not, is apparently somewhat random. Considering that this bug hasn't been fixed for so long, it is probably quite seldom :-) ) >Fix: -Initialize size. -Fix the return value for this case and adjust the comment. Index: kern_sysctl.c =================================================================== RCS file: /ncvs/src/sys/kern/kern_sysctl.c,v retrieving revision 1.105 diff -u -r1.105 kern_sysctl.c --- kern_sysctl.c 2001/02/04 13:12:22 1.105 +++ kern_sysctl.c 2001/03/01 14:58:26 @@ -1217,6 +1217,7 @@ { int error, name[6]; size_t size; + u_int needed = 0; switch (uap->op & 0xff00) { @@ -1280,16 +1281,15 @@ * 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; @@ -1312,13 +1312,15 @@ 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) @@ -1344,7 +1346,7 @@ } 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)); >Release-Note: >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200103011509.f21F9fl01218>