|
Bugzilla – Full Text Bug Listing |
| Summary: | glibc: _SC_GETGR_R_SIZE_MAX < maximal needed size for getgrgid_r() | ||
|---|---|---|---|
| Product: | [openSUSE] SUSE LINUX 10.0 | Reporter: | Tobias Burnus <burnus> |
| Component: | Basesystem | Assignee: | Dr. Werner Fink <werner> |
| Status: | RESOLVED INVALID | QA Contact: | E-mail List <qa-bugs> |
| Severity: | Normal | ||
| Priority: | P5 - None | ||
| Version: | Final | ||
| Target Milestone: | --- | ||
| Hardware: | Other | ||
| OS: | Other | ||
| Whiteboard: | |||
| Found By: | Other | Services Priority: | |
| Business Priority: | Blocker: | --- | |
| Marketing QA Status: | --- | IT Deployment: | --- |
| Attachments: | Usage: ./getent_test <groupname>; compile: g++ -o getent_test getent_test.cpp | ||
|
Description
Tobias Burnus
2005-12-01 19:46:46 UTC
Created attachment 59617 [details]
Usage: ./getent_test <groupname>; compile: g++ -o getent_test getent_test.cpp
Attached program calls getgrnam_r()
For small groups, it works ok,
for large groups I get a floating-point exception (independent whether the buffer is big enough or not).
This is with /etc/group as above and "group: compat" in /etc/nsswitch.conf.
Actually, if the buffer is too small I'd expect:
[ERANGE] ("Insufficient storage was supplied via buffer and bufsize to contain the data to be referenced by the resulting group structure.").
Probably I completely fail to understand getgrnam_r(), but for non-existing groups the buffers are all not NULL and the return value is 0 (sucess).
I had expected a return code of not 0 - or at least one of the buffers be NULL.
For getgrnam POSIX is clear: returned buffer = NULL if an error occured or no item has been found.
For getgrnam, it is not that clear, but I would expect the same result. (I think glibc uses ENOENT for getgrnam.)
Ok, for group not found, I found my error: It must be:
if(gbufp == NULL) { printf("gbufp == NULL"); return;}
(w/o the &...)
Remains:
a) sysconf(_SC_GETGR_R_SIZE_MAX)
returns 1024 rather than maxlen(group)
b) getgrnam_r()
- crashes for groups > 1024, independent of the size of the buffer
- expected: work, if buffer is too small, return ERANGE
A last post scriptum: Using
errno = 0;
grp = getgrnam("IDoNotExist");
I get a grp == NULL and a errno of 2 (ENOENT). Actually, I would expect to get an errno of 0 as POSIX states:
"The getgrnam() function shall return a null pointer if either the requested entry was not found, or an error occurred. On error, errno shall be set to indicate the error."
(In reply to comment #0) > Create a group with lots of members, > e.g. > test:x:12345:member1,member2, ...., m1000 > > Call sysconf(_SC_GETGR_R_SIZE_MAX) > > Expected: The size returned by _SC_GETGR_R_SIZE_MAX is large enough to get all > data. > Actual result: 1024 is returned (no, this time no 42) Correct, the old limit is 1024. A lot of protocols have this hardcoded. If you use more for your entries, they are outside of the spec. > According to POSIX "_SC_GETGR_R_SIZE_MAX: Maximum size of getgrgid_r() and > getgrnam_r() data buffers" Yes, but this does not mean you are allowed to use larger group entries. (In reply to comment #3) > A last post scriptum: Using > errno = 0; > grp = getgrnam("IDoNotExist"); > I get a grp == NULL and a errno of 2 (ENOENT). Actually, I would expect to > get an errno of 0 as POSIX states: > > "The getgrnam() function shall return a null pointer if either the requested > entry was not found, or an error occurred. On error, errno shall be set to > indicate the error." sorry, read POSIX again. errno is undefined if no error occours. If you check for errno == 0, your application is broken. > Correct, the old limit is 1024. A lot of protocols have this hardcoded. > If you use more for your entries, they are outside of the spec. Shouldn't then getgrnam_r not return some error rather than just crash? > > errno = 0; > > grp = getgrnam("IDoNotExist"); > > I get a grp == NULL and a errno of 2 (ENOENT). Actually, I would expect > > to get an errno of 0 > sorry, read POSIX again. errno is undefined if no error occours. If you > check for errno == 0, your application is broken. Are you sure? "The getgrnam() function shall return a null pointer if either the requested entry was not found, or an error occurred. On error, errno shall be set to indicate the error." For me this sounds like: - Error errno is set to the error code - Not found: errno is not set & contains the previous value If it would contain a completely random value, how would you distinguish between not found and an error as both time you get a NULL pointer from the structure? Explain the latter and I happily accept if you close this bug as INVALID. (In reply to comment #6) > > Correct, the old limit is 1024. A lot of protocols have this hardcoded. > > If you use more for your entries, they are outside of the spec. > > Shouldn't then getgrnam_r not return some error rather than just crash? If you get a crash, you make something wrong. For me it works fine for entries which are even 8k. > > > > errno = 0; > > > grp = getgrnam("IDoNotExist"); > > > I get a grp == NULL and a errno of 2 (ENOENT). Actually, I would expect > > > to get an errno of 0 > > > sorry, read POSIX again. errno is undefined if no error occours. If you > > check for errno == 0, your application is broken. > > Are you sure? > > "The getgrnam() function shall return a null pointer if either the requested > entry was not found, or an error occurred. On error, errno shall be set to > indicate the error." > > For me this sounds like: > - Error errno is set to the error code > - Not found: errno is not set & contains the previous value > > If it would contain a completely random value, how would you distinguish > between not found and an error as both time you get a NULL pointer from the > structure? ENOENT means no entry found. So what is the problem? If NULL means, entry not found, errno is undefined. If NULL means we have an error and it is set to ENOENT, you know that the entry was not found. |