Wireshark-dev: Re: [Wireshark-dev] assertion for malformed packets?

From: Guy Harris <guy@xxxxxxxxxxxx>
Date: Mon, 16 Apr 2007 03:36:17 -0700
Jeff Morriss wrote:

Bug 1511 replaced a g_assert() by a DISSECTOR_ASSERT() to avoid exiting on a bad packet, but that will show up as a "dissector bug" when really the problem is in the packet.
You're correct - neither g_assert() nor DISSECTOR_ASSERT() are 
appropriate for problems with packet data.  An assert is something that 
should be used to test something that should *always* be true - i.e., 
there's an error in the code if it's not true.  That applies to 
assert(), g_assert(), and DISSECTOR_ASSERT() - and to any 
DISSECTOR_ASSERT_... macro.
Any objections to, say, DISSECTOR_ASSERT_MALFORMED_PACKET which would throw a BoundsError for use in this kind of situations? (No, it's not
really a bounds error
Then it shouldn't be BoundsError.

but the effect is the desired one: the user gets shown "malformed packet".) I have, in the past, also wanted a simple assertion like that when a dissector finds illogical stuff in the packet.
In that particular case, dissection shouldn't necessarily be aborted if 
an AVP has a bogus length - a bad AVP within a Grouped AVP should 
terminate dissection of the grouped AVP, but the dissector should be 
able to dissect the next AVP.
If there are problems at a low level in a packet that should truly abort 
the dissection of that entire packet, not just a sub-item in the packet, 
we should probably add a new exception for that purpose; we're already 
abusing ReportedBoundsError for that in some places.  If the problem is 
associated with a particular  item in the packet, the exception 
shouldn't add its own item to the protocol tree, as happens with 
ReportedBoundsError - the item in the packet should be displayed with an 
error indication, and then the exception should be thrown.  That 
exception should be caught in the same places that ReportedBoundsError 
is caught, so that if a given lower-level packet has data from more than 
one higher-level packet, an error in the higher-level packet doesn't 
abort dissection of the lower-level packet.
This raises several questions:

1) I seem to remember noticing that, at some point, generic TVL/AVP/{whatever the particular protocol spec calls them} dissection code was added for use by dissectors, although I can't remember where it was. Am I misremembering? If not, where's that code, and could we convert more dissectors to use it? Presumably if it can dissect TVL's/AVP's/whatever's when the length is the total length of the item, rather than the length of the value, it checks for a length that's shorter than the length of the type field + the length of the length field, and somehow reports an error.
	2) Perhaps some mechanism for flagging a packet as being somehow "bad" 
would be useful, so a display filter could check for "bad" packets, and 
various types of problems, including but not limited to actual 
ReportedBoundsErrors?
	   Would the expert mechanism be appropriate for that?  We can already 
mark a packet as having an error with an expert severity of PI_ERROR; 
should we support display filters to check for particular expert severities?
	3) Speaking of the expert mechanism, why are the PI_ values defined in 
proto.h rather than expert.h?
	4) In a number of dissectors, length checking when dissecting sub-items 
within an item is done by creating a tvbuff for the item; that means 
that if the item is too short, a ReportedBoundsError exception is thrown 
if the item is too short, so dissection of the entire packet is aborted 
even if items past the too-short item can be dissected.