This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: Question on /etc/nsswitch.conf
- From: Yury Norov <ynorov at caviumnetworks dot com>
- To: Florian Weimer <fweimer at redhat dot com>
- Cc: libc-alpha at sourceware dot org, Steve dot Ellcey at cavium dot com, maxim dot kuvyrkov at linaro dot org
- Date: Thu, 28 Sep 2017 14:28:47 +0300
- Subject: Re: Question on /etc/nsswitch.conf
- Authentication-results: sourceware.org; auth=none
- Authentication-results: spf=none (sender IP is ) smtp.mailfrom=Yuri dot Norov at cavium dot com;
- References: <20170927215018.6nagohfthyezs3mo@yury-thinkpad> <de59bd81-d555-b9dc-5089-2926b5a2573a@redhat.com>
- Spamdiagnosticmetadata: NSPM
- Spamdiagnosticoutput: 1:99
On Thu, Sep 28, 2017 at 12:13:43PM +0200, Florian Weimer wrote:
> On 09/27/2017 11:50 PM, Yury Norov wrote:
> > Hi all,
> >
> > Recently Linaro issued the toolchain for arm64/ilp32 [1], and
> > running LTP compiled with it, I found multiple regressions. I
> > tracked them down to function family getpw*(). The problem is
> > that they return NULL, and don't set any errno.
> >
> > #include <sys/types.h>
> > #include <pwd.h>
> > #include <errno.h>
> > #include <stdio.h>
> > #include <stddef.h>
> > #include <unistd.h>
> >
> > int main(void)
> > {
> > struct passwd *pwent;
> > uid_t uid = getuid();
> > printf("uid == %d, errno = %d\n", uid,
> > errno);
> >
> > pwent = getpwuid(uid);
> > printf("pwent == %p, errno == %d\n", pwent, errno);
> >
> > return 0;
> > }
> >
> > Steve Ellcey noticed that it's related to the "passwd: compat"
> > record in /etc/nsswitch.conf. On my testing system (Ubuntu 14.04) I replaced the
> > file with one coming in glibc sources (passwd is "db_files" there), and it fixed
> > the problem.
> >
> > By this email I'd like to report the issue to community and ask some
> > questions:
> > - I think it shuld be a bug if function returns NULL instead the pointer
> > to the structure, and doesn't set errno. The POSIX [2] is not
> > specific here: "If getpwuid() returns a null pointer and errno is
> > set to non-zero, an error occurred". But if getpwuid() returns null,
> > it is an error from user point of view (LTP treats is like this for
> > example). But Glibc doesn't set errno, and POSIX doesn't restrict it
> > explicitly.
>
> POSIX requires that if the user does not exist, NULL is returned. But this
> is not an error, so errno is not set.
>
> Callers need to set errno to zero before calling those NSS functions.
> (Currently, many of them incorrectly set errno to zero on success, which is
> not allowed by POSIX.) If LTP tests do not do this, these LTP tests need to
> be fixed.
>
> Does this address your concerns?
>
> Florian
Yes, it is, thanks. It means that getpwuid(), getpwnam() etc are
broken because with NUll in return value and untouched errno they
report that no user record found in passwd. Whilst the record exists.
Below is the problem function from LTP, for reference. It doesn't
reset errno before calling getpwnam(), but this is different issue.
Yury
struct passwd *safe_getpwnam(const char *file, const int lineno,
void (*cleanup_fn) (void), const char *name)
{
struct passwd *rval;
rval = getpwnam(name);
if (rval == NULL) {
tst_brkm(TBROK | TERRNO, cleanup_fn,
"%s:%d: getpwnam(%s) failed",
file, lineno, name);
}
return rval;
}