aboutsummaryrefslogtreecommitdiffstats
path: root/epan/reassemble.c
diff options
context:
space:
mode:
authorBill Meier <wmeier@newsguy.com>2008-05-21 16:53:07 +0000
committerBill Meier <wmeier@newsguy.com>2008-05-21 16:53:07 +0000
commitbf018e2a96c5ae82a029c537b7157697ef95c905 (patch)
treee91cd01d22726c2218304a49536a5ca4a1133b10 /epan/reassemble.c
parentad761ed3fdc3ab30dbed6f5676c8ffcdc0b7eb2b (diff)
Fix for bug #2470; (don't memcmp past end of g_malloc'd buffer).
svn path=/trunk/; revision=25343
Diffstat (limited to 'epan/reassemble.c')
-rw-r--r--epan/reassemble.c35
1 files changed, 22 insertions, 13 deletions
diff --git a/epan/reassemble.c b/epan/reassemble.c
index 9e678f95dc..b61ac02e5d 100644
--- a/epan/reassemble.c
+++ b/epan/reassemble.c
@@ -794,22 +794,19 @@ fragment_add_work(fragment_data *fd_head, tvbuff_t *tvb, int offset,
/* add all data fragments */
for (dfpos=0,fd_i=fd_head;fd_i;fd_i=fd_i->next) {
if (fd_i->len) {
- if (fd_i->offset < dfpos) {
- fd_i->flags |= FD_OVERLAP;
- fd_head->flags |= FD_OVERLAP;
- if ( memcmp(fd_head->data+fd_i->offset,
- fd_i->data,
- MIN(fd_i->len,(dfpos-fd_i->offset))
- ) ){
- fd_i->flags |= FD_OVERLAPCONFLICT;
- fd_head->flags |= FD_OVERLAPCONFLICT;
- }
- }
/* dfpos is always >= than fd_i->offset */
/* No gaps can exist here, max_loop(above) does this */
/* XXX - true? Can we get fd_i->offset+fd-i->len */
/* overflowing, for example? */
- if( fd_i->offset+fd_i->len > dfpos ) {
+ /* Actually: there is at least one pathological case wherein there can be fragments
+ on the list which are for offsets greater than max (i.e.: following a gap after max).
+ (Something related to "defrag_until_fin" where the fin packet has an offset less than
+ the highestfragment offset seen ? [Seen from a fuzz-test: bug #2470]).
+ So: the "overlap" compare must only be done for fragments with (offset+len) <= max
+ and thus within the newly g_malloc'd buffer.
+ */
+
+ if ( fd_i->offset+fd_i->len > dfpos ) {
if (fd_i->offset+fd_i->len > max)
g_warning("Reassemble error in frame %u: offset %u + len %u > max %u",
pinfo->fd->num, fd_i->offset,
@@ -821,10 +818,22 @@ fragment_add_work(fragment_data *fd_head, tvbuff_t *tvb, int offset,
g_warning("Reassemble error in frame %u: dfpos %u - offset %u > len %u",
pinfo->fd->num, dfpos, fd_i->offset,
fd_i->len);
- else
+ else {
+ if (fd_i->offset < dfpos) {
+ fd_i->flags |= FD_OVERLAP;
+ fd_head->flags |= FD_OVERLAP;
+ if ( memcmp(fd_head->data+fd_i->offset,
+ fd_i->data,
+ MIN(fd_i->len,(dfpos-fd_i->offset))
+ ) ) {
+ fd_i->flags |= FD_OVERLAPCONFLICT;
+ fd_head->flags |= FD_OVERLAPCONFLICT;
+ }
+ }
memcpy(fd_head->data+dfpos,
fd_i->data+(dfpos-fd_i->offset),
fd_i->len-(dfpos-fd_i->offset));
+ }
} else {
if (fd_i->offset+fd_i->len < fd_i->offset)
g_warning("Reassemble error in frame %u: offset %u + len %u < offset",