An application encounters segmentation fault in glibc's times(2) function

Solution In Progress - Updated -

Environment

  • Red Hat Enterprise Linux 6.3
  • kernel-2.6.32-279.14.1.el6
  • glibc-2.12-1.80.el6_3.6

Issue

  • An application encounters segmentation fault in glibc's times(2) function:
Core was generated by `<an application>'.
Program terminated with signal 11, Segmentation fault.
#0  __times (buf=0x0) at ../sysdeps/unix/sysv/linux/times.c:43
43            touch (buf->tms_utime);
Missing separate debuginfos, use: debuginfo-install clusterpro-3.1.7-1.i686
(gdb) bt
#0  __times (buf=0x0) at ../sysdeps/unix/sysv/linux/times.c:43
#1  0x00e73da9 in xmllib_times (buf=0x0) at src/xml.c:785
#2  0x080518b5 in rm_wait_monitor (pmon=0x8f4a2b8, nintv=10) at src/rm.c:1477
#3  0x08051e25 in rm_monitor (pmon=0x8f4a2b8) at src/rm.c:1596
#4  0x00bd9a49 in start_thread (arg=0xb5fa6b70) at pthread_create.c:301
#5  0x00b1663e in clone () at ../sysdeps/unix/sysv/linux/i386/clone.S:133
(gdb)

Resolution

Update glibc-2.12-1.166.el6 or later.
RHBA-2015:1286-3

Root Cause

  • glibc __times() function doesn't handle properly a situation when the application passes NULL pointer as an argument and the kernel returns EFAULT

Diagnostic Steps

$ gdb /usr/sbin/clprm core.3916
...
Core was generated by `clprm'.
Program terminated with signal 11, Segmentation fault.
#0  __times (buf=0x0) at ../sysdeps/unix/sysv/linux/times.c:43
43            touch (buf->tms_utime);
(gdb) bt
#0  __times (buf=0x0) at ../sysdeps/unix/sysv/linux/times.c:43
#1  0x00e73da9 in xmllib_times (buf=0x0) at src/xml.c:785
#2  0x080518b5 in rm_wait_monitor (pmon=0x8f4a2b8, nintv=10) at src/rm.c:1477
#3  0x08051e25 in rm_monitor (pmon=0x8f4a2b8) at src/rm.c:1596
#4  0x00bd9a49 in start_thread (arg=0xb5fa6b70) at pthread_create.c:301
#5  0x00b1663e in clone () at ../sysdeps/unix/sysv/linux/i386/clone.S:133
(gdb) p $eip
$1 = (void (*)()) 0xad4df2 <__times+50>
(gdb) disassemble 
Dump of assembler code for function __times:
...
=> 0x00ad4df2 <+50>:    mov    (%edx),%ecx
...
(gdb) p $edx
$2 = 0
(gdb) list __times
21      #include <sysdep.h>
22
23
24      clock_t
25      __times (struct tms *buf)
26      {
27        INTERNAL_SYSCALL_DECL (err);
28        clock_t ret = INTERNAL_SYSCALL (times, err, 1, buf);
29        if (INTERNAL_SYSCALL_ERROR_P (ret, err)
30            && __builtin_expect (INTERNAL_SYSCALL_ERRNO (ret, err) == EFAULT, 0))
31          {
(gdb) p ret
$3 = -14
(gdb)

from above we can see the argument passed is 0x0 (NULL) and the value returned from times syscall is EFAULT (14):

/usr/include/asm-generic/errno-base.h:
#define EFAULT          14      /* Bad address */

This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.