forked from osmocom/wireshark
Add sanity checks to make sure the claimed block size is big enough to:
1) contain the block length fields and block type field; 2) contain that plus the fixed-length portion of the block; 3) for blocks that have a variable-length portion other than the options, contain that variable-length portion. Fixes a crash we're seeing with a bad pcap-NG file in the Wireshark menagerie (7799-lastPacketWithoutComment.pcapng - the last packet's block length is 128, but it claims to have 98 bytes of packet data, which requires a 132-byte block). Clean up white space (use 8-space tabs). svn path=/trunk/; revision=41143
This commit is contained in:
parent
0ebef9a0fa
commit
3b262a0621
283
wiretap/pcapng.c
283
wiretap/pcapng.c
|
@ -101,6 +101,11 @@ typedef struct pcapng_block_header_s {
|
|||
/* guint32 block_total_length */
|
||||
} pcapng_block_header_t;
|
||||
|
||||
/*
|
||||
* Minimum block size = size of block header + size of block trailer.
|
||||
*/
|
||||
#define MIN_BLOCK_SIZE ((guint32)(sizeof(pcapng_block_header_t) + sizeof(guint32)))
|
||||
|
||||
/* pcapng: section header block */
|
||||
typedef struct pcapng_section_header_block_s {
|
||||
/* pcapng_block_header_t */
|
||||
|
@ -111,6 +116,11 @@ typedef struct pcapng_section_header_block_s {
|
|||
/* ... Options ... */
|
||||
} pcapng_section_header_block_t;
|
||||
|
||||
/*
|
||||
* Minimum SHB size = minimum block size + size of fixed length portion of SHB.
|
||||
*/
|
||||
#define MIN_SHB_SIZE ((guint32)(MIN_BLOCK_SIZE + sizeof(pcapng_section_header_block_t)))
|
||||
|
||||
/* pcapng: interface description block */
|
||||
typedef struct pcapng_interface_description_block_s {
|
||||
guint16 linktype;
|
||||
|
@ -119,6 +129,11 @@ typedef struct pcapng_interface_description_block_s {
|
|||
/* ... Options ... */
|
||||
} pcapng_interface_description_block_t;
|
||||
|
||||
/*
|
||||
* Minimum IDB size = minimum block size + size of fixed length portion of IDB.
|
||||
*/
|
||||
#define MIN_IDB_SIZE ((guint32)(MIN_BLOCK_SIZE + sizeof(pcapng_interface_description_block_t)))
|
||||
|
||||
/* pcapng: packet block (obsolete) */
|
||||
typedef struct pcapng_packet_block_s {
|
||||
guint16 interface_id;
|
||||
|
@ -132,6 +147,11 @@ typedef struct pcapng_packet_block_s {
|
|||
/* ... Options ... */
|
||||
} pcapng_packet_block_t;
|
||||
|
||||
/*
|
||||
* Minimum PB size = minimum block size + size of fixed length portion of PB.
|
||||
*/
|
||||
#define MIN_PB_SIZE ((guint32)(MIN_BLOCK_SIZE + sizeof(pcapng_packet_block_t)))
|
||||
|
||||
/* pcapng: enhanced packet block */
|
||||
typedef struct pcapng_enhanced_packet_block_s {
|
||||
guint32 interface_id;
|
||||
|
@ -144,6 +164,11 @@ typedef struct pcapng_enhanced_packet_block_s {
|
|||
/* ... Options ... */
|
||||
} pcapng_enhanced_packet_block_t;
|
||||
|
||||
/*
|
||||
* Minimum EPB size = minimum block size + size of fixed length portion of EPB.
|
||||
*/
|
||||
#define MIN_EPB_SIZE ((guint32)(MIN_BLOCK_SIZE + sizeof(pcapng_enhanced_packet_block_t)))
|
||||
|
||||
/* pcapng: simple packet block */
|
||||
typedef struct pcapng_simple_packet_block_s {
|
||||
guint32 packet_len;
|
||||
|
@ -151,6 +176,11 @@ typedef struct pcapng_simple_packet_block_s {
|
|||
/* ... Padding ... */
|
||||
} pcapng_simple_packet_block_t;
|
||||
|
||||
/*
|
||||
* Minimum SPB size = minimum block size + size of fixed length portion of SPB.
|
||||
*/
|
||||
#define MIN_SPB_SIZE ((guint32)(MIN_BLOCK_SIZE + sizeof(pcapng_simple_packet_block_t)))
|
||||
|
||||
/* pcapng: name resolution block */
|
||||
typedef struct pcapng_name_resolution_block_s {
|
||||
guint16 record_type;
|
||||
|
@ -158,6 +188,12 @@ typedef struct pcapng_name_resolution_block_s {
|
|||
/* ... Record ... */
|
||||
} pcapng_name_resolution_block_t;
|
||||
|
||||
/*
|
||||
* Minimum NRB size = minimum block size + size of smallest NRB record
|
||||
* (there must at least be an "end of records" record).
|
||||
*/
|
||||
#define MIN_NRB_SIZE ((guint32)(MIN_BLOCK_SIZE + sizeof(pcapng_name_resolution_block_t)))
|
||||
|
||||
/* pcapng: interface statistics block */
|
||||
typedef struct pcapng_interface_statistics_block_s {
|
||||
guint32 interface_id;
|
||||
|
@ -166,6 +202,11 @@ typedef struct pcapng_interface_statistics_block_s {
|
|||
/* ... Options ... */
|
||||
} pcapng_interface_statistics_block_t;
|
||||
|
||||
/*
|
||||
* Minimum ISB size = minimum block size + size of fixed length portion of ISB.
|
||||
*/
|
||||
#define MIN_ISB_SIZE ((guint32)(MIN_BLOCK_SIZE + sizeof(pcapng_interface_statistics_block_t)))
|
||||
|
||||
/* pcapng: common option header for every option type */
|
||||
typedef struct pcapng_option_header_s {
|
||||
guint16 option_code;
|
||||
|
@ -445,6 +486,20 @@ pcapng_read_section_header_block(FILE_T fh, gboolean first_block,
|
|||
pcapng_option_header_t oh;
|
||||
char *option_content = NULL; /* Allocate as large as the options block */
|
||||
|
||||
/*
|
||||
* Is this block long enough to be an SHB?
|
||||
*/
|
||||
if (bh->block_total_length < MIN_SHB_SIZE) {
|
||||
/*
|
||||
* No.
|
||||
*/
|
||||
if (first_block)
|
||||
return 0; /* probably not a pcap-ng file */
|
||||
*err = WTAP_ERR_BAD_FILE;
|
||||
*err_info = g_strdup_printf("pcapng_read_section_header_block: total block length %u of an SHB is less than the minimum SHB size %u",
|
||||
bh->block_total_length, MIN_SHB_SIZE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* read block content */
|
||||
errno = WTAP_ERR_CANT_READ;
|
||||
|
@ -539,10 +594,7 @@ pcapng_read_section_header_block(FILE_T fh, gboolean first_block,
|
|||
|
||||
/* Options */
|
||||
errno = WTAP_ERR_CANT_READ;
|
||||
to_read = bh->block_total_length -
|
||||
(int)sizeof(pcapng_block_header_t) -
|
||||
(int)sizeof(pcapng_section_header_block_t) -
|
||||
(int)sizeof(bh->block_total_length);
|
||||
to_read = bh->block_total_length - MIN_SHB_SIZE;
|
||||
/* Allocate enough memory to hold all options */
|
||||
opt_cont_buf_len = to_read;
|
||||
option_content = g_malloc(opt_cont_buf_len);
|
||||
|
@ -623,7 +675,18 @@ pcapng_read_if_descr_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn,
|
|||
pcapng_option_header_t oh;
|
||||
char *option_content = NULL; /* Allocate as large as the options block */
|
||||
|
||||
|
||||
/*
|
||||
* Is this block long enough to be an IDB?
|
||||
*/
|
||||
if (bh->block_total_length < MIN_IDB_SIZE) {
|
||||
/*
|
||||
* No.
|
||||
*/
|
||||
*err = WTAP_ERR_BAD_FILE;
|
||||
*err_info = g_strdup_printf("pcapng_read_if_descr_block: total block length %u of an IDB is less than the minimum IDB size %u",
|
||||
bh->block_total_length, MIN_IDB_SIZE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* read block content */
|
||||
errno = WTAP_ERR_CANT_READ;
|
||||
|
@ -682,10 +745,7 @@ pcapng_read_if_descr_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn,
|
|||
|
||||
/* Options */
|
||||
errno = WTAP_ERR_CANT_READ;
|
||||
to_read = bh->block_total_length -
|
||||
(int)sizeof(pcapng_block_header_t) -
|
||||
(int)sizeof (pcapng_interface_description_block_t) -
|
||||
(int)sizeof(bh->block_total_length);
|
||||
to_read = bh->block_total_length - MIN_IDB_SIZE;
|
||||
|
||||
/* Allocate enough memory to hold all options */
|
||||
opt_cont_buf_len = to_read;
|
||||
|
@ -855,6 +915,7 @@ pcapng_read_packet_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn, wta
|
|||
pcapng_enhanced_packet_block_t epb;
|
||||
pcapng_packet_block_t pb;
|
||||
guint32 block_total_length;
|
||||
guint32 padding;
|
||||
pcapng_option_header_t oh;
|
||||
gint wtap_encap;
|
||||
int pseudo_header_len;
|
||||
|
@ -864,6 +925,18 @@ pcapng_read_packet_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn, wta
|
|||
/* "(Enhanced) Packet Block" read fixed part */
|
||||
errno = WTAP_ERR_CANT_READ;
|
||||
if (enhanced) {
|
||||
/*
|
||||
* Is this block long enough to be an EPB?
|
||||
*/
|
||||
if (bh->block_total_length < MIN_EPB_SIZE) {
|
||||
/*
|
||||
* No.
|
||||
*/
|
||||
*err = WTAP_ERR_BAD_FILE;
|
||||
*err_info = g_strdup_printf("pcapng_read_packet_block: total block length %u of an EPB is less than the minimum EPB size %u",
|
||||
bh->block_total_length, MIN_EPB_SIZE);
|
||||
return -1;
|
||||
}
|
||||
bytes_read = file_read(&epb, sizeof epb, fh);
|
||||
if (bytes_read != sizeof epb) {
|
||||
pcapng_debug0("pcapng_read_packet_block: failed to read packet data");
|
||||
|
@ -875,19 +948,31 @@ pcapng_read_packet_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn, wta
|
|||
if (pn->byte_swapped) {
|
||||
wblock->data.packet.interface_id = BSWAP32(epb.interface_id);
|
||||
wblock->data.packet.drops_count = -1; /* invalid */
|
||||
wblock->data.packet.ts_high = BSWAP32(epb.timestamp_high);
|
||||
wblock->data.packet.ts_low = BSWAP32(epb.timestamp_low);
|
||||
wblock->data.packet.cap_len = BSWAP32(epb.captured_len);
|
||||
wblock->data.packet.ts_high = BSWAP32(epb.timestamp_high);
|
||||
wblock->data.packet.ts_low = BSWAP32(epb.timestamp_low);
|
||||
wblock->data.packet.cap_len = BSWAP32(epb.captured_len);
|
||||
wblock->data.packet.packet_len = BSWAP32(epb.packet_len);
|
||||
} else {
|
||||
wblock->data.packet.interface_id = epb.interface_id;
|
||||
wblock->data.packet.drops_count = -1; /* invalid */
|
||||
wblock->data.packet.ts_high = epb.timestamp_high;
|
||||
wblock->data.packet.ts_low = epb.timestamp_low;
|
||||
wblock->data.packet.cap_len = epb.captured_len;
|
||||
wblock->data.packet.ts_high = epb.timestamp_high;
|
||||
wblock->data.packet.ts_low = epb.timestamp_low;
|
||||
wblock->data.packet.cap_len = epb.captured_len;
|
||||
wblock->data.packet.packet_len = epb.packet_len;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Is this block long enough to be a PB?
|
||||
*/
|
||||
if (bh->block_total_length < MIN_PB_SIZE) {
|
||||
/*
|
||||
* No.
|
||||
*/
|
||||
*err = WTAP_ERR_BAD_FILE;
|
||||
*err_info = g_strdup_printf("pcapng_read_packet_block: total block length %u of a PB is less than the minimum PB size %u",
|
||||
bh->block_total_length, MIN_PB_SIZE);
|
||||
return -1;
|
||||
}
|
||||
bytes_read = file_read(&pb, sizeof pb, fh);
|
||||
if (bytes_read != sizeof pb) {
|
||||
pcapng_debug0("pcapng_read_packet_block: failed to read packet data");
|
||||
|
@ -899,18 +984,62 @@ pcapng_read_packet_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn, wta
|
|||
if (pn->byte_swapped) {
|
||||
wblock->data.packet.interface_id = BSWAP16(pb.interface_id);
|
||||
wblock->data.packet.drops_count = BSWAP16(pb.drops_count);
|
||||
wblock->data.packet.ts_high = BSWAP32(pb.timestamp_high);
|
||||
wblock->data.packet.ts_low = BSWAP32(pb.timestamp_low);
|
||||
wblock->data.packet.cap_len = BSWAP32(pb.captured_len);
|
||||
wblock->data.packet.ts_high = BSWAP32(pb.timestamp_high);
|
||||
wblock->data.packet.ts_low = BSWAP32(pb.timestamp_low);
|
||||
wblock->data.packet.cap_len = BSWAP32(pb.captured_len);
|
||||
wblock->data.packet.packet_len = BSWAP32(pb.packet_len);
|
||||
} else {
|
||||
wblock->data.packet.interface_id = pb.interface_id;
|
||||
wblock->data.packet.drops_count = pb.drops_count;
|
||||
wblock->data.packet.ts_high = pb.timestamp_high;
|
||||
wblock->data.packet.ts_low = pb.timestamp_low;
|
||||
wblock->data.packet.cap_len = pb.captured_len;
|
||||
wblock->data.packet.ts_high = pb.timestamp_high;
|
||||
wblock->data.packet.ts_low = pb.timestamp_low;
|
||||
wblock->data.packet.cap_len = pb.captured_len;
|
||||
wblock->data.packet.packet_len = pb.packet_len;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* How much padding is there at the end of the packet data?
|
||||
*/
|
||||
if ((wblock->data.packet.cap_len % 4) != 0)
|
||||
padding = 4 - (wblock->data.packet.cap_len % 4);
|
||||
else
|
||||
padding = 0;
|
||||
|
||||
/* add padding bytes to "block total length" */
|
||||
/* (the "block total length" of some example files don't contain the packet data padding bytes!) */
|
||||
if (bh->block_total_length % 4) {
|
||||
block_total_length = bh->block_total_length + 4 - (bh->block_total_length % 4);
|
||||
} else {
|
||||
block_total_length = bh->block_total_length;
|
||||
}
|
||||
|
||||
/*
|
||||
* Is this block long enough to hold the packet data?
|
||||
*/
|
||||
if (enhanced) {
|
||||
if (block_total_length <
|
||||
MIN_EPB_SIZE + wblock->data.packet.cap_len + padding) {
|
||||
/*
|
||||
* No.
|
||||
*/
|
||||
*err = WTAP_ERR_BAD_FILE;
|
||||
*err_info = g_strdup_printf("pcapng_read_packet_block: total block length %u of EPB is too small for %u bytes of packet data",
|
||||
block_total_length, wblock->data.packet.cap_len);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if (block_total_length <
|
||||
MIN_PB_SIZE + wblock->data.packet.cap_len + padding) {
|
||||
/*
|
||||
* No.
|
||||
*/
|
||||
*err = WTAP_ERR_BAD_FILE;
|
||||
*err_info = g_strdup_printf("pcapng_read_packet_block: total block length %u of PB is too small for %u bytes of packet data",
|
||||
block_total_length, wblock->data.packet.cap_len);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (wblock->data.packet.cap_len > wblock->data.packet.packet_len) {
|
||||
|
@ -970,22 +1099,14 @@ pcapng_read_packet_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn, wta
|
|||
block_read += bytes_read;
|
||||
|
||||
/* jump over potential padding bytes at end of the packet data */
|
||||
if( (wblock->data.packet.cap_len % 4) != 0) {
|
||||
file_offset64 = file_seek(fh, 4 - (wblock->data.packet.cap_len % 4), SEEK_CUR, err);
|
||||
if (padding != 0) {
|
||||
file_offset64 = file_seek(fh, padding, SEEK_CUR, err);
|
||||
if (file_offset64 <= 0) {
|
||||
if (*err != 0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
block_read += 4 - (wblock->data.packet.cap_len % 4);
|
||||
}
|
||||
|
||||
/* add padding bytes to "block total length" */
|
||||
/* (the "block total length" of some example files don't contain the packet data padding bytes!) */
|
||||
if (bh->block_total_length % 4) {
|
||||
block_total_length = bh->block_total_length + 4 - (bh->block_total_length % 4);
|
||||
} else {
|
||||
block_total_length = bh->block_total_length;
|
||||
block_read += padding;
|
||||
}
|
||||
|
||||
/* Option defaults */
|
||||
|
@ -1101,6 +1222,18 @@ pcapng_read_simple_packet_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *
|
|||
int pseudo_header_len;
|
||||
pcapng_simple_packet_block_t spb;
|
||||
|
||||
/*
|
||||
* Is this block long enough to be an SPB?
|
||||
*/
|
||||
if (bh->block_total_length < MIN_SPB_SIZE) {
|
||||
/*
|
||||
* No.
|
||||
*/
|
||||
*err = WTAP_ERR_BAD_FILE;
|
||||
*err_info = g_strdup_printf("pcapng_read_simple_packet_block: total block length %u of an SPB is less than the minimum SPB size %u",
|
||||
bh->block_total_length, MIN_SPB_SIZE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* "Simple Packet Block" read fixed part */
|
||||
errno = WTAP_ERR_CANT_READ;
|
||||
|
@ -1118,7 +1251,7 @@ pcapng_read_simple_packet_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *
|
|||
wblock->data.simple_packet.packet_len = spb.packet_len;
|
||||
}
|
||||
|
||||
wblock->data.simple_packet.cap_len = bh->block_total_length
|
||||
wblock->data.simple_packet.cap_len = bh->block_total_length -
|
||||
- (guint32)sizeof(pcapng_simple_packet_block_t)
|
||||
- (guint32)sizeof(bh->block_total_length);
|
||||
|
||||
|
@ -1206,12 +1339,34 @@ pcapng_read_name_resolution_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t
|
|||
guint8 nrb_rec[MAX_NRB_REC_SIZE];
|
||||
guint32 v4_addr;
|
||||
|
||||
/*
|
||||
* Is this block long enough to be an NRB?
|
||||
*/
|
||||
if (bh->block_total_length < MIN_NRB_SIZE) {
|
||||
/*
|
||||
* No.
|
||||
*/
|
||||
*err = WTAP_ERR_BAD_FILE;
|
||||
*err_info = g_strdup_printf("pcapng_read_name_resolution_block: total block length %u is too small (< %u)",
|
||||
bh->block_total_length, MIN_NRB_SIZE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
errno = WTAP_ERR_CANT_READ;
|
||||
to_read = bh->block_total_length
|
||||
- sizeof(pcapng_block_header_t)
|
||||
- sizeof(bh->block_total_length);
|
||||
to_read = bh->block_total_length - MIN_NRB_SIZE;
|
||||
|
||||
while (block_read < to_read) {
|
||||
/*
|
||||
* There must be at least one record's worth of data
|
||||
* here.
|
||||
*/
|
||||
if ((size_t)(to_read - block_read) < sizeof nrb) {
|
||||
*err = WTAP_ERR_BAD_FILE;
|
||||
*err_info = g_strdup_printf("pcapng_read_name_resolution_block: %d bytes left in the block < NRB record header size %u",
|
||||
to_read - block_read,
|
||||
(guint)sizeof nrb);
|
||||
return -1;
|
||||
}
|
||||
bytes_read = file_read(&nrb, sizeof nrb, fh);
|
||||
if (bytes_read != sizeof nrb) {
|
||||
pcapng_debug0("pcapng_read_name_resolution_block: failed to read record header");
|
||||
|
@ -1225,13 +1380,26 @@ pcapng_read_name_resolution_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t
|
|||
nrb.record_len = BSWAP16(nrb.record_len);
|
||||
}
|
||||
|
||||
if (to_read - block_read < nrb.record_len + PADDING4(nrb.record_len)) {
|
||||
*err = WTAP_ERR_BAD_FILE;
|
||||
*err_info = g_strdup_printf("pcapng_read_name_resolution_block: %d bytes left in the block < NRB record length + padding %u",
|
||||
to_read - block_read,
|
||||
nrb.record_len + PADDING4(nrb.record_len));
|
||||
return -1;
|
||||
}
|
||||
switch(nrb.record_type) {
|
||||
case NRES_ENDOFRECORD:
|
||||
/* There shouldn't be any more data */
|
||||
to_read = 0;
|
||||
break;
|
||||
case NRES_IP4RECORD:
|
||||
if (nrb.record_len < 6 || nrb.record_len > MAX_NRB_REC_SIZE || to_read < nrb.record_len) {
|
||||
if (nrb.record_len < 4) {
|
||||
*err = WTAP_ERR_BAD_FILE;
|
||||
*err_info = g_strdup_printf("pcapng_read_name_resolution_block: NRB record length for IPv4 record %u < minimum length 4",
|
||||
nrb.record_len);
|
||||
return -1;
|
||||
}
|
||||
if (nrb.record_len > MAX_NRB_REC_SIZE) {
|
||||
pcapng_debug0("pcapng_read_name_resolution_block: bad length or insufficient data for IPv4 record");
|
||||
return 0;
|
||||
}
|
||||
|
@ -1259,7 +1427,13 @@ pcapng_read_name_resolution_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t
|
|||
block_read += PADDING4(nrb.record_len);
|
||||
break;
|
||||
case NRES_IP6RECORD:
|
||||
if (nrb.record_len < 18 || nrb.record_len > MAX_NRB_REC_SIZE || to_read < nrb.record_len) {
|
||||
if (nrb.record_len < 16) {
|
||||
*err = WTAP_ERR_BAD_FILE;
|
||||
*err_info = g_strdup_printf("pcapng_read_name_resolution_block: NRB record length for IPv6 record %u < minimum length 16",
|
||||
nrb.record_len);
|
||||
return -1;
|
||||
}
|
||||
if (nrb.record_len > MAX_NRB_REC_SIZE || to_read < nrb.record_len) {
|
||||
pcapng_debug0("pcapng_read_name_resolution_block: bad length or insufficient data for IPv6 record");
|
||||
return 0;
|
||||
}
|
||||
|
@ -1309,6 +1483,18 @@ pcapng_read_interface_statistics_block(FILE_T fh, pcapng_block_header_t *bh, pca
|
|||
pcapng_option_header_t oh;
|
||||
char *option_content = NULL; /* Allocate as large as the options block */
|
||||
|
||||
/*
|
||||
* Is this block long enough to be an ISB?
|
||||
*/
|
||||
if (bh->block_total_length < MIN_ISB_SIZE) {
|
||||
/*
|
||||
* No.
|
||||
*/
|
||||
*err = WTAP_ERR_BAD_FILE;
|
||||
*err_info = g_strdup_printf("pcapng_read_name_resolution_block: total block length %u is too small (< %u)",
|
||||
bh->block_total_length, MIN_NRB_SIZE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* "Interface Statistics Block" read fixed part */
|
||||
errno = WTAP_ERR_CANT_READ;
|
||||
|
@ -1339,9 +1525,7 @@ pcapng_read_interface_statistics_block(FILE_T fh, pcapng_block_header_t *bh, pca
|
|||
/* Options */
|
||||
errno = WTAP_ERR_CANT_READ;
|
||||
to_read = bh->block_total_length -
|
||||
sizeof(pcapng_block_header_t) -
|
||||
block_read - /* fixed and variable part, including padding */
|
||||
sizeof(bh->block_total_length);
|
||||
(MIN_BLOCK_SIZE + block_read); /* fixed and variable part, including padding */
|
||||
|
||||
/* Allocate enough memory to hold all options */
|
||||
opt_cont_buf_len = to_read;
|
||||
|
@ -1473,7 +1657,7 @@ pcapng_read_interface_statistics_block(FILE_T fh, pcapng_block_header_t *bh, pca
|
|||
|
||||
g_free(option_content);
|
||||
|
||||
return block_read;
|
||||
return block_read;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1493,7 +1677,7 @@ pcapng_read_unknown_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn _U_
|
|||
block_total_length = bh->block_total_length;
|
||||
}
|
||||
|
||||
block_read = block_total_length - (guint32)sizeof(pcapng_block_header_t) - (guint32)sizeof(bh->block_total_length);
|
||||
block_read = block_total_length - MIN_BLOCK_SIZE;
|
||||
|
||||
/* jump over this unknown block */
|
||||
file_offset64 = file_seek(fh, block_read, SEEK_CUR, err);
|
||||
|
@ -1551,6 +1735,19 @@ pcapng_read_block(FILE_T fh, gboolean first_block, pcapng_t *pn, wtapng_block_t
|
|||
return 0; /* not a pcap-ng file */
|
||||
}
|
||||
|
||||
if (bh.block_total_length < MIN_BLOCK_SIZE) {
|
||||
/*
|
||||
* This isn't even enough for the block type and 2
|
||||
* block total length fields.
|
||||
*/
|
||||
if (first_block)
|
||||
return 0; /* probably not a pcap-ng file */
|
||||
*err = WTAP_ERR_BAD_FILE;
|
||||
*err_info = g_strdup_printf("pcapng_read_block: total block length %u is too small (< %u)",
|
||||
bh.block_total_length, (guint32)MIN_BLOCK_SIZE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch(bh.block_type) {
|
||||
case(BLOCK_TYPE_SHB):
|
||||
bytes_read = pcapng_read_section_header_block(fh, first_block, &bh, pn, wblock, err, err_info);
|
||||
|
|
Loading…
Reference in New Issue