mirror of
https://github.com/nmap/nmap.git
synced 2025-12-25 08:59:01 +00:00
Skip over entire ifreq struct in NEXTIFR.
On platforms supporting sa_len, NEXTIFR would skip over sa_len bytes
starting at the beginning of ifr_addr, and assume that was the end of
the struct. (The idea being that a large address such as a sockaddr_in6
could overflow the nominal struct boundary.) This logic was wrong when
there was something else in the union bigger than sa_len; we would
increment into somewhere in the middle of the same struct.
This exhibited itself on NetBSD, where struct ifreq has a
sockaddr_storage member in its internal union:
struct ifreq {
char ifr_name[IFNAMSIZ]; /* if name, e.g. "en0" */
union {
struct sockaddr ifru_addr;
struct sockaddr ifru_dstaddr;
struct sockaddr ifru_broadaddr;
struct sockaddr_storage ifru_space;
No, we skip over sa_len bytes, or to the nominal end of the struct,
whichever is larger.
Unix Network Programming gets this wrong too; in figure 17.8 they do
ptr += sizeof(ifr->ifr_name) + max(sizeof(struct sockaddr), ifr->ifr_addr.sa_len);
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
# Nmap Changelog ($Id$); -*-text-*-
|
||||
|
||||
o Fixed interface listing on NetBSD. The bug was first noticed by
|
||||
Fredrik Pettai and diagnosed by Jan Schaumann. [David Fifield]
|
||||
|
||||
o [Ncat] Applied a blocking-socket workaround for a bug that could
|
||||
prevent some sends from working in listen mode. The problem was
|
||||
reported by Jonas Wielicki. [Alex Weber, David Fifield]
|
||||
|
||||
@@ -1177,3 +1177,25 @@ index 6a32958..973f16c 100644
|
||||
}
|
||||
if (best.base + 2 + best.len == IP6_ADDR_LEN) {
|
||||
*p = '\0';
|
||||
|
||||
o Fixed interface listing on platforms where ifr_addr does not take up
|
||||
the whole of struct ifreq.
|
||||
|
||||
diff --git libdnet-stripped/src/intf.c libdnet-stripped/src/intf.c
|
||||
index 865e500..4fe059c 100644
|
||||
--- libdnet-stripped/src/intf.c
|
||||
+++ libdnet-stripped/src/intf.c
|
||||
@@ -64,9 +64,10 @@
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SOCKADDR_SA_LEN
|
||||
-# define NEXTIFR(i) ((struct ifreq *)((u_char *)&i->ifr_addr + \
|
||||
- (i->ifr_addr.sa_len ? i->ifr_addr.sa_len : \
|
||||
- sizeof(i->ifr_addr))))
|
||||
+# define max(a, b) ((a) > (b) ? (a) : (b))
|
||||
+# define NEXTIFR(i) ((struct ifreq *) \
|
||||
+ max((u_char *)i + sizeof(struct ifreq), \
|
||||
+ (u_char *)&i->ifr_addr + i->ifr_addr.sa_len))
|
||||
#else
|
||||
# define NEXTIFR(i) (i + 1)
|
||||
#endif
|
||||
|
||||
@@ -64,9 +64,10 @@
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SOCKADDR_SA_LEN
|
||||
# define NEXTIFR(i) ((struct ifreq *)((u_char *)&i->ifr_addr + \
|
||||
(i->ifr_addr.sa_len ? i->ifr_addr.sa_len : \
|
||||
sizeof(i->ifr_addr))))
|
||||
# define max(a, b) ((a) > (b) ? (a) : (b))
|
||||
# define NEXTIFR(i) ((struct ifreq *) \
|
||||
max((u_char *)i + sizeof(struct ifreq), \
|
||||
(u_char *)&i->ifr_addr + i->ifr_addr.sa_len))
|
||||
#else
|
||||
# define NEXTIFR(i) (i + 1)
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user