public inbox for glibc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug nscd/15139] New: getpwuid_r does not return ERANGE consistently
@ 2013-02-13 11:13 tsegismo at redhat dot com
  2013-02-13 16:27 ` [Bug nscd/15139] " carlos at redhat dot com
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: tsegismo at redhat dot com @ 2013-02-13 11:13 UTC (permalink / raw)
  To: glibc-bugs

http://sourceware.org/bugzilla/show_bug.cgi?id=15139

             Bug #: 15139
           Summary: getpwuid_r does not return ERANGE consistently
           Product: glibc
           Version: 2.12
            Status: NEW
          Severity: normal
          Priority: P2
         Component: nscd
        AssignedTo: unassigned@sourceware.org
        ReportedBy: tsegismo@redhat.com
                CC: drepper.fsp@gmail.com
    Classification: Unclassified


Hi,

I have a problem when calling getpwuid_r on a RHEL6 64 bit machine and as it
seems, it does not return ERANGE consistently.

Here are the details.

In my Java project we use a library called Sigar to do things we can't do with
pure Java code. In particular, we use Sigar to determine user name from user
id.

On a 64 bit RHEL6 machine, Sigar fails to find a particular user (hudson,
uid=600, LDAP database). The code involved uses getpwuid_r which returns
ERANGE.

I tried two things:
* I downloaded the library sources [1], changed the value of R_SIZE_MAX to 2048
and rebuilt it; then it worked
* I extracted the original code as a simple program [2] and kept original
R_SIZE_MAX value (1024); it was also able to find the user name (prints
'hudson') 

How come the same piece of code works alone and not through the Sigar library?
May the code in getXXbyYY_r.c behave differently in different contexts?
getpwuid_r does not return ERANGE consistently?

Thanks for your help.

[1] http://tinyurl.com/d2hkgtq (see sigar_user_name_get function)
[2] http://pastebin.com/1bXycrnW

-- 
Configure bugmail: http://sourceware.org/bugzilla/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Bug nscd/15139] getpwuid_r does not return ERANGE consistently
  2013-02-13 11:13 [Bug nscd/15139] New: getpwuid_r does not return ERANGE consistently tsegismo at redhat dot com
@ 2013-02-13 16:27 ` carlos at redhat dot com
  2013-02-13 16:43 ` tsegismo at redhat dot com
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: carlos at redhat dot com @ 2013-02-13 16:27 UTC (permalink / raw)
  To: glibc-bugs

http://sourceware.org/bugzilla/show_bug.cgi?id=15139

Carlos O'Donell <carlos at redhat dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |WAITING
                 CC|                            |carlos at redhat dot com

--- Comment #1 from Carlos O'Donell <carlos at redhat dot com> 2013-02-13 16:26:58 UTC ---
Thomas,

The function is allowed to return ERANGE at *any* time and the user application
must grow the buffer. The fault is with Sigar here.

However, there is an orthogonal issue in that sysconf (_SC_GETPW_R_SIZE_MAX)
returns a static 1024 on Linux and that is technically too small for some
results. It is my opinion that it should return -1, indicating that there is no
limit and that it is up to the user to choose a reasonably large value and to
watch out for ERANGE.

If anything the bug is that sysconf (_SC_GETPW_R_SIZE_MAX) returns a limit,
that when used, is actually too small.

The correct solution on the glibc side is likely going to be to return -1 for
sysconf (_SC_GETPW_R_SIZE_MAX), and the fix on the Sigar side is going to be to
be to do something like this (completely off the top of my head with no
testing):

/* sysconf(_SC_GET{PW,GR}_R_SIZE_MAX) == -1, choose a reasonable buffer size. 
*/
#define R_SIZE_MAX 8192   /* Multiple of 2*R_SIZE_INIT */
#define R_SIZE_INIT 1024

...
# ifdef HAVE_GETPWUID_R
    struct passwd pwbuf;
    int saved_errno;
    char *buffer;
    /* Allocate an initial buffer.  */
    size_t buflen = R_SIZE_INIT;
    buffer = (char *) malloc (buflen);
    if (buffer == NULL)
      return errno;
    do {
      if (getpwuid_r(uid, &pwbuf, buffer, sizeof(buffer), &pw) != 0) {
        saved_errno = errno;
        /* We handle ERANGE, but anything else return as an error.  */
        if (errno != ERANGE)
          return errno;
        /* Double the buffer size and try again.  */
        buflen = buflen * 2;
        if (buflen > R_SIZE_MAX)
          /* We hit our own internal limit. Return artificial ENOMEM.  */
          return ENOMEM; 
        buffer = (char *) realloc (buffer, buflen);
        if (buffer == NULL)
          return errno;
      }
      if (!pw) {
          return ENOENT;
      }
    } while (saved_errno == ERANGE)
# else
...

Does that make sense?

-- 
Configure bugmail: http://sourceware.org/bugzilla/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Bug nscd/15139] getpwuid_r does not return ERANGE consistently
  2013-02-13 11:13 [Bug nscd/15139] New: getpwuid_r does not return ERANGE consistently tsegismo at redhat dot com
  2013-02-13 16:27 ` [Bug nscd/15139] " carlos at redhat dot com
