1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
|
From: Ian Jackson <ijackson@chiark.greenend.org.uk>
Date: Tue, 21 Jan 2025 18:44:42 +0000
Subject: Replace data race with use of pthread_once (ftpl_init)
At the cost of no longer nicely detecting recursive initialisation
problems.
Closes: #1093599
This patch is part of an upstream MR:
https://github.com/wolfcw/libfaketime/pull/488
---
src/libfaketime.c | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/src/libfaketime.c b/src/libfaketime.c
index c0e793a..0cbdbf9 100644
--- a/src/libfaketime.c
+++ b/src/libfaketime.c
@@ -319,7 +319,7 @@ static bool check_missing_real(const char *name, bool missing)
#define CHECK_MISSING_REAL(name) \
check_missing_real(#name, (NULL == real_##name))
-static int initialized = 0;
+static pthread_once_t initialized_once_control = PTHREAD_ONCE_INIT;
/* prototypes */
static int fake_gettimeofday(struct timeval *tv);
@@ -2361,6 +2361,13 @@ int clock_gettime(clockid_t clk_id, struct timespec *tp)
#endif
{
int result;
+ ftpl_init();
+ // If ftpl_init ends up recursing, pthread_once will deadlock.
+ // So the remaining recursion code is now unreachable.
+ // Hopefully this doesn't happen in practice.
+
+/*
+
static int recursion_depth = 0;
if (!initialized)
@@ -2399,6 +2406,7 @@ int clock_gettime(clockid_t clk_id, struct timespec *tp)
#endif
recursion_depth--;
}
+ */
/* sanity check */
if (tp == NULL)
{
@@ -2859,7 +2867,6 @@ static void ftpl_really_init(void)
#undef dlsym
#undef dlvsym
- initialized = 1;
#ifdef FAKE_STATELESS
if (0) ft_shm_init();
@@ -3110,10 +3117,7 @@ static void ftpl_really_init(void)
}
inline static void ftpl_init(void) {
- if (!initialized)
- {
- ftpl_really_init();
- }
+ pthread_once(&initialized_once_control, ftpl_really_init);
}
void *ft_dlvsym(void *handle, const char *symbol, const char *version,
|