Upstream fixes for issues found with afl (Issue #417).

- Fix length checking.

Check both the captured length and the on-the-wire length (the latter
*should* be greater than or equal to the former, but that's not
guaranteed).

Add some additional length checks, so neither caplen nor length
underflow.

If we stop dissecting because the packet is too short, return 1, not 0,
as we've "dissected" what we can; 0 means "this is LLC+SNAP with an OUI
of 0 and an unknown Ethertype".

commit:	743bcecdc92f88b118ec7aac4f68b606601205cc

- Clean up length checks.

Check only the amount of length that matters at any given point; yes,
this means we do multiple checks, but so it goes.

We don't need to check for LLC+SNAP - llc_print() does that for us.  We
do, however, need to check to make sure we can safely skip the Fore
header.

commit:	5c65e7532fa16308e01299988852b0dc5b027559
This commit is contained in:
Pedro F. Giffuni 2015-01-31 16:26:21 +00:00
parent aae6b2073a
commit d3b6650ba6
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/vendor/tcpdump/dist/; revision=277981
2 changed files with 25 additions and 5 deletions

View File

@ -165,7 +165,7 @@ atm_if_print(netdissect_options *ndo,
uint32_t llchdr;
u_int hdrlen = 0;
if (caplen < 8) {
if (caplen < 1 || length < 1) {
ND_PRINT((ndo, "%s", tstr));
return (caplen);
}
@ -178,6 +178,15 @@ atm_if_print(netdissect_options *ndo,
return hdrlen;
}
/*
* Must have at least a DSAP, an SSAP, and the first byte of the
* control field.
*/
if (caplen < 3 || length < 3) {
ND_PRINT((ndo, "%s", tstr));
return (caplen);
}
/*
* Extract the presumed LLC header into a variable, for quick
* testing.
@ -205,6 +214,10 @@ atm_if_print(netdissect_options *ndo,
* packets? If so, could it be changed to use a
* new DLT_IEEE802_6 value if we added it?
*/
if (caplen < 20 || length < 20) {
ND_PRINT((ndo, "%s", tstr));
return (caplen);
}
if (ndo->ndo_eflag)
ND_PRINT((ndo, "%08x%08x %08x%08x ",
EXTRACT_32BITS(p),

View File

@ -151,10 +151,10 @@ llc_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen,
*extracted_ethertype = 0;
if (caplen < 3) {
if (caplen < 3 || length < 3) {
ND_PRINT((ndo, "[|llc]"));
ND_DEFAULTPRINT((u_char *)p, caplen);
return(0);
return (1);
}
dsap_field = *p;
@ -177,10 +177,10 @@ llc_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen,
* The control field in I and S frames is
* 2 bytes...
*/
if (caplen < 4) {
if (caplen < 4 || length < 4) {
ND_PRINT((ndo, "[|llc]"));
ND_DEFAULTPRINT((u_char *)p, caplen);
return(0);
return (1);
}
/*
@ -240,6 +240,11 @@ llc_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen,
if (ssap == LLCSAP_IP && dsap == LLCSAP_IP &&
control == LLC_UI) {
if (caplen < 4 || length < 4) {
ND_PRINT((ndo, "[|llc]"));
ND_DEFAULTPRINT((u_char *)p, caplen);
return (1);
}
ip_print(ndo, p+4, length-4);
return (1);
}
@ -368,6 +373,8 @@ snap_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen,
register int ret;
ND_TCHECK2(*p, 5);
if (caplen < 5 || length < 5)
goto trunc;
orgcode = EXTRACT_24BITS(p);
et = EXTRACT_16BITS(p + 3);