unarchive 466491
reopen 466491
retitle 466491 libc6: gettimeofday() on amd64 causes segmentation fault if
first argument is NULL
thanks
With the following program on a lenny amd64 machine, I can trigger this
bug:
$ cat test.c
#include stdio.h
#include sys/time.h
int main(void)
{
struct timezone tz;
gettimeofday(NULL, tz);
return 0;
}
The gettimeofday(2) manual says that if either parameter is NULL, that
structure is not set. It doesn't say that the first parameter
(struct timeval *tv) is required.
Package information:
$ uname -a
Linux ned3g6 2.6.26-2-amd64 #1 SMP Fri Mar 27 04:02:59 UTC 2009 x86_64
GNU/Linux
$ dpkg -l libc6 linux-image-$(uname -r)
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Cfg-files/Unpacked/Failed-cfg/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Hold/Reinst-required/X=both-problems (Status,Err:
uppercase=bad)
||/ Name VersionDescription
+++-==-==-
ii libc6 2.7-18 GNU C Library: Shared libraries
ii linux-image-2. 2.6.26-15 Linux 2.6.26 image on AMD64
Here's what I can glean from gdb:
$ gcc -g -o test test.c
$ gdb ./test
GNU gdb 6.8-debian
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later http://gnu.org/licenses/gpl.html
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type show copying
and show warranty for details.
This GDB was configured as x86_64-linux-gnu...
(gdb) run
Starting program: /home/jswright/test
Program received signal SIGSEGV, Segmentation fault.
0x7fff031ff5d8 in ?? ()
(gdb) bt
#0 0x7fff031ff5d8 in ?? ()
#1 0x7fff031ff69e in gettimeofday ()
#2 0x7f3ffab3588a in gettimeofday () from /lib/libc.so.6
#3 0x004004f2 in main () at test.c:8
(gdb) disassemble 0x7fff031ff5d8
No function contains specified address.
(gdb) disassemble 0x7fff031ff69e
Dump of assembler code for function gettimeofday:
0x7fff031ff670 gettimeofday+0: sub$0x18,%rsp
0x7fff031ff674 gettimeofday+4: mov-0x1ab(%rip),%rax#
0x7fff031ff4d0
0x7fff031ff67b gettimeofday+11: mov%rbx,0x8(%rsp)
0x7fff031ff680 gettimeofday+16: mov%rbp,0x10(%rsp)
0x7fff031ff685 gettimeofday+21: mov%rdi,%rbx
0x7fff031ff688 gettimeofday+24: mov%rsi,%rbp
0x7fff031ff68b gettimeofday+27: mov0x14(%rax),%edx
0x7fff031ff68e gettimeofday+30: test %edx,%edx
0x7fff031ff690 gettimeofday+32: je 0x7fff031ff6e6 gettimeofday+118
0x7fff031ff692 gettimeofday+34: cmpq $0x0,0x20(%rax)
0x7fff031ff697 gettimeofday+39: je 0x7fff031ff6e6 gettimeofday+118
0x7fff031ff699 gettimeofday+41: callq 0x7fff031ff5b0
0x7fff031ff69e gettimeofday+46: mov0x8(%rbx),%rcx
0x7fff031ff6a2 gettimeofday+50: mov$0x20c49ba5e353f7cf,%rdx
0x7fff031ff6ac gettimeofday+60: mov%rcx,%rax
0x7fff031ff6af gettimeofday+63: sar$0x3f,%rcx
0x7fff031ff6b3 gettimeofday+67: imul %rdx
0x7fff031ff6b6 gettimeofday+70: xor%eax,%eax
0x7fff031ff6b8 gettimeofday+72: sar$0x7,%rdx
0x7fff031ff6bc gettimeofday+76: sub%rcx,%rdx
0x7fff031ff6bf gettimeofday+79: test %rbp,%rbp
0x7fff031ff6c2 gettimeofday+82: mov%rdx,0x8(%rbx)
0x7fff031ff6c6 gettimeofday+86: je 0x7fff031ff6f3 gettimeofday+131
0x7fff031ff6c8 gettimeofday+88: mov-0x1ff(%rip),%rax#
0x7fff031ff4d0
0x7fff031ff6cf gettimeofday+95: mov0x18(%rax),%eax
0x7fff031ff6d2 gettimeofday+98: mov%eax,0x0(%rbp)
0x7fff031ff6d5 gettimeofday+101:mov-0x20c(%rip),%rax
# 0x7fff031ff4d0
0x7fff031ff6dc gettimeofday+108:mov0x1c(%rax),%eax
0x7fff031ff6df gettimeofday+111:mov%eax,0x4(%rbp)
0x7fff031ff6e2 gettimeofday+114:xor%eax,%eax
0x7fff031ff6e4 gettimeofday+116:jmp0x7fff031ff6f3
gettimeofday+131
0x7fff031ff6e6 gettimeofday+118:mov$0x60,%eax
0x7fff031ff6eb gettimeofday+123:mov%rbx,%rdi
0x7fff031ff6ee gettimeofday+126:mov%rbp,%rsi
0x7fff031ff6f1 gettimeofday+129:syscall
0x7fff031ff6f3 gettimeofday+131:mov0x8(%rsp),%rbx
0x7fff031ff6f8 gettimeofday+136:mov0x10(%rsp),%rbp
0x7fff031ff6fd gettimeofday+141:add$0x18,%rsp
0x7fff031ff701 gettimeofday+145:retq
End of assembler dump.
Note this line:
0x7fff031ff69e gettimeofday+46: mov0x8(%rbx),%rcx
Earlier, %rbx gets the value from %rdi, the first argument (NULL in our
program above):
0x7fff031ff685 gettimeofday+21: mov%rdi,%rbx
But 0x8(%rbx) means to deference 8 bytes into the memory address pointed
to by %rbx, which in