74 lines
2.9 KiB
Diff
74 lines
2.9 KiB
Diff
From 5844f389429f26a0a62a65561fa3006feaaf6f3b Mon Sep 17 00:00:00 2001
|
|
From: Ondrej Mosnacek <omosnace@redhat.com>
|
|
Date: Tue, 26 Oct 2021 13:52:32 +0200
|
|
Subject: [PATCH] label_file: fix a data race
|
|
|
|
The 'matches' member of 'struct spec' may be written to by different
|
|
threads, so it needs to be accessed using the proper atomic constructs.
|
|
Since the actual count of matches doesn't matter and is not used,
|
|
convert this field to a bool and just atomically set/read it using GCC
|
|
__atomic builtins (which are already being used in another place).
|
|
|
|
If the compiler lacks support for __atomic builtins (which seem to have
|
|
been introduced in GCC 4.1), just fail the compilation. I don't think
|
|
it's worth tryin to invent a workaround to support a 15 years old
|
|
compiler.
|
|
|
|
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
|
|
---
|
|
libselinux/src/label_file.c | 15 +++++++++++++--
|
|
libselinux/src/label_file.h | 2 +-
|
|
2 files changed, 14 insertions(+), 3 deletions(-)
|
|
|
|
diff --git a/libselinux/src/label_file.c b/libselinux/src/label_file.c
|
|
index c1306c9979e7..33d395e414f0 100644
|
|
--- a/libselinux/src/label_file.c
|
|
+++ b/libselinux/src/label_file.c
|
|
@@ -951,7 +951,12 @@ static struct spec **lookup_all(struct selabel_handle *rec,
|
|
rc = regex_match(spec->regex, key, partial);
|
|
if (rc == REGEX_MATCH || (partial && rc == REGEX_MATCH_PARTIAL)) {
|
|
if (rc == REGEX_MATCH) {
|
|
- spec->matches++;
|
|
+#ifdef __ATOMIC_RELAXED
|
|
+ __atomic_store_n(&spec->any_matches,
|
|
+ true, __ATOMIC_RELAXED);
|
|
+#else
|
|
+#error "Please use a compiler that supports __atomic builtins"
|
|
+#endif
|
|
}
|
|
|
|
if (strcmp(spec_arr[i].lr.ctx_raw, "<<none>>") == 0) {
|
|
@@ -1249,9 +1254,15 @@ static void stats(struct selabel_handle *rec)
|
|
struct saved_data *data = (struct saved_data *)rec->data;
|
|
unsigned int i, nspec = data->nspec;
|
|
struct spec *spec_arr = data->spec_arr;
|
|
+ bool any_matches;
|
|
|
|
for (i = 0; i < nspec; i++) {
|
|
- if (spec_arr[i].matches == 0) {
|
|
+#ifdef __ATOMIC_RELAXED
|
|
+ any_matches = __atomic_load_n(&spec_arr[i].any_matches, __ATOMIC_RELAXED);
|
|
+#else
|
|
+#error "Please use a compiler that supports __atomic builtins"
|
|
+#endif
|
|
+ if (!any_matches) {
|
|
if (spec_arr[i].type_str) {
|
|
COMPAT_LOG(SELINUX_WARNING,
|
|
"Warning! No matches for (%s, %s, %s)\n",
|
|
diff --git a/libselinux/src/label_file.h b/libselinux/src/label_file.h
|
|
index 343ffc705e43..b453e13f8075 100644
|
|
--- a/libselinux/src/label_file.h
|
|
+++ b/libselinux/src/label_file.h
|
|
@@ -51,7 +51,7 @@ struct spec {
|
|
bool regex_compiled; /* bool to indicate if the regex is compiled */
|
|
pthread_mutex_t regex_lock; /* lock for lazy compilation of regex */
|
|
mode_t mode; /* mode format value */
|
|
- int matches; /* number of matching pathnames */
|
|
+ bool any_matches; /* did any pathname match? */
|
|
int stem_id; /* indicates which stem-compression item */
|
|
char hasMetaChars; /* regular expression has meta-chars */
|
|
char from_mmap; /* this spec is from an mmap of the data */
|
|
--
|
|
2.33.1
|
|
|