git: 25c862ae503a - main - libthr pshared: correct a bug in allocation

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Wed, 01 Feb 2023 23:41:38 UTC
The branch main has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=25c862ae503a1c99458f4e055fd50c878fadbea3

commit 25c862ae503a1c99458f4e055fd50c878fadbea3
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2023-02-01 20:12:45 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2023-02-01 22:59:27 +0000

    libthr pshared: correct a bug in allocation
    
    When __thr_pshared_offpage() is called for allocation, it must not use
    the cached offpage for the key.  Instead, the cached offpage must be
    unmapped and removed from the cache, if any.
    
    It is legitimate for the user code to unmap the shared lock object without
    destroying it, and then mapping something over the freed VA to carry
    another shared lock.  In this case the cached offpage must be un-cached.
    
    PR:     269277
    Reported by:    rau8344@gmail.com
    Reviewed by:    markj
    Sponsored by:   The FreeBSD Foundation
    MFC after:      1 week
    Differential revision:  https://reviews.freebsd.org/D38345
---
 lib/libthr/thread/thr_pshared.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/lib/libthr/thread/thr_pshared.c b/lib/libthr/thread/thr_pshared.c
index 37b44ab73582..446e9983bcae 100644
--- a/lib/libthr/thread/thr_pshared.c
+++ b/lib/libthr/thread/thr_pshared.c
@@ -232,11 +232,16 @@ __thr_pshared_offpage(void *key, int doalloc)
 	int fd, ins_done;
 
 	curthread = _get_curthread();
-	pshared_rlock(curthread);
-	res = pshared_lookup(key);
-	pshared_unlock(curthread);
-	if (res != NULL)
-		return (res);
+	if (doalloc) {
+		pshared_destroy(curthread, key);
+		res = NULL;
+	} else {
+		pshared_rlock(curthread);
+		res = pshared_lookup(key);
+		pshared_unlock(curthread);
+		if (res != NULL)
+			return (res);
+	}
 	fd = _umtx_op(NULL, UMTX_OP_SHM, doalloc ? UMTX_SHM_CREAT :
 	    UMTX_SHM_LOOKUP, key, NULL);
 	if (fd == -1)