1
0
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:
david
2012-09-10 01:17:28 +00:00
parent 6f61403f52
commit 0674925f73
3 changed files with 29 additions and 3 deletions

View File

@@ -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]

View File

@@ -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

View File

@@ -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