diff mbox series

[userspace,v4,5/8] libselinux: make is_context_customizable() thread-safe

Message ID 20211026115239.267449-6-omosnace@redhat.com (mailing list archive)
State Accepted
Headers show
Series Parallel setfiles/restorecon | expand

Commit Message

Ondrej Mosnacek Oct. 26, 2021, 11:52 a.m. UTC
Use the __selinux_once() macro to ensure that threads don't race to
initialize the list of customizable types.

Reported-by: Christian Göttsche <cgzones@googlemail.com>
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
---
 libselinux/src/is_customizable_type.c | 23 +++++++++++------------
 1 file changed, 11 insertions(+), 12 deletions(-)

Comments

Christian Göttsche Nov. 5, 2021, 3:32 p.m. UTC | #1
On Tue, 26 Oct 2021 at 13:52, Ondrej Mosnacek <omosnace@redhat.com> wrote:
>
> Use the __selinux_once() macro to ensure that threads don't race to
> initialize the list of customizable types.
>
> Reported-by: Christian Göttsche <cgzones@googlemail.com>
> Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
> ---
>  libselinux/src/is_customizable_type.c | 23 +++++++++++------------
>  1 file changed, 11 insertions(+), 12 deletions(-)
>

Tested-by: Christian Göttsche <cgzones@googlemail.com>

Found no further thread sanitizer issues while testing.

> diff --git a/libselinux/src/is_customizable_type.c b/libselinux/src/is_customizable_type.c
> index 1b17860c..f83e1e83 100644
> --- a/libselinux/src/is_customizable_type.c
> +++ b/libselinux/src/is_customizable_type.c
> @@ -9,7 +9,10 @@
>  #include "selinux_internal.h"
>  #include "context_internal.h"
>
> -static int get_customizable_type_list(char *** retlist)
> +static char **customizable_list = NULL;
> +static pthread_once_t customizable_once = PTHREAD_ONCE_INIT;
> +
> +static void customizable_init(void)
>  {
>         FILE *fp;
>         char *buf;
> @@ -18,12 +21,12 @@ static int get_customizable_type_list(char *** retlist)
>
>         fp = fopen(selinux_customizable_types_path(), "re");
>         if (!fp)
> -               return -1;
> +               return;
>
>         buf = malloc(selinux_page_size);
>         if (!buf) {
>                 fclose(fp);
> -               return -1;
> +               return;
>         }
>         while (fgets_unlocked(buf, selinux_page_size, fp) && ctr < UINT_MAX) {
>                 ctr++;
> @@ -54,23 +57,19 @@ static int get_customizable_type_list(char *** retlist)
>         fclose(fp);
>         free(buf);
>         if (!list)
> -               return -1;
> -       *retlist = list;
> -       return 0;
> +               return;
> +       customizable_list = list;
>  }
>
> -static char **customizable_list = NULL;
> -
>  int is_context_customizable(const char * scontext)
>  {
>         int i;
>         const char *type;
>         context_t c;
>
> -       if (!customizable_list) {
> -               if (get_customizable_type_list(&customizable_list) != 0)
> -                       return -1;
> -       }
> +       __selinux_once(customizable_once, customizable_init);
> +       if (!customizable_list)
> +               return -1;
>
>         c = context_new(scontext);
>         if (!c)
> --
> 2.31.1
>
diff mbox series

Patch

diff --git a/libselinux/src/is_customizable_type.c b/libselinux/src/is_customizable_type.c
index 1b17860c..f83e1e83 100644
--- a/libselinux/src/is_customizable_type.c
+++ b/libselinux/src/is_customizable_type.c
@@ -9,7 +9,10 @@ 
 #include "selinux_internal.h"
 #include "context_internal.h"
 
-static int get_customizable_type_list(char *** retlist)
+static char **customizable_list = NULL;
+static pthread_once_t customizable_once = PTHREAD_ONCE_INIT;
+
+static void customizable_init(void)
 {
 	FILE *fp;
 	char *buf;
@@ -18,12 +21,12 @@  static int get_customizable_type_list(char *** retlist)
 
 	fp = fopen(selinux_customizable_types_path(), "re");
 	if (!fp)
-		return -1;
+		return;
 
 	buf = malloc(selinux_page_size);
 	if (!buf) {
 		fclose(fp);
-		return -1;
+		return;
 	}
 	while (fgets_unlocked(buf, selinux_page_size, fp) && ctr < UINT_MAX) {
 		ctr++;
@@ -54,23 +57,19 @@  static int get_customizable_type_list(char *** retlist)
 	fclose(fp);
 	free(buf);
 	if (!list)
-		return -1;
-	*retlist = list;
-	return 0;
+		return;
+	customizable_list = list;
 }
 
-static char **customizable_list = NULL;
-
 int is_context_customizable(const char * scontext)
 {
 	int i;
 	const char *type;
 	context_t c;
 
-	if (!customizable_list) {
-		if (get_customizable_type_list(&customizable_list) != 0)
-			return -1;
-	}
+	__selinux_once(customizable_once, customizable_init);
+	if (!customizable_list)
+		return -1;
 
 	c = context_new(scontext);
 	if (!c)