Bug 12491

Summary: Calling getpwuid in a statically linked program should return an error, not a seg fault.
Product: glibc Reporter: Geir Johansen <geir>
Component: libcAssignee: Ulrich Drepper <drepper.fsp>
Status: RESOLVED WONTFIX    
Severity: normal CC: ovilewade9
Priority: P2 Flags: fweimer: security-
Version: 2.9   
Target Milestone: ---   
Host: Target:
Build: Last reconfirmed:

Description Geir Johansen 2011-02-14 23:32:24 UTC
For a system that is NOT running the nscd daemon, a statically linked program that calls getpwuid will return a segmentation fault.  The resulting core file does not provide much help in debugging the problem.   getpwuid or the routines that it calls should be more robust and not seg fault in this situation, but rather return an error to the user.

I realize that a link time warning message is shown about using getpwuid in a statically linked program, but this warning message can easily be overlooked when building a large application that has other warning messages.

test case:

$ cat getpwuid.c
#include <sys/types.h>
#include <stdio.h>
#include <pwd.h>
int main(){
    int uid;
    struct passwd *pw;

    uid=getuid();
    printf("UID=%d\n", uid);
    pw = getpwuid(uid);
    printf("Done.\n");
    printf("Name=%s\n", pw->pw_name);
    return 0;
}
$  strings /usr/lib64/libc.a | grep -i "release version"
GNU C Library stable release version 2.9 (20081117), by Roland McGrath et al.
$ gcc -g -static -o getpwuid getpwuid.c
/tmp/pbs.581087.sdb/ccyZpaUZ.o: In function `main':
/home/users/geir/getpwuid.c:10: warning: Using 'getpwuid' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
$ ps -ale | grep nscd
$ ./getpwuid
UID=10682
Segmentation fault
$

Here is the unhelpful traceback of the corefile:

(gdb) bt
#0  0x0000000000000000 in ?? ()
#1  0x00002aaaad4fd5dc in __pthread_initialize_minimal_internal ()
   from /lib64/libpthread.so.0
#2  0x00002aaaad4fce49 in _init () from /lib64/libpthread.so.0
#3  0x0000000000000000 in ?? ()
(gdb)
Comment 1 Geir Johansen 2011-03-04 23:55:15 UTC
Here is where the problem looks like it starts to occur:

(gdb) x/30i 0x00000000004284c2
0x4284c2 <get_mapping+674>:    je     0x4284d3 <get_mapping+691>
0x4284c4 <get_mapping+676>:    mov    $0xffffffff,%eax
0x4284c9 <get_mapping+681>:    lock xadd %eax,0x18(%rdi)
0x4284ce <get_mapping+686>:    sub    $0x1,%eax
0x4284d1 <get_mapping+689>:    je     0x428500 <get_mapping+736>
0x4284d3 <get_mapping+691>:    lea    -0x28(%rbp),%rsp
0x4284d7 <get_mapping+695>:    mov    %rbx,%rax
0x4284da <get_mapping+698>:    pop    %rbx
0x4284db <get_mapping+699>:    pop    %r12
0x4284dd <get_mapping+701>:    pop    %r13
0x4284df <get_mapping+703>:    pop    %r14
0x4284e1 <get_mapping+705>:    pop    %r15
0x4284e3 <get_mapping+707>:    leaveq 
0x4284e4 <get_mapping+708>:    retq   
0x4284e5 <get_mapping+709>:    nopl   (%rax)
0x4284e8 <get_mapping+712>:    mov    -0x144(%rbp),%edi
0x4284ee <get_mapping+718>:    mov    $0xffffffffffffffff,%rbx
0x4284f5 <get_mapping+725>:    callq  0x422410 <close>
0x4284fa <get_mapping+730>:    jmp    0x42849b <get_mapping+635>
0x4284fc <get_mapping+732>:    nopl   0x0(%rax)
0x428500 <get_mapping+736>:    callq  0x4281e0 <__nscd_unmap>
0x428505 <get_mapping+741>:    nopl   (%rax)
0x428508 <get_mapping+744>:    jmp    0x4284d3 <get_mapping+691>
0x42850a <get_mapping+746>:    nopw   0x0(%rax,%rax,1)
0x428510 <get_mapping+752>:    mov    -0x38(%rbp),%rsi
0x428514 <get_mapping+756>:    mov    %r12,%rdi
0x428517 <get_mapping+759>:    mov    $0xffffffffffffffff,%rbx
0x42851e <get_mapping+766>:    callq  0x423530 <munmap>
0x428523 <get_mapping+771>:    nopl   0x0(%rax,%rax,1)
0x428528 <get_mapping+776>:    jmpq   0x428485 <get_mapping+613>
(gdb) bt 
#0  0x00000000004284e3 in get_mapping (type=<value optimized out>, 
    key=<value optimized out>, mappedp=0x6a28b8) at nscd_helper.c:419
#1  0x0000000000428697 in __nscd_get_map_ref (type=GETFDPW, 
    name=0x476c3f "passwd", mapptr=0x6a28b0, gc_cyclep=0x7fffffffb4ac)
    at nscd_helper.c:450
#2  0x0000000000425e65 in nscd_getpw_r (key=0x7fffffffb506 "10682", keylen=6, 
    type=GETPWBYUID, resultbuf=0x6a1c00, 
    buffer=0x6e75722f7261762f <Address 0x6e75722f7261762f out of bounds>, 
    buflen=1, result=0x7fffffffb5d0) at nscd_getpw_r.c:97
#3  0x0000000000426236 in __nscd_getpwuid_r (uid=<value optimized out>, 
    resultbuf=0x6a1c00, buffer=0x6a59e0 "", buflen=1024, result=0x7fffffffb5d0)
    at nscd_getpw_r.c:65
#4  0x0000000000421a85 in __getpwuid_r (uid=10682, resbuf=0x6a1c00, 
    buffer=0x6a59e0 "", buflen=1024, result=0x7fffffffb5d0)
    at ../nss/getXXbyYY_r.c:191
#5  0x00000000004217fd in getpwuid (uid=10682) at ../nss/getXXbyYY.c:116
#6  0x0000000000400353 in main () at getpwuid.c:10
(gdb) stepi
Cannot access memory at address 0x8
(gdb) bt
#0  0x00000000004284e4 in get_mapping (type=<value optimized out>, 
Cannot access memory at address 0xfffffffffffffea8
Cannot access memory at address 0x8
    key=<value optimized out>, mappedp=) at nscd_helper.c:419
(gdb)
Comment 2 Ulrich Drepper 2011-04-18 02:26:16 UTC
getpwuid works just fine under the only conditions when it cane work, just as described in the link message.  If you overlook that message it is your problem.
Comment 3 Geir Johansen 2011-09-15 16:14:45 UTC
(In reply to comment #2)
> getpwuid works just fine under the only conditions when it can work, just as
> described in the link message.  If you overlook that message it is your
> problem.

My editorial comment on this resolution:

If the nscd daemon is running on the system, the program will run fine without problems.

If the nscd daemon is not running on the system, the program will get a segmentation fault and the user will not have any idea why the program is failing. In my opinion this behavior is unacceptable. The library should be more robust and at the very least report an error in this case.
Comment 4 ovile009988 2021-09-12 16:46:02 UTC Comment hidden (spam)