diff options
author | Guy Harris <guy@alum.mit.edu> | 2015-06-27 15:29:37 -0700 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2015-06-27 22:30:12 +0000 |
commit | 80efc53b05ffdbcbc6cb68abbb0bcc56097f140e (patch) | |
tree | 4f20d369b42cfb5ad710d455b31981ce362d2f49 | |
parent | 74a5f50c806c557ee8412d3f0c0f8120e41153f3 (diff) | |
download | wireshark-80efc53b05ffdbcbc6cb68abbb0bcc56097f140e.tar.gz |
Quick and dirty overflow checking.
We really need a better way to handle packet offset overflows.
Change-Id: I6e476f7bc6ddac2c5515c4e09192d88f528ea091
Reviewed-on: https://code.wireshark.org/review/9194
Reviewed-by: Guy Harris <guy@alum.mit.edu>
-rw-r--r-- | epan/dissectors/packet-aeron.c | 33 |
1 files changed, 29 insertions, 4 deletions
diff --git a/epan/dissectors/packet-aeron.c b/epan/dissectors/packet-aeron.c index 59c64a25c5..c1d72ad3dc 100644 --- a/epan/dissectors/packet-aeron.c +++ b/epan/dissectors/packet-aeron.c @@ -32,6 +32,7 @@ #include <epan/uat.h> #include <epan/tap.h> #include <epan/conversation.h> +#include <epan/exceptions.h> #include <epan/to_str.h> #ifndef HAVE_INET_ATON #include <wsutil/inet_aton.h> @@ -124,9 +125,18 @@ static guint32 aeron_pos_delta(const aeron_pos_t * pos1, const aeron_pos_t * pos return ((guint32) (delta & G_GUINT64_CONSTANT(0x00000000ffffffff))); } -static void aeron_pos_add_length(aeron_pos_t * pos, guint32 length, guint32 term_length) +static gboolean aeron_pos_add_length(aeron_pos_t * pos, guint32 length, guint32 term_length) { - guint32 next_term_offset = aeron_pos_roundup(pos->term_offset + length); + guint32 next_term_offset; + guint32 rounded_next_term_offset; + + next_term_offset = pos->term_offset + length; + if (next_term_offset < pos->term_offset) + return FALSE; /* overflow */ + rounded_next_term_offset = aeron_pos_roundup(next_term_offset); + if (rounded_next_term_offset < next_term_offset) + return FALSE; /* overflow */ + next_term_offset = rounded_next_term_offset; if (next_term_offset >= term_length) { @@ -137,6 +147,7 @@ static void aeron_pos_add_length(aeron_pos_t * pos, guint32 length, guint32 term { pos->term_offset = next_term_offset; } + return TRUE; } /*----------------------------------------------------------------------------*/ @@ -1249,7 +1260,8 @@ static void aeron_frame_stream_analysis_setup(packet_info * pinfo, aeron_packet_ case HDR_TYPE_PAD: dp.term_id = info->term_id; dp.term_offset = info->term_offset; - aeron_pos_add_length(&dp, info->length, stream->term_length); + if (!aeron_pos_add_length(&dp, info->length, stream->term_length)) + THROW(ReportedBoundsError); if (pdpv) { if (dp.term_id > stream->high.term_id) @@ -1377,7 +1389,8 @@ static void aeron_frame_stream_analysis_setup(packet_info * pinfo, aeron_packet_ expected_dp.term_id = pdp.term_id; expected_dp.term_offset = pdp.term_offset; - aeron_pos_add_length(&expected_dp, info->length, stream->term_length); + if (!aeron_pos_add_length(&expected_dp, info->length, stream->term_length)) + THROW(ReportedBoundsError); erc = aeron_pos_compare(&expected_dp, &dp); if (erc > 0) { @@ -2186,6 +2199,8 @@ static int dissect_aeron_pad(tvbuff_t * tvb, int offset, packet_info * pinfo, pr frame_length = tvb_get_letohl(tvb, offset + O_AERON_PAD_FRAME_LENGTH); rounded_length = (int) aeron_pos_roundup(frame_length); + if (rounded_length < 0) + THROW(ReportedBoundsError); term_offset = tvb_get_letohl(tvb, offset + O_AERON_PAD_TERM_OFFSET); session_id = tvb_get_letohl(tvb, offset + O_AERON_PAD_SESSION_ID); transport = aeron_transport_add(cinfo, session_id, pinfo->fd->num); @@ -2325,6 +2340,8 @@ static int dissect_aeron_data(tvbuff_t * tvb, int offset, packet_info * pinfo, p { offset_increment = aeron_pos_roundup(frame_length); rounded_length = (int) offset_increment; + if (rounded_length < 0) + THROW(ReportedBoundsError); data_length = frame_length - O_AERON_DATA_DATA; } term_offset = tvb_get_letohl(tvb, offset + O_AERON_DATA_TERM_OFFSET); @@ -2429,6 +2446,8 @@ static int dissect_aeron_nak(tvbuff_t * tvb, int offset, packet_info * pinfo, pr frame_length = tvb_get_letohl(tvb, offset + O_AERON_NAK_FRAME_LENGTH); rounded_length = (int) aeron_pos_roundup(frame_length); + if (rounded_length < 0) + THROW(ReportedBoundsError); session_id = tvb_get_letohl(tvb, offset + O_AERON_NAK_SESSION_ID); transport = aeron_transport_add(cinfo, session_id, pinfo->fd->num); stream_id = tvb_get_letohl(tvb, offset + O_AERON_NAK_STREAM_ID); @@ -2511,6 +2530,8 @@ static int dissect_aeron_sm(tvbuff_t * tvb, int offset, packet_info * pinfo, pro frame_length = tvb_get_letohl(tvb, offset + O_AERON_SM_FRAME_LENGTH); feedback_length = frame_length - O_AERON_SM_FEEDBACK; rounded_length = (int) aeron_pos_roundup(frame_length); + if (rounded_length < 0) + THROW(ReportedBoundsError); session_id = tvb_get_letohl(tvb, offset + O_AERON_SM_SESSION_ID); transport = aeron_transport_add(cinfo, session_id, pinfo->fd->num); stream_id = tvb_get_letohl(tvb, offset + O_AERON_SM_STREAM_ID); @@ -2603,6 +2624,8 @@ static int dissect_aeron_err(tvbuff_t * tvb, int offset, packet_info * pinfo, pr proto_tree_add_item(subtree, hf_aeron_err_string, tvb, offset + ofs, string_length, ENC_ASCII|ENC_NA); } rounded_length = (int) aeron_pos_roundup(frame_length); + if (rounded_length < 0) + THROW(ReportedBoundsError); proto_item_set_len(err_item, rounded_length); if (frame_length < L_AERON_ERR_MIN) { @@ -2648,6 +2671,8 @@ static int dissect_aeron_setup(tvbuff_t * tvb, int offset, packet_info * pinfo, frame_length = tvb_get_letohl(tvb, offset + O_AERON_SETUP_FRAME_LENGTH); rounded_length = (int) aeron_pos_roundup(frame_length); + if (rounded_length < 0) + THROW(ReportedBoundsError); term_offset = tvb_get_letohl(tvb, offset + O_AERON_SETUP_TERM_OFFSET); session_id = tvb_get_letohl(tvb, offset + O_AERON_SETUP_SESSION_ID); transport = aeron_transport_add(cinfo, session_id, pinfo->fd->num); |