View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0007324 | CentOS-7 | glibc | public | 2014-07-09 01:26 | 2014-07-09 07:16 |
Reporter | vignatyuk | Assigned To | |||
Priority | normal | Severity | major | Reproducibility | always |
Status | acknowledged | Resolution | open | ||
Platform | x86_64 | OS | CentOS | OS Version | 7 |
Product Version | 7.0-1406 | ||||
Summary | 0007324: getpwnam_r | ||||
Description | int 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 Reproduce | there 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 Information | Tests 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) | ||||
Tags | No tags attached. | ||||
abrt_hash | |||||
URL | |||||
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; } |
|
Upstream bug: https://bugzilla.redhat.com/show_bug.cgi?id=1099235 | |