summaryrefslogtreecommitdiff
path: root/epan/reassemble.c
diff options
context:
space:
mode:
authorMartin Kaiser <wireshark@kaiser.cx>2013-01-08 22:18:52 +0000
committerMartin Kaiser <wireshark@kaiser.cx>2013-01-08 22:18:52 +0000
commitd3b504f33126c32850462f9aee50e507d4c59d5c (patch)
tree1e4d370ee886e1a9a0793af0093f1c77bf06c173 /epan/reassemble.c
parent697514cd353cb9e8da4f8a72cc150fc38cc6fb98 (diff)
downloadwireshark-d3b504f33126c32850462f9aee50e507d4c59d5c.tar.gz
From Evan:
sanity checks before setting a packet's total length in fragment_set_tot_len() (from me: check if fragments exist for the given id) hopefully, this fixes #8111 and #8163 without causing troubles for other protocols that use fragmentation and reassembly svn path=/trunk/; revision=46999
Diffstat (limited to 'epan/reassemble.c')
-rw-r--r--epan/reassemble.c38
1 files changed, 33 insertions, 5 deletions
diff --git a/epan/reassemble.c b/epan/reassemble.c
index abc84dffdc..54e20b10db 100644
--- a/epan/reassemble.c
+++ b/epan/reassemble.c
@@ -523,7 +523,9 @@ fragment_set_tot_len(const packet_info *pinfo, const guint32 id, GHashTable *fra
const guint32 tot_len)
{
fragment_data *fd_head;
- fragment_key key;
+ fragment_data *fd;
+ fragment_key key;
+ guint32 max_offset = 0;
/* create key to search hash with */
key.src = pinfo->src;
@@ -531,13 +533,39 @@ fragment_set_tot_len(const packet_info *pinfo, const guint32 id, GHashTable *fra
key.id = id;
fd_head = g_hash_table_lookup(fragment_table, &key);
+ if (!fd_head)
+ return;
- if(fd_head){
- fd_head->datalen = tot_len;
- fd_head->flags |= FD_DATALEN_SET;
+ /* Verify that the length (or block sequence number) we're setting
+ * doesn't conflict with values set by existing fragments.
+ */
+ fd = fd_head;
+ if (fd_head->flags & FD_BLOCKSEQUENCE) {
+ while (fd) {
+ if (fd->offset > max_offset) {
+ max_offset = fd->offset;
+ DISSECTOR_ASSERT(max_offset <= tot_len);
+ }
+ fd = fd->next;
+ }
+ }
+ else {
+ while (fd) {
+ if (fd->offset + fd->len > max_offset) {
+ max_offset = fd->offset + fd->len;
+ DISSECTOR_ASSERT(max_offset <= tot_len);
+ }
+ fd = fd->next;
+ }
+ }
+
+ if (fd_head->flags & FD_DEFRAGMENTED) {
+ DISSECTOR_ASSERT(max_offset == tot_len);
}
- return;
+ /* We got this far so the value is sane. */
+ fd_head->datalen = tot_len;
+ fd_head->flags |= FD_DATALEN_SET;
}
guint32