From owner-dev-commits-src-all@freebsd.org Sat Feb 20 16:35:55 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 A278E54D593; Sat, 20 Feb 2021 16:35:55 +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 4DjYwW2FqDz3sT6; Sat, 20 Feb 2021 16:35:55 +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 0908922171; Sat, 20 Feb 2021 16:35:55 +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 11KGZsgW028831; Sat, 20 Feb 2021 16:35:54 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 11KGZsMN028830; Sat, 20 Feb 2021 16:35:54 GMT (envelope-from git) Date: Sat, 20 Feb 2021 16:35:54 GMT Message-Id: <202102201635.11KGZsMN028830@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Mark Johnston Subject: git: a8499077ab1b - stable/12 - 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/stable/12 X-Git-Reftype: branch X-Git-Commit: a8499077ab1b23c432c251874cf931e1025d8636 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: Sat, 20 Feb 2021 16:35:55 -0000 The branch stable/12 has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=a8499077ab1b23c432c251874cf931e1025d8636 commit a8499077ab1b23c432c251874cf931e1025d8636 Author: Mark Johnston AuthorDate: 2021-01-21 19:30:19 +0000 Commit: Mark Johnston CommitDate: 2021-02-20 16:35:32 +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 (cherry picked from commit 5619d49e07d3942e438f3d06269f3c1c466cf5b7) --- 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;