@ 2013-02-13 16:43 ` tsegismo at redhat dot com
  2013-02-13 18:58 ` carlos at redhat dot com
  2014-06-13 18:50 ` fweimer at redhat dot com
  3 siblings, 0 replies; 5+ messages in thread
From: tsegismo at redhat dot com @ 2013-02-13 16:43 UTC (permalink / raw)
  To: glibc-bugs

http://sourceware.org/bugzilla/show_bug.cgi?id=15139

--- Comment #2 from Thomas Segismont <tsegismo at redhat dot com> 2013-02-13 16:42:34 UTC ---
Thanks Carlos for analysis. I will talk with Sigar team to take your advice
into account.

Still, I don't understand why the extracted test case with 1024 sized buffer
works whereas the same code in Sigar doesn't. Or is it why you say "the
function is allowed to return ERANGE at *any* time"?

Cheers

-- 
Configure bugmail: http://sourceware.org/bugzilla/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Bug nscd/15139] getpwuid_r does not return ERANGE consistently
  2013-02-13 11:13 [Bug nscd/15139] New: getpwuid_r does not return ERANGE consistently tsegismo at redhat dot com
  2013-02-13 16:27 ` [Bug nscd/15139] " carlos at redhat dot com
  2013-02-13 16:43 ` tsegismo at redhat dot com
@ 2013-02-13 18:58 ` carlos at redhat dot com
  2014-06-13 18:50 ` fweimer at redhat dot com
  3 siblings, 0 replies; 5+ messages in thread
From: carlos at redhat dot com @ 2013-02-13 18:58 UTC (permalink / raw)
  To: glibc-bugs

http://sourceware.org/bugzilla/show_bug.cgi?id=15139

Carlos O'Donell <carlos at redhat dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|WAITING                     |RESOLVED
         Resolution|                            |INVALID

--- Comment #3 from Carlos O'Donell <carlos at redhat dot com> 2013-02-13 18:58:32 UTC ---
(In reply to comment #2)
> Thanks Carlos for analysis. I will talk with Sigar team to take your advice
> into account.
> 
> Still, I don't understand why the extracted test case with 1024 sized buffer
> works whereas the same code in Sigar doesn't. Or is it why you say "the
> function is allowed to return ERANGE at *any* time"?

You are assuming that the implementation requires a deterministic amount of
buffer in all conditions and that is unfortunately not true. I can't currently
guarantee that, all I can guarantee is that if the implementation requires more
buffer it will return ERANGE and you have to start the query all over again.

As it turns out POSIX.1-2008 says:
"A call to sysconf(_SC_GETPW_R_SIZE_MAX) returns either -1 without changing
errno or an initial value suggested for the size of this buffer."

Therefore, despite the name "SIZE_MAX" it is actually a suggested initial value
for the buffer e.g. a minimum, and not a maximum.

I'm closing this as RESOLVED/INVALID since the standard says it's an initial
suggested value, and as Roland points out "The purpose of _SC_GETPW_R_SIZE_MAX
is to suggest a buffer size that is likely to be sufficient for a single cycle
of allocation and call to satisfy the request, as an optimization for the
common case."

Thus the fix is entirely in Sigar to increase the buffer when ERANGE is
returned. Taking care not to introduce a DoS by increasing the buffer without
bounds.

-- 
Configure bugmail: http://sourceware.org/bugzilla/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Bug nscd/15139] getpwuid_r does not return ERANGE consistently
  2013-02-13 11:13 [Bug nscd/15139] New: getpwuid_r does not return ERANGE consistently tsegismo at redhat dot com
                   ` (2 preceding siblings ...)
  2013-02-13 18:58 ` carlos at redhat dot com
@ 2014-06-13 18:50 ` fweimer at redhat dot com
  3 siblings, 0 replies; 5+ messages in thread
From: fweimer at redhat dot com @ 2014-06-13 18:50 UTC (permalink / raw)
  To: glibc-bugs

https://sourceware.org/bugzilla/show_bug.cgi?id=15139

Florian Weimer <fweimer at redhat dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
              Flags|                            |security-

-- 
You are receiving this mail because:
You are on the CC list for the bug.


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2014-06-13 18:50 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-02-13 11:13 [Bug nscd/15139] New: getpwuid_r does not return ERANGE consistently tsegismo at redhat dot com
2013-02-13 16:27 ` [Bug nscd/15139] " carlos at redhat dot com
2013-02-13 16:43 ` tsegismo at redhat dot com
2013-02-13 18:58 ` carlos at redhat dot com
2014-06-13 18:50 ` fweimer at redhat dot com

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).