* foreachaddr.c (SLOP): New macro.
authorKen Raeburn <raeburn@mit.edu>
Wed, 6 Mar 2002 01:20:45 +0000 (01:20 +0000)
committerKen Raeburn <raeburn@mit.edu>
Wed, 6 Mar 2002 01:20:45 +0000 (01:20 +0000)
(foreach_localaddr): Use it as the amount of extra space we look for past the
ifreq structures actually filled in.  Add SLOP to the size of the buffer
allocated to hold the ifreq structures.  Place an upper bound on the buffer
size.  Don't crash if the returned ifc_len is larger than the supplied buffer
size.

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@14226 dc483132-0cff-0310-8789-dd5450dbe970

src/include/ChangeLog
src/include/foreachaddr.c

index 9e5d7a358a836a037fd8a14c37e6aad01d7d0ed0..b76eee76248346e86821d7a56fa2d48c29f1b3bd 100644 (file)
@@ -1,3 +1,12 @@
+2002-03-05  Ken Raeburn  <raeburn@mit.edu>
+
+       * foreachaddr.c (SLOP): New macro.
+       (foreach_localaddr): Use it as the amount of extra space we look
+       for past the ifreq structures actually filled in.  Add SLOP to the
+       size of the buffer allocated to hold the ifreq structures.  Place
+       an upper bound on the buffer size.  Don't crash if the returned
+       ifc_len is larger than the supplied buffer size.
+
 2002-02-22  Ken Raeburn  <raeburn@mit.edu>
 
        * krb5.hin, k5-int.h: Use const instead of krb5_const.
index 07a2a0e0ad39ad158b554cf3a75dd15eae2f033a..3c3adad52204eed9d8afecb96c9452b911b79166 100644 (file)
@@ -594,6 +594,8 @@ punt:
 
 #else /* not defined (SIOCGLIFNUM) */
 
+#define SLOP (sizeof (struct ifreq) + 128)
+
 static int
 foreach_localaddr (/*@null@*/ void *data,
                   int (*pass1fn) (/*@null@*/ void *, struct sockaddr *) /*@*/,
@@ -642,7 +644,7 @@ foreach_localaddr (/*@null@*/ void *data,
        est_if_count = numifs;
 #endif
     if (current_buf_size == 0)
-       current_buf_size = est_ifreq_size * est_if_count;
+       current_buf_size = est_ifreq_size * est_if_count + SLOP;
     buf = malloc (current_buf_size);
     if (buf == NULL)
        return errno;
@@ -663,17 +665,21 @@ foreach_localaddr (/*@null@*/ void *data,
        the only indication we get, complicated by the fact that the
        associated address may make the required storage a little
        bigger than the size of an ifreq.  */
-    if (current_buf_size - size < sizeof (struct ifreq) + 40
+    if (current_buf_size - size < SLOP
 #ifdef SIOCGSIZIFCONF
+       /* Unless we hear SIOCGSIZIFCONF is broken somewhere, let's
+          trust the value it returns.  */
        && ifconfsize <= 0
 #elif defined (SIOCGIFNUM)
        && numifs <= 0
 #endif
+       /* And we need *some* sort of bounds.  */
+       && current_buf_size <= 100000
        ) {
        size_t new_size;
 
        est_if_count *= 2;
-       new_size = est_ifreq_size * est_if_count;
+       new_size = est_ifreq_size * est_if_count + SLOP;
        buf = grow_or_free (buf, new_size);
        if (buf == 0)
            return errno;
@@ -682,7 +688,15 @@ foreach_localaddr (/*@null@*/ void *data,
     }
 
     n = size;
-
+    if (n > current_buf_size)
+       n = current_buf_size;
+
+    /* Note: Apparently some systems put the size (used or wanted?)
+       into the start of the buffer, just none that I'm actually
+       using.  Fix this when there's such a test system available.
+       The Samba mailing list archives mention that NTP looks for the
+       size on these systems: *-fujitsu-uxp* *-ncr-sysv4*
+       *-univel-sysv*.  */
     for (i = 0; i < n; i+= ifreq_size(*ifr) ) {
        ifr = (struct ifreq *)((caddr_t) buf+i);