Don't write out packets that have a "captured length" bigger than we're

willing to read or that's bigger than will fit in the file format;
instead, report an error.

For the "I can't write a packet of that type in that file type" error,
report the file type in question.

svn path=/trunk/; revision=54882
This commit is contained in:
Guy Harris 2014-01-22 00:26:36 +00:00
parent 5c825d6a36
commit 90d7c5f59b
23 changed files with 254 additions and 24 deletions

View File

@ -1529,11 +1529,27 @@ main(int argc, char *argv[])
case WTAP_ERR_UNSUPPORTED_ENCAP:
/*
* This is a problem with the particular frame we're
* writing; note that, and give the frame number.
* writing and the file type and subtype we're
* writing; note that, and report the frame number
* and file type/subtype.
*/
fprintf(stderr,
"editcap: Frame %u of \"%s\" has a network type that can't be saved in a file with that format\n.",
read_count, argv[optind]);
"editcap: Frame %u of \"%s\" has a network type that can't be saved in a \"%s\" file\n.",
read_count, argv[optind],
wtap_file_type_subtype_string(out_file_type_subtype));
break;
case WTAP_ERR_PACKET_TOO_LARGE:
/*
* This is a problem with the particular frame we're
* writing and the file type and subtype we're
* writing; note that, and report the frame number
* and file type/subtype.
*/
fprintf(stderr,
"editcap: Frame %u of \"%s\" is too large for a \"%s\" file\n.",
read_count, argv[optind],
wtap_file_type_subtype_string(out_file_type_subtype));
break;
default:

35
file.c
View File

