Package: arpwatch
Version: 2.1a15-1.2
Severity: important
Tags: patch

Dear Maintainer,

after upgrading from squeeze I noticed arpwatch aborts upon start:

| arpwatch: *** buffer overflow detected ***: /usr/sbin/arpwatch terminated

Starting arpwatch manually shows:

*** buffer overflow detected ***: /usr/sbin/arpwatch terminated
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(__fortify_fail+0x37)[0x7f977f0232a7]
/lib/x86_64-linux-gnu/libc.so.6(+0xee160)[0x7f977f022160]
/usr/sbin/arpwatch[0x4038ba]
/usr/sbin/arpwatch[0x403f1f]
/usr/sbin/arpwatch[0x40489f]
/usr/sbin/arpwatch[0x404f47]
/usr/sbin/arpwatch[0x4025ad]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xfd)[0x7f977ef52ead]
/usr/sbin/arpwatch[0x402925]
======= Memory map: ========
00400000-00408000 r-xp 00000000 08:05 25900                              
/usr/sbin/arpwatch
00607000-00608000 r--p 00007000 08:05 25900                              
/usr/sbin/arpwatch
00608000-00609000 rw-p 00008000 08:05 25900                              
/usr/sbin/arpwatch
00609000-00809000 rw-p 00000000 00:00 0 
01d29000-01d6b000 rw-p 00000000 00:00 0                                  [heap]
7f977e2e7000-7f977e2fc000 r-xp 00000000 08:05 1208                       
/lib/x86_64-linux-gnu/libgcc_s.so.1
7f977e2fc000-7f977e4fc000 ---p 00015000 08:05 1208                       
/lib/x86_64-linux-gnu/libgcc_s.so.1
7f977e4fc000-7f977e4fd000 rw-p 00015000 08:05 1208                       
/lib/x86_64-linux-gnu/libgcc_s.so.1
7f977e4fd000-7f977e508000 r-xp 00000000 08:05 7417                       
/lib/x86_64-linux-gnu/libnss_files-2.13.so
7f977e508000-7f977e707000 ---p 0000b000 08:05 7417                       
/lib/x86_64-linux-gnu/libnss_files-2.13.so
7f977e707000-7f977e708000 r--p 0000a000 08:05 7417                       
/lib/x86_64-linux-gnu/libnss_files-2.13.so
7f977e708000-7f977e709000 rw-p 0000b000 08:05 7417                       
/lib/x86_64-linux-gnu/libnss_files-2.13.so
7f977e709000-7f977e713000 r-xp 00000000 08:05 7429                       
/lib/x86_64-linux-gnu/libnss_nis-2.13.so
7f977e713000-7f977e912000 ---p 0000a000 08:05 7429                       
/lib/x86_64-linux-gnu/libnss_nis-2.13.so
7f977e912000-7f977e913000 r--p 00009000 08:05 7429                       
/lib/x86_64-linux-gnu/libnss_nis-2.13.so
7f977e913000-7f977e914000 rw-p 0000a000 08:05 7429                       
/lib/x86_64-linux-gnu/libnss_nis-2.13.so
7f977e914000-7f977e929000 r-xp 00000000 08:05 7427                       
/lib/x86_64-linux-gnu/libnsl-2.13.so
7f977e929000-7f977eb28000 ---p 00015000 08:05 7427                       
/lib/x86_64-linux-gnu/libnsl-2.13.so
7f977eb28000-7f977eb29000 r--p 00014000 08:05 7427                       
/lib/x86_64-linux-gnu/libnsl-2.13.so
7f977eb29000-7f977eb2a000 rw-p 00015000 08:05 7427                       
/lib/x86_64-linux-gnu/libnsl-2.13.so
7f977eb2a000-7f977eb2c000 rw-p 00000000 00:00 0 
7f977eb2c000-7f977eb33000 r-xp 00000000 08:05 7419                       
/lib/x86_64-linux-gnu/libnss_compat-2.13.so
7f977eb33000-7f977ed32000 ---p 00007000 08:05 7419                       
/lib/x86_64-linux-gnu/libnss_compat-2.13.so
7f977ed32000-7f977ed33000 r--p 00006000 08:05 7419                       
/lib/x86_64-linux-gnu/libnss_compat-2.13.so
7f977ed33000-7f977ed34000 rw-p 00007000 08:05 7419                       
/lib/x86_64-linux-gnu/libnss_compat-2.13.so
7f977ed34000-7f977ef34000 rw-s 00000000 00:06 12829                      
socket:[12829]
7f977ef34000-7f977f0b4000 r-xp 00000000 08:05 7423                       
/lib/x86_64-linux-gnu/libc-2.13.so
7f977f0b4000-7f977f2b4000 ---p 00180000 08:05 7423                       
/lib/x86_64-linux-gnu/libc-2.13.so
7f977f2b4000-7f977f2b8000 r--p 00180000 08:05 7423                       
/lib/x86_64-linux-gnu/libc-2.13.so
7f977f2b8000-7f977f2b9000 rw-p 00184000 08:05 7423                       
/lib/x86_64-linux-gnu/libc-2.13.so
7f977f2b9000-7f977f2be000 rw-p 00000000 00:00 0 
7f977f2be000-7f977f2de000 r-xp 00000000 08:05 7426                       
/lib/x86_64-linux-gnu/ld-2.13.so
7f977f495000-7f977f498000 rw-p 00000000 00:00 0 
7f977f498000-7f977f4d0000 r-xp 00000000 08:05 25790                      
/usr/lib/x86_64-linux-gnu/libpcap.so.1.3.0
7f977f4d0000-7f977f4d2000 r--p 00037000 08:05 25790                      
/usr/lib/x86_64-linux-gnu/libpcap.so.1.3.0
7f977f4d2000-7f977f4d3000 rw-p 00039000 08:05 25790                      
/usr/lib/x86_64-linux-gnu/libpcap.so.1.3.0
7f977f4d3000-7f977f4d4000 rw-p 00000000 00:00 0 
7f977f4da000-7f977f4dd000 rw-p 00000000 00:00 0 
7f977f4dd000-7f977f4de000 r--p 0001f000 08:05 7426                       
/lib/x86_64-linux-gnu/ld-2.13.so
7f977f4de000-7f977f4df000 rw-p 00020000 08:05 7426                       
/lib/x86_64-linux-gnu/ld-2.13.so
7f977f4df000-7f977f4e0000 rw-p 00000000 00:00 0 
7ffff0d01000-7ffff0d22000 rw-p 00000000 00:00 0                          [stack]
7ffff0dff000-7ffff0e00000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  
[vsyscall]
Aborted


