aboutsummaryrefslogtreecommitdiffstats
path: root/wiretap
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2014-01-22 00:26:36 +0000
committerGuy Harris <guy@alum.mit.edu>2014-01-22 00:26:36 +0000
commit90d7c5f59b574e254bc1bb70aaaf12372fe97cc3 (patch)
tree7bc8e69b7cc459b8dfef190d1b33a7cb092a7bf3 /wiretap
parent5c825d6a364d83dace7b6c682aa47678e89df79b (diff)
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
Diffstat (limited to 'wiretap')
-rw-r--r--wiretap/5views.c6
-rw-r--r--wiretap/btsnoop.c15
-rw-r--r--wiretap/commview.c8
-rw-r--r--wiretap/erf.c13
-rw-r--r--wiretap/eyesdn.c8
-rw-r--r--wiretap/k12.c6
-rw-r--r--wiretap/k12text.l6
-rw-r--r--wiretap/lanalyzer.c8
-rw-r--r--wiretap/libpcap.c6
-rw-r--r--wiretap/netmon.c28
-rw-r--r--wiretap/nettl.c6
-rw-r--r--wiretap/network_instruments.c7
-rw-r--r--wiretap/netxray.c13
-rw-r--r--wiretap/ngsniffer.c7
-rw-r--r--wiretap/pcapng.c6
-rw-r--r--wiretap/snoop.c7
-rw-r--r--wiretap/visual.c6
-rw-r--r--wiretap/wtap.c3
-rw-r--r--wiretap/wtap.h4
19 files changed, 154 insertions, 9 deletions
diff --git a/wiretap/5views.c b/wiretap/5views.c
index 5ff61101dc..c43fb35c8d 100644
--- a/wiretap/5views.c
+++ b/wiretap/5views.c
@@ -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);
diff --git a/wiretap/btsnoop.c b/wiretap/btsnoop.c
index 9fc2cb06f4..3c67f84198 100644
--- a/wiretap/btsnoop.c
+++ b/wiretap/btsnoop.c
@@ -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;
diff --git a/wiretap/commview.c b/wiretap/commview.c
index 4283a6f44b..0687a18b69 100644
--- a/wiretap/commview.c
+++ b/wiretap/commview.c
@@ -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);
diff --git a/wiretap/erf.c b/wiretap/erf.c
index 7eebe0a44a..5ac2ae76fe 100644
--- a/wiretap/erf.c
+++ b/wiretap/erf.c
@@ -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{
diff --git a/wiretap/eyesdn.c b/wiretap/eyesdn.c
index 66897b81df..ea0af9ffdd 100644
--- a/wiretap/eyesdn.c
+++ b/wiretap/eyesdn.c
@@ -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;
diff --git a/wiretap/k12.c b/wiretap/k12.c
index 10687f8412..8dfaef6e0c 100644
--- a/wiretap/k12.c
+++ b/wiretap/k12.c
@@ -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);
}
diff --git a/wiretap/k12text.l b/wiretap/k12text.l
index ebec0ac7b9..afdc267cba 100644
--- a/wiretap/k12text.l
+++ b/wiretap/k12text.l
@@ -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) {
diff --git a/wiretap/lanalyzer.c b/wiretap/lanalyzer.c
index 97f9764411..494e2591de 100644
--- a/wiretap/lanalyzer.c
+++ b/wiretap/lanalyzer.c
@@ -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))
diff --git a/wiretap/libpcap.c b/wiretap/libpcap.c
index c73a357835..a323cde1b3 100644
--- a/wiretap/libpcap.c
+++ b/wiretap/libpcap.c
@@ -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;
diff --git a/wiretap/netmon.c b/wiretap/netmon.c
index ad1aacb8f6..717992a738 100644
--- a/wiretap/netmon.c
+++ b/wiretap/netmon.c
@@ -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?
diff --git a/wiretap/nettl.c b/wiretap/nettl.c
index e869fb711f..ac3f7ed499 100644
--- a/wiretap/nettl.c
+++ b/wiretap/nettl.c
@@ -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);
diff --git a/wiretap/network_instruments.c b/wiretap/network_instruments.c
index 2e9f340288..07e3e3a7e2 100644
--- a/wiretap/network_instruments.c
+++ b/wiretap/network_instruments.c
@@ -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) {
diff --git a/wiretap/netxray.c b/wiretap/netxray.c
index 189c70a04c..774262cf3e 100644
--- a/wiretap/netxray.c
+++ b/wiretap/netxray.c
@@ -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
diff --git a/wiretap/ngsniffer.c b/wiretap/ngsniffer.c
index 0e33072ca7..58031ff38e 100644
--- a/wiretap/ngsniffer.c
+++ b/wiretap/ngsniffer.c
@@ -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
diff --git a/wiretap/pcapng.c b/wiretap/pcapng.c
index 86be49d20d..6afc024f7c 100644
--- a/wiretap/pcapng.c
+++ b/wiretap/pcapng.c
@@ -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);
diff --git a/wiretap/snoop.c b/wiretap/snoop.c
index fb9253706b..985cfe9f9e 100644
--- a/wiretap/snoop.c
+++ b/wiretap/snoop.c
@@ -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);
diff --git a/wiretap/visual.c b/wiretap/visual.c
index d73fa2515a..a0822aa855 100644
--- a/wiretap/visual.c
+++ b/wiretap/visual.c
@@ -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)
diff --git a/wiretap/wtap.c b/wiretap/wtap.c
index d5b4c89e6d..28bba7a79c 100644
--- a/wiretap/wtap.c
+++ b/wiretap/wtap.c
@@ -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])
diff --git a/wiretap/wtap.h b/wiretap/wtap.h
index b70c893df7..95459d5462 100644
--- a/wiretap/wtap.h
+++ b/wiretap/wtap.h
@@ -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 */