Package: libc6 Version: 2.3.2.ds1-11 Severity: important Tags: security The non-debug libc6 binaries do strange things to the stack. I haven't figured out the specifics to this bug, but I have found two ways to reliably reproduce the problem.
Method 1: #include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { printf("aborting...\n"); abort(); } Resulting stack trace on abort(): #0 0xffffe410 in __kernel_vsyscall () #1 0x4005acf3 in raise () from /lib/tls/i686/cmov/libc.so.6 #2 0x4016706c in ?? () from /lib/tls/i686/cmov/libc.so.6 Resulting (expected) stack trace with libc6-dbg: #0 0x40041571 in kill () from /usr/lib/debug/libc.so.6 #1 0x40041315 in *__GI_raise (sig=6) at ../linuxthreads/sysdeps/unix/sysv/linux/raise.c:32 #2 0x40042838 in *__GI_abort () at ../sysdeps/generic/abort.c:88 #3 0x080483ae in main (argc=1, argv=0xbffff4b4) at test1.c:8 One other place I encountered the problem was while trying to walk the stack in an LD_PRELOADed library that wrapped around gettimeofday(). I used __builtin_frame_address (a gcc internal) to walk backwards through the stack (the function is supposed to return 0 when the top of the stack is reached.) The results end with some characters of the program name (which is stored after the stack) with a non-debug libc. Method 2: #include <time.h> #include <stdio.h> #include <sys/time.h> #define STACKFRAME(x) \ printf("%d: %p\n", x, __builtin_frame_address(x)); \ fflush(stdout); \ if (__builtin_frame_address(x) == NULL) \ return 0; int gettimeofday(struct timeval *tv, struct timezone *tz) { if (tv != NULL) { tv->tv_sec = 946684800; tv->tv_usec = 0; } STACKFRAME(0) STACKFRAME(1) STACKFRAME(2) STACKFRAME(3) STACKFRAME(4) STACKFRAME(5) STACKFRAME(6) STACKFRAME(7) STACKFRAME(8) STACKFRAME(9) STACKFRAME(10) STACKFRAME(11) STACKFRAME(12) STACKFRAME(13) STACKFRAME(14) STACKFRAME(15) printf("16: [more...]\n"); return 0; } Compile this code as a .so, and LD_PRELOAD it before running a program that uses gettimeofday() (e.g. LD_PRELOAD=./test-gettimeofday.so top) Resulting output: 0: 0xbfffeef8 1: 0xbfffef68 2: 0xbfffef88 3: 0xbffff0c8 4: 0xbffff358 5: 0xbffff428 6: 0xbffff4b4 7: 0xbffff615 8: 0x706f74 ^^^^^^^^ 'top^@' in little endian. [program crashes at this point] Resulting (expected) output with libc6-dbg: 0: 0xbfffeef8 1: 0xbfffef68 2: 0xbfffef88 3: 0xbffff0c8 4: 0xbffff358 5: 0xbffff428 6: 0xbffff448 7: (nil) Unfortunately, I haven't found any other ways to reproduce this with a short test program. The libsafe package is affected by this bug, because it relies on a valid stack in order to determine whether or not a variable is stack or heap, and the size of that variable should it reside on the stack. Since libsafe always fails to determine that a variable is on the stack (and presumes it's on the heap, instead), libsafe is rendered completely ineffective, which is why I marked this bug with the 'security' tag. Versions of relevant packages: ii gcc 3.3.2-2 The GNU C compiler ii libsafe 2.0-16-6 Protection against buffer overflow vulnerabi -- System Information: Debian Release: testing/unstable APT prefers unstable APT policy: (500, 'unstable'), (1, 'experimental') Architecture: i386 (i686) Kernel: Linux 2.6.3 Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 Versions of packages libc6 depends on: ii libdb1-compat 2.1.3-7 The Berkeley database routines [gl -- no debconf information -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]