]> 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>
Mon, 1 Jul 2024 19:54:14 +0000 (21:54 +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>
(cherry picked from commit a3f1255f1891ddbaf3bb6a32af28569c0e6f3b91)

libuuid/src/Makemodule.am
libuuid/src/gen_uuid.c

index be27811230261a359cacd04eb034a42398c1fe57..867ad7be5ec6463d761daff0dfb432957ad8b50b 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 c40f9d66f64bfe7e8677b7c8830098e6a8365562..3b76ddc9aae94da1b94bfa7872a107655c53153c 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"
@@ -591,9 +593,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) {
@@ -622,8 +636,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++;