summaryrefslogtreecommitdiff
path: root/net/nmap/patches/patch-ad
blob: bbb514329ec7f8e86a2dc54dd8d75f08ec8f65b0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
$NetBSD: patch-ad,v 1.15 2010/03/27 13:37:34 pettai Exp $

Correct handling of the length of data returned by SIOCGIFCONF.  The
actual length of each item is never less than sizeof(struct ifreq), but
may be more than that.  If the platform's struct sockaddr has an sa_len
field, and if the length in sa_len is larger then the space available in
ifr_ifru, then the data extends beyond the end of the ifr_ifru field by
the difference in sizes.

The previous code of the form

    len = ifr->ifr_addr.sa_len + sizeof(ifr->ifr_name);

had two problems:

1) It assumes that ifr_name and ifr_ifru are the only members
   of struct ifreq, so that sizeof(ifr->ifr_name) is equivalent to
   sizeof(struct ifr) - sizeof(ifr->ifr_ifreq).  This assumption may
   be incorrect on some thypothetical systems,
   and it's just as efficient to use code that
   avoids making the assumption.

2) It assumes that ifr->ifr_addr.sa_len will never be smaller than
   sizeof(ifr->ifr_ifru).  This assumption is incorrect on some
   systems, at least on NetBSD.

--- tcpip.cc.orig	2010-01-15 04:55:23.000000000 +0100
+++ tcpip.cc	2010-01-27 22:46:10.000000000 +0100
@@ -3053,12 +3053,13 @@
     int rc;
     char *p;
 
-    /* On some platforms (such as FreeBSD), the length of each ifr changes
-       based on the sockaddr type used, so we get the next length now. */
-#if HAVE_SOCKADDR_SA_LEN
-    len = ifr->ifr_addr.sa_len + sizeof(ifr->ifr_name);
-#else
+    /* On some platforms struct sockaddr has an sa_len member, if
+      ifr_ddr.sa_len is larger then sizeof ifr_ifru, then the actual
+      data extends beyond the end of ifr_ifru. */
     len = sizeof(struct ifreq);
+#if HAVE_SOCKADDR_SA_LEN
+    if (ifr->ifr_addr.sa_len > sizeof(ifr->ifr_ifru))
+      len += (ifr->ifr_addr.sa_len - sizeof(ifr->ifr_ifru));
 #endif
 
     /* skip any device with no name */