Bug 137199

Summary: getXXXent_r functions don't set errno=ENOENT at end of data
Product: [Fedora] Fedora Reporter: Mike Bird <mgb>
Component: glibcAssignee: Jakub Jelinek <jakub>
Status: CLOSED NOTABUG QA Contact: Brian Brock <bbrock>
Severity: medium Docs Contact:
Priority: medium    
Version: 3   
Target Milestone: ---   
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2004-10-26 20:22:39 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Attachments:
Description Flags
Sample getgrent_r tester which demonstrates glibc bug. none

Description Mike Bird 2004-10-26 17:06:26 UTC
Description of problem:

The getXXXent_r functions return ENOENT at end of data but they leave
errno unchanged.  This is a particular problem if an earlier
getXXXent_r had set errno to ERANGE.  Code sees status!=0 and
errno=ERANGE and tries again with a larger buffer until memory is
exhausted.  Perl's getXXXent functions are affected by this, which
explains why they blow up on large systems but not test systems. 
WebMin is a popular system administration tool which blows up as a
result of this.

Google reveals a number of reports for which this bug is the
explanation.  The relevant maintainers seem to have rejected the bug
reports as unreproducible because they didn't have long enough lines
in their /etc/group.

Version-Release number of selected component (if applicable):

Reproduced in glibc-2.3.2-27.9.7, glibc-2.3.3-27, and glibc-2.3.3-53.

How reproducible:

Always.

Steps to Reproduce:
1. Run attached program.
2.
3.
  
Actual results:

At end of /etc/group it keeps retrying with ever larger buffer sizes.

Expected results:

Should have set errno=ENOENT when it returned ENOENT, i.e. as soon as
it had a large enough buffer.

Additional info:

Comment 1 Mike Bird 2004-10-26 17:08:17 UTC
Created attachment 105803 [details]
Sample getgrent_r tester which demonstrates glibc bug.

Comment 2 Jakub Jelinek 2004-10-26 20:22:39 UTC
That is not a glibc bug.  errno is not defined after getgrent_r
call.
man getgrent_r has:
RETURN VALUE
       On  success,  these  functions  return 0 and *gbufp is a pointer to the
       struct group.  On error, these functions  return  an  error  value  and
       *gbufp is NULL.
No words about errno being set.
POSIX doesn't cover getgrent_r, but getgrnam_r is similar enough and
covered by POSIX:
     ^[TSF] [Option Start] If successful, the getgrnam_r() function shall return zero; otherwise, an error number shall be
     returned to indicate the error. [Option End]

So, your testcase should be checking } else if (rc == ENOENT) { ... } else if (rc != ERANGE) { ... } else { ... }

Comment 3 Mike Bird 2004-10-26 20:34:21 UTC
Does this mean that it is a bug that getgrent_r clobbers errno without
warning in the ERANGE case?

Comment 4 Jakub Jelinek 2004-10-26 20:46:48 UTC
errno is undefined after getgrent_r call.
See
http://www.opengroup.org/onlinepubs/009695399/functions/errno.html
The value of errno should only be examined when it is
indicated to be valid by a function's return value.
...
The setting of errno after a successful call to a function is unspecified unless the description of that function specifies that errno shall not be
modified.
http://www.opengroup.org/onlinepubs/009695399/functions/getgrnam.html
doesn't indicate errno is not modified, nor claims errno is always set,
nor does have any return value that indicates errno is valid.
Therefore after you call getgrnam_r errno should not be examined.

getgrent_r is not covered by POSIX, but behaves in this regard like
getgrnam_r (and man getgrent_r describes this).

Comment 5 Mike Bird 2004-10-26 21:02:06 UTC
PERL bug report updated with your information:

  https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=137202