On Thu, Jun 13, 2002 at 04:28:42PM +0200, Andreas Ferber wrote:
> It looks like something is trashing data on the stack

Probably.

I can't reproduce it on my machine by reading that particular file, but
the bogus address in

        Cannot access memory at address 0x3631785b

looks like the string [x16, which would be part of a string printed for
RFC 2673 bitstring labels in DNS, and with a really large bit count that
string could overflow a buffer.

The attached patch *should* prevent that; get the 0.9.4 source, apply
the patch to "packet-dns.c", rebuild, and try to run the resulting
Ethereal on the capture file that caused the crash.

> The crash occurs with both ethereal 0.8.20 and 0.9.4, and affects both
> the GUI and the commandline version. editcap doesn't crash on the
> packet, so the problem seems to be somewhere in the packet decoding
> code. The trace was captured originally with tcpdump, so I can't tell
> if it would crash ethereal while only capturing into a file without
> showing decoded data.

It probably wouldn't crash Ethereal or Tethereal if you're only
capturing to a file.
Index: packet-dns.c
===================================================================
RCS file: /usr/local/cvsroot/ethereal/packet-dns.c,v
retrieving revision 1.87
diff -c -r1.87 packet-dns.c
*** packet-dns.c        15 May 2002 07:24:20 -0000      1.87
--- packet-dns.c        14 Jun 2002 07:43:32 -0000
***************
*** 536,552 ****
        {
          int bit_count;
          int label_len;
  
          bit_count = tvb_get_guint8(tvb, offset);
          offset++;
          label_len = (bit_count - 1) / 8 + 1;
        
!         np += sprintf(np, "\\[x");
          while(label_len--) {
!           np += sprintf(np, "%02x", tvb_get_guint8(tvb, offset));
            offset++;
          }
!         np += sprintf(np, "/%d]", bit_count);
        }
        break;
  
--- 536,590 ----
        {
          int bit_count;
          int label_len;
+         int print_len;
  
          bit_count = tvb_get_guint8(tvb, offset);
          offset++;
          label_len = (bit_count - 1) / 8 + 1;
        
!         if (maxname > 0) {
!           print_len = snprintf(np, maxname + 1, "\\[x");
!           if (print_len != -1) {
!             /* Some versions of snprintf return -1 if they'd truncate
!                the output. */
!             np += print_len;
!             maxname -= print_len;
!           } else {
!             /* Nothing printed, as there's no room.
!                Suppress all subsequent printing. */
!             maxname = 0;
!           }
!         }
          while(label_len--) {
!           if (maxname > 0) {
!             print_len = snprintf(np, maxname + 1, "%02x",
!               tvb_get_guint8(tvb, offset));
!             if (print_len != -1) {
!               /* Some versions of snprintf return -1 if they'd truncate
!                the output. */
!               np += print_len;
!               maxname -= print_len;
!             } else {
!               /* Nothing printed, as there's no room.
!                  Suppress all subsequent printing. */
!               maxname = 0;
!             }
!           }
            offset++;
          }
!         if (maxname > 0) {
!           print_len = snprintf(np, maxname + 1, "/%d]", bit_count);
!           if (print_len != -1) {
!             /* Some versions of snprintf return -1 if they'd truncate
!                the output. */
!             np += print_len;
!             maxname -= print_len;
!           } else {
!             /* Nothing printed, as there's no room.
!                Suppress all subsequent printing. */
!             maxname = 0;
!           }
!         }
        }
        break;
  

Reply via email to