Rebase to 4.7.3

Fixes for CVE-2015-0261 CVE-2015-2154 CVE-2015-2153 CVE-2015-2155.

Resolves: #1201573,#1201799,#1201792,#1201795,#1201797
This commit is contained in:
Michal Sekletar 2015-03-25 14:41:16 +01:00
parent 4821efb245
commit 3719c98bef
14 changed files with 80 additions and 1999 deletions

1
.gitignore vendored
View File

@ -9,3 +9,4 @@ tcpdump-4.1.1.tar.gz
/tcpdump-4.5.0-20131108gitb07944a.tar.gz
/tcpdump-4.5.1.tar.gz
/tcpdump-4.6.2.tar.gz
/tcpdump-4.7.3.tar.gz

View File

@ -1,19 +1,19 @@
From 964bd27d3544cf952db1820c0badb79a71227b12 Mon Sep 17 00:00:00 2001
From ec4e1a40fcf43d96a121a1ead877f2db4953dabb Mon Sep 17 00:00:00 2001
From: rpm-build <rpm-build>
Date: Mon, 20 Oct 2014 14:32:43 +0200
Subject: [PATCH 3/7] Drop root priviledges before opening first savefile if
Date: Wed, 25 Mar 2015 13:13:49 +0100
Subject: [PATCH] Drop root priviledges before opening first savefile if
running with -Z root
---
tcpdump.1.in | 7 ++++++-
tcpdump.c | 34 +++++++++++++++++++++++++++++++---
2 files changed, 37 insertions(+), 4 deletions(-)
tcpdump.c | 35 ++++++++++++++++++++++++++++++++---
2 files changed, 38 insertions(+), 4 deletions(-)
diff --git a/tcpdump.1.in b/tcpdump.1.in
index a966469..e3a6ef4 100644
index f9522cb..3f1bc5f 100644
--- a/tcpdump.1.in
+++ b/tcpdump.1.in
@@ -241,6 +241,9 @@ have the name specified with the
@@ -249,6 +249,9 @@ have the name specified with the
flag, with a number after it, starting at 1 and continuing upward.
The units of \fIfile_size\fP are millions of bytes (1,000,000 bytes,
not 1,048,576 bytes).
@ -23,7 +23,7 @@ index a966469..e3a6ef4 100644
.TP
.B \-d
Dump the compiled packet-matching code in a human readable form to
@@ -848,7 +851,9 @@ but before opening any savefiles for output, change the user ID to
@@ -865,7 +868,9 @@ but before opening any savefiles for output, change the user ID to
and the group ID to the primary group of
.IR user .
.IP
@ -35,40 +35,47 @@ index a966469..e3a6ef4 100644
.RS
selects which packets will be dumped.
diff --git a/tcpdump.c b/tcpdump.c
index 8d615d7..9110ccf 100644
index 2fd1617..4cbeb05 100644
--- a/tcpdump.c
+++ b/tcpdump.c
@@ -1699,11 +1699,24 @@ main(int argc, char **argv)
}
#endif /* HAVE_CAP_NG_H */
- if (getuid() == 0 || geteuid() == 0) {
@@ -1029,6 +1029,7 @@ main(int argc, char **argv)
cap_rights_t rights;
int cansandbox;
#endif /* HAVE_CAPSICUM */
+ int chown_flag;
#ifdef WIN32
if(wsockinit() != 0) return 1;
@@ -1841,10 +1842,23 @@ main(int argc, char **argv)
}
capng_apply(CAPNG_SELECT_BOTH);
#endif /* HAVE_LIBCAP_NG */
- if (username || chroot_dir)
+ /* If user is running tcpdump as root and wants to write to the savefile,
+ * we will check if -C is set and if it is, we will drop root
+ * privileges right away and consequent call to pcap_dump_open()
+ * will most likely fail for the first file. If -C flag is not set we
+ * will create file as root then change ownership of file to proper
+ * user(default tcpdump) and drop root privileges.
+ */
+ int chown_flag = 0;
+
+ if (WFileName && (getuid() == 0 || geteuid() == 0))
+ if (Cflag && (username || chroot_dir))
+ droproot(username, chroot_dir);
+ else
+ chown_flag = 1;
+ else
+ if ((getuid() == 0 || geteuid() == 0) && (username || chroot_dir))
droproot(username, chroot_dir);
- droproot(username, chroot_dir);
+ /* If user is running tcpdump as root and wants to write to the savefile,
+ * we will check if -C is set and if it is, we will drop root
+ * privileges right away and consequent call to pcap_dump_open()
+ * will most likely fail for the first file. If -C flag is not set we
+ * will create file as root then change ownership of file to proper
+ * user(default tcpdump) and drop root privileges.
+ */
+ if (WFileName)
+ if (Cflag && (username || chroot_dir))
+ droproot(username, chroot_dir);
+ else
+ chown_flag = 1;
+ else
+ if (username || chroot_dir)
+ droproot(username, chroot_dir);
+ }
- }
#endif /* WIN32 */
if (pcap_setfilter(pd, &fcode) < 0)
@@ -1738,6 +1751,21 @@ main(int argc, char **argv)
@@ -1879,6 +1893,21 @@ main(int argc, char **argv)
MakeFilename(dumpinfo.CurrentFileName, WFileName, 0, 0);
p = pcap_dump_open(pd, dumpinfo.CurrentFileName);
+
+ /* Change ownership of file and drop root privileges */
@ -85,9 +92,8 @@ index 8d615d7..9110ccf 100644
+ if (username || chroot_dir)
+ droproot(username, chroot_dir);
+ }
#ifdef HAVE_CAP_NG_H
/* Give up capabilities, clear Effective set */
capng_clear(CAPNG_EFFECTIVE);
--
1.8.3.1
#ifdef HAVE_LIBCAP_NG
/* Give up CAP_DAC_OVERRIDE capability.
* Only allow it to be restored if the -C or -G flag have been
--
2.3.4

View File

@ -18,9 +18,9 @@ index 1e2d051..23aa105 100644
*/
-#define PACKET_HDR_LEN (sizeof( struct pcap_pkthdr ))
+#define PACKET_HDR_LEN (sizeof( struct pcap_sf_pkthdr ))
extern int snaplen;
@@ -111,16 +111,24 @@ reasonable_header( struct pcap_pkthdr *hdr, time_t first_time, time_t last_time
static void
extract_header( pcap_t *p, u_char *buf, struct pcap_pkthdr *hdr )
@ -29,7 +29,7 @@ index 1e2d051..23aa105 100644
+ struct pcap_sf_pkthdr hdri;
+
+ memcpy((char *) &hdri, (char *) buf, sizeof(struct pcap_sf_pkthdr));
if ( pcap_is_swapped( p ) )
{
- hdr->ts.tv_sec = SWAPLONG(hdr->ts.tv_sec);
@ -58,8 +58,8 @@ index de4a01c..9b220de 100644
+++ b/tcpslice-1.2a3/tcpslice.h
@@ -20,6 +20,26 @@
*/
+#include <time.h>
+/* #include <net/bpf.h> */
+
@ -68,7 +68,7 @@ index de4a01c..9b220de 100644
+ * It has to use the same types everywhere, independent of the actual
+ * `struct timeval'
+ */
+
+
+struct pcap_timeval {
+ bpf_int32 tv_sec; /* seconds */
+ bpf_int32 tv_usec; /* microseconds */
@ -81,8 +81,7 @@ index de4a01c..9b220de 100644
+};
+
time_t gwtm2secs( struct tm *tm );
int sf_find_end( struct pcap *p, struct timeval *first_timestamp,
--
1.8.3.1
int sf_find_end( struct pcap *p, struct timeval *first_timestamp,
--
1.8.3.1

View File

@ -1,39 +1,36 @@
From 780db0477c304196a700894bdfd9a3096b5857fd Mon Sep 17 00:00:00 2001
From: Michal Sekletar <msekleta@redhat.com>
Date: Tue, 21 Oct 2014 13:37:24 +0200
Subject: [PATCH 8/8] Don't print out we dropped root, we are always dropping
it.
From 6a204e4e6d2268594858c85c642d98c082190787 Mon Sep 17 00:00:00 2001
From: rpm-build <rpm-build>
Date: Wed, 25 Mar 2015 13:38:54 +0100
Subject: [PATCH] Don't print out we dropped root, we are always dropping it
---
tcpdump.c | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
tcpdump.c | 6 ------
1 file changed, 6 deletions(-)
diff --git a/tcpdump.c b/tcpdump.c
index 9110ccf..8ce9102 100644
index 1a17361..7d45924 100644
--- a/tcpdump.c
+++ b/tcpdump.c
@@ -726,9 +726,7 @@ droproot(const char *username, const char *chroot_dir)
@@ -758,9 +758,6 @@ droproot(const char *username, const char *chroot_dir)
if (ret < 0) {
fprintf(stderr, "error : ret %d\n", ret);
}
- else {
- printf("dropped privs to %s\n", username);
- fprintf(stderr, "dropped privs to %s\n", username);
- }
+
/* We don't need CAP_SETUID and CAP_SETGID */
capng_update(CAPNG_DROP, CAPNG_EFFECTIVE, CAP_SETUID);
capng_update(CAPNG_DROP, CAPNG_EFFECTIVE, CAP_SETUID);
@@ -746,9 +744,7 @@ droproot(const char *username, const char *chroot_dir)
#else
if (initgroups(pw->pw_name, pw->pw_gid) != 0 ||
setgid(pw->pw_gid) != 0 || setuid(pw->pw_uid) != 0) {
@@ -771,9 +768,6 @@ droproot(const char *username, const char *chroot_dir)
pcap_strerror(errno));
exit(1);
}
- else {
- printf("dropped privs to %s\n", username);
- fprintf(stderr, "dropped privs to %s\n", username);
- }
+
#endif /* HAVE_CAP_NG_H */
#endif /* HAVE_LIBCAP_NG */
}
else {
--
1.8.3.1
2.3.4

View File

@ -1,183 +0,0 @@
From 3b223228a87434f214ea3f80d9af420491a76434 Mon Sep 17 00:00:00 2001
From: Guy Harris <guy@alum.mit.edu>
Date: Tue, 11 Nov 2014 16:49:39 -0800
Subject: [PATCH 9/9] Do more bounds checking and length checking.
Don't run past the end of the captured data, and don't run past the end
of the packet (i.e., don't make the length variable go negative).
Also, stop dissecting if the message length isn't valid.
---
print-olsr.c | 56 +++++++++++++++++++++++++++++++++++++++++++-------------
1 file changed, 43 insertions(+), 13 deletions(-)
diff --git a/print-olsr.c b/print-olsr.c
index 6fa0d76..6d2d65f 100644
--- a/print-olsr.c
+++ b/print-olsr.c
@@ -178,7 +178,7 @@ struct olsr_lq_neighbor6 {
/*
* print a neighbor list with LQ extensions.
*/
-static void
+static int
olsr_print_lq_neighbor4(netdissect_options *ndo,
const u_char *msg_data, u_int hello_len)
{
@@ -187,6 +187,8 @@ olsr_print_lq_neighbor4(netdissect_options *ndo,
while (hello_len >= sizeof(struct olsr_lq_neighbor4)) {
lq_neighbor = (struct olsr_lq_neighbor4 *)msg_data;
+ if (!ND_TTEST(*lq_neighbor))
+ return (-1);
ND_PRINT((ndo, "\n\t neighbor %s, link-quality %.2lf%%"
", neighbor-link-quality %.2lf%%",
@@ -197,10 +199,11 @@ olsr_print_lq_neighbor4(netdissect_options *ndo,
msg_data += sizeof(struct olsr_lq_neighbor4);
hello_len -= sizeof(struct olsr_lq_neighbor4);
}
+ return (0);
}
#if INET6
-static void
+static int
olsr_print_lq_neighbor6(netdissect_options *ndo,
const u_char *msg_data, u_int hello_len)
{
@@ -209,6 +212,8 @@ olsr_print_lq_neighbor6(netdissect_options *ndo,
while (hello_len >= sizeof(struct olsr_lq_neighbor6)) {
lq_neighbor = (struct olsr_lq_neighbor6 *)msg_data;
+ if (!ND_TTEST(*lq_neighbor))
+ return (-1);
ND_PRINT((ndo, "\n\t neighbor %s, link-quality %.2lf%%"
", neighbor-link-quality %.2lf%%",
@@ -219,13 +224,14 @@ olsr_print_lq_neighbor6(netdissect_options *ndo,
msg_data += sizeof(struct olsr_lq_neighbor6);
hello_len -= sizeof(struct olsr_lq_neighbor6);
}
+ return (0);
}
#endif /* INET6 */
/*
* print a neighbor list.
*/
-static void
+static int
olsr_print_neighbor(netdissect_options *ndo,
const u_char *msg_data, u_int hello_len)
{
@@ -236,6 +242,8 @@ olsr_print_neighbor(netdissect_options *ndo,
while (hello_len >= sizeof(struct in_addr)) {
+ if (!ND_TTEST2(*msg_data, sizeof(struct in_addr)))
+ return (-1);
/* print 4 neighbors per line */
ND_PRINT((ndo, "%s%s", ipaddr_string(ndo, msg_data),
@@ -244,6 +252,7 @@ olsr_print_neighbor(netdissect_options *ndo,
msg_data += sizeof(struct in_addr);
hello_len -= sizeof(struct in_addr);
}
+ return (0);
}
@@ -326,6 +335,9 @@ olsr_print(netdissect_options *ndo,
ME_TO_DOUBLE(msgptr.v6->vtime),
EXTRACT_16BITS(msgptr.v6->msg_seq),
msg_len, (msg_len_valid == 0) ? " (invalid)" : ""));
+ if (!msg_len_valid) {
+ return;
+ }
msg_tlen = msg_len - sizeof(struct olsr_msg6);
msg_data = tptr + sizeof(struct olsr_msg6);
@@ -354,6 +366,9 @@ olsr_print(netdissect_options *ndo,
ME_TO_DOUBLE(msgptr.v4->vtime),
EXTRACT_16BITS(msgptr.v4->msg_seq),
msg_len, (msg_len_valid == 0) ? " (invalid)" : ""));
+ if (!msg_len_valid) {
+ return;
+ }
msg_tlen = msg_len - sizeof(struct olsr_msg4);
msg_data = tptr + sizeof(struct olsr_msg4);
@@ -362,6 +377,8 @@ olsr_print(netdissect_options *ndo,
switch (msg_type) {
case OLSR_HELLO_MSG:
case OLSR_HELLO_LQ_MSG:
+ if (msg_tlen < sizeof(struct olsr_hello))
+ goto trunc;
ND_TCHECK2(*msg_data, sizeof(struct olsr_hello));
ptr.hello = (struct olsr_hello *)msg_data;
@@ -401,15 +418,21 @@ olsr_print(netdissect_options *ndo,
msg_tlen -= sizeof(struct olsr_hello_link);
hello_len -= sizeof(struct olsr_hello_link);
+ ND_TCHECK2(*msg_data, hello_len);
if (msg_type == OLSR_HELLO_MSG) {
- olsr_print_neighbor(ndo, msg_data, hello_len);
+ if (olsr_print_neighbor(ndo, msg_data, hello_len) == -1)
+ goto trunc;
} else {
#if INET6
- if (is_ipv6)
- olsr_print_lq_neighbor6(ndo, msg_data, hello_len);
- else
+ if (is_ipv6) {
+ if (olsr_print_lq_neighbor6(ndo, msg_data, hello_len) == -1)
+ goto trunc;
+ } else
#endif
- olsr_print_lq_neighbor4(ndo, msg_data, hello_len);
+ {
+ if (olsr_print_lq_neighbor4(ndo, msg_data, hello_len) == -1)
+ goto trunc;
+ }
}
msg_data += hello_len;
@@ -419,6 +442,8 @@ olsr_print(netdissect_options *ndo,
case OLSR_TC_MSG:
case OLSR_TC_LQ_MSG:
+ if (msg_tlen < sizeof(struct olsr_tc))
+ goto trunc;
ND_TCHECK2(*msg_data, sizeof(struct olsr_tc));
ptr.tc = (struct olsr_tc *)msg_data;
@@ -428,14 +453,19 @@ olsr_print(netdissect_options *ndo,
msg_tlen -= sizeof(struct olsr_tc);
if (msg_type == OLSR_TC_MSG) {
- olsr_print_neighbor(ndo, msg_data, msg_tlen);
+ if (olsr_print_neighbor(ndo, msg_data, msg_tlen) == -1)
+ goto trunc;
} else {
#if INET6
- if (is_ipv6)
- olsr_print_lq_neighbor6(ndo, msg_data, msg_tlen);
- else
+ if (is_ipv6) {
+ if (olsr_print_lq_neighbor6(ndo, msg_data, msg_tlen) == -1)
+ goto trunc;
+ } else
#endif
- olsr_print_lq_neighbor4(ndo, msg_data, msg_tlen);
+ {
+ if (olsr_print_lq_neighbor4(ndo, msg_data, msg_tlen) == -1)
+ goto trunc;
+ }
}
break;
--
1.8.3.1

View File

@ -1,343 +0,0 @@
From 9255c9b05b0a04b8d89739b3efcb9f393a617fe9 Mon Sep 17 00:00:00 2001
From: Guy Harris <guy@alum.mit.edu>
Date: Tue, 11 Nov 2014 15:51:54 -0800
Subject: [PATCH] Do bounds checking and length checking.
Don't run past the end of the captured data, and don't run past the end
of the packet (i.e., don't make the length variable go negative).
---
print-geonet.c | 270 ++++++++++++++++++++++++++++++++-------------------------
1 file changed, 151 insertions(+), 119 deletions(-)
diff --git a/print-geonet.c b/print-geonet.c
index d902066..edfb7f2 100644
--- a/print-geonet.c
+++ b/print-geonet.c
@@ -56,16 +56,12 @@ static const struct tok msg_type_values[] = {
static void
print_btp_body(netdissect_options *ndo,
- const u_char *bp, u_int length)
+ const u_char *bp)
{
int version;
int msg_type;
const char *msg_type_str;
- if (length <= 2) {
- return;
- }
-
/* Assuming ItsDpuHeader */
version = bp[0];
msg_type = bp[1];
@@ -83,7 +79,7 @@ print_btp(netdissect_options *ndo,
ND_PRINT((ndo, "; BTP Dst:%u Src:%u", dest, src));
}
-static void
+static int
print_long_pos_vector(netdissect_options *ndo,
const u_char *bp)
{
@@ -91,10 +87,13 @@ print_long_pos_vector(netdissect_options *ndo,
ND_PRINT((ndo, "GN_ADDR:%s ", linkaddr_string (ndo, bp, 0, GEONET_ADDR_LEN)));
+ if (!ND_TTEST2(*(bp+12), 8))
+ return (-1);
lat = EXTRACT_32BITS(bp+12);
ND_PRINT((ndo, "lat:%d ", lat));
lon = EXTRACT_32BITS(bp+16);
ND_PRINT((ndo, "lon:%d", lon));
+ return (0);
}
@@ -105,137 +104,170 @@ print_long_pos_vector(netdissect_options *ndo,
void
geonet_print(netdissect_options *ndo, const u_char *eth, const u_char *bp, u_int length)
{
+ int version;
+ int next_hdr;
+ int hdr_type;
+ int hdr_subtype;
+ uint16_t payload_length;
+ int hop_limit;
+ const char *next_hdr_txt = "Unknown";
+ const char *hdr_type_txt = "Unknown";
+ int hdr_size = -1;
+
ND_PRINT((ndo, "GeoNet src:%s; ", etheraddr_string(ndo, eth+6)));
- if (length >= 36) {
- /* Process Common Header */
- int version = bp[0] >> 4;
- int next_hdr = bp[0] & 0x0f;
- int hdr_type = bp[1] >> 4;
- int hdr_subtype = bp[1] & 0x0f;
- uint16_t payload_length = EXTRACT_16BITS(bp+4);
- int hop_limit = bp[7];
- const char *next_hdr_txt = "Unknown";
- const char *hdr_type_txt = "Unknown";
- int hdr_size = -1;
+ /* Process Common Header */
+ if (length < 36)
+ goto malformed;
+
+ ND_TCHECK2(*bp, 7);
+ version = bp[0] >> 4;
+ next_hdr = bp[0] & 0x0f;
+ hdr_type = bp[1] >> 4;
+ hdr_subtype = bp[1] & 0x0f;
+ payload_length = EXTRACT_16BITS(bp+4);
+ hop_limit = bp[7];
- switch (next_hdr) {
- case 0: next_hdr_txt = "Any"; break;
- case 1: next_hdr_txt = "BTP-A"; break;
- case 2: next_hdr_txt = "BTP-B"; break;
- case 3: next_hdr_txt = "IPv6"; break;
- }
+ switch (next_hdr) {
+ case 0: next_hdr_txt = "Any"; break;
+ case 1: next_hdr_txt = "BTP-A"; break;
+ case 2: next_hdr_txt = "BTP-B"; break;
+ case 3: next_hdr_txt = "IPv6"; break;
+ }
- switch (hdr_type) {
- case 0: hdr_type_txt = "Any"; break;
- case 1: hdr_type_txt = "Beacon"; break;
- case 2: hdr_type_txt = "GeoUnicast"; break;
- case 3: switch (hdr_subtype) {
- case 0: hdr_type_txt = "GeoAnycastCircle"; break;
- case 1: hdr_type_txt = "GeoAnycastRect"; break;
- case 2: hdr_type_txt = "GeoAnycastElipse"; break;
- }
- break;
- case 4: switch (hdr_subtype) {
- case 0: hdr_type_txt = "GeoBroadcastCircle"; break;
- case 1: hdr_type_txt = "GeoBroadcastRect"; break;
- case 2: hdr_type_txt = "GeoBroadcastElipse"; break;
- }
- break;
- case 5: switch (hdr_subtype) {
- case 0: hdr_type_txt = "TopoScopeBcast-SH"; break;
- case 1: hdr_type_txt = "TopoScopeBcast-MH"; break;
- }
- break;
- case 6: switch (hdr_subtype) {
- case 0: hdr_type_txt = "LocService-Request"; break;
- case 1: hdr_type_txt = "LocService-Reply"; break;
- }
- break;
- }
+ switch (hdr_type) {
+ case 0: hdr_type_txt = "Any"; break;
+ case 1: hdr_type_txt = "Beacon"; break;
+ case 2: hdr_type_txt = "GeoUnicast"; break;
+ case 3: switch (hdr_subtype) {
+ case 0: hdr_type_txt = "GeoAnycastCircle"; break;
+ case 1: hdr_type_txt = "GeoAnycastRect"; break;
+ case 2: hdr_type_txt = "GeoAnycastElipse"; break;
+ }
+ break;
+ case 4: switch (hdr_subtype) {
+ case 0: hdr_type_txt = "GeoBroadcastCircle"; break;
+ case 1: hdr_type_txt = "GeoBroadcastRect"; break;
+ case 2: hdr_type_txt = "GeoBroadcastElipse"; break;
+ }
+ break;
+ case 5: switch (hdr_subtype) {
+ case 0: hdr_type_txt = "TopoScopeBcast-SH"; break;
+ case 1: hdr_type_txt = "TopoScopeBcast-MH"; break;
+ }
+ break;
+ case 6: switch (hdr_subtype) {
+ case 0: hdr_type_txt = "LocService-Request"; break;
+ case 1: hdr_type_txt = "LocService-Reply"; break;
+ }
+ break;
+ }
+
+ ND_PRINT((ndo, "v:%d ", version));
+ ND_PRINT((ndo, "NH:%d-%s ", next_hdr, next_hdr_txt));
+ ND_PRINT((ndo, "HT:%d-%d-%s ", hdr_type, hdr_subtype, hdr_type_txt));
+ ND_PRINT((ndo, "HopLim:%d ", hop_limit));
+ ND_PRINT((ndo, "Payload:%d ", payload_length));
+ if (print_long_pos_vector(ndo, bp + 8) == -1)
+ goto trunc;
- ND_PRINT((ndo, "v:%d ", version));
- ND_PRINT((ndo, "NH:%d-%s ", next_hdr, next_hdr_txt));
- ND_PRINT((ndo, "HT:%d-%d-%s ", hdr_type, hdr_subtype, hdr_type_txt));
- ND_PRINT((ndo, "HopLim:%d ", hop_limit));
- ND_PRINT((ndo, "Payload:%d ", payload_length));
- print_long_pos_vector(ndo, bp + 8);
+ /* Skip Common Header */
+ length -= 36;
+ bp += 36;
- /* Skip Common Header */
- length -= 36;
- bp += 36;
+ /* Process Extended Headers */
+ switch (hdr_type) {
+ case 0: /* Any */
+ hdr_size = 0;
+ break;
+ case 1: /* Beacon */
+ hdr_size = 0;
+ break;
+ case 2: /* GeoUnicast */
+ break;
+ case 3: switch (hdr_subtype) {
+ case 0: /* GeoAnycastCircle */
+ break;
+ case 1: /* GeoAnycastRect */
+ break;
+ case 2: /* GeoAnycastElipse */
+ break;
+ }
+ break;
+ case 4: switch (hdr_subtype) {
+ case 0: /* GeoBroadcastCircle */
+ break;
+ case 1: /* GeoBroadcastRect */
+ break;
+ case 2: /* GeoBroadcastElipse */
+ break;
+ }
+ break;
+ case 5: switch (hdr_subtype) {
+ case 0: /* TopoScopeBcast-SH */
+ hdr_size = 0;
+ break;
+ case 1: /* TopoScopeBcast-MH */
+ hdr_size = 68 - 36;
+ break;
+ }
+ break;
+ case 6: switch (hdr_subtype) {
+ case 0: /* LocService-Request */
+ break;
+ case 1: /* LocService-Reply */
+ break;
+ }
+ break;
+ }
- /* Process Extended Headers */
- switch (hdr_type) {
+ /* Skip Extended headers */
+ if (hdr_size >= 0) {
+ if (length < (u_int)hdr_size)
+ goto malformed;
+ ND_TCHECK2(*bp, hdr_size);
+ length -= hdr_size;
+ bp += hdr_size;
+ switch (next_hdr) {
case 0: /* Any */
- hdr_size = 0;
- break;
- case 1: /* Beacon */
- hdr_size = 0;
- break;
- case 2: /* GeoUnicast */
break;
- case 3: switch (hdr_subtype) {
- case 0: /* GeoAnycastCircle */
- break;
- case 1: /* GeoAnycastRect */
- break;
- case 2: /* GeoAnycastElipse */
- break;
+ case 1:
+ case 2: /* BTP A/B */
+ if (length < 4)
+ goto malformed;
+ ND_TCHECK2(*bp, 4);
+ print_btp(ndo, bp);
+ length -= 4;
+ bp += 4;
+ if (length >= 2) {
+ /*
+ * XXX - did print_btp_body()
+ * return if length < 2
+ * because this is optional,
+ * or was that just not
+ * reporting genuine errors?
+ */
+ ND_TCHECK2(*bp, 2);
+ print_btp_body(ndo, bp);
}
break;
- case 4: switch (hdr_subtype) {
- case 0: /* GeoBroadcastCircle */
- break;
- case 1: /* GeoBroadcastRect */
- break;
- case 2: /* GeoBroadcastElipse */
- break;
- }
- break;
- case 5: switch (hdr_subtype) {
- case 0: /* TopoScopeBcast-SH */
- hdr_size = 0;
- break;
- case 1: /* TopoScopeBcast-MH */
- hdr_size = 68 - 36;
- break;
- }
- break;
- case 6: switch (hdr_subtype) {
- case 0: /* LocService-Request */
- break;
- case 1: /* LocService-Reply */
- break;
- }
+ case 3: /* IPv6 */
break;
}
-
- /* Skip Extended headers */
- if (hdr_size >= 0) {
- length -= hdr_size;
- bp += hdr_size;
- switch (next_hdr) {
- case 0: /* Any */
- break;
- case 1:
- case 2: /* BTP A/B */
- print_btp(ndo, bp);
- length -= 4;
- bp += 4;
- print_btp_body(ndo, bp, length);
- break;
- case 3: /* IPv6 */
- break;
- }
- }
- } else {
- ND_PRINT((ndo, "Malformed (small) "));
}
/* Print user data part */
if (ndo->ndo_vflag)
ND_DEFAULTPRINT(bp, length);
+ return;
+
+malformed:
+ ND_PRINT((ndo, " Malformed (small) "));
+ /* XXX - print the remaining data as hex? */
+ return;
+
+trunc:
+ ND_PRINT((ndo, "[|geonet]"));
}
--
1.8.3.1

View File

@ -1,516 +0,0 @@
From ab4e52b94aac6cb729a5a695aa612d5ebda2ec3a Mon Sep 17 00:00:00 2001
From: Guy Harris <guy@alum.mit.edu>
Date: Tue, 11 Nov 2014 17:24:12 -0800
Subject: [PATCH] Add initial bounds check, get rid of union aodv.
Fetch the type field without using a structure, and check to make sure
it's not past the end of the packet.
Pass to each dissection routine a pointer to the appropriate message
type structure, rather than a pointer to a union of all the message type
structures.
---
print-aodv.c | 274 ++++++++++++++++++++++++++++-------------------------------
1 file changed, 130 insertions(+), 144 deletions(-)
diff --git a/print-aodv.c b/print-aodv.c
index 093e174..da5b169 100644
--- a/print-aodv.c
+++ b/print-aodv.c
@@ -163,19 +163,6 @@ struct aodv_rrep_ack {
uint8_t ra_zero0;
};
-union aodv {
- struct aodv_rreq rreq;
- struct aodv_rrep rrep;
- struct aodv_rerr rerr;
- struct aodv_rrep_ack rrep_ack;
-#ifdef INET6
- struct aodv_rreq6 rreq6;
- struct aodv_rreq6_draft_01 rreq6_draft_01;
- struct aodv_rrep6 rrep6;
- struct aodv_rrep6_draft_01 rrep6_draft_01;
-#endif
-};
-
#define AODV_RREQ 1 /* route request */
#define AODV_RREP 2 /* route response */
#define AODV_RERR 3 /* error report */
@@ -232,7 +219,7 @@ aodv_extension(netdissect_options *ndo,
static void
aodv_rreq(netdissect_options *ndo,
- const union aodv *ap, const u_char *dat, u_int length)
+ const struct aodv_rreq *ap, const u_char *dat, u_int length)
{
u_int i;
@@ -241,31 +228,31 @@ aodv_rreq(netdissect_options *ndo,
return;
}
i = min(length, (u_int)(ndo->ndo_snapend - dat));
- if (i < sizeof(ap->rreq)) {
+ if (i < sizeof(*ap)) {
ND_PRINT((ndo, " [|rreq]"));
return;
}
- i -= sizeof(ap->rreq);
+ i -= sizeof(*ap);
ND_PRINT((ndo, " rreq %u %s%s%s%s%shops %u id 0x%08lx\n"
"\tdst %s seq %lu src %s seq %lu", length,
- ap->rreq.rreq_type & RREQ_JOIN ? "[J]" : "",
- ap->rreq.rreq_type & RREQ_REPAIR ? "[R]" : "",
- ap->rreq.rreq_type & RREQ_GRAT ? "[G]" : "",
- ap->rreq.rreq_type & RREQ_DEST ? "[D]" : "",
- ap->rreq.rreq_type & RREQ_UNKNOWN ? "[U] " : " ",
- ap->rreq.rreq_hops,
- (unsigned long)EXTRACT_32BITS(&ap->rreq.rreq_id),
- ipaddr_string(ndo, &ap->rreq.rreq_da),
- (unsigned long)EXTRACT_32BITS(&ap->rreq.rreq_ds),
- ipaddr_string(ndo, &ap->rreq.rreq_oa),
- (unsigned long)EXTRACT_32BITS(&ap->rreq.rreq_os)));
+ ap->rreq_type & RREQ_JOIN ? "[J]" : "",
+ ap->rreq_type & RREQ_REPAIR ? "[R]" : "",
+ ap->rreq_type & RREQ_GRAT ? "[G]" : "",
+ ap->rreq_type & RREQ_DEST ? "[D]" : "",
+ ap->rreq_type & RREQ_UNKNOWN ? "[U] " : " ",
+ ap->rreq_hops,
+ (unsigned long)EXTRACT_32BITS(&ap->rreq_id),
+ ipaddr_string(ndo, &ap->rreq_da),
+ (unsigned long)EXTRACT_32BITS(&ap->rreq_ds),
+ ipaddr_string(ndo, &ap->rreq_oa),
+ (unsigned long)EXTRACT_32BITS(&ap->rreq_os)));
if (i >= sizeof(struct aodv_ext))
- aodv_extension(ndo, (void *)(&ap->rreq + 1), i);
+ aodv_extension(ndo, (void *)(ap + 1), i);
}
static void
aodv_rrep(netdissect_options *ndo,
- const union aodv *ap, const u_char *dat, u_int length)
+ const struct aodv_rrep *ap, const u_char *dat, u_int length)
{
u_int i;
@@ -274,28 +261,28 @@ aodv_rrep(netdissect_options *ndo,
return;
}
i = min(length, (u_int)(ndo->ndo_snapend - dat));
- if (i < sizeof(ap->rrep)) {
+ if (i < sizeof(*ap)) {
ND_PRINT((ndo, " [|rrep]"));
return;
}
- i -= sizeof(ap->rrep);
+ i -= sizeof(*ap);
ND_PRINT((ndo, " rrep %u %s%sprefix %u hops %u\n"
"\tdst %s dseq %lu src %s %lu ms", length,
- ap->rrep.rrep_type & RREP_REPAIR ? "[R]" : "",
- ap->rrep.rrep_type & RREP_ACK ? "[A] " : " ",
- ap->rrep.rrep_ps & RREP_PREFIX_MASK,
- ap->rrep.rrep_hops,
- ipaddr_string(ndo, &ap->rrep.rrep_da),
- (unsigned long)EXTRACT_32BITS(&ap->rrep.rrep_ds),
- ipaddr_string(ndo, &ap->rrep.rrep_oa),
- (unsigned long)EXTRACT_32BITS(&ap->rrep.rrep_life)));
+ ap->rrep_type & RREP_REPAIR ? "[R]" : "",
+ ap->rrep_type & RREP_ACK ? "[A] " : " ",
+ ap->rrep_ps & RREP_PREFIX_MASK,
+ ap->rrep_hops,
+ ipaddr_string(ndo, &ap->rrep_da),
+ (unsigned long)EXTRACT_32BITS(&ap->rrep_ds),
+ ipaddr_string(ndo, &ap->rrep_oa),
+ (unsigned long)EXTRACT_32BITS(&ap->rrep_life)));
if (i >= sizeof(struct aodv_ext))
- aodv_extension(ndo, (void *)(&ap->rrep + 1), i);
+ aodv_extension(ndo, (void *)(ap + 1), i);
}
static void
aodv_rerr(netdissect_options *ndo,
- const union aodv *ap, const u_char *dat, u_int length)
+ const struct aodv_rerr *ap, const u_char *dat, u_int length)
{
u_int i;
const struct rerr_unreach *dp = NULL;
@@ -311,14 +298,14 @@ aodv_rerr(netdissect_options *ndo,
return;
}
i -= offsetof(struct aodv_rerr, r);
- dp = &ap->rerr.r.dest[0];
- n = ap->rerr.rerr_dc * sizeof(ap->rerr.r.dest[0]);
+ dp = &ap->r.dest[0];
+ n = ap->rerr_dc * sizeof(ap->r.dest[0]);
ND_PRINT((ndo, " rerr %s [items %u] [%u]:",
- ap->rerr.rerr_flags & RERR_NODELETE ? "[D]" : "",
- ap->rerr.rerr_dc, length));
- trunc = n - (i/sizeof(ap->rerr.r.dest[0]));
- for (; i >= sizeof(ap->rerr.r.dest[0]);
- ++dp, i -= sizeof(ap->rerr.r.dest[0])) {
+ ap->rerr_flags & RERR_NODELETE ? "[D]" : "",
+ ap->rerr_dc, length));
+ trunc = n - (i/sizeof(ap->r.dest[0]));
+ for (; i >= sizeof(ap->r.dest[0]);
+ ++dp, i -= sizeof(ap->r.dest[0])) {
ND_PRINT((ndo, " {%s}(%ld)", ipaddr_string(ndo, &dp->u_da),
(unsigned long)EXTRACT_32BITS(&dp->u_ds)));
}
@@ -329,10 +316,10 @@ aodv_rerr(netdissect_options *ndo,
static void
#ifdef INET6
aodv_v6_rreq(netdissect_options *ndo,
- const union aodv *ap, const u_char *dat, u_int length)
+ const struct aodv_rreq6 *ap, const u_char *dat, u_int length)
#else
aodv_v6_rreq(netdissect_options *ndo,
- const union aodv *ap _U_, const u_char *dat _U_, u_int length)
+ const struct aodv_rreq6 *ap _U_, const u_char *dat _U_, u_int length)
#endif
{
#ifdef INET6
@@ -343,26 +330,26 @@ aodv_v6_rreq(netdissect_options *ndo,
return;
}
i = min(length, (u_int)(ndo->ndo_snapend - dat));
- if (i < sizeof(ap->rreq6)) {
+ if (i < sizeof(*ap)) {
ND_PRINT((ndo, " [|rreq6]"));
return;
}
- i -= sizeof(ap->rreq6);
+ i -= sizeof(*ap);
ND_PRINT((ndo, " v6 rreq %u %s%s%s%s%shops %u id 0x%08lx\n"
"\tdst %s seq %lu src %s seq %lu", length,
- ap->rreq6.rreq_type & RREQ_JOIN ? "[J]" : "",
- ap->rreq6.rreq_type & RREQ_REPAIR ? "[R]" : "",
- ap->rreq6.rreq_type & RREQ_GRAT ? "[G]" : "",
- ap->rreq6.rreq_type & RREQ_DEST ? "[D]" : "",
- ap->rreq6.rreq_type & RREQ_UNKNOWN ? "[U] " : " ",
- ap->rreq6.rreq_hops,
- (unsigned long)EXTRACT_32BITS(&ap->rreq6.rreq_id),
- ip6addr_string(ndo, &ap->rreq6.rreq_da),
- (unsigned long)EXTRACT_32BITS(&ap->rreq6.rreq_ds),
- ip6addr_string(ndo, &ap->rreq6.rreq_oa),
- (unsigned long)EXTRACT_32BITS(&ap->rreq6.rreq_os)));
+ ap->rreq_type & RREQ_JOIN ? "[J]" : "",
+ ap->rreq_type & RREQ_REPAIR ? "[R]" : "",
+ ap->rreq_type & RREQ_GRAT ? "[G]" : "",
+ ap->rreq_type & RREQ_DEST ? "[D]" : "",
+ ap->rreq_type & RREQ_UNKNOWN ? "[U] " : " ",
+ ap->rreq_hops,
+ (unsigned long)EXTRACT_32BITS(&ap->rreq_id),
+ ip6addr_string(ndo, &ap->rreq_da),
+ (unsigned long)EXTRACT_32BITS(&ap->rreq_ds),
+ ip6addr_string(ndo, &ap->rreq_oa),
+ (unsigned long)EXTRACT_32BITS(&ap->rreq_os)));
if (i >= sizeof(struct aodv_ext))
- aodv_extension(ndo, (void *)(&ap->rreq6 + 1), i);
+ aodv_extension(ndo, (void *)(ap + 1), i);
#else
ND_PRINT((ndo, " v6 rreq %u", length));
#endif
@@ -371,10 +358,10 @@ aodv_v6_rreq(netdissect_options *ndo,
static void
#ifdef INET6
aodv_v6_rrep(netdissect_options *ndo,
- const union aodv *ap, const u_char *dat, u_int length)
+ const struct aodv_rrep6 *ap, const u_char *dat, u_int length)
#else
aodv_v6_rrep(netdissect_options *ndo,
- const union aodv *ap _U_, const u_char *dat _U_, u_int length)
+ const struct aodv_rrep6 *ap _U_, const u_char *dat _U_, u_int length)
#endif
{
#ifdef INET6
@@ -385,23 +372,23 @@ aodv_v6_rrep(netdissect_options *ndo,
return;
}
i = min(length, (u_int)(ndo->ndo_snapend - dat));
- if (i < sizeof(ap->rrep6)) {
+ if (i < sizeof(*ap)) {
ND_PRINT((ndo, " [|rrep6]"));
return;
}
- i -= sizeof(ap->rrep6);
+ i -= sizeof(*ap);
ND_PRINT((ndo, " rrep %u %s%sprefix %u hops %u\n"
"\tdst %s dseq %lu src %s %lu ms", length,
- ap->rrep6.rrep_type & RREP_REPAIR ? "[R]" : "",
- ap->rrep6.rrep_type & RREP_ACK ? "[A] " : " ",
- ap->rrep6.rrep_ps & RREP_PREFIX_MASK,
- ap->rrep6.rrep_hops,
- ip6addr_string(ndo, &ap->rrep6.rrep_da),
- (unsigned long)EXTRACT_32BITS(&ap->rrep6.rrep_ds),
- ip6addr_string(ndo, &ap->rrep6.rrep_oa),
- (unsigned long)EXTRACT_32BITS(&ap->rrep6.rrep_life)));
+ ap->rrep_type & RREP_REPAIR ? "[R]" : "",
+ ap->rrep_type & RREP_ACK ? "[A] " : " ",
+ ap->rrep_ps & RREP_PREFIX_MASK,
+ ap->rrep_hops,
+ ip6addr_string(ndo, &ap->rrep_da),
+ (unsigned long)EXTRACT_32BITS(&ap->rrep_ds),
+ ip6addr_string(ndo, &ap->rrep_oa),
+ (unsigned long)EXTRACT_32BITS(&ap->rrep_life)));
if (i >= sizeof(struct aodv_ext))
- aodv_extension(ndo, (void *)(&ap->rrep6 + 1), i);
+ aodv_extension(ndo, (void *)(ap + 1), i);
#else
ND_PRINT((ndo, " rrep %u", length));
#endif
@@ -410,10 +397,10 @@ aodv_v6_rrep(netdissect_options *ndo,
static void
#ifdef INET6
aodv_v6_rerr(netdissect_options *ndo,
- const union aodv *ap, u_int length)
+ const struct aodv_rerr *ap, u_int length)
#else
aodv_v6_rerr(netdissect_options *ndo,
- const union aodv *ap _U_, u_int length)
+ const struct aodv_rerr *ap _U_, u_int length)
#endif
{
#ifdef INET6
@@ -421,12 +408,12 @@ aodv_v6_rerr(netdissect_options *ndo,
int i, j, n, trunc;
i = length - offsetof(struct aodv_rerr, r);
- j = sizeof(ap->rerr.r.dest6[0]);
- dp6 = &ap->rerr.r.dest6[0];
- n = ap->rerr.rerr_dc * j;
+ j = sizeof(ap->r.dest6[0]);
+ dp6 = &ap->r.dest6[0];
+ n = ap->rerr_dc * j;
ND_PRINT((ndo, " rerr %s [items %u] [%u]:",
- ap->rerr.rerr_flags & RERR_NODELETE ? "[D]" : "",
- ap->rerr.rerr_dc, length));
+ ap->rerr_flags & RERR_NODELETE ? "[D]" : "",
+ ap->rerr_dc, length));
trunc = n - (i/j);
for (; i -= j >= 0; ++dp6) {
ND_PRINT((ndo, " {%s}(%ld)", ip6addr_string(ndo, &dp6->u_da),
@@ -442,11 +429,10 @@ aodv_v6_rerr(netdissect_options *ndo,
static void
#ifdef INET6
aodv_v6_draft_01_rreq(netdissect_options *ndo,
- const union aodv *ap, const u_char *dat, u_int length)
+ const struct aodv_rreq6_draft_01 *ap, const u_char *dat, u_int length)
#else
aodv_v6_draft_01_rreq(netdissect_options *ndo,
- const union aodv *ap _U_, const u_char *dat _U_,
- u_int length)
+ const struct aodv_rreq6_draft_01 *ap _U_, const u_char *dat _U_, u_int length)
#endif
{
#ifdef INET6
@@ -457,26 +443,26 @@ aodv_v6_draft_01_rreq(netdissect_options *ndo,
return;
}
i = min(length, (u_int)(ndo->ndo_snapend - dat));
- if (i < sizeof(ap->rreq6_draft_01)) {
+ if (i < sizeof(*ap)) {
ND_PRINT((ndo, " [|rreq6]"));
return;
}
- i -= sizeof(ap->rreq6_draft_01);
+ i -= sizeof(*ap);
ND_PRINT((ndo, " rreq %u %s%s%s%s%shops %u id 0x%08lx\n"
"\tdst %s seq %lu src %s seq %lu", length,
- ap->rreq6_draft_01.rreq_type & RREQ_JOIN ? "[J]" : "",
- ap->rreq6_draft_01.rreq_type & RREQ_REPAIR ? "[R]" : "",
- ap->rreq6_draft_01.rreq_type & RREQ_GRAT ? "[G]" : "",
- ap->rreq6_draft_01.rreq_type & RREQ_DEST ? "[D]" : "",
- ap->rreq6_draft_01.rreq_type & RREQ_UNKNOWN ? "[U] " : " ",
- ap->rreq6_draft_01.rreq_hops,
- (unsigned long)EXTRACT_32BITS(&ap->rreq6_draft_01.rreq_id),
- ip6addr_string(ndo, &ap->rreq6_draft_01.rreq_da),
- (unsigned long)EXTRACT_32BITS(&ap->rreq6_draft_01.rreq_ds),
- ip6addr_string(ndo, &ap->rreq6_draft_01.rreq_oa),
- (unsigned long)EXTRACT_32BITS(&ap->rreq6_draft_01.rreq_os)));
+ ap->rreq_type & RREQ_JOIN ? "[J]" : "",
+ ap->rreq_type & RREQ_REPAIR ? "[R]" : "",
+ ap->rreq_type & RREQ_GRAT ? "[G]" : "",
+ ap->rreq_type & RREQ_DEST ? "[D]" : "",
+ ap->rreq_type & RREQ_UNKNOWN ? "[U] " : " ",
+ ap->rreq_hops,
+ (unsigned long)EXTRACT_32BITS(&ap->rreq_id),
+ ip6addr_string(ndo, &ap->rreq_da),
+ (unsigned long)EXTRACT_32BITS(&ap->rreq_ds),
+ ip6addr_string(ndo, &ap->rreq_oa),
+ (unsigned long)EXTRACT_32BITS(&ap->rreq_os)));
if (i >= sizeof(struct aodv_ext))
- aodv_extension(ndo, (void *)(&ap->rreq6_draft_01 + 1), i);
+ aodv_extension(ndo, (void *)(ap + 1), i);
#else
ND_PRINT((ndo, " rreq %u", length));
#endif
@@ -485,11 +471,10 @@ aodv_v6_draft_01_rreq(netdissect_options *ndo,
static void
#ifdef INET6
aodv_v6_draft_01_rrep(netdissect_options *ndo,
- const union aodv *ap, const u_char *dat, u_int length)
+ const struct aodv_rrep6_draft_01 *ap, const u_char *dat, u_int length)
#else
aodv_v6_draft_01_rrep(netdissect_options *ndo,
- const union aodv *ap _U_, const u_char *dat _U_,
- u_int length)
+ const struct aodv_rrep6_draft_01 *ap _U_, const u_char *dat _U_, u_int length)
#endif
{
#ifdef INET6
@@ -500,23 +485,23 @@ aodv_v6_draft_01_rrep(netdissect_options *ndo,
return;
}
i = min(length, (u_int)(ndo->ndo_snapend - dat));
- if (i < sizeof(ap->rrep6_draft_01)) {
+ if (i < sizeof(*ap)) {
ND_PRINT((ndo, " [|rrep6]"));
return;
}
- i -= sizeof(ap->rrep6_draft_01);
+ i -= sizeof(*ap);
ND_PRINT((ndo, " rrep %u %s%sprefix %u hops %u\n"
"\tdst %s dseq %lu src %s %lu ms", length,
- ap->rrep6_draft_01.rrep_type & RREP_REPAIR ? "[R]" : "",
- ap->rrep6_draft_01.rrep_type & RREP_ACK ? "[A] " : " ",
- ap->rrep6_draft_01.rrep_ps & RREP_PREFIX_MASK,
- ap->rrep6_draft_01.rrep_hops,
- ip6addr_string(ndo, &ap->rrep6_draft_01.rrep_da),
- (unsigned long)EXTRACT_32BITS(&ap->rrep6_draft_01.rrep_ds),
- ip6addr_string(ndo, &ap->rrep6_draft_01.rrep_oa),
- (unsigned long)EXTRACT_32BITS(&ap->rrep6_draft_01.rrep_life)));
+ ap->rrep_type & RREP_REPAIR ? "[R]" : "",
+ ap->rrep_type & RREP_ACK ? "[A] " : " ",
+ ap->rrep_ps & RREP_PREFIX_MASK,
+ ap->rrep_hops,
+ ip6addr_string(ndo, &ap->rrep_da),
+ (unsigned long)EXTRACT_32BITS(&ap->rrep_ds),
+ ip6addr_string(ndo, &ap->rrep_oa),
+ (unsigned long)EXTRACT_32BITS(&ap->rrep_life)));
if (i >= sizeof(struct aodv_ext))
- aodv_extension(ndo, (void *)(&ap->rrep6_draft_01 + 1), i);
+ aodv_extension(ndo, (void *)(ap + 1), i);
#else
ND_PRINT((ndo, " rrep %u", length));
#endif
@@ -525,10 +510,10 @@ aodv_v6_draft_01_rrep(netdissect_options *ndo,
static void
#ifdef INET6
aodv_v6_draft_01_rerr(netdissect_options *ndo,
- const union aodv *ap, u_int length)
+ const struct aodv_rerr *ap, u_int length)
#else
aodv_v6_draft_01_rerr(netdissect_options *ndo,
- const union aodv *ap _U_, u_int length)
+ const struct aodv_rerr *ap _U_, u_int length)
#endif
{
#ifdef INET6
@@ -536,12 +521,12 @@ aodv_v6_draft_01_rerr(netdissect_options *ndo,
int i, j, n, trunc;
i = length - offsetof(struct aodv_rerr, r);
- j = sizeof(ap->rerr.r.dest6_draft_01[0]);
- dp6 = &ap->rerr.r.dest6_draft_01[0];
- n = ap->rerr.rerr_dc * j;
+ j = sizeof(ap->r.dest6_draft_01[0]);
+ dp6 = &ap->r.dest6_draft_01[0];
+ n = ap->rerr_dc * j;
ND_PRINT((ndo, " rerr %s [items %u] [%u]:",
- ap->rerr.rerr_flags & RERR_NODELETE ? "[D]" : "",
- ap->rerr.rerr_dc, length));
+ ap->rerr_flags & RERR_NODELETE ? "[D]" : "",
+ ap->rerr_dc, length));
trunc = n - (i/j);
for (; i -= j >= 0; ++dp6) {
ND_PRINT((ndo, " {%s}(%ld)", ip6addr_string(ndo, &dp6->u_da),
@@ -558,40 +543,37 @@ void
aodv_print(netdissect_options *ndo,
const u_char *dat, u_int length, int is_ip6)
{
- const union aodv *ap;
-
- ap = (union aodv *)dat;
- if (ndo->ndo_snapend < dat) {
- ND_PRINT((ndo, " [|aodv]"));
- return;
- }
- if (min(length, (u_int)(ndo->ndo_snapend - dat)) < sizeof(ap->rrep_ack)) {
- ND_PRINT((ndo, " [|aodv]"));
- return;
- }
+ uint8_t msg_type;
+
+ /*
+ * The message type is the first byte; make sure we have it
+ * and then fetch it.
+ */
+ ND_TCHECK(*dat);
+ msg_type = *dat;
ND_PRINT((ndo, " aodv"));
- switch (ap->rerr.rerr_type) {
+ switch (msg_type) {
case AODV_RREQ:
if (is_ip6)
- aodv_v6_rreq(ndo, ap, dat, length);
+ aodv_v6_rreq(ndo, (const struct aodv_rreq6 *)dat, dat, length);
else
- aodv_rreq(ndo, ap, dat, length);
+ aodv_rreq(ndo, (const struct aodv_rreq *)dat, dat, length);
break;
case AODV_RREP:
if (is_ip6)
- aodv_v6_rrep(ndo, ap, dat, length);
+ aodv_v6_rrep(ndo, (const struct aodv_rrep6 *)dat, dat, length);
else
- aodv_rrep(ndo, ap, dat, length);
+ aodv_rrep(ndo, (const struct aodv_rrep *)dat, dat, length);
break;
case AODV_RERR:
if (is_ip6)
- aodv_v6_rerr(ndo, ap, length);
+ aodv_v6_rerr(ndo, (const struct aodv_rerr *)dat, length);
else
- aodv_rerr(ndo, ap, dat, length);
+ aodv_rerr(ndo, (const struct aodv_rerr *)dat, dat, length);
break;
case AODV_RREP_ACK:
@@ -599,15 +581,15 @@ aodv_print(netdissect_options *ndo,
break;
case AODV_V6_DRAFT_01_RREQ:
- aodv_v6_draft_01_rreq(ndo, ap, dat, length);
+ aodv_v6_draft_01_rreq(ndo, (const struct aodv_rreq6_draft_01 *)dat, dat, length);
break;
case AODV_V6_DRAFT_01_RREP:
- aodv_v6_draft_01_rrep(ndo, ap, dat, length);
+ aodv_v6_draft_01_rrep(ndo, (const struct aodv_rrep6_draft_01 *)dat, dat, length);
break;
case AODV_V6_DRAFT_01_RERR:
- aodv_v6_draft_01_rerr(ndo, ap, length);
+ aodv_v6_draft_01_rerr(ndo, (const struct aodv_rerr *)dat, length);
break;
case AODV_V6_DRAFT_01_RREP_ACK:
@@ -615,6 +597,10 @@ aodv_print(netdissect_options *ndo,
break;
default:
- ND_PRINT((ndo, " %u %u", ap->rreq.rreq_type, length));
+ ND_PRINT((ndo, " type %u %u", msg_type, length));
}
+ return;
+
+trunc:
+ ND_PRINT((ndo, " [|aodv]"));
}
--
1.8.3.1

View File

@ -1,190 +0,0 @@
From 3e8a443c3671baa37ae7870f08fb9b4bf386fd24 Mon Sep 17 00:00:00 2001
From: Guy Harris <guy@alum.mit.edu>
Date: Tue, 11 Nov 2014 18:37:35 -0800
Subject: [PATCH 1/4] Clean up error message printing.
Have "struct aodv_rerr" just be the header, not including the actual
destinations.
Simplify the logic somewhat, and make it similar in the print routines
for the three types of error messages.
---
print-aodv.c | 88 +++++++++++++++++++++++++++++++-----------------------------
1 file changed, 46 insertions(+), 42 deletions(-)
diff --git a/print-aodv.c b/print-aodv.c
index da5b169..da26473 100644
--- a/print-aodv.c
+++ b/print-aodv.c
@@ -146,13 +146,6 @@ struct aodv_rerr {
uint8_t rerr_flags; /* various flags */
uint8_t rerr_zero0; /* reserved, set to zero */
uint8_t rerr_dc; /* destination count */
- union {
- struct rerr_unreach dest[1];
-#ifdef INET6
- struct rerr_unreach6 dest6[1];
- struct rerr_unreach6_draft_01 dest6_draft_01[1];
-#endif
- } r;
};
#define RERR_NODELETE 0x80 /* don't delete the link */
@@ -284,32 +277,29 @@ static void
aodv_rerr(netdissect_options *ndo,
const struct aodv_rerr *ap, const u_char *dat, u_int length)
{
- u_int i;
- const struct rerr_unreach *dp = NULL;
- int n, trunc;
+ u_int i, dc;
+ const struct rerr_unreach *dp;
if (ndo->ndo_snapend < dat) {
ND_PRINT((ndo, " [|aodv]"));
return;
}
i = min(length, (u_int)(ndo->ndo_snapend - dat));
- if (i < offsetof(struct aodv_rerr, r)) {
+ if (i < sizeof(*ap)) {
ND_PRINT((ndo, " [|rerr]"));
return;
}
- i -= offsetof(struct aodv_rerr, r);
- dp = &ap->r.dest[0];
- n = ap->rerr_dc * sizeof(ap->r.dest[0]);
+ i -= sizeof(*ap);
ND_PRINT((ndo, " rerr %s [items %u] [%u]:",
ap->rerr_flags & RERR_NODELETE ? "[D]" : "",
ap->rerr_dc, length));
- trunc = n - (i/sizeof(ap->r.dest[0]));
- for (; i >= sizeof(ap->r.dest[0]);
- ++dp, i -= sizeof(ap->r.dest[0])) {
+ dp = (struct rerr_unreach *)(void *)(ap + 1);
+ for (dc = ap->rerr_dc; dc != 0 && i >= sizeof(*dp);
+ ++dp, --dc, i -= sizeof(*dp)) {
ND_PRINT((ndo, " {%s}(%ld)", ipaddr_string(ndo, &dp->u_da),
(unsigned long)EXTRACT_32BITS(&dp->u_ds)));
}
- if (trunc)
+ if ((i % sizeof(*dp)) != 0)
ND_PRINT((ndo, "[|rerr]"));
}
@@ -397,29 +387,36 @@ aodv_v6_rrep(netdissect_options *ndo,
static void
#ifdef INET6
aodv_v6_rerr(netdissect_options *ndo,
- const struct aodv_rerr *ap, u_int length)
+ const struct aodv_rerr *ap, const u_char *dat, u_int length)
#else
aodv_v6_rerr(netdissect_options *ndo,
- const struct aodv_rerr *ap _U_, u_int length)
+ const struct aodv_rerr *ap _U_, const u_char *dat, u_int length)
#endif
{
#ifdef INET6
- const struct rerr_unreach6 *dp6 = NULL;
- int i, j, n, trunc;
+ u_int i, dc;
+ const struct rerr_unreach6 *dp6;
- i = length - offsetof(struct aodv_rerr, r);
- j = sizeof(ap->r.dest6[0]);
- dp6 = &ap->r.dest6[0];
- n = ap->rerr_dc * j;
+ if (ndo->ndo_snapend < dat) {
+ ND_PRINT((ndo, " [|aodv]"));
+ return;
+ }
+ i = min(length, (u_int)(ndo->ndo_snapend - dat));
+ if (i < sizeof(*ap)) {
+ ND_PRINT((ndo, " [|rerr]"));
+ return;
+ }
+ i -= sizeof(*ap);
ND_PRINT((ndo, " rerr %s [items %u] [%u]:",
ap->rerr_flags & RERR_NODELETE ? "[D]" : "",
ap->rerr_dc, length));
- trunc = n - (i/j);
- for (; i -= j >= 0; ++dp6) {
+ dp6 = (struct rerr_unreach6 *)(void *)(ap + 1);
+ for (dc = ap->rerr_dc; dc != 0 && i >= sizeof(*dp6);
+ ++dp6, --dc, i -= sizeof(*dp6)) {
ND_PRINT((ndo, " {%s}(%ld)", ip6addr_string(ndo, &dp6->u_da),
(unsigned long)EXTRACT_32BITS(&dp6->u_ds)));
}
- if (trunc)
+ if ((i % sizeof(*dp6)) != 0)
ND_PRINT((ndo, "[|rerr]"));
#else
ND_PRINT((ndo, " rerr %u", length));
@@ -510,29 +507,36 @@ aodv_v6_draft_01_rrep(netdissect_options *ndo,
static void
#ifdef INET6
aodv_v6_draft_01_rerr(netdissect_options *ndo,
- const struct aodv_rerr *ap, u_int length)
+ const struct aodv_rerr *ap, const u_char *dat, u_int length)
#else
aodv_v6_draft_01_rerr(netdissect_options *ndo,
- const struct aodv_rerr *ap _U_, u_int length)
+ const struct aodv_rerr *ap _U_, const u_char *dat, u_int length)
#endif
{
#ifdef INET6
- const struct rerr_unreach6_draft_01 *dp6 = NULL;
- int i, j, n, trunc;
+ u_int i, dc;
+ const struct rerr_unreach6_draft_01 *dp6;
- i = length - offsetof(struct aodv_rerr, r);
- j = sizeof(ap->r.dest6_draft_01[0]);
- dp6 = &ap->r.dest6_draft_01[0];
- n = ap->rerr_dc * j;
+ if (ndo->ndo_snapend < dat) {
+ ND_PRINT((ndo, " [|aodv]"));
+ return;
+ }
+ i = min(length, (u_int)(ndo->ndo_snapend - dat));
+ if (i < sizeof(*ap)) {
+ ND_PRINT((ndo, " [|rerr]"));
+ return;
+ }
+ i -= sizeof(*ap);
ND_PRINT((ndo, " rerr %s [items %u] [%u]:",
ap->rerr_flags & RERR_NODELETE ? "[D]" : "",
ap->rerr_dc, length));
- trunc = n - (i/j);
- for (; i -= j >= 0; ++dp6) {
+ dp6 = (struct rerr_unreach6_draft_01 *)(void *)(ap + 1);
+ for (dc = ap->rerr_dc; dc != 0 && i >= sizeof(*dp6);
+ ++dp6, --dc, i -= sizeof(*dp6)) {
ND_PRINT((ndo, " {%s}(%ld)", ip6addr_string(ndo, &dp6->u_da),
(unsigned long)EXTRACT_32BITS(&dp6->u_ds)));
}
- if (trunc)
+ if ((i % sizeof(*dp6)) != 0)
ND_PRINT((ndo, "[|rerr]"));
#else
ND_PRINT((ndo, " rerr %u", length));
@@ -571,7 +575,7 @@ aodv_print(netdissect_options *ndo,
case AODV_RERR:
if (is_ip6)
- aodv_v6_rerr(ndo, (const struct aodv_rerr *)dat, length);
+ aodv_v6_rerr(ndo, (const struct aodv_rerr *)dat, dat, length);
else
aodv_rerr(ndo, (const struct aodv_rerr *)dat, dat, length);
break;
@@ -589,7 +593,7 @@ aodv_print(netdissect_options *ndo,
break;
case AODV_V6_DRAFT_01_RERR:
- aodv_v6_draft_01_rerr(ndo, (const struct aodv_rerr *)dat, length);
+ aodv_v6_draft_01_rerr(ndo, (const struct aodv_rerr *)dat, dat, length);
break;
case AODV_V6_DRAFT_01_RREP_ACK:
--
1.8.3.1

View File

@ -1,524 +0,0 @@
From e302ff0e4a6bde6915bee1c89373aa14c823dd60 Mon Sep 17 00:00:00 2001
From: Guy Harris <guy@alum.mit.edu>
Date: Tue, 11 Nov 2014 19:05:48 -0800
Subject: [PATCH 2/4] Further cleanups.
Use ND_TCHECK() rather than home-brew bounds checks. Do simpler length
checks.
Let i be the length of the actual remaining packet data; use ND_TCHECK()
inside loops that iterate over the remaining data.
Let the printers for particular message types cast the raw data pointer
to a pointer of the appropriate type, rather than passing two pointers,
with different types, to the same data.
---
print-aodv.c | 277 +++++++++++++++++++++++++++--------------------------------
1 file changed, 126 insertions(+), 151 deletions(-)
diff --git a/print-aodv.c b/print-aodv.c
index da26473..2649936 100644
--- a/print-aodv.c
+++ b/print-aodv.c
@@ -184,22 +184,14 @@ static void
aodv_extension(netdissect_options *ndo,
const struct aodv_ext *ep, u_int length)
{
- u_int i;
const struct aodv_hello *ah;
switch (ep->type) {
case AODV_EXT_HELLO:
- if (ndo->ndo_snapend < (u_char *) ep) {
- ND_PRINT((ndo, " [|hello]"));
- return;
- }
- i = min(length, (u_int)(ndo->ndo_snapend - (u_char *)ep));
- if (i < sizeof(struct aodv_hello)) {
- ND_PRINT((ndo, " [|hello]"));
- return;
- }
- i -= sizeof(struct aodv_hello);
- ah = (void *)ep;
+ ah = (const struct aodv_hello *)(const void *)ep;
+ ND_TCHECK(*ah);
+ if (length < sizeof(struct aodv_hello))
+ goto trunc;
ND_PRINT((ndo, "\n\text HELLO %ld ms",
(unsigned long)EXTRACT_32BITS(&ah->interval)));
break;
@@ -208,24 +200,21 @@ aodv_extension(netdissect_options *ndo,
ND_PRINT((ndo, "\n\text %u %u", ep->type, ep->length));
break;
}
+ return;
+
+trunc:
+ ND_PRINT((ndo, " [|hello]"));
}
static void
-aodv_rreq(netdissect_options *ndo,
- const struct aodv_rreq *ap, const u_char *dat, u_int length)
+aodv_rreq(netdissect_options *ndo, const u_char *dat, u_int length)
{
u_int i;
+ const struct aodv_rreq *ap = (const struct aodv_rreq *)dat;
- if (ndo->ndo_snapend < dat) {
- ND_PRINT((ndo, " [|aodv]"));
- return;
- }
- i = min(length, (u_int)(ndo->ndo_snapend - dat));
- if (i < sizeof(*ap)) {
- ND_PRINT((ndo, " [|rreq]"));
- return;
- }
- i -= sizeof(*ap);
+ ND_TCHECK(*ap);
+ if (length < sizeof(*ap))
+ goto trunc;
ND_PRINT((ndo, " rreq %u %s%s%s%s%shops %u id 0x%08lx\n"
"\tdst %s seq %lu src %s seq %lu", length,
ap->rreq_type & RREQ_JOIN ? "[J]" : "",
@@ -239,26 +228,24 @@ aodv_rreq(netdissect_options *ndo,
(unsigned long)EXTRACT_32BITS(&ap->rreq_ds),
ipaddr_string(ndo, &ap->rreq_oa),
(unsigned long)EXTRACT_32BITS(&ap->rreq_os)));
+ i = length - sizeof(*ap);
if (i >= sizeof(struct aodv_ext))
- aodv_extension(ndo, (void *)(ap + 1), i);
+ aodv_extension(ndo, (const struct aodv_ext *)(dat + sizeof(*ap)), i);
+ return;
+
+trunc:
+ ND_PRINT((ndo, " [|rreq"));
}
static void
-aodv_rrep(netdissect_options *ndo,
- const struct aodv_rrep *ap, const u_char *dat, u_int length)
+aodv_rrep(netdissect_options *ndo, const u_char *dat, u_int length)
{
u_int i;
+ const struct aodv_rrep *ap = (const struct aodv_rrep *)dat;
- if (ndo->ndo_snapend < dat) {
- ND_PRINT((ndo, " [|aodv]"));
- return;
- }
- i = min(length, (u_int)(ndo->ndo_snapend - dat));
- if (i < sizeof(*ap)) {
- ND_PRINT((ndo, " [|rrep]"));
- return;
- }
- i -= sizeof(*ap);
+ ND_TCHECK(*ap);
+ if (length < sizeof(*ap))
+ goto trunc;
ND_PRINT((ndo, " rrep %u %s%sprefix %u hops %u\n"
"\tdst %s dseq %lu src %s %lu ms", length,
ap->rrep_type & RREP_REPAIR ? "[R]" : "",
@@ -269,62 +256,58 @@ aodv_rrep(netdissect_options *ndo,
(unsigned long)EXTRACT_32BITS(&ap->rrep_ds),
ipaddr_string(ndo, &ap->rrep_oa),
(unsigned long)EXTRACT_32BITS(&ap->rrep_life)));
+ i = length - sizeof(*ap);
if (i >= sizeof(struct aodv_ext))
- aodv_extension(ndo, (void *)(ap + 1), i);
+ aodv_extension(ndo, (const struct aodv_ext *)(dat + sizeof(*ap)), i);
+ return;
+
+trunc:
+ ND_PRINT((ndo, " [|rreq"));
}
static void
-aodv_rerr(netdissect_options *ndo,
- const struct aodv_rerr *ap, const u_char *dat, u_int length)
+aodv_rerr(netdissect_options *ndo, const u_char *dat, u_int length)
{
u_int i, dc;
+ const struct aodv_rerr *ap = (const struct aodv_rerr *)dat;
const struct rerr_unreach *dp;
- if (ndo->ndo_snapend < dat) {
- ND_PRINT((ndo, " [|aodv]"));
- return;
- }
- i = min(length, (u_int)(ndo->ndo_snapend - dat));
- if (i < sizeof(*ap)) {
- ND_PRINT((ndo, " [|rerr]"));
- return;
- }
- i -= sizeof(*ap);
+ ND_TCHECK(*ap);
+ if (length < sizeof(*ap))
+ goto trunc;
ND_PRINT((ndo, " rerr %s [items %u] [%u]:",
ap->rerr_flags & RERR_NODELETE ? "[D]" : "",
ap->rerr_dc, length));
- dp = (struct rerr_unreach *)(void *)(ap + 1);
+ dp = (struct rerr_unreach *)(dat + sizeof(*ap));
+ i = length - sizeof(*ap);
for (dc = ap->rerr_dc; dc != 0 && i >= sizeof(*dp);
++dp, --dc, i -= sizeof(*dp)) {
+ ND_TCHECK(*dp);
ND_PRINT((ndo, " {%s}(%ld)", ipaddr_string(ndo, &dp->u_da),
(unsigned long)EXTRACT_32BITS(&dp->u_ds)));
}
if ((i % sizeof(*dp)) != 0)
- ND_PRINT((ndo, "[|rerr]"));
+ goto trunc;
+ return;
+
+trunc:
+ ND_PRINT((ndo, "[|rerr]"));
}
static void
#ifdef INET6
-aodv_v6_rreq(netdissect_options *ndo,
- const struct aodv_rreq6 *ap, const u_char *dat, u_int length)
+aodv_v6_rreq(netdissect_options *ndo, const u_char *dat, u_int length)
#else
-aodv_v6_rreq(netdissect_options *ndo,
- const struct aodv_rreq6 *ap _U_, const u_char *dat _U_, u_int length)
+aodv_v6_rreq(netdissect_options *ndo, const u_char *dat _U_, u_int length)
#endif
{
#ifdef INET6
u_int i;
+ const struct aodv_rreq6 *ap = (const struct aodv_rreq6 *)dat;
- if (ndo->ndo_snapend < dat) {
- ND_PRINT((ndo, " [|aodv]"));
- return;
- }
- i = min(length, (u_int)(ndo->ndo_snapend - dat));
- if (i < sizeof(*ap)) {
- ND_PRINT((ndo, " [|rreq6]"));
- return;
- }
- i -= sizeof(*ap);
+ ND_TCHECK(*ap);
+ if (length < sizeof(*ap))
+ goto trunc;
ND_PRINT((ndo, " v6 rreq %u %s%s%s%s%shops %u id 0x%08lx\n"
"\tdst %s seq %lu src %s seq %lu", length,
ap->rreq_type & RREQ_JOIN ? "[J]" : "",
@@ -338,8 +321,13 @@ aodv_v6_rreq(netdissect_options *ndo,
(unsigned long)EXTRACT_32BITS(&ap->rreq_ds),
ip6addr_string(ndo, &ap->rreq_oa),
(unsigned long)EXTRACT_32BITS(&ap->rreq_os)));
+ i = length - sizeof(*ap);
if (i >= sizeof(struct aodv_ext))
- aodv_extension(ndo, (void *)(ap + 1), i);
+ aodv_extension(ndo, (const struct aodv_ext *)(dat + sizeof(*ap)), i);
+ return;
+
+trunc:
+ ND_PRINT((ndo, " [|rreq"));
#else
ND_PRINT((ndo, " v6 rreq %u", length));
#endif
@@ -347,26 +335,18 @@ aodv_v6_rreq(netdissect_options *ndo,
static void
#ifdef INET6
-aodv_v6_rrep(netdissect_options *ndo,
- const struct aodv_rrep6 *ap, const u_char *dat, u_int length)
+aodv_v6_rrep(netdissect_options *ndo, const u_char *dat, u_int length)
#else
-aodv_v6_rrep(netdissect_options *ndo,
- const struct aodv_rrep6 *ap _U_, const u_char *dat _U_, u_int length)
+aodv_v6_rrep(netdissect_options *ndo, const u_char *dat _U_, u_int length)
#endif
{
#ifdef INET6
u_int i;
+ const struct aodv_rrep6 *ap = (const struct aodv_rrep6 *)dat;
- if (ndo->ndo_snapend < dat) {
- ND_PRINT((ndo, " [|aodv]"));
- return;
- }
- i = min(length, (u_int)(ndo->ndo_snapend - dat));
- if (i < sizeof(*ap)) {
- ND_PRINT((ndo, " [|rrep6]"));
- return;
- }
- i -= sizeof(*ap);
+ ND_TCHECK(*ap);
+ if (length < sizeof(*ap))
+ goto trunc;
ND_PRINT((ndo, " rrep %u %s%sprefix %u hops %u\n"
"\tdst %s dseq %lu src %s %lu ms", length,
ap->rrep_type & RREP_REPAIR ? "[R]" : "",
@@ -377,8 +357,13 @@ aodv_v6_rrep(netdissect_options *ndo,
(unsigned long)EXTRACT_32BITS(&ap->rrep_ds),
ip6addr_string(ndo, &ap->rrep_oa),
(unsigned long)EXTRACT_32BITS(&ap->rrep_life)));
+ i = length - sizeof(*ap);
if (i >= sizeof(struct aodv_ext))
- aodv_extension(ndo, (void *)(ap + 1), i);
+ aodv_extension(ndo, (const struct aodv_ext *)(dat + sizeof(*ap)), i);
+ return;
+
+trunc:
+ ND_PRINT((ndo, " [|rreq"));
#else
ND_PRINT((ndo, " rrep %u", length));
#endif
@@ -386,38 +371,36 @@ aodv_v6_rrep(netdissect_options *ndo,
static void
#ifdef INET6
-aodv_v6_rerr(netdissect_options *ndo,
- const struct aodv_rerr *ap, const u_char *dat, u_int length)
+aodv_v6_rerr(netdissect_options *ndo, const u_char *dat, u_int length)
#else
-aodv_v6_rerr(netdissect_options *ndo,
- const struct aodv_rerr *ap _U_, const u_char *dat, u_int length)
+aodv_v6_rerr(netdissect_options *ndo, const u_char *dat _U_, u_int length)
#endif
{
#ifdef INET6
u_int i, dc;
+ const struct aodv_rerr *ap = (const struct aodv_rerr *)dat;
const struct rerr_unreach6 *dp6;
- if (ndo->ndo_snapend < dat) {
- ND_PRINT((ndo, " [|aodv]"));
- return;
- }
- i = min(length, (u_int)(ndo->ndo_snapend - dat));
- if (i < sizeof(*ap)) {
- ND_PRINT((ndo, " [|rerr]"));
- return;
- }
- i -= sizeof(*ap);
+ ND_TCHECK(*ap);
+ if (length < sizeof(*ap))
+ goto trunc;
ND_PRINT((ndo, " rerr %s [items %u] [%u]:",
ap->rerr_flags & RERR_NODELETE ? "[D]" : "",
ap->rerr_dc, length));
dp6 = (struct rerr_unreach6 *)(void *)(ap + 1);
+ i = length - sizeof(*ap);
for (dc = ap->rerr_dc; dc != 0 && i >= sizeof(*dp6);
++dp6, --dc, i -= sizeof(*dp6)) {
+ ND_TCHECK(*dp6);
ND_PRINT((ndo, " {%s}(%ld)", ip6addr_string(ndo, &dp6->u_da),
(unsigned long)EXTRACT_32BITS(&dp6->u_ds)));
}
if ((i % sizeof(*dp6)) != 0)
- ND_PRINT((ndo, "[|rerr]"));
+ goto trunc;
+ return;
+
+trunc:
+ ND_PRINT((ndo, "[|rerr]"));
#else
ND_PRINT((ndo, " rerr %u", length));
#endif
@@ -425,26 +408,18 @@ aodv_v6_rerr(netdissect_options *ndo,
static void
#ifdef INET6
-aodv_v6_draft_01_rreq(netdissect_options *ndo,
- const struct aodv_rreq6_draft_01 *ap, const u_char *dat, u_int length)
+aodv_v6_draft_01_rreq(netdissect_options *ndo, const u_char *dat, u_int length)
#else
-aodv_v6_draft_01_rreq(netdissect_options *ndo,
- const struct aodv_rreq6_draft_01 *ap _U_, const u_char *dat _U_, u_int length)
+aodv_v6_draft_01_rreq(netdissect_options *ndo, const u_char *dat _U_, u_int length)
#endif
{
#ifdef INET6
u_int i;
+ const struct aodv_rreq6_draft_01 *ap = (const struct aodv_rreq6_draft_01 *)dat;
- if (ndo->ndo_snapend < dat) {
- ND_PRINT((ndo, " [|aodv]"));
- return;
- }
- i = min(length, (u_int)(ndo->ndo_snapend - dat));
- if (i < sizeof(*ap)) {
- ND_PRINT((ndo, " [|rreq6]"));
- return;
- }
- i -= sizeof(*ap);
+ ND_TCHECK(*ap);
+ if (length < sizeof(*ap))
+ goto trunc;
ND_PRINT((ndo, " rreq %u %s%s%s%s%shops %u id 0x%08lx\n"
"\tdst %s seq %lu src %s seq %lu", length,
ap->rreq_type & RREQ_JOIN ? "[J]" : "",
@@ -458,8 +433,13 @@ aodv_v6_draft_01_rreq(netdissect_options *ndo,
(unsigned long)EXTRACT_32BITS(&ap->rreq_ds),
ip6addr_string(ndo, &ap->rreq_oa),
(unsigned long)EXTRACT_32BITS(&ap->rreq_os)));
+ i = length - sizeof(*ap);
if (i >= sizeof(struct aodv_ext))
- aodv_extension(ndo, (void *)(ap + 1), i);
+ aodv_extension(ndo, (const struct aodv_ext *)(dat + sizeof(*ap)), i);
+ return;
+
+trunc:
+ ND_PRINT((ndo, " [|rreq"));
#else
ND_PRINT((ndo, " rreq %u", length));
#endif
@@ -467,26 +447,18 @@ aodv_v6_draft_01_rreq(netdissect_options *ndo,
static void
#ifdef INET6
-aodv_v6_draft_01_rrep(netdissect_options *ndo,
- const struct aodv_rrep6_draft_01 *ap, const u_char *dat, u_int length)
+aodv_v6_draft_01_rrep(netdissect_options *ndo, const u_char *dat, u_int length)
#else
-aodv_v6_draft_01_rrep(netdissect_options *ndo,
- const struct aodv_rrep6_draft_01 *ap _U_, const u_char *dat _U_, u_int length)
+aodv_v6_draft_01_rrep(netdissect_options *ndo, const u_char *dat _U_, u_int length)
#endif
{
#ifdef INET6
u_int i;
+ const struct aodv_rrep6_draft_01 *ap = (const struct aodv_rrep6_draft_01 *)dat;
- if (ndo->ndo_snapend < dat) {
- ND_PRINT((ndo, " [|aodv]"));
- return;
- }
- i = min(length, (u_int)(ndo->ndo_snapend - dat));
- if (i < sizeof(*ap)) {
- ND_PRINT((ndo, " [|rrep6]"));
- return;
- }
- i -= sizeof(*ap);
+ ND_TCHECK(*ap);
+ if (length < sizeof(*ap))
+ goto trunc;
ND_PRINT((ndo, " rrep %u %s%sprefix %u hops %u\n"
"\tdst %s dseq %lu src %s %lu ms", length,
ap->rrep_type & RREP_REPAIR ? "[R]" : "",
@@ -497,8 +469,13 @@ aodv_v6_draft_01_rrep(netdissect_options *ndo,
(unsigned long)EXTRACT_32BITS(&ap->rrep_ds),
ip6addr_string(ndo, &ap->rrep_oa),
(unsigned long)EXTRACT_32BITS(&ap->rrep_life)));
+ i = length - sizeof(*ap);
if (i >= sizeof(struct aodv_ext))
- aodv_extension(ndo, (void *)(ap + 1), i);
+ aodv_extension(ndo, (const struct aodv_ext *)(dat + sizeof(*ap)), i);
+ return;
+
+trunc:
+ ND_PRINT((ndo, " [|rreq"));
#else
ND_PRINT((ndo, " rrep %u", length));
#endif
@@ -506,38 +483,36 @@ aodv_v6_draft_01_rrep(netdissect_options *ndo,
static void
#ifdef INET6
-aodv_v6_draft_01_rerr(netdissect_options *ndo,
- const struct aodv_rerr *ap, const u_char *dat, u_int length)
+aodv_v6_draft_01_rerr(netdissect_options *ndo, const u_char *dat, u_int length)
#else
-aodv_v6_draft_01_rerr(netdissect_options *ndo,
- const struct aodv_rerr *ap _U_, const u_char *dat, u_int length)
+aodv_v6_draft_01_rerr(netdissect_options *ndo, const u_char *dat _U_, u_int length)
#endif
{
#ifdef INET6
u_int i, dc;
+ const struct aodv_rerr *ap = (const struct aodv_rerr *)dat;
const struct rerr_unreach6_draft_01 *dp6;
- if (ndo->ndo_snapend < dat) {
- ND_PRINT((ndo, " [|aodv]"));
- return;
- }
- i = min(length, (u_int)(ndo->ndo_snapend - dat));
- if (i < sizeof(*ap)) {
- ND_PRINT((ndo, " [|rerr]"));
- return;
- }
- i -= sizeof(*ap);
+ ND_TCHECK(*ap);
+ if (length < sizeof(*ap))
+ goto trunc;
ND_PRINT((ndo, " rerr %s [items %u] [%u]:",
ap->rerr_flags & RERR_NODELETE ? "[D]" : "",
ap->rerr_dc, length));
dp6 = (struct rerr_unreach6_draft_01 *)(void *)(ap + 1);
+ i = length - sizeof(*ap);
for (dc = ap->rerr_dc; dc != 0 && i >= sizeof(*dp6);
++dp6, --dc, i -= sizeof(*dp6)) {
+ ND_TCHECK(*dp6);
ND_PRINT((ndo, " {%s}(%ld)", ip6addr_string(ndo, &dp6->u_da),
(unsigned long)EXTRACT_32BITS(&dp6->u_ds)));
}
if ((i % sizeof(*dp6)) != 0)
- ND_PRINT((ndo, "[|rerr]"));
+ goto trunc;
+ return;
+
+trunc:
+ ND_PRINT((ndo, "[|rerr]"));
#else
ND_PRINT((ndo, " rerr %u", length));
#endif
@@ -561,23 +536,23 @@ aodv_print(netdissect_options *ndo,
case AODV_RREQ:
if (is_ip6)
- aodv_v6_rreq(ndo, (const struct aodv_rreq6 *)dat, dat, length);
+ aodv_v6_rreq(ndo, dat, length);
else
- aodv_rreq(ndo, (const struct aodv_rreq *)dat, dat, length);
+ aodv_rreq(ndo, dat, length);
break;
case AODV_RREP:
if (is_ip6)
- aodv_v6_rrep(ndo, (const struct aodv_rrep6 *)dat, dat, length);
+ aodv_v6_rrep(ndo, dat, length);
else
- aodv_rrep(ndo, (const struct aodv_rrep *)dat, dat, length);
+ aodv_rrep(ndo, dat, length);
break;
case AODV_RERR:
if (is_ip6)
- aodv_v6_rerr(ndo, (const struct aodv_rerr *)dat, dat, length);
+ aodv_v6_rerr(ndo, dat, length);
else
- aodv_rerr(ndo, (const struct aodv_rerr *)dat, dat, length);
+ aodv_rerr(ndo, dat, length);
break;
case AODV_RREP_ACK:
@@ -585,15 +560,15 @@ aodv_print(netdissect_options *ndo,
break;
case AODV_V6_DRAFT_01_RREQ:
- aodv_v6_draft_01_rreq(ndo, (const struct aodv_rreq6_draft_01 *)dat, dat, length);
+ aodv_v6_draft_01_rreq(ndo, dat, length);
break;
case AODV_V6_DRAFT_01_RREP:
- aodv_v6_draft_01_rrep(ndo, (const struct aodv_rrep6_draft_01 *)dat, dat, length);
+ aodv_v6_draft_01_rrep(ndo, dat, length);
break;
case AODV_V6_DRAFT_01_RERR:
- aodv_v6_draft_01_rerr(ndo, (const struct aodv_rerr *)dat, dat, length);
+ aodv_v6_draft_01_rerr(ndo, dat, length);
break;
case AODV_V6_DRAFT_01_RREP_ACK:
--
1.8.3.1

View File

@ -1,26 +0,0 @@
From 54d2912c19240a1a1866ba1519889086868038c4 Mon Sep 17 00:00:00 2001
From: Guy Harris <guy@alum.mit.edu>
Date: Tue, 11 Nov 2014 19:18:12 -0800
Subject: [PATCH 3/4] Not using offsetof() any more, so no need for <stddef.h>.
---
print-aodv.c | 3 ---
1 file changed, 3 deletions(-)
diff --git a/print-aodv.c b/print-aodv.c
index 2649936..9b3523a 100644
--- a/print-aodv.c
+++ b/print-aodv.c
@@ -37,9 +37,6 @@
#include <tcpdump-stdinc.h>
-/* for offsetof */
-#include <stddef.h>
-
#include "interface.h"
#include "addrtoname.h"
#include "extract.h" /* must come after interface.h */
--
1.8.3.1

View File

@ -1,81 +0,0 @@
From 3f5693a2bb783b1caa2a308e64ee34d167f36f05 Mon Sep 17 00:00:00 2001
From: Guy Harris <guy@alum.mit.edu>
Date: Wed, 12 Nov 2014 01:09:27 -0800
Subject: [PATCH 4/4] Report a too-long unreachable destination list.
Running out of packet length before running out of unreachable
destinations is an error; report it as such.
Don't worry about leftover data past the end of the list of unreachable
destinations.
---
print-aodv.c | 27 +++++++++++++++------------
1 file changed, 15 insertions(+), 12 deletions(-)
diff --git a/print-aodv.c b/print-aodv.c
index 9b3523a..ef27eee 100644
--- a/print-aodv.c
+++ b/print-aodv.c
@@ -277,14 +277,15 @@ aodv_rerr(netdissect_options *ndo, const u_char *dat, u_int length)
ap->rerr_dc, length));
dp = (struct rerr_unreach *)(dat + sizeof(*ap));
i = length - sizeof(*ap);
- for (dc = ap->rerr_dc; dc != 0 && i >= sizeof(*dp);
- ++dp, --dc, i -= sizeof(*dp)) {
+ for (dc = ap->rerr_dc; dc != 0; dc--) {
ND_TCHECK(*dp);
+ if (i < sizeof(*dp))
+ goto trunc;
ND_PRINT((ndo, " {%s}(%ld)", ipaddr_string(ndo, &dp->u_da),
(unsigned long)EXTRACT_32BITS(&dp->u_ds)));
+ dp++;
+ i -= sizeof(*dp);
}
- if ((i % sizeof(*dp)) != 0)
- goto trunc;
return;
trunc:
@@ -386,14 +387,15 @@ aodv_v6_rerr(netdissect_options *ndo, const u_char *dat _U_, u_int length)
ap->rerr_dc, length));
dp6 = (struct rerr_unreach6 *)(void *)(ap + 1);
i = length - sizeof(*ap);
- for (dc = ap->rerr_dc; dc != 0 && i >= sizeof(*dp6);
- ++dp6, --dc, i -= sizeof(*dp6)) {
+ for (dc = ap->rerr_dc; dc != 0; dc--) {
ND_TCHECK(*dp6);
+ if (i < sizeof(*dp6))
+ goto trunc;
ND_PRINT((ndo, " {%s}(%ld)", ip6addr_string(ndo, &dp6->u_da),
(unsigned long)EXTRACT_32BITS(&dp6->u_ds)));
+ dp6++;
+ i -= sizeof(*dp6);
}
- if ((i % sizeof(*dp6)) != 0)
- goto trunc;
return;
trunc:
@@ -498,14 +500,15 @@ aodv_v6_draft_01_rerr(netdissect_options *ndo, const u_char *dat _U_, u_int leng
ap->rerr_dc, length));
dp6 = (struct rerr_unreach6_draft_01 *)(void *)(ap + 1);
i = length - sizeof(*ap);
- for (dc = ap->rerr_dc; dc != 0 && i >= sizeof(*dp6);
- ++dp6, --dc, i -= sizeof(*dp6)) {
+ for (dc = ap->rerr_dc; dc != 0; dc--) {
ND_TCHECK(*dp6);
+ if (i < sizeof(*dp6))
+ goto trunc;
ND_PRINT((ndo, " {%s}(%ld)", ip6addr_string(ndo, &dp6->u_da),
(unsigned long)EXTRACT_32BITS(&dp6->u_ds)));
+ dp6++;
+ i -= sizeof(*dp6);
}
- if ((i % sizeof(*dp6)) != 0)
- goto trunc;
return;
trunc:
--
1.8.3.1

View File

@ -1,55 +0,0 @@
From 34303452e4286e4894117adbfa017897597cbbb6 Mon Sep 17 00:00:00 2001
From: Guy Harris <guy@alum.mit.edu>
Date: Wed, 22 Oct 2014 12:31:21 -0700
Subject: [PATCH] Do bounds checking when unescaping PPP.
Clean up a const issue while we're at it.
---
print-ppp.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/print-ppp.c b/print-ppp.c
index b858b73..eacba34 100644
--- a/print-ppp.c
+++ b/print-ppp.c
@@ -1351,14 +1351,15 @@ static void
ppp_hdlc(netdissect_options *ndo,
const u_char *p, int length)
{
- u_char *b, *s, *t, c;
+ u_char *b, *t, c;
+ const u_char *s;
int i, proto;
const void *se;
if (length <= 0)
return;
- b = (uint8_t *)malloc(length);
+ b = (u_char *)malloc(length);
if (b == NULL)
return;
@@ -1367,14 +1368,13 @@ ppp_hdlc(netdissect_options *ndo,
* Do this so that we dont overwrite the original packet
* contents.
*/
- for (s = (u_char *)p, t = b, i = length; i > 0; i--) {
+ for (s = p, t = b, i = length; i > 0 && ND_TTEST(*s); i--) {
c = *s++;
if (c == 0x7d) {
- if (i > 1) {
- i--;
- c = *s++ ^ 0x20;
- } else
- continue;
+ if (i <= 1 || !ND_TTEST(*s))
+ break;
+ i--;
+ c = *s++ ^ 0x20;
}
*t++ = c;
}
--
1.8.3.1

View File

@ -1,2 +1,2 @@
74d0d3728b3cdc60db872d842e7f1598 tcpdump-4.6.2.tar.gz
334a4761594b29f80793c1303f0f4acc tcpdump-4.7.3.tar.gz
e329cbeb7e589f132d92c3447c477190 tcpslice-1.2a3.tar.gz

View File

@ -1,8 +1,8 @@
Summary: A network traffic monitoring tool
Name: tcpdump
Epoch: 14
Version: 4.6.2
Release: 3%{?dist}
Version: 4.7.3
Release: 1%{?dist}
License: BSD with advertising
URL: http://www.tcpdump.org
Group: Applications/Internet
@ -20,14 +20,6 @@ Patch0005: 0005-tcpslice-remove-unneeded-include.patch
Patch0006: 0006-tcpslice-don-t-test-the-pointer-but-pointee-for-NULL.patch
Patch0007: 0007-Introduce-nn-option.patch
Patch0008: 0008-Don-t-print-out-we-dropped-root-we-are-always-droppi.patch
Patch0009: 0009-Do-more-bounds-checking-and-length-checking.patch
Patch0010: 0010-Do-bounds-checking-and-length-checking.patch
Patch0011: 0011-Add-initial-bounds-check-get-rid-of-union-aodv.patch
Patch0012: 0012-Clean-up-error-message-printing.patch
Patch0013: 0013-Further-cleanups.patch
Patch0014: 0014-Not-using-offsetof-any-more-so-no-need-for-stddef.h.patch
Patch0015: 0015-Report-a-too-long-unreachable-destination-list.patch
Patch0016: 0016-Do-bounds-checking-when-unescaping-PPP.patch
%define tcpslice_dir tcpslice-1.2a3
@ -90,6 +82,10 @@ exit 0
%{_mandir}/man8/tcpdump.8*
%changelog
* Wed Mar 25 2015 Michal Sekletar <msekleta@redhat.com> - 14:4.7.3-1
- rebase to 4.7.3 (#1201573)
- contains fixes for CVE-2015-0261 CVE-2015-2154 CVE-2015-2153 CVE-2015-2155 (#1201799,#1201792,#1201795,#1201797)
* Wed Dec 03 2014 Michal Sekletar <msekleta@redhat.com> - 14:4.6.2-3
- fix for CVE-2014-9140