Using a self-compiled arpwatch and gdb led to

(gdb) bt
#0  0x00007ffff7a85475 in raise () from /lib/x86_64-linux-gnu/libc.so.6
#1  0x00007ffff7a886f0 in abort () from /lib/x86_64-linux-gnu/libc.so.6
#2  0x00007ffff7ac052b in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#3  0x00007ffff7b422a7 in __fortify_fail () from /lib/x86_64-linux-gnu/libc.so.6
#4  0x00007ffff7b41160 in __chk_fail () from /lib/x86_64-linux-gnu/libc.so.6
#5  0x0000000000403909 in strcpy (__src=0x7fffffffe00b 
"a-hostname-longer-than-34-characters", 
    __dest=0x82c0f6 "a-hostname-longer-than-34-characte") at 
/usr/include/x86_64-linux-gnu/bits/string3.h:105
#6  elist_alloc (a=a@entry=2490776406, e=e@entry=0x7fffffffdfd0 "\002", 
t=1366566013, 
    h=h@entry=0x7fffffffe00b "a-hostname-longer-than-34-characters", 
    interface=interface@entry=0x7fffffffe030 "eth0") at ./db.c:297
#7  0x0000000000403f6d in ent_add (a=a@entry=2490776406, 
e=e@entry=0x7fffffffdfd0 "\002", 
    t=t@entry=1366566013, h=0x7fffffffe00b 
"a-hostname-longer-than-34-characters", 
    interface=interface@entry=0x7fffffffe030 "eth0") at ./db.c:125
