Skip to content

Commit a50195c

Browse files
besser82solardiz
authored andcommitted
libtcb: Use thread-local storage for tcb_drop_priv and tcb_gain_priv.
tcb_drop_priv and tcb_gain_priv now use per-thread storage areas for their operations, allocated upon the first call in each thread that uses them. This makes it safe to call these functions from multiple threads simultaneously. The introduction of this feature is a safety net against sloppy coding. Programs are still strongly encouraged to use the reentrant functions tcb_drop_priv_r and tcb_gain_priv_r instead. Signed-off-by: Björn Esser <[email protected]>
1 parent 557818c commit a50195c

File tree

2 files changed

+28
-6
lines changed

2 files changed

+28
-6
lines changed

ChangeLog

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,21 @@
1111

1212
2024-12-12 Björn Esser <besser82 at fedoraproject.org>
1313

14+
libtcb: Use thread-local storage for tcb_drop_priv and tcb_gain_priv.
15+
tcb_drop_priv and tcb_gain_priv now use per-thread storage areas
16+
for their operations, allocated upon the first call in each thread
17+
that uses them. This makes it safe to call these functions from
18+
multiple threads simultaneously.
19+
The introduction of this feature is a safety net against sloppy
20+
coding. Programs are still strongly encouraged to use the reentrant
21+
functions tcb_drop_priv_r and tcb_gain_priv_r instead.
22+
* libs/libtcb.c (get_thread_local_privs): New function, a thin
23+
wrapper to return the pointer to the thread-local storage area of
24+
the former file-global struct tcb_privs glob_privs.
25+
(tcb_drop_priv): Use the pointer to the thread-local struct tcb_privs
26+
provided by get_thread_local_privs().
27+
(tcb_gain_priv): Likewise.
28+
1429
Makefile: Pass CFLAGS to the compiler when invoking the linker.
1530
Some CFLAGS imply effects on the linker too (e.g., -fsanitize=),
1631
so they must get passed within the linker rule as well.

libs/libtcb.c

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -139,9 +139,6 @@ int ulckpwdf_tcb(void)
139139
return 0;
140140
}
141141

142-
static gid_t glob_grplist[TCB_NGROUPS];
143-
static struct tcb_privs glob_privs = { glob_grplist, 0, -1, -1, 0 };
144-
145142
/*
146143
* Two setfsuid() in a row - stupid, but how the hell am I supposed to check
147144
* whether setfsuid() succeeded?
@@ -247,15 +244,25 @@ int tcb_gain_priv_r(struct tcb_privs *p)
247244
return 0;
248245
}
249246

247+
static struct tcb_privs *get_thread_local_privs(void)
248+
{
249+
static __thread gid_t grplist[TCB_NGROUPS];
250+
static __thread struct tcb_privs privs = { NULL, 0, -1, -1, 0 };
251+
/* no need to conditionalize here */
252+
privs.grplist = grplist;
253+
return &privs;
254+
}
255+
250256
int tcb_drop_priv(const char *name)
251257
{
252-
glob_privs.number_of_groups = TCB_NGROUPS;
253-
return tcb_drop_priv_r(name, &glob_privs);
258+
struct tcb_privs *privs = get_thread_local_privs();
259+
privs->number_of_groups = TCB_NGROUPS;
260+
return tcb_drop_priv_r(name, privs);
254261
}
255262

256263
int tcb_gain_priv()
257264
{
258-
return tcb_gain_priv_r(&glob_privs);
265+
return tcb_gain_priv_r(get_thread_local_privs());
259266
}
260267

261268
int tcb_is_suspect(int fd)

0 commit comments

Comments
 (0)