From owner-dev-commits-src-all@freebsd.org Thu Jan 21 19:30:47 2021 Return-Path: Delivered-To: dev-commits-src-all@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id F36D04DDA2D; Thu, 21 Jan 2021 19:30:46 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4DMCD62Hy5z4nf8; Thu, 21 Jan 2021 19:30:46 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 39BB311A98; Thu, 21 Jan 2021 19:30:46 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 10LJUkSY068878; Thu, 21 Jan 2021 19:30:46 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 10LJUkL2068877; Thu, 21 Jan 2021 19:30:46 GMT (envelope-from git) Date: Thu, 21 Jan 2021 19:30:46 GMT Message-Id: <202101211930.10LJUkL2068877@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Mark Johnston Subject: git: 5619d49e07d3 - main - libc/nss: Restore iterator state when doing passwd/group lookups MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: markj X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 5619d49e07d3942e438f3d06269f3c1c466cf5b7 Auto-Submitted: auto-generated X-BeenThere: dev-commits-src-all@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Commit messages for all branches of the src repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 21 Jan 2021 19:30:47 -0000 The branch main has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=5619d49e07d3942e438f3d06269f3c1c466cf5b7 commit 5619d49e07d3942e438f3d06269f3c1c466cf5b7 Author: Mark Johnston AuthorDate: 2021-01-21 19:30:19 +0000 Commit: Mark Johnston CommitDate: 2021-01-21 19:30:19 +0000 libc/nss: Restore iterator state when doing passwd/group lookups The getpwent(3) and getgrent(3) implementations maintain some internal iterator state. Interleaved calls to functions which do passwd/group lookups using a key, such as getpwnam(3), would in some cases clobber this state, causing a subsequent getpwent() or getgrent() call to restart iteration from the beginning of the database or to terminate early. This is particularly troublesome in programming environments where execution of green threads is interleaved within a single OS thread. Take care to restore any iterator state following a keyed lookup. The "files" provider for the passwd database was already handling this correctly, but "compat" was not, and both providers had this problem when accessing the group database. PR: 252094 Submitted by: Viktor Dukhovni MFC after: 1 month --- lib/libc/gen/getgrent.c | 34 +++++++++++++++------------------- lib/libc/gen/getpwent.c | 18 +++++++++++------- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/lib/libc/gen/getgrent.c b/lib/libc/gen/getgrent.c index b3699cae3c45..6abccea30c6b 100644 --- a/lib/libc/gen/getgrent.c +++ b/lib/libc/gen/getgrent.c @@ -882,16 +882,12 @@ files_group(void *retval, void *mdata, va_list ap) } fresh = 1; } - if (how == nss_lt_all) - stayopen = 1; - else { - if (!fresh) - rewind(st->fp); - stayopen = st->stayopen; - } - rv = NS_NOTFOUND; + stayopen = (how == nss_lt_all || !fresh) ? 1 : st->stayopen; if (stayopen) pos = ftello(st->fp); + if (how != nss_lt_all && !fresh) + rewind(st->fp); + rv = NS_NOTFOUND; while ((line = fgetln(st->fp, &linesize)) != NULL) { if (line[linesize-1] == '\n') linesize--; @@ -913,13 +909,15 @@ files_group(void *retval, void *mdata, va_list ap) &buffer[linesize + 1], bufsize - linesize - 1, errnop); if (rv & NS_TERMINATE) break; - if (stayopen) + if (how == nss_lt_all) pos = ftello(st->fp); } if (st->fp != NULL && !stayopen) { fclose(st->fp); st->fp = NULL; } + if (st->fp != NULL && how != nss_lt_all) + fseeko(st->fp, pos, SEEK_SET); if (rv == NS_SUCCESS && retval != NULL) *(struct group **)retval = grp; else if (rv == NS_RETURN && *errnop == ERANGE && st->fp != NULL) @@ -1364,13 +1362,11 @@ compat_group(void *retval, void *mdata, va_list ap) } fresh = 1; } - if (how == nss_lt_all) - stayopen = 1; - else { - if (!fresh) - rewind(st->fp); - stayopen = st->stayopen; - } + stayopen = (how == nss_lt_all || !fresh) ? 1 : st->stayopen; + if (stayopen) + pos = ftello(st->fp); + if (how != nss_lt_all && !fresh) + rewind(st->fp); docompat: switch (st->compat) { case COMPAT_MODE_ALL: @@ -1431,8 +1427,6 @@ docompat: break; } rv = NS_NOTFOUND; - if (stayopen) - pos = ftello(st->fp); while ((line = fgetln(st->fp, &linesize)) != NULL) { if (line[linesize-1] == '\n') linesize--; @@ -1473,7 +1467,7 @@ docompat: &buffer[linesize + 1], bufsize - linesize - 1, errnop); if (rv & NS_TERMINATE) break; - if (stayopen) + if (how == nss_lt_all) pos = ftello(st->fp); } fin: @@ -1481,6 +1475,8 @@ fin: fclose(st->fp); st->fp = NULL; } + if (st->fp != NULL && how != nss_lt_all) + fseeko(st->fp, pos, SEEK_SET); if (rv == NS_SUCCESS && retval != NULL) *(struct group **)retval = grp; else if (rv == NS_RETURN && *errnop == ERANGE && st->fp != NULL) diff --git a/lib/libc/gen/getpwent.c b/lib/libc/gen/getpwent.c index 09f84f9576ee..a07ee109e2df 100644 --- a/lib/libc/gen/getpwent.c +++ b/lib/libc/gen/getpwent.c @@ -1733,6 +1733,7 @@ compat_passwd(void *retval, void *mdata, va_list ap) { char keybuf[MAXLOGNAME + 1]; DBT key, entry; + pwkeynum keynum; struct compat_state *st; enum nss_lookup_type how; const char *name; @@ -1783,9 +1784,10 @@ compat_passwd(void *retval, void *mdata, va_list ap) rv = NS_NOTFOUND; goto fin; } + keynum = st->keynum; stayopen = 1; } else { - st->keynum = 0; + keynum = 0; stayopen = st->stayopen; } docompat: @@ -1829,13 +1831,13 @@ docompat: } key.data = keybuf; rv = NS_NOTFOUND; - while (st->keynum >= 0) { - st->keynum++; + while (keynum >= 0) { + keynum++; if (st->version < _PWD_CURRENT_VERSION) { - memcpy(&keybuf[1], &st->keynum, sizeof(st->keynum)); - key.size = sizeof(st->keynum) + 1; + memcpy(&keybuf[1], &keynum, sizeof(keynum)); + key.size = sizeof(keynum) + 1; } else { - store = htonl(st->keynum); + store = htonl(keynum); memcpy(&keybuf[1], &store, sizeof(store)); key.size = sizeof(store) + 1; } @@ -1846,7 +1848,7 @@ docompat: rv = NS_UNAVAIL; goto fin; } else if (rv == 1) { - st->keynum = -1; + keynum = -1; rv = NS_NOTFOUND; goto fin; } @@ -1931,6 +1933,8 @@ docompat: break; } fin: + if (how == nss_lt_all) + st->keynum = keynum; if (st->db != NULL && !stayopen) { (void)st->db->close(st->db); st->db = NULL;