View Issue Details

IDProjectCategoryView StatusLast Update
0007324CentOS-7glibcpublic2014-07-09 07:16
Reportervignatyuk Assigned To 
PrioritynormalSeveritymajorReproducibilityalways
Status acknowledgedResolutionopen 
Platformx86_64OSCentOSOS Version7
Product Version7.0-1406 
Summary0007324: getpwnam_r
Descriptionint getpwuid_r(uid_t uid, struct passwd *pwd, char *buf, size_t buflen, struct passwd **result)
returns wrong error codes. In case when supplied buffer is too smal it should return not zero value and set errno to ERANGE. In fact it returns zero.

Steps To Reproducethere is a test program in the attachment. It may be compiled using next command:

cc test.c -o test

It maps user "nobody" to the uid. It accepts single parameter which is a buffer size.
By running test with buffer too small we may see that syscall returns zero.

too small buffer (incorrect behavior):
[root@db6 getpwnam]# ./test 8
rc=0, ppw=(nil)

good buffer size:
[root@db6 getpwnam]# ./test 128
rc=0, ppw=0x7fffd13ba360, pw_uid=99, pw_gid=99

Additional InformationTests on other OS/versions do work as expected:

Test on Fedora 20:

[ivrom@devlin tmp]$ ./test 128
rc=0, ppw=0x7fffc4544670, pw_uid=99, pw_gid=99
[ivrom@devlin tmp]$ ./test 8
rc=34, ppw=(nil)


Test on CentOS 6:
-sh-4.1$ ./test 128
rc=0, ppw=0x7fff3b7bf880, pw_uid=99, pw_gid=99
-sh-4.1$ ./test 8
rc=34, ppw=(nil)
TagsNo tags attached.
abrt_hash
URL

Activities

vignatyuk

vignatyuk

2014-07-09 01:26

reporter  

test.c (980 bytes)   
#include <sys/types.h>
#include <pwd.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>


/*
    On success, getpwnam_r() and getpwuid_r() return zero, and set *result to pwd.
    If no matching password record was found, these functions return 0 and store NULL in *result.  In case of error, an error number is returned, and NULL is stored in *result
    
    in case of too small buffer: ERANGE Insufficient buffer space supplied
*/

int main(int argc, char** argv) {
    struct passwd   pw;
    struct passwd* ppw = 0;
    const char* user = "nobody";
    size_t len = argc > 1 ? atoi(argv[1]) : 128;
    char* buffer= (char*) malloc(len);
    
    int rc = getpwnam_r(user, &pw, buffer, len, &ppw);
    
    printf("rc=%d, ppw=%p", rc, ppw);
    if ((rc == 0) && (ppw != NULL)) {
	printf(", pw_uid=%ld, pw_gid=%ld", (long) ppw->pw_uid, (long) ppw->pw_uid);
    }
    printf("\n");
    fflush(stdout);
    
    free(buffer);
    
    return rc;
}
test.c (980 bytes)   
avij

avij

2014-07-09 07:16

updater   ~0020264

Upstream bug: https://bugzilla.redhat.com/show_bug.cgi?id=1099235

Issue History

Date Modified Username Field Change
2014-07-09 01:26 vignatyuk New Issue
2014-07-09 01:26 vignatyuk File Added: test.c
2014-07-09 07:16 avij Note Added: 0020264
2014-07-09 07:16 avij Status new => acknowledged