Reassemble: fix premature free
authorJohn A. Thacker <johnthacker@gmail.com>
Fri, 18 Nov 2016 23:35:28 +0000 (18:35 -0500)
committerMichael Mann <mmann78@netscape.net>
Sat, 19 Nov 2016 22:58:08 +0000 (22:58 +0000)
Fix a memory error found by the buildbot and valgrind in my recent patch

Bug: 13100
Change-Id: Ieb21aa25e048f90ce7192546b0ad3d4718ff07df
Reviewed-on: https://code.wireshark.org/review/18877
Petri-Dish: Michael Mann <mmann78@netscape.net>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Michael Mann <mmann78@netscape.net>
epan/reassemble.c

index e18da27431d06652b66ad0cf0516df3171fea109..62fb9519c02045a22ad3ad1b6732f5f94e889620 100644 (file)
@@ -2212,11 +2212,6 @@ fragment_add_seq_single_work(reassembly_table *table, tvbuff_t *tvb,
                                        }
                                }
                                prev_fd->next = NULL;
-                               if (new_fh->next == NULL) {
-                                       old_tvb_data = fragment_delete(table, pinfo, id-frag_number, data);
-                                       if (old_tvb_data)
-                                               tvb_free(old_tvb_data);
-                               }
                                break;
                        }
                }
@@ -2230,14 +2225,23 @@ fragment_add_seq_single_work(reassembly_table *table, tvbuff_t *tvb,
                                }
                        }
                        MERGE_FRAG(fh, fd);
-                       /* If we've moved a Last packet, change the datalen.
-                        * Second part of this test should be unnecessary. */
-                       if (new_fh->flags & FD_DATALEN_SET &&
-                           new_fh->datalen >= frag_number) {
-                               fh->flags |= FD_DATALEN_SET;
-                               fh->datalen = new_fh->datalen - frag_number;
-                               new_fh->flags &= ~FD_DATALEN_SET;
-                               new_fh->datalen = 0;
+                       if (new_fh != NULL) {
+                               /* If we've moved a Last packet, change datalen.
+                                * Second part of this test prob. redundant? */
+                               if (new_fh->flags & FD_DATALEN_SET &&
+                                   new_fh->datalen >= frag_number) {
+                                       fh->flags |= FD_DATALEN_SET;
+                                       fh->datalen = new_fh->datalen - frag_number;
+                                       new_fh->flags &= ~FD_DATALEN_SET;
+                                       new_fh->datalen = 0;
+                               }
+                               /* If we've moved all the fragments,
+                                * delete the old head */
+                               if (new_fh->next == NULL) {
+                                       old_tvb_data = fragment_delete(table, pinfo, id-frag_number, data);
+                                       if (old_tvb_data)
+                                               tvb_free(old_tvb_data);
+                               }
                        } else {
                        /* Look forward and take off the next (this is
                         * necessary in some edge cases where max_frags