[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#466491: Reproducer and more information



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           Version        Description
  +++-==============-==============-============================================
  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.
  0x00007fff031ff5d8 in ?? ()
  (gdb) bt
  #0  0x00007fff031ff5d8 in ?? ()
  #1  0x00007fff031ff69e in gettimeofday ()
  #2  0x00007f3ffab3588a in gettimeofday () from /lib/libc.so.6
  #3  0x00000000004004f2 in main () at test.c:8
  (gdb) disassemble 0x00007fff031ff5d8
  No function contains specified address.
  (gdb) disassemble 0x00007fff031ff69e
  Dump of assembler code for function gettimeofday:
  0x00007fff031ff670 <gettimeofday+0>:	sub    $0x18,%rsp
  0x00007fff031ff674 <gettimeofday+4>:	mov    -0x1ab(%rip),%rax        # 0x7fff031ff4d0
  0x00007fff031ff67b <gettimeofday+11>:	mov    %rbx,0x8(%rsp)
  0x00007fff031ff680 <gettimeofday+16>:	mov    %rbp,0x10(%rsp)
  0x00007fff031ff685 <gettimeofday+21>:	mov    %rdi,%rbx
  0x00007fff031ff688 <gettimeofday+24>:	mov    %rsi,%rbp
  0x00007fff031ff68b <gettimeofday+27>:	mov    0x14(%rax),%edx
  0x00007fff031ff68e <gettimeofday+30>:	test   %edx,%edx
  0x00007fff031ff690 <gettimeofday+32>:	je     0x7fff031ff6e6 <gettimeofday+118>
  0x00007fff031ff692 <gettimeofday+34>:	cmpq   $0x0,0x20(%rax)
  0x00007fff031ff697 <gettimeofday+39>:	je     0x7fff031ff6e6 <gettimeofday+118>
  0x00007fff031ff699 <gettimeofday+41>:	callq  0x7fff031ff5b0
  0x00007fff031ff69e <gettimeofday+46>:	mov    0x8(%rbx),%rcx
  0x00007fff031ff6a2 <gettimeofday+50>:	mov    $0x20c49ba5e353f7cf,%rdx
  0x00007fff031ff6ac <gettimeofday+60>:	mov    %rcx,%rax
  0x00007fff031ff6af <gettimeofday+63>:	sar    $0x3f,%rcx
  0x00007fff031ff6b3 <gettimeofday+67>:	imul   %rdx
  0x00007fff031ff6b6 <gettimeofday+70>:	xor    %eax,%eax
  0x00007fff031ff6b8 <gettimeofday+72>:	sar    $0x7,%rdx
  0x00007fff031ff6bc <gettimeofday+76>:	sub    %rcx,%rdx
  0x00007fff031ff6bf <gettimeofday+79>:	test   %rbp,%rbp
  0x00007fff031ff6c2 <gettimeofday+82>:	mov    %rdx,0x8(%rbx)
  0x00007fff031ff6c6 <gettimeofday+86>:	je     0x7fff031ff6f3 <gettimeofday+131>
  0x00007fff031ff6c8 <gettimeofday+88>:	mov    -0x1ff(%rip),%rax        # 0x7fff031ff4d0
  0x00007fff031ff6cf <gettimeofday+95>:	mov    0x18(%rax),%eax
  0x00007fff031ff6d2 <gettimeofday+98>:	mov    %eax,0x0(%rbp)
  0x00007fff031ff6d5 <gettimeofday+101>:	mov    -0x20c(%rip),%rax        # 0x7fff031ff4d0
  0x00007fff031ff6dc <gettimeofday+108>:	mov    0x1c(%rax),%eax
  0x00007fff031ff6df <gettimeofday+111>:	mov    %eax,0x4(%rbp)
  0x00007fff031ff6e2 <gettimeofday+114>:	xor    %eax,%eax
  0x00007fff031ff6e4 <gettimeofday+116>:	jmp    0x7fff031ff6f3 <gettimeofday+131>
  0x00007fff031ff6e6 <gettimeofday+118>:	mov    $0x60,%eax
  0x00007fff031ff6eb <gettimeofday+123>:	mov    %rbx,%rdi
  0x00007fff031ff6ee <gettimeofday+126>:	mov    %rbp,%rsi
  0x00007fff031ff6f1 <gettimeofday+129>:	syscall 
  0x00007fff031ff6f3 <gettimeofday+131>:	mov    0x8(%rsp),%rbx
  0x00007fff031ff6f8 <gettimeofday+136>:	mov    0x10(%rsp),%rbp
  0x00007fff031ff6fd <gettimeofday+141>:	add    $0x18,%rsp
  0x00007fff031ff701 <gettimeofday+145>:	retq   
  End of assembler dump.


Note this line:

  0x00007fff031ff69e <gettimeofday+46>:	mov    0x8(%rbx),%rcx

Earlier, %rbx gets the value from %rdi, the first argument (NULL in our
program above):

  0x00007fff031ff685 <gettimeofday+21>:	mov    %rdi,%rbx

But 0x8(%rbx) means to deference 8 bytes into the memory address pointed
to by %rbx, which in this case is NULL, hence the segmentation fault.
I'm not familiar enough with the glibc code base yet, so I haven't found
the offending code in glibc itself, but this should be a good start.
Also, this program doesn't segfault on i386.

-- 
+----------------------------------------------------------+
| John Wright <john.wright@hp.com>                         |
| HP Mission Critical OS Enablement & Solution Test (MOST) |
+----------------------------------------------------------+



Reply to: