Ethereal-dev: Re: [Ethereal-dev] desegmentation patch

Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.

From: Guy Harris <gharris@xxxxxxxxx>
Date: Sat, 2 Feb 2002 14:29:58 -0800
On Sat, Feb 02, 2002 at 07:39:17PM +0000, Ricardo Barroetave�a wrote:
> pls find attached a patch file for reassemble.c/h & packet-tcp.c .

I have a capture file on which it drops core.

The problem is that in the "add all data fragments" part of
"fragment_add()", "fd_i->len" is less than 'dfpos - fd_i->offset" for
one TCP segment, so the argument to "memcpy()" is negative.

The list of fragments (TCP segments) is:

(gdb) print fd_head
$1 = (fragment_data *) 0x83af9d4
(gdb) print *$1
$2 = {next = 0x83af9f0, frame = 4022250974, offset = 0, len = 0, 
  datalen = 32916, flags = 2, data = 0x8446000}

(That's the item for the reassembled packet, hence the bogus frame
number.)

(gdb) print *$2.next
$3 = {next = 0x83afa7c, frame = 1351, offset = 0, len = 1460, 
  datalen = 4022250974, flags = 0, data = 0x0}
(gdb) print *$3.next
$4 = {next = 0x83afab4, frame = 1359, offset = 0, len = 664, 
  datalen = 3203391149, flags = 2, data = 0x83a5c00}
(gdb) print *$4.next
$5 = {next = 0x83afa0c, frame = 1366, offset = 664, len = 1460, 
  datalen = 4022250974, flags = 0, data = 0x839d800}
(gdb) print *$5.next
$6 = {next = 0x83afa28, frame = 1352, offset = 1460, len = 1460, 
  datalen = 4022250974, flags = 0, data = 0x83bf800}
(gdb) print *$6.next
$7 = {next = 0x83afa44, frame = 1354, offset = 2920, len = 1460, 
  datalen = 4022250974, flags = 0, data = 0x83c0000}
(gdb) print *$7.next
$8 = {next = 0x83afa98, frame = 1355, offset = 4380, len = 1460, 
  datalen = 3203391149, flags = 0, data = 0x83c0800}
(gdb) print *$8.next
$9 = {next = 0x83afad0, frame = 1361, offset = 5840, len = 1460, 
  datalen = 3203391149, flags = 0, data = 0x837a000}
(gdb) print *$9.next
$10 = {next = 0x83afaec, frame = 1369, offset = 7300, len = 1460, 
  datalen = 4022250974, flags = 0, data = 0x83a600}
(gdb) print *$10.next
$11 = {next = 0x83afb08, frame = 1370, offset = 8760, len = 1460, 
  datalen = 4022250974, flags = 0, data = 0x83a6800}
(gdb) print *$11.next
$12 = {next = 0x83afb24, frame = 1372, offset = 10220, len = 1460, 
  datalen = 4022250974, flags = 0, data = 0x83a8000}
(gdb) print *$12.next
$13 = {next = 0x83afb40, frame = 1373, offset = 11680, len = 1460, 
  datalen = 3203391149, flags = 0, data = 0x83a880}
(gdb) print *$13.next
$14 = {next = 0x83afb5c, frame = 1374, offset = 13140, len = 1460, 
  datalen = 3203391149, flags = 0, data = 0x83a9000}
(gdb) print *$14.next
$15 = {next = 0x83afb78, frame = 1376, offset = 14600, len = 1460, 
  datalen = 3203391149, flags = 0, data = 0x83a980}
(gdb) print *$15.next
$16 = {next = 0x83afb94, frame = 1377, offset = 16060, len = 1460, 
  datalen = 3203391149, flags = 0, data = 0x83aa000}
(gdb) print *$16.next
$17 = {next = 0x83afbb0, frame = 1378, offset = 17520, len = 1460, 
  datalen = 4022250974, flags = 0, data = 0x83aa800}
(gdb) print *$17.next
$18 = {next = 0x83afbcc, frame = 1380, offset = 18980, len = 1460, 
  datalen = 4022250974, flags = 0, data = 0x83ac000}
(gdb) print *$18.next
$19 = {next = 0x83afbe8, frame = 1381, offset = 20440, len = 1460, 
  datalen = 4022250974, flags = 0, data = 0x83ac800}
(gdb) print *$19.next
$20 = {next = 0x83afc04, frame = 1383, offset = 21900, len = 1460, 
  datalen = 4022250974, flags = 0, data = 0x83ad000}
(gdb) print *$20.next
$21 = {next = 0x83afc20, frame = 1385, offset = 23360, len = 1460, 
  datalen = 3203391149, flags = 0, data = 0x83ad800}
(gdb) print *$21.next
$22 = {next = 0x83afc3c, frame = 1386, offset = 24820, len = 1460, 
  datalen = 3203391149, flags = 0, data = 0x83b9000}
(gdb) print *$22.next
$23 = {next = 0x83afc58, frame = 1387, offset = 26280, len = 1460, 
  datalen = 3203391149, flags = 0, data = 0x83b9800}
(gdb) print *$23.next
$24 = {next = 0x83afc74, frame = 1388, offset = 27740, len = 1460, 
  datalen = 3203391149, flags = 0, data = 0x83ba000}
(gdb) print *$24.next
$25 = {next = 0x83afc90, frame = 1390, offset = 29200, len = 1460, 
  datalen = 4022250974, flags = 0, data = 0x83ba800}
(gdb) print *$25.next
$26 = {next = 0x83afcac, frame = 1391, offset = 30660, len = 1460, 
  datalen = 4022250974, flags = 0, data = 0x83bb000}
(gdb) print *$26.next
$27 = {next = 0x0, frame = 1393, offset = 32120, len = 796, 
  datalen = 4022250974, flags = 0, data = 0x83a5800}

The offending "fd_i" is 0x83afa7c, and it points to

	$4 = {next = 0x83afab4, frame = 1359, offset = 0, len = 664, 
	  datalen = 3203391149, flags = 2, data = 0x83a5c00}

"dfpos" is 1460, and "dfpos - fd_i->offset" is also 1460.

However, in the capture, frame 1351 has a sequence number of 562636910
and a next sequence number of 562638370, for a length of 1460, and frame
1359 has a sequence number of a sequence number of 562636114 and a next
sequence number of 562637574, also with a length of 1460.  1351 and 1359
*do* overlap - the last 664 bytes of frame 1359 overlap the first 664
bytes of frame 1351.

It may be that the reassembly code isn't dealing with retransmissions,
out-of-order transmissions, and overlaps as well as it should.