[Bug 252094] nss "compat": getpw(nam|uid)_r(3) inadvertently reset next entry key for getpwent_r(3)

bugzilla-noreply at freebsd.org bugzilla-noreply at freebsd.org
Thu Dec 24 01:25:37 UTC 2020


https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=252094

            Bug ID: 252094
           Summary: nss "compat": getpw(nam|uid)_r(3) inadvertently reset
                    next entry key for getpwent_r(3)
           Product: Base System
           Version: Unspecified
          Hardware: Any
                OS: Any
            Status: New
          Severity: Affects Many People
          Priority: ---
         Component: bin
          Assignee: bugs at FreeBSD.org
          Reporter: ietf-dane at dukhovni.org

Created attachment 220877
  --> https://bugs.freebsd.org/bugzilla/attachment.cgi?id=220877&action=edit
Proposed patch

When testing the Haskell "unix" library, an unexpected interaction was
encountered between interleaved calls to getpwent_r(3) and either of
getpwnam_r(3) and getpwuid_r(3), which manifests only in the default
configuration with nsswitch.conf having "passwd: compat".  Changing to "passwd:
files" resolves the issue.

The reason is that the "compat" code incorrectly mutates the "global" (really
thread-local) st->keynum not only when doing a getpwent() walk, but also when
calling getpwnam() or getpwuid(), which should not mutate the keynum (and don't
in files_passwd, but inadvertently do in compat_passwd).

A similar issue is present with getgr(nam|gid)_r(3) vs. getgrent_r(3), but
there the problem is more entrenched, because the walk position for getgrent()
is just an implicit file offset into the open group file.  Fixing this might
require adding appropriate fseeko()/ftello() calls so that getgrent_r(3) can
resume at the expected offset even after an intervening call to getgrnam_r(3),
...  Alternatively, it might simply make sense to not bother using the already
open file with getgr(nam|uid)_r(3), file systems are sufficiently fast these
days, and the relevant metadata will be in the cache...

I'm willing to contribute a separate fix for the group case, but first would
like to get feedback on the passwd case, and preferred solution for the group
case.

Link to the Haskell issue: <https://github.com/haskell/unix/pull/169>.  This
can affect any language or system that interleaves multiple user-level "green"
threads within a single OS thread.  Or just for some chooses to interleave
getpwnam() calls in the middle of walking the list with getpwent() (somewhat
less like, but not manifestly invalid).

-- 
You are receiving this mail because:
You are the assignee for the bug.


More information about the freebsd-bugs mailing list