From c8182253c827999183ee56f9c968a525ce451eb6 Mon Sep 17 00:00:00 2001 From: Guy Harris Date: Tue, 13 Dec 2011 01:24:12 +0000 Subject: Add missing checks for a too-large packet, so we don't blow up trying to allocate a huge buffer; fixes bug 6668. Also add some other checks for invalid records. svn path=/trunk/; revision=40167 --- wiretap/iptrace.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 64 insertions(+), 2 deletions(-) diff --git a/wiretap/iptrace.c b/wiretap/iptrace.c index e1f1858bdf..91fd750b5c 100644 --- a/wiretap/iptrace.c +++ b/wiretap/iptrace.c @@ -152,7 +152,18 @@ static gboolean iptrace_read_1_0(wtap *wth, int *err, gchar **err_info, wth->phdr.pkt_encap = wtap_encap_ift(pkt_hdr.if_type); /* Read the packet data */ - packet_size = pntohl(&header[0]) - IPTRACE_1_0_PDATA_SIZE; + packet_size = pntohl(&header[0]); + if (packet_size < IPTRACE_1_0_PDATA_SIZE) { + /* + * Uh-oh, the record isn't big enough to even have a + * packet meta-data header. + */ + *err = WTAP_ERR_BAD_RECORD; + *err_info = g_strdup_printf("iptrace: file has a %u-byte record, too small to have even a packet meta-data header", + packet_size); + return FALSE; + } + packet_size -= IPTRACE_1_0_PDATA_SIZE; /* * AIX appears to put 3 bytes of padding in front of FDDI @@ -163,6 +174,16 @@ static gboolean iptrace_read_1_0(wtap *wth, int *err, gchar **err_info, * The packet size is really a record size and includes * the padding. */ + if (packet_size < 3) { + /* + * Uh-oh, the record isn't big enough to even have + * the padding. + */ + *err = WTAP_ERR_BAD_RECORD; + *err_info = g_strdup_printf("iptrace: file has a %u-byte record, too small to have even a packet meta-data header", + packet_size + IPTRACE_1_0_PDATA_SIZE); + return FALSE; + } packet_size -= 3; wth->data_offset += 3; @@ -173,6 +194,16 @@ static gboolean iptrace_read_1_0(wtap *wth, int *err, gchar **err_info, err_info)) return FALSE; /* Read error */ } + if (packet_size > WTAP_MAX_PACKET_SIZE) { + /* + * Probably a corrupt capture file; don't blow up trying + * to allocate space for an immensely-large packet. + */ + *err = WTAP_ERR_BAD_RECORD; + *err_info = g_strdup_printf("iptrace: File has %u-byte packet, bigger than maximum of %u", + packet_size, WTAP_MAX_PACKET_SIZE); + return FALSE; + } buffer_assure_space( wth->frame_buffer, packet_size ); data_ptr = buffer_start_ptr( wth->frame_buffer ); @@ -335,7 +366,18 @@ static gboolean iptrace_read_2_0(wtap *wth, int *err, gchar **err_info, wth->phdr.pkt_encap = wtap_encap_ift(pkt_hdr.if_type); /* Read the packet data */ - packet_size = pntohl(&header[0]) - IPTRACE_2_0_PDATA_SIZE; + packet_size = pntohl(&header[0]); + if (packet_size < IPTRACE_2_0_PDATA_SIZE) { + /* + * Uh-oh, the record isn't big enough to even have a + * packet meta-data header. + */ + *err = WTAP_ERR_BAD_RECORD; + *err_info = g_strdup_printf("iptrace: file has a %u-byte record, too small to have even a packet meta-data header", + packet_size); + return FALSE; + } + packet_size -= IPTRACE_2_0_PDATA_SIZE; /* * AIX appears to put 3 bytes of padding in front of FDDI @@ -346,6 +388,16 @@ static gboolean iptrace_read_2_0(wtap *wth, int *err, gchar **err_info, * The packet size is really a record size and includes * the padding. */ + if (packet_size < 3) { + /* + * Uh-oh, the record isn't big enough to even have + * the padding. + */ + *err = WTAP_ERR_BAD_RECORD; + *err_info = g_strdup_printf("iptrace: file has a %u-byte record, too small to have even a packet meta-data header", + packet_size + IPTRACE_2_0_PDATA_SIZE); + return FALSE; + } packet_size -= 3; wth->data_offset += 3; @@ -356,6 +408,16 @@ static gboolean iptrace_read_2_0(wtap *wth, int *err, gchar **err_info, err_info)) return FALSE; /* Read error */ } + if (packet_size > WTAP_MAX_PACKET_SIZE) { + /* + * Probably a corrupt capture file; don't blow up trying + * to allocate space for an immensely-large packet. + */ + *err = WTAP_ERR_BAD_RECORD; + *err_info = g_strdup_printf("iptrace: File has %u-byte packet, bigger than maximum of %u", + packet_size, WTAP_MAX_PACKET_SIZE); + return FALSE; + } buffer_assure_space( wth->frame_buffer, packet_size ); data_ptr = buffer_start_ptr( wth->frame_buffer ); -- cgit v1.2.3