@ -1625,8 +1625,9 @@ cf_merge_files(char **out_filenamep, int in_file_count,
case WTAP_ERR_UNSUPPORTED_ENCAP:
/*
* This is a problem with the particular frame we're writing;
* note that, and give the frame number.
* This is a problem with the particular frame we're writing and
* the file type and subtype we're writing; note that, and report
* the frame number and file type/subtype.
*/
display_basename = g_filename_display_basename(in_file->filename);
simple_error_message_box(
@ -1636,6 +1637,20 @@ cf_merge_files(char **out_filenamep, int in_file_count,
g_free(display_basename);
break;
case WTAP_ERR_PACKET_TOO_LARGE:
/*
* This is a problem with the particular frame we're writing and
* the file type and subtype we're writing; note that, and report
* the frame number and file type/subtype.
*/
display_basename = g_filename_display_basename(in_file->filename);
simple_error_message_box(
"Frame %u of \"%s\" is too large for a \"%s\" file.",
in_file->packet_num, display_basename,
wtap_file_type_subtype_string(file_type));
g_free(display_basename);
break;
default:
display_basename = g_filename_display_basename(out_filename);
simple_error_message_box(
@ -4147,14 +4162,26 @@ save_packet(capture_file *cf _U_, frame_data *fdata,
case WTAP_ERR_UNSUPPORTED_ENCAP:
/*
* This is a problem with the particular frame we're writing;
* note that, and give the frame number.
* This is a problem with the particular frame we're writing and
* the file type and subtype we're writing; note that, and report
* the frame number and file type/subtype.
*/
simple_error_message_box(
"Frame %u has a network type that can't be saved in a \"%s\" file.",
fdata->num, wtap_file_type_subtype_string(args->file_type));
break;
case WTAP_ERR_PACKET_TOO_LARGE:
/*
* This is a problem with the particular frame we're writing and
* the file type and subtype we're writing; note that, and report
* the frame number and file type/subtype.
*/
simple_error_message_box(
"Frame %u is larger than Wireshark supports in a \"%s\" file.",
fdata->num, wtap_file_type_subtype_string(args->file_type));
break;
default:
display_basename = g_filename_display_basename(args->fname);
simple_error_message_box(

View File

@ -507,11 +507,24 @@ main(int argc, char *argv[])
case WTAP_ERR_UNSUPPORTED_ENCAP:
/*
* This is a problem with the particular frame we're writing;
* note that, and give the frame number.
* This is a problem with the particular frame we're writing and
* the file type and subtype we're wwriting; note that, and
* report the frame number and file type/subtype.
*/
fprintf(stderr, "mergecap: Frame %u of \"%s\" has a network type that can't be saved in a file with that format\n.",
in_file->packet_num, in_file->filename);
fprintf(stderr, "mergecap: Frame %u of \"%s\" has a network type that can't be saved in a \"%s\" file.\n",
in_file->packet_num, in_file->filename,
wtap_file_type_subtype_string(file_type));
break;
case WTAP_ERR_PACKET_TOO_LARGE:
/*
* This is a problem with the particular frame we're writing and
* the file type and subtype we're wwriting; note that, and
* report the frame number and file type/subtype.
*/
fprintf(stderr, "mergecap: Frame %u of \"%s\" is too large for a \"%s\" file\n.",
in_file->packet_num, in_file->filename,
wtap_file_type_subtype_string(file_type));
break;
default:

View File

@ -3204,8 +3204,9 @@ load_cap_file(capture_file *cf, char *save_file, int out_file_type,
case WTAP_ERR_UNSUPPORTED_ENCAP:
/*
* This is a problem with the particular frame we're writing;
* note that, and give the frame number.
* This is a problem with the particular frame we're writing
* and the file type and subtype we're writing; note that,
* and report the frame number and file type/subtype.
*
* XXX - framenum is not necessarily the frame number in
* the input file if there was a read filter.
@ -3216,6 +3217,21 @@ load_cap_file(capture_file *cf, char *save_file, int out_file_type,
wtap_file_type_subtype_short_string(out_file_type));
break;
case WTAP_ERR_PACKET_TOO_LARGE:
/*
* This is a problem with the particular frame we're writing
* and the file type and subtype we're writing; note that,
* and report the frame number and file type/subtype.
*
* XXX - framenum is not necessarily the frame number in
* the input file if there was a read filter.
*/
fprintf(stderr,
"Frame %u of \"%s\" is too large for a \"%s\" file.\n",
framenum, cf->filename,
wtap_file_type_subtype_short_string(out_file_type));
break;
default:
show_capture_file_io_error(save_file, err, FALSE);
break;
@ -3271,8 +3287,9 @@ load_cap_file(capture_file *cf, char *save_file, int out_file_type,
case WTAP_ERR_UNSUPPORTED_ENCAP:
/*
* This is a problem with the particular frame we're writing;
* note that, and give the frame number.
* This is a problem with the particular frame we're writing
* and the file type and subtype we're writing; note that,
* and report the frame number and file type/subtype.
*/
fprintf(stderr,
"Frame %u of \"%s\" has a network type that can't be saved in a \"%s\" file.\n",
@ -3280,6 +3297,18 @@ load_cap_file(capture_file *cf, char *save_file, int out_file_type,
wtap_file_type_subtype_short_string(out_file_type));
break;
case WTAP_ERR_PACKET_TOO_LARGE:
/*
* This is a problem with the particular frame we're writing
* and the file type and subtype we're writing; note that,
* and report the frame number and file type/subtype.
*/
fprintf(stderr,
"Frame %u of \"%s\" is too large for a \"%s\" file.\n",
framenum, cf->filename,
wtap_file_type_subtype_short_string(out_file_type));
break;
default:
show_capture_file_io_error(save_file, err, FALSE);
break;

View File

@ -372,6 +372,12 @@ static gboolean _5views_dump(wtap_dumper *wdh,
_5views_dump_t *_5views = (_5views_dump_t *)wdh->priv;
t_5VW_TimeStamped_Header HeaderFrame;
/* Don't write out something bigger than we can read. */
if (phdr->caplen > WTAP_MAX_PACKET_SIZE) {
*err = WTAP_ERR_PACKET_TOO_LARGE;
return FALSE;
}
/* Frame Header */
/* constant fields */
HeaderFrame.Key = GUINT32_TO_LE(CST_5VW_RECORDS_HEADER_KEY);

View File

@ -333,6 +333,15 @@ static gboolean btsnoop_dump_h1(wtap_dumper *wdh,
const union wtap_pseudo_header *pseudo_header = &phdr->pseudo_header;
struct btsnooprec_hdr rec_hdr;
/*
* Don't write out anything bigger than we can read.
* (This will also fail on a caplen of 0, as it should.)
*/
if (phdr->caplen-1 > WTAP_MAX_PACKET_SIZE) {
*err = WTAP_ERR_PACKET_TOO_LARGE;
return FALSE;
}
if (!btsnoop_dump_partial_rec_hdr(wdh, phdr, pseudo_header, pd, err, &rec_hdr))
return FALSE;
@ -362,6 +371,12 @@ static gboolean btsnoop_dump_h4(wtap_dumper *wdh,
const union wtap_pseudo_header *pseudo_header = &phdr->pseudo_header;
struct btsnooprec_hdr rec_hdr;
/* Don't write out anything bigger than we can read. */
if (phdr->caplen > WTAP_MAX_PACKET_SIZE) {
*err = WTAP_ERR_PACKET_TOO_LARGE;
return FALSE;
}
if (!btsnoop_dump_partial_rec_hdr(wdh, phdr, pseudo_header, pd, err, &rec_hdr))
return FALSE;

View File

@ -277,6 +277,14 @@ static gboolean commview_dump(wtap_dumper *wdh,
commview_header_t cv_hdr;
struct tm *tm;
/* Don't write out anything bigger than we can read.
* (The length field in packet headers is 16 bits, which
* imposes a hard limit.) */
if (phdr->caplen > 65535) {
*err = WTAP_ERR_PACKET_TOO_LARGE;
return FALSE;
}
memset(&cv_hdr, 0, sizeof(cv_hdr));
cv_hdr.data_len = GUINT16_TO_LE((guint16)phdr->caplen);

View File

@ -153,8 +153,7 @@ extern int erf_open(wtap *wth, int *err, gchar **err_info)
if (packet_size > WTAP_MAX_PACKET_SIZE) {
/*
* Probably a corrupt capture file or a file that's not an ERF file
* but that passed earlier tests; don't blow up trying
* to allocate space for an immensely-large packet.
* but that passed earlier tests.
*/
return 0;
}
@ -239,8 +238,8 @@ extern int erf_open(wtap *wth, int *err, gchar **err_info)
is reached whereas the record is truncated */
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.
* Probably a corrupt capture file or a file that's not an ERF file
* but that passed earlier tests.
*/
return 0;
}
@ -592,6 +591,12 @@ static gboolean erf_dump(
gboolean must_add_crc = FALSE;
guint32 crc32 = 0x00000000;
/* Don't write anything bigger than we're willing to read. */
if(phdr->caplen > WTAP_MAX_PACKET_SIZE) {
*err = WTAP_ERR_PACKET_TOO_LARGE;
return FALSE;
}
if(wdh->encap == WTAP_ENCAP_PER_PACKET){
encap = phdr->pkt_encap;
}else{

View File

@ -417,6 +417,14 @@ static gboolean eyesdn_dump(wtap_dumper *wdh,
int protocol;
int size;
/* Don't write out anything bigger than we can read.
* (The length field in packet headers is 16 bits, which
* imposes a hard limit.) */
if (phdr->caplen > 65535) {
*err = WTAP_ERR_PACKET_TOO_LARGE;
return FALSE;
}
usecs=phdr->ts.nsecs/1000;
secs=phdr->ts.secs;
size=phdr->caplen;

View File

@ -1190,7 +1190,7 @@ static gboolean k12_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
/* encountered in k12_dump_src_setting). */
g_hash_table_foreach(file_data->src_by_id,k12_dump_src_setting,wdh);
}
obj.record.len = 0x20 + phdr->len;
obj.record.len = 0x20 + phdr->caplen;
obj.record.len += (obj.record.len % 4) ? 4 - obj.record.len % 4 : 0;
len = obj.record.len;
@ -1198,12 +1198,12 @@ static gboolean k12_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
obj.record.len = g_htonl(obj.record.len);
obj.record.type = g_htonl(K12_REC_PACKET);
obj.record.frame_len = g_htonl(phdr->len);
obj.record.frame_len = g_htonl(phdr->caplen);
obj.record.input = g_htonl(pseudo_header->k12.input);
obj.record.ts = GUINT64_TO_BE((((guint64)phdr->ts.secs - 631152000) * 2000000) + (phdr->ts.nsecs / 1000 * 2));
memcpy(obj.record.frame,pd,phdr->len);
memcpy(obj.record.frame,pd,phdr->caplen);
return k12_dump_record(wdh,len,obj.buffer, err);
}

View File

@ -375,6 +375,12 @@ k12text_dump(wtap_dumper *wdh _U_, const struct wtap_pkthdr *phdr,
gboolean ret;
struct tm *tmp;
/* Don't write anything bigger than we're willing to read. */
if (phdr->caplen > WTAP_MAX_PACKET_SIZE) {
*err = WTAP_ERR_PACKET_TOO_LARGE;
return FALSE;
}
str_enc = NULL;
for(i=0; encaps[i].s; i++) {
if (phdr->pkt_encap == encaps[i].e) {

View File

@ -658,7 +658,7 @@ static gboolean lanalyzer_dump(wtap_dumper *wdh,
double x;
int i;
int len;
struct timeval tv;
struct timeval tv;
LA_TmpInfo *itmp = (LA_TmpInfo*)(wdh->priv);
struct timeval td;
@ -672,6 +672,12 @@ static gboolean lanalyzer_dump(wtap_dumper *wdh,
len = phdr->caplen + (phdr->caplen ? LA_PacketRecordSize : 0);
/* len goes into a 16-bit field, so there's a hard limit of 65535. */
if (len > 65535) {
*err = WTAP_ERR_PACKET_TOO_LARGE;
return FALSE;
}
if (!s16write(wdh, GUINT16_TO_LE(0x1005), err))
return FALSE;
if (!s16write(wdh, GUINT16_TO_LE(len), err))

View File

@ -935,6 +935,12 @@ static gboolean libpcap_dump(wtap_dumper *wdh,
phdrsize = pcap_get_phdr_size(wdh->encap, pseudo_header);
/* Don't write anything we're not willing to read. */
if (phdr->caplen + phdrsize > WTAP_MAX_PACKET_SIZE) {
*err = WTAP_ERR_PACKET_TOO_LARGE;
return FALSE;
}
rec_hdr.hdr.ts_sec = (guint32) phdr->ts.secs;
if(wdh->tsprecision == WTAP_FILE_TSPREC_NSEC) {
rec_hdr.hdr.ts_usec = phdr->ts.nsecs;

View File

@ -1027,6 +1027,34 @@ static gboolean netmon_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
gint64 secs;
gint32 nsecs;
switch (wdh->file_type_subtype) {
case WTAP_FILE_TYPE_SUBTYPE_NETMON_1_x:
/*
* The length fields are 16-bit, so there's a hard limit
* of 65535.
*/
if (phdr->caplen > 65535) {
*err = WTAP_ERR_PACKET_TOO_LARGE;
return FALSE;
}
break;
case WTAP_FILE_TYPE_SUBTYPE_NETMON_2_x:
/* Don't write anything we're not willing to read. */
if (phdr->caplen > WTAP_MAX_PACKET_SIZE) {
*err = WTAP_ERR_PACKET_TOO_LARGE;
return FALSE;
}
break;
default:
/* We should never get here - our open routine
should only get called for the types above. */
*err = WTAP_ERR_UNSUPPORTED_FILE_TYPE;
return FALSE;
}
if (wdh->encap == WTAP_ENCAP_PER_PACKET) {
/*
* Is this network type supported?

View File

@ -734,6 +734,12 @@ static gboolean nettl_dump(wtap_dumper *wdh,
struct nettlrec_hdr rec_hdr;
guint8 dummyc[24];
/* Don't write anything we're not willing to read. */
if (phdr->caplen > WTAP_MAX_PACKET_SIZE) {
*err = WTAP_ERR_PACKET_TOO_LARGE;
return FALSE;
}
memset(&rec_hdr,0,sizeof(rec_hdr));
/* HP-UX 11.X header should be 68 bytes */
rec_hdr.hdr_len = g_htons(sizeof(rec_hdr) + 4);

View File

@ -699,6 +699,13 @@ static gboolean observer_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
packet_entry_header packet_header;
guint64 seconds_since_2000;
/* The captured size field is 16 bits, so there's a hard limit of
65535. */
if (phdr->caplen > 65535) {
*err = WTAP_ERR_PACKET_TOO_LARGE;
return FALSE;
}
/* convert the number of seconds since epoch from ANSI-relative to
Observer-relative */
if (phdr->ts.secs < ansi_to_observer_epoch_offset) {

View File

@ -1742,6 +1742,13 @@ netxray_dump_1_1(wtap_dumper *wdh,
guint32 t32;
struct netxrayrec_1_x_hdr rec_hdr;
/* The captured length field is 16 bits, so there's a hard
limit of 65535. */
if (phdr->caplen > 65535) {
*err = WTAP_ERR_PACKET_TOO_LARGE;
return FALSE;
}
/* NetXRay/Windows Sniffer files have a capture start date/time
in the header, in a UNIX-style format, with one-second resolution,
and a start time stamp with microsecond resolution that's just
@ -1908,6 +1915,12 @@ netxray_dump_2_0(wtap_dumper *wdh,
guint32 t32;
struct netxrayrec_2_x_hdr rec_hdr;
/* Don't write anything we're not willing to read. */
if (phdr->caplen > WTAP_MAX_PACKET_SIZE) {
*err = WTAP_ERR_PACKET_TOO_LARGE;
return FALSE;
}
/* NetXRay/Windows Sniffer files have a capture start date/time
in the header, in a UNIX-style format, with one-second resolution,
and a start time stamp with microsecond resolution that's just

View File

@ -2075,6 +2075,13 @@ ngsniffer_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
guint16 start_date;
struct tm *tm;
/* The captured length field is 16 bits, so there's a hard
limit of 65535. */
if (phdr->caplen > 65535) {
*err = WTAP_ERR_PACKET_TOO_LARGE;
return FALSE;
}
/* Sniffer files have a capture start date in the file header, and
have times relative to the beginning of that day in the packet
headers; pick the date of the first packet as the capture start

View File

@ -3253,6 +3253,12 @@ pcapng_write_enhanced_packet_block(wtap_dumper *wdh,
guint32 comment_len = 0, comment_pad_len = 0;
wtapng_if_descr_t int_data;
/* Don't write anything we're not willing to read. */
if (phdr->caplen > WTAP_MAX_PACKET_SIZE) {
*err = WTAP_ERR_PACKET_TOO_LARGE;
return FALSE;
}
phdr_len = (guint32)pcap_get_phdr_size(phdr->pkt_encap, pseudo_header);
if ((phdr_len + phdr->caplen) % 4) {
pad_len = 4 - ((phdr_len + phdr->caplen) % 4);

View File

@ -887,10 +887,17 @@ static gboolean snoop_dump(wtap_dumper *wdh,
/* Record length = header length plus data length... */
reclen = (int)sizeof rec_hdr + phdr->caplen + atm_hdrsize;
/* ... plus enough bytes to pad it to a 4-byte boundary. */
padlen = ((reclen + 3) & ~3) - reclen;
reclen += padlen;
/* Don't write anything we're not willing to read. */
if (phdr->caplen + atm_hdrsize > WTAP_MAX_PACKET_SIZE) {
*err = WTAP_ERR_PACKET_TOO_LARGE;
return FALSE;
}
rec_hdr.orig_len = g_htonl(phdr->len + atm_hdrsize);
rec_hdr.incl_len = g_htonl(phdr->caplen + atm_hdrsize);
rec_hdr.rec_len = g_htonl(reclen);

View File

@ -682,6 +682,12 @@ static gboolean visual_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
guint delta_msec;
guint32 packet_status;
/* Don't write anything we're not willing to read. */
if (phdr->caplen > WTAP_MAX_PACKET_SIZE) {
*err = WTAP_ERR_PACKET_TOO_LARGE;
return FALSE;
}
/* If the visual structure was never allocated then nothing useful
can be done. */
if (visual == 0)

View File

@ -797,7 +797,8 @@ static const char *wtap_errlist[] = {
NULL,
NULL,
"Uncompression error",
"Internal error"
"Internal error",
"The packet being written is too large for that format"
};
#define WTAP_ERRLIST_SIZE (sizeof wtap_errlist / sizeof wtap_errlist[0])

View File

@ -1546,6 +1546,10 @@ int wtap_register_encap_type(const char* name, const char* short_name);
#define WTAP_ERR_INTERNAL -23
/** "Shouldn't happen" internal errors */
#define WTAP_ERR_PACKET_TOO_LARGE -24
/** Packet being written is larger than we support; do not use when
reading, use WTAP_ERR_BAD_FILE instead */
#ifdef __cplusplus
}
#endif /* __cplusplus */