#8  0x000000000040487a in file_loop (f=f@entry=0x82bdf0, fn=0x403bb0 <ent_add>, 
    name=0x7fffffffe90e "eth0.dat") at ./file.c:145
#9  0x0000000000404f57 in readdata () at ./util.c:163
#10 0x00000000004025f7 in main (argc=<optimized out>, argv=<optimized out>) at 
./arpwatch.c:445
(gdb) 


which is the strcpy in elist_alloc in ec.c:

    if (h != NULL && !isdigit((int)*h))
        strcpy(ep->h, h);
    ep->t = t;


Analysis:
In earlier versions, arpwatch would more or less happily handle
hostnames returned in IP lookups that are longer than 33 octets,
resulting in /var/lib/arpwatch/eth0.dat hostnames records longer that
arpwatch can handle. In wheezy, at least on amd64, reading that file
upon start now triggers the error above. Earlier, you could probably
overwrite memory in the arpwatch process, although exploiting that
doesn't look like an easy job.

How to repeat:
* stop arpwatch
* add a line with a long hostname to /var/lib/arpwatch/eth0.dat, for
  example (note: MUST be tab separated):
  02:00:de:ad:be:ef 86.59.118.148 1366566013 
a-hostname-longer-than-34-characters eth0
* Start arpwatch
  /usr/sbin/arpwatch -d  -i eth0 -f eth0.dat -N -u arpwatch -p


How to repair:

On an affected installation: Stop arpwatch and remove the offending
lines from /var/lib/arpwatch/*.dat

How to fix:

The patch below uses strncpy (in one case: fixes strncpy usage) in
three places that seem to be vulnerable. Interface names with more
than 16 characters might be a bit unusual but playing safe is the
better idea. The other usages of strcpy and strncat in the sources
look somewhat OK, although the constraints are well hidden.

Note: A previous analysis of that error had been done in
https://bugs.launchpad.net/ubuntu/+source/arpwatch/+bug/1097289

    Christoph

-- System Information:
Debian Release: 7.0
  APT prefers testing
  APT policy: (500, 'testing')
Architecture: amd64 (x86_64)

Kernel: Linux 3.4.38
Locale: LANG=de_DE.UTF-8, LC_CTYPE=de_DE.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash

Versions of packages arpwatch depends on:
ii  adduser     3.113+nmu3
ii  libc6       2.13-38
ii  libpcap0.8  1.3.0-1

arpwatch recommends no packages.

arpwatch suggests no packages.

-- Configuration Files:
/etc/arpwatch.conf changed [not included]

-- no debconf information

commit 3a56bb6499ea57de9711e9c53280d94601d2de18
Author: Christoph Biedl <debian.a...@manchmal.in-ulm.de>
Date:   Sun Apr 21 20:38:44 2013 +0200

    Protect some string copy operations

diff --git a/db.c b/db.c
index 03089dc..bdfcff3 100644
--- a/db.c
+++ b/db.c
@@ -293,11 +293,15 @@ elist_alloc(register u_int32_t a, register u_char *e, 
register time_t t,
        BCOPY(e, ep->e, 6);
        if (h == NULL && !initializing)
                h = getsname(a);
-       if (h != NULL && !isdigit((int)*h))
-               strcpy(ep->h, h);
+       if (h != NULL && !isdigit((int)*h)) {
+               strncpy(ep->h, h, 34);
+               ep->h[33] = '\0';
+       }
        ep->t = t;
-       if (interface != NULL)
+       if (interface != NULL) {
                strncpy(ep->i, interface, 16);
+               ep->i[15] = '\0';
+       }
        return (ep);
 }
 
@@ -316,7 +320,8 @@ check_hname(register struct ainfo *ap)
        if (!isdigit((int)*h) && strcmp(h, ep->h) != 0) {
                syslog(LOG_INFO, "hostname changed %s %s %s -> %s",
                    intoa(ap->a), e2str(ep->e), ep->h, h);
-               strcpy(ep->h, h);
+               strncpy(ep->h, h, 34);
+               ep->h[33] = '\0';
        }
 }
 

Attachment: signature.asc
Description: Digital signature

Reply via email to