Re: [PATCH v3 1/5] libselinux: avc: use pthread mutexes by default when no lock callbacks set
James Carter <[email protected]>
| Newsgroups | org.kernel.vger.selinux |
|---|---|
| Message-ID | <CAP+JOzRA48R83Bb6=OXMCqjizYftiRbdGbZKFWbYPuS3+YtFNw@mail.gmail.com> |
On Mon, Jul 6, 2026 at 10:32 AM Stephen Smalley <[email protected]> wrote: > > The AVC has a set of locking calls but defaults to no locking, and > only the deprecated avc_init() allowed applications to set their own > locking callbacks. Since selinux_check_access() is now commonly used > by applications implementing userspace SELinux permission checks and > it uses avc_open() internally, such calls are currently not > thread-safe. Provide fallbacks to using pthread mutexes by > default. Single-threaded programs that do not link -lpthread will be > unaffected due to the existing __pthread_mutex() helpers. Applications > that explicitly specify locking callbacks via the deprecated > avc_init() will also be unaffected. > > This is the first step toward a thread-safe selinux_check_access(); > the class-string cache and status-page transition handling are > addressed in follow-up changes. > > Fixes: #287 #335 #336 > Link: https://lore.kernel.org/selinux/CAJsHiNx1E7x1jaBkS0i4L1nBWXp8YXLHRWcCaDaH4LOn=zm+Zw@mail.gmail.com/ > Link: https://lore.kernel.org/selinux/[email protected]/ > Reported-by: Seth Moore <[email protected]> > Reported-by: Purushottam Choudhary <[email protected]> > > Signed-off-by: Stephen Smalley <[email protected]> For these five patches: Acked-by: James Carter <[email protected]> > --- > libselinux/src/avc_internal.h | 19 ++++++++++++++++++- > 1 file changed, 18 insertions(+), 1 deletion(-) > > diff --git a/libselinux/src/avc_internal.h b/libselinux/src/avc_internal.h > index 719be934..3c21ffef 100644 > --- a/libselinux/src/avc_internal.h > +++ b/libselinux/src/avc_internal.h > @@ -14,6 +14,7 @@ > #include <string.h> > #include <selinux/avc.h> > #include "callbacks.h" > +#include "selinux_internal.h" > > /* callback pointers */ > extern void *(*avc_func_malloc)(size_t); > @@ -115,25 +116,41 @@ static inline void avc_stop_thread(void *thread) > > static inline void *avc_alloc_lock(void) > { > - return avc_func_alloc_lock ? avc_func_alloc_lock() : NULL; > + pthread_mutex_t *m; > + > + if (avc_func_alloc_lock) > + return avc_func_alloc_lock(); > + > + m = avc_malloc(sizeof(*m)); > + if (m) > + __pthread_mutex_init(m, NULL); > + return m; > } > > static inline void avc_get_lock(void *lock) > { > if (avc_func_get_lock) > avc_func_get_lock(lock); > + else if (lock) > + __pthread_mutex_lock((pthread_mutex_t *)lock); > } > > static inline void avc_release_lock(void *lock) > { > if (avc_func_release_lock) > avc_func_release_lock(lock); > + else if (lock) > + __pthread_mutex_unlock((pthread_mutex_t *)lock); > } > > static inline void avc_free_lock(void *lock) > { > if (avc_func_free_lock) > avc_func_free_lock(lock); > + else if (lock) { > + __pthread_mutex_destroy((pthread_mutex_t *)lock); > + avc_free(lock); > + } > } > > /* statistics helper routines */ > -- > 2.54.0 >