core: make nm_utils_get_nm_[ug]id() thread safe

While NetworkManager is of course (mostly) single threaded,
our static functions really should be thread safe.

"mostly" single threaded because we have GDBus's worker
thread, we use a thread for writing non-blocking SR-IOV sysctl,
in the past (or still?) we used a thread for async glibc resolver.

Anyway, a low-level function like must be thread safe, when it
uses global data.

Granted, the initialize-once pattern with the flag and the
int variable, is probably in many cases good enough. But it
makes me unhappy, the thought of accessing static data without
a synchronized operation.
This commit is contained in:
Thomas Haller
2022-01-18 18:21:01 +01:00
parent b2660b7012
commit 31dbcb81fe

View File

@@ -5157,14 +5157,22 @@ nm_utils_spawn_helper_finish(GAsyncResult *result, GError **error)
uid_t uid_t
nm_utils_get_nm_uid(void) nm_utils_get_nm_uid(void)
{ {
static uint8_t nm_uid_flag = 0; static int u_static = -1;
static uid_t nm_uid; int u;
if (!nm_uid_flag) { again:
nm_uid = geteuid(); if ((u = g_atomic_int_get(&u_static)) == -1) {
nm_uid_flag = 1; uid_t u2;
u2 = geteuid();
u = u2;
nm_assert(u == u2);
nm_assert(u >= 0);
if (!g_atomic_int_compare_and_exchange(&u_static, -1, u))
goto again;
} }
return nm_uid;
return u;
} }
/** /**
@@ -5176,12 +5184,20 @@ nm_utils_get_nm_uid(void)
gid_t gid_t
nm_utils_get_nm_gid(void) nm_utils_get_nm_gid(void)
{ {
static uint8_t nm_gid_flag = 0; static int g_static = -1;
static gid_t nm_gid; int g;
if (!nm_gid_flag) { again:
nm_gid = getegid(); if ((g = g_atomic_int_get(&g_static)) == -1) {
nm_gid_flag = 1; gid_t g2;
g2 = geteuid();
g = g2;
nm_assert(g == g2);
nm_assert(g >= 0);
if (!g_atomic_int_compare_and_exchange(&g_static, -1, g))
goto again;
} }
return nm_gid;
return g;
} }