Package: isdnlog
Version: 1:3.25+dfsg1-3wheezy1
Severity: normal

Dear Maintainer,

isdnlog on i386 dies with a segmentation fault when handling a HUP
signal. To repeat, just do "/etc/init.d/isdnutils-common reload
isdnlog". This happens in both squeeze and wheezy.

backtrace (line numbers may be slightly different)

#0  0xb7f36f68 in select () from /lib/libc.so.6
#1  0x0804a6af in loop () at isdnlog/isdnlog.c:700
#2  0x0804d861 in main (argc=3, argv=0xbffff7e4, envp=0xbffff7f4) at 
isdnlog/isdnlog.c:1831

According to strace, the HUP handler seems to destroy context needed
by select().

    select(8, [5 7], NULL, [], NULL) = ? ERESTARTNOHAND (To be restarted)
    --- SIGHUP (Hangup) @ 0 (0) ---
    time(NULL)        = 1356551326
    send(4, "<30>Dec 26 20:48:46 isdnlog: restarting /usr/sbin/isdnlog\n\0", 
59, MSG_NOSIGNAL) = 59
    write(6, "restarting /usr/sbin/isdnlog\n", 29) = 29
    write(3, "restarting /usr/sbin/isdnlog\n", 29) = 29
    time(NULL)        = 1356551326
    send(4, "<30>Dec 26 20:48:46 isdnlog: exit now -9\n\0", 42, MSG_NOSIGNAL) = 
42
    write(6, "exit now -9\n", 12) = 12
    write(3, "exit now -9\n", 12) = 12
    close(5)          = 0
    close(7)          = 0
    close(4)          = 0
    close(3)          = 0
    munmap(0xb7703000, 4096) = 0
    rename("/etc/isdn/charge.dat", "/etc/isdn/charge.dat.old") = 0
    open("/etc/isdn/charge.dat", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
    close(3)          = 0
    open("/var/run/isdnlog.isdnctrl0.pid", O_RDONLY) = 3
    fstat64(3, {st_mode=S_IFREG|0644, st_size=6, ...}) = 0
    mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 
0xb7703000
    read(3, "18006\n", 4096) = 6
    unlink("/var/run/isdnlog.isdnctrl0.pid") = 0
    time(NULL)        = 1356551326
    socket(PF_FILE, SOCK_DGRAM|SOCK_CLOEXEC, 0) = 4
    connect(4, {sa_family=AF_FILE, path="/dev/log"}, 110) = -1 EPROTOTYPE 
(Protocol wrong type for socket)
    close(4)          = 0
    socket(PF_FILE, SOCK_STREAM|SOCK_CLOEXEC, 0) = 4
    connect(4, {sa_family=AF_FILE, path="/dev/log"}, 110) = 0
    send(4, "<30>Dec 26 20:48:46 isdnlog: File /var/run/isdnlog.isdnctrl0.pid 
removed!\n\0", 75, MSG_NOSIGNAL) = 75
    write(6, "File /var/run/isdnlog.isdnctrl0.pid removed!\n", 45) = 45
    close(3)          = 0
    munmap(0xb7703000, 4096) = 0
    open("/var/lock/LCK..isdnctrl0", O_RDONLY) = 3
    fstat64(3, {st_mode=S_IFREG|0644, st_size=11, ...}) = 0
    mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 
0xb7703000
    read(3, "     18006\n", 4096) = 11
    unlink("/var/lock/LCK..isdnctrl0") = 0
    time(NULL)        = 1356551326
    send(4, "<30>Dec 26 20:48:46 isdnlog: File /var/lock/LCK..isdnctrl0 
removed!\n\0", 69, MSG_NOSIGNAL) = 69
    write(6, "File /var/lock/LCK..isdnctrl0 removed!\n", 39) = 39
    mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 
0xb7700000
    --- SIGSEGV (Segmentation fault) @ 0 (0) ---

It seems the last write statement from handle_runfiles in isdntools.c
triggers the segmentation fault since following debug print_msg calls
were not executed. I suspect using *printf in a signal handler is not
safe, it might work until a certain amount of bytes were written.
Adding more print_msg calls causes the segfault to happen earlier or
results in other abort messages like "*** glibc detected ***
/usr/bin/isdnlog: malloc(): smallbin double linked list corrupted:
0x08e28668 ***"

Severity left to normal since, as far as I can see, this is not
exploitable.

How to fix: Well, besides fixing the root cause which might take some
time, there's hope since the HUP handler basically restarts isdnlog.
So at least the "reload" in /etc/init.d/isdnutils-common can easily be
changed to stop and start isdnlog instead of sending the signal.

Cheers,

    Christoph

Attachment: signature.asc
Description: Digital signature

Reply via email to