As Philipp Mergenthaler wrote:

> I saw something like this some time ago, too.  In my case it was
> because in kern_sysctl:ogetkerninfo(), in "case KINFO_BSDI_SYSINFO:",
> the variable "size" is not always given a value.  Maybe the patch in
> http://www.FreeBSD.org/cgi/query-pr.cgi?pr=25476
> fixes it for you, too?

Yep.

> (Hm, now I think my patch could need a comment: "size" will only be
> returned if needed==0.  There are two ways this can happen:

After taking a look at the BSD/OS source code (which we are now
allowed to do), i decided to slightly modify the patch.  Here's the
result for review.

Index: kern_sysctl.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/kern_sysctl.c,v
retrieving revision 1.112
diff -u -r1.112 kern_sysctl.c
--- kern_sysctl.c       25 Jul 2001 17:21:15 -0000      1.112
+++ kern_sysctl.c       30 Aug 2001 20:34:57 -0000
@@ -1237,6 +1237,7 @@
 {
        int error, name[6];
        size_t size;
+       u_int needed = 0;
 
        switch (uap->op & 0xff00) {
 
@@ -1300,16 +1301,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;
 
@@ -1338,11 +1338,13 @@
                        error = 0;
                        break;
                }
-
-
-               /* if too much buffer supplied, trim it down */
-               if (size > needed)
-                       size = needed;
+               if ((error = copyin(uap->size, &size, sizeof(size))) != 0)
+                       break;
+               if (size < needed) {
+                       error = ENOMEM;
+                       break;
+               }
+               size = needed;
 
                /* how much of the buffer is remaining */
                left = size;
@@ -1364,7 +1366,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));

-- 
cheers, J"org               .-.-.   --... ...--   -.. .  DL8DTL

http://www.sax.de/~joerg/                        NIC: JW11-RIPE
Never trust an operating system you don't have sources for. ;-)

To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-current" in the body of the message

Reply via email to