]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libuuid: clear uuidd cache on fork()
authorThomas Weißschuh <thomas@t-8ch.de>
Tue, 7 May 2024 11:44:31 +0000 (13:44 +0200)
committerThomas Weißschuh <thomas@t-8ch.de>
Tue, 14 May 2024 10:13:58 +0000 (12:13 +0200)
After fork() the memory of the calling thread is preserved into the new
process. This also includes TLS.
Make sure to reset the cache after a fork to avoid reuse of cached
values.

Only the TLS of the thread calling fork() is relevant as that is the
only thread that gets forked.
New threads will received newly initialized TLS.

Fixes https://github.com/util-linux/util-linux/issues/3009
Signed-off-by: Thomas Weißschuh <thomas@t-8ch.de>
libuuid/src/Makemodule.am
libuuid/src/gen_uuid.c

index e58fa261cf77bfb86159af27119577c8291d389e..417fd2bd55e8ae393dd35b4044175f0849a9ee93 100644 (file)
@@ -31,7 +31,7 @@ libuuid_la_SOURCES = \
 EXTRA_libuuid_la_DEPENDENCIES = \
        libuuid/src/libuuid.sym
 
-libuuid_la_LIBADD       = $(LDADD) $(SOCKET_LIBS)
+libuuid_la_LIBADD       = $(LDADD) $(SOCKET_LIBS) -lpthread
 
 libuuid_la_CFLAGS = \
        $(AM_CFLAGS) \
index e82e005befe3732e47bfe4752ab7098a75b9d222..9c690d5226d3fc0b62d2e19ceac17518ad1cfdec 100644 (file)
@@ -80,6 +80,8 @@
 #if defined(__linux__) && defined(HAVE_SYS_SYSCALL_H)
 #include <sys/syscall.h>
 #endif
+#include <pthread.h>
+#include <signal.h>
 
 #include "all-io.h"
 #include "uuidP.h"
@@ -592,9 +594,21 @@ THREAD_LOCAL struct {
        .cache_size = CS_MIN,
 };
 
+static void reset_uuidd_cache(void)
+{
+       memset(&uuidd_cache, 0, sizeof(uuidd_cache));
+       uuidd_cache.cache_size = CS_MIN;
+}
+
 static int uuid_generate_time_generic(uuid_t out) {
+       static volatile sig_atomic_t atfork_registered;
        time_t  now;
 
+       if (!atfork_registered) {
+               pthread_atfork(NULL, NULL, reset_uuidd_cache);
+               atfork_registered = 1;
+       }
+
        if (uuidd_cache.num > 0) { /* expire cache */
                now = time(NULL);
                if (now > uuidd_cache.last_time+1) {
@@ -623,8 +637,7 @@ static int uuid_generate_time_generic(uuid_t out) {
                        return 0;
                }
                /* request to daemon failed, reset cache */
-               uuidd_cache.num = 0;
-               uuidd_cache.cache_size = CS_MIN;
+               reset_uuidd_cache();
        }
        if (uuidd_cache.num > 0) { /* serve uuid from cache */
                uuidd_cache.uu.time_low++;