Skip to content

Commit

Permalink
libtcb: Use thread-local storage for tcb_drop_priv and tcb_gain_priv.
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
besser82 authored and solardiz committed Dec 19, 2024
1 parent 557818c commit a50195c
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 6 deletions.
15 changes: 15 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,21 @@

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

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.
* libs/libtcb.c (get_thread_local_privs): New function, a thin
wrapper to return the pointer to the thread-local storage area of
the former file-global struct tcb_privs glob_privs.
(tcb_drop_priv): Use the pointer to the thread-local struct tcb_privs
provided by get_thread_local_privs().
(tcb_gain_priv): Likewise.

Makefile: Pass CFLAGS to the compiler when invoking the linker.
Some CFLAGS imply effects on the linker too (e.g., -fsanitize=),
so they must get passed within the linker rule as well.
Expand Down
19 changes: 13 additions & 6 deletions libs/libtcb.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,9 +139,6 @@ int ulckpwdf_tcb(void)
return 0;
}

static gid_t glob_grplist[TCB_NGROUPS];
static struct tcb_privs glob_privs = { glob_grplist, 0, -1, -1, 0 };

/*
* Two setfsuid() in a row - stupid, but how the hell am I supposed to check
* whether setfsuid() succeeded?
Expand Down Expand Up @@ -247,15 +244,25 @@ int tcb_gain_priv_r(struct tcb_privs *p)
return 0;
}

static struct tcb_privs *get_thread_local_privs(void)
{
static __thread gid_t grplist[TCB_NGROUPS];
static __thread struct tcb_privs privs = { NULL, 0, -1, -1, 0 };
/* no need to conditionalize here */
privs.grplist = grplist;
return &privs;
}

int tcb_drop_priv(const char *name)
{
glob_privs.number_of_groups = TCB_NGROUPS;
return tcb_drop_priv_r(name, &glob_privs);
struct tcb_privs *privs = get_thread_local_privs();
privs->number_of_groups = TCB_NGROUPS;
return tcb_drop_priv_r(name, privs);
}

int tcb_gain_priv()
{
return tcb_gain_priv_r(&glob_privs);
return tcb_gain_priv_r(get_thread_local_privs());
}

int tcb_is_suspect(int fd)
Expand Down

0 comments on commit a50195c

Please sign in to comment.