All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Christian Göttsche" <cgzones@googlemail.com>
To: selinux@vger.kernel.org
Cc: Evgeny Vereshchagin <evverx@gmail.com>
Subject: [RFC PATCH v2 8/9] libselinux: add selabel_file(5) fuzzer
Date: Wed, 31 Jan 2024 14:08:34 +0100	[thread overview]
Message-ID: <20240131130840.48155-9-cgzones@googlemail.com> (raw)
In-Reply-To: <20240131130840.48155-1-cgzones@googlemail.com>

Add two fuzzers reading and performing lookup on selabel_file(5)
databases.  One fuzzer takes input in form of a textual fcontext
definition, the other one takes compiled fcontexts definitions.  The
lookup key and whether to lookup any or a specific file type is also
part of the generated input.

CC: Evgeny Vereshchagin <evverx@gmail.com>
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
---
v2: add patch
---
 libselinux/fuzz/input                         |   0
 .../fuzz/selabel_file_compiled-fuzzer.c       | 281 ++++++++++++++++++
 libselinux/fuzz/selabel_file_text-fuzzer.c    | 225 ++++++++++++++
 libselinux/src/label_file.c                   |  38 ++-
 libselinux/src/label_file.h                   |  17 ++
 scripts/oss-fuzz.sh                           |  25 ++
 6 files changed, 566 insertions(+), 20 deletions(-)
 create mode 100644 libselinux/fuzz/input
 create mode 100644 libselinux/fuzz/selabel_file_compiled-fuzzer.c
 create mode 100644 libselinux/fuzz/selabel_file_text-fuzzer.c

diff --git a/libselinux/fuzz/input b/libselinux/fuzz/input
new file mode 100644
index 00000000..e69de29b
diff --git a/libselinux/fuzz/selabel_file_compiled-fuzzer.c b/libselinux/fuzz/selabel_file_compiled-fuzzer.c
new file mode 100644
index 00000000..cf0710ad
--- /dev/null
+++ b/libselinux/fuzz/selabel_file_compiled-fuzzer.c
@@ -0,0 +1,281 @@
+#include <errno.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+#include <selinux/label.h>
+
+#include "../src/label_file.h"
+
+extern int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
+
+#define MEMFD_FILE_NAME "file_contexts"
+#define CTRL_PARTIAL  (1U << 0)
+#define CTRL_FIND_ALL (1U << 1)
+#define CTRL_MODE     (1U << 2)
+
+
+__attribute__ ((format(printf, 2, 3)))
+static int null_log(int type __attribute__((unused)), const char *fmt __attribute__((unused)), ...)
+{
+	return 0;
+}
+
+static int validate_context(char **ctxp)
+{
+	assert(strcmp(*ctxp, "<<none>>") != 0);
+
+	if (*ctxp[0] == '\0') {
+		errno = EINVAL;
+		return -1;
+	}
+
+	return 0;
+}
+
+static int write_full(int fd, const void *data, size_t size)
+{
+	ssize_t rc;
+	const unsigned char *p = data;
+
+	while (size > 0) {
+		rc = write(fd, p, size);
+		if (rc == -1) {
+			if (errno == EINTR)
+				continue;
+
+			return -1;
+		}
+
+		p += rc;
+		size -= rc;
+	}
+
+	return 0;
+}
+
+static FILE* convert_data(const uint8_t *data, size_t size)
+{
+	FILE* stream;
+	int fd, rc;
+
+	fd = memfd_create(MEMFD_FILE_NAME, MFD_CLOEXEC);
+	if (fd == -1)
+		return NULL;
+
+	rc = write_full(fd, data, size);
+	if (rc == -1) {
+		close(fd);
+		return NULL;
+	}
+
+	stream = fdopen(fd, "r");
+	if (!stream) {
+		close(fd);
+		return NULL;
+	}
+
+	rc = fseek(stream, 0L, SEEK_SET);
+	if (rc == -1) {
+		fclose(stream);
+		return NULL;
+	}
+
+	return stream;
+}
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
+{
+	struct selabel_handle rec;
+	struct saved_data sdata = {};
+	struct spec_node *root = NULL;
+	FILE* fp = NULL;
+	struct lookup_result *result = NULL;
+	uint8_t control;
+	uint8_t *fcontext_data1 = NULL, *fcontext_data2 = NULL, *fcontext_data3 = NULL;
+	char *key = NULL;
+	size_t fcontext_data1_len, fcontext_data2_len, fcontext_data3_len, key_len;
+	bool partial, find_all;
+	mode_t mode;
+	int rc;
+
+	/*
+	 * Treat first byte as control byte, whether to use partial mode, find all matches or mode to lookup
+	 */
+	if (size == 0)
+		return 0;
+
+	control = data[0];
+	data++;
+	size--;
+
+	if (control & ~(CTRL_PARTIAL | CTRL_FIND_ALL | CTRL_MODE))
+		return 0;
+
+	partial  = control & CTRL_PARTIAL;
+	find_all = control & CTRL_FIND_ALL;
+	/* S_IFSOCK has the highest integer value */
+	mode     = (control & CTRL_MODE) ? S_IFSOCK : 0;
+
+
+	/*
+	 * Split the fuzzer input into up to four pieces: one to three compiled fcontext
+	 * definitions (to mimic file_contexts, file_contexts.homedirs and file_contexts.local,
+	 * and the lookup key
+	 */
+	const unsigned char separator[4] = { 0xde, 0xad, 0xbe, 0xef };
+	const uint8_t *sep = memmem(data, size, separator, 4);
+	if (!sep || sep == data)
+		return 0;
+
+	fcontext_data1_len = sep - data;
+	fcontext_data1 = malloc(fcontext_data1_len);
+	if (!fcontext_data1)
+		goto cleanup;
+
+	memcpy(fcontext_data1, data, fcontext_data1_len);
+	data += fcontext_data1_len + 4;
+	size -= fcontext_data1_len + 4;
+
+	sep = memmem(data, size, separator, 4);
+	if (sep) {
+		fcontext_data2_len = sep - data;
+		fcontext_data2 = malloc(fcontext_data2_len);
+		if (!fcontext_data2)
+			goto cleanup;
+
+		memcpy(fcontext_data2, data, fcontext_data2_len);
+		data += fcontext_data2_len + 4;
+		size -= fcontext_data2_len + 4;
+	}
+
+	sep = memmem(data, size, separator, 4);
+	if (sep) {
+		fcontext_data3_len = sep - data;
+		fcontext_data3 = malloc(fcontext_data3_len);
+		if (!fcontext_data3)
+			goto cleanup;
+
+		memcpy(fcontext_data3, data, fcontext_data3_len);
+		data += fcontext_data3_len + 4;
+		size -= fcontext_data3_len + 4;
+	}
+
+	key_len = size;
+	key = malloc(key_len + 1);
+	if (!key)
+		goto cleanup;
+
+	memcpy(key, data, key_len);
+	key[key_len] = '\0';
+
+
+	/*
+	 * Mock selabel handle
+	 */
+	rec = (struct selabel_handle) {
+		.backend = SELABEL_CTX_FILE,
+		.validating = 1,
+		.data = &sdata,
+	};
+
+	selinux_set_callback(SELINUX_CB_LOG, (union selinux_callback) { .func_log = &null_log });
+	/* validate to pre-compile regular expressions */
+	selinux_set_callback(SELINUX_CB_VALIDATE, (union selinux_callback) { .func_validate = &validate_context });
+
+	root = calloc(1, sizeof(*root));
+	if (!root)
+		goto cleanup;
+
+	sdata.root = root;
+
+	fp = convert_data(fcontext_data1, fcontext_data1_len);
+	if (!fp)
+		goto cleanup;
+
+	errno = 0;
+	rc = load_mmap(fp, fcontext_data1_len, &rec, MEMFD_FILE_NAME);
+	if (rc) {
+		assert(errno != 0);
+		goto cleanup;
+	}
+
+	fclose(fp);
+
+	fp = convert_data(fcontext_data2, fcontext_data2_len);
+	if (!fp)
+		goto cleanup;
+
+	errno = 0;
+	rc = load_mmap(fp, fcontext_data2_len, &rec, MEMFD_FILE_NAME);
+	if (rc) {
+		assert(errno != 0);
+		goto cleanup;
+	}
+
+	fclose(fp);
+
+	fp = convert_data(fcontext_data3, fcontext_data3_len);
+	if (!fp)
+		goto cleanup;
+
+	errno = 0;
+	rc = load_mmap(fp, fcontext_data3_len, &rec, MEMFD_FILE_NAME);
+	if (rc) {
+		assert(errno != 0);
+		goto cleanup;
+	}
+
+	sort_specs(&sdata);
+
+	assert(cmp(&rec, &rec) == SELABEL_EQUAL);
+
+	errno = 0;
+	result = lookup_all(&rec, key, mode, partial, find_all);
+
+	if (!result)
+		assert(errno != 0);
+
+	for (const struct lookup_result *res = result; res; res = res->next) {
+		assert(res->regex_str);
+		assert(res->regex_str[0] != '\0');
+		assert(res->lr->ctx_raw);
+		assert(res->lr->ctx_raw[0] != '\0');
+		assert(strcmp(res->lr->ctx_raw, "<<none>>") != 0);
+		assert(!res->lr->ctx_trans);
+		assert(res->lr->validated);
+		assert(res->prefix_len <= strlen(res->regex_str));
+	}
+
+
+cleanup:
+	free_lookup_result(result);
+	if (fp)
+		fclose(fp);
+	if (sdata.root) {
+		free_spec_node(sdata.root);
+		free(sdata.root);
+	}
+
+	{
+		struct mmap_area *area, *last_area;
+
+		area = sdata.mmap_areas;
+		while (area) {
+			rc = munmap(area->addr, area->len);
+			assert(rc == 0);
+			last_area = area;
+			area = area->next;
+			free(last_area);
+		}
+	}
+
+	free(key);
+	free(fcontext_data3);
+	free(fcontext_data2);
+	free(fcontext_data1);
+
+	/* Non-zero return values are reserved for future use. */
+	return 0;
+}
diff --git a/libselinux/fuzz/selabel_file_text-fuzzer.c b/libselinux/fuzz/selabel_file_text-fuzzer.c
new file mode 100644
index 00000000..5d851de1
--- /dev/null
+++ b/libselinux/fuzz/selabel_file_text-fuzzer.c
@@ -0,0 +1,225 @@
+#include <errno.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+#include <selinux/label.h>
+
+#include "../src/label_file.h"
+
+extern int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
+
+#define MEMFD_FILE_NAME "file_contexts"
+#define CTRL_PARTIAL  (1U << 0)
+#define CTRL_FIND_ALL (1U << 1)
+#define CTRL_MODE     (1U << 2)
+
+
+__attribute__ ((format(printf, 2, 3)))
+static int null_log(int type __attribute__((unused)), const char *fmt __attribute__((unused)), ...)
+{
+	return 0;
+}
+
+static int validate_context(char **ctxp)
+{
+	assert(strcmp(*ctxp, "<<none>>") != 0);
+
+	if (*ctxp[0] == '\0') {
+		errno = EINVAL;
+		return -1;
+	}
+
+	return 0;
+}
+
+static int write_full(int fd, const void *data, size_t size)
+{
+	ssize_t rc;
+	const unsigned char *p = data;
+
+	while (size > 0) {
+		rc = write(fd, p, size);
+		if (rc == -1) {
+			if (errno == EINTR)
+				continue;
+
+			return -1;
+		}
+
+		p += rc;
+		size -= rc;
+	}
+
+	return 0;
+}
+
+static FILE* convert_data(const uint8_t *data, size_t size)
+{
+	FILE* stream;
+	int fd, rc;
+
+	fd = memfd_create(MEMFD_FILE_NAME, MFD_CLOEXEC);
+	if (fd == -1)
+		return NULL;
+
+	rc = write_full(fd, data, size);
+	if (rc == -1) {
+		close(fd);
+		return NULL;
+	}
+
+	stream = fdopen(fd, "r");
+	if (!stream) {
+		close(fd);
+		return NULL;
+	}
+
+	rc = fseek(stream, 0L, SEEK_SET);
+	if (rc == -1) {
+		fclose(stream);
+		return NULL;
+	}
+
+	return stream;
+}
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
+{
+	struct selabel_handle rec;
+	struct saved_data sdata = {};
+	struct spec_node *root = NULL;
+	FILE* fp = NULL;
+	struct lookup_result *result = NULL;
+	uint8_t control;
+	uint8_t *fcontext_data = NULL;
+	char *key = NULL;
+	size_t fcontext_data_len, key_len;
+	bool partial, find_all;
+	mode_t mode;
+	int rc;
+
+	/*
+	 * Treat first byte as control byte, whether to use partial mode, find all matches or mode to lookup
+	 */
+	if (size == 0)
+		return 0;
+
+	control = data[0];
+	data++;
+	size--;
+
+	if (control & ~(CTRL_PARTIAL | CTRL_FIND_ALL | CTRL_MODE))
+		return 0;
+
+	partial  = control & CTRL_PARTIAL;
+	find_all = control & CTRL_FIND_ALL;
+	/* S_IFSOCK has the highest integer value */
+	mode     = (control & CTRL_MODE) ? S_IFSOCK : 0;
+
+
+	/*
+	 * Split the fuzzer input into two pieces: the textual fcontext definition and the lookup key
+	 */
+	const unsigned char separator[4] = { 0xde, 0xad, 0xbe, 0xef };
+	const uint8_t *sep = memmem(data, size, separator, 4);
+	if (!sep || sep == data)
+		return 0;
+
+	fcontext_data_len = sep - data;
+	fcontext_data = malloc(fcontext_data_len);
+	if (!fcontext_data)
+		goto cleanup;
+
+	memcpy(fcontext_data, data, fcontext_data_len);
+
+	key_len = size - fcontext_data_len - 4;
+	key = malloc(key_len + 1);
+	if (!key)
+		goto cleanup;
+
+	memcpy(key, sep + 4, key_len);
+	key[key_len] = '\0';
+
+
+	/*
+	 * Mock selabel handle
+	 */
+	rec = (struct selabel_handle) {
+		.backend = SELABEL_CTX_FILE,
+		.validating = 1,
+		.data = &sdata,
+	};
+
+	selinux_set_callback(SELINUX_CB_LOG, (union selinux_callback) { .func_log = &null_log });
+	/* validate to pre-compile regular expressions */
+	selinux_set_callback(SELINUX_CB_VALIDATE, (union selinux_callback) { .func_validate = &validate_context });
+
+	root = calloc(1, sizeof(*root));
+	if (!root)
+		goto cleanup;
+
+	sdata.root = root;
+
+	fp = convert_data(fcontext_data, fcontext_data_len);
+	if (!fp)
+		goto cleanup;
+
+	errno = 0;
+	rc = process_text_file(fp, /*prefix=*/ NULL, &rec, MEMFD_FILE_NAME);
+	if (rc) {
+		assert(errno != 0);
+		goto cleanup;
+	}
+
+	sort_specs(&sdata);
+
+	assert(cmp(&rec, &rec) == SELABEL_EQUAL);
+
+	errno = 0;
+	result = lookup_all(&rec, key, mode, partial, find_all);
+
+	if (!result)
+		assert(errno != 0);
+
+	for (const struct lookup_result *res = result; res; res = res->next) {
+		assert(res->regex_str);
+		assert(res->regex_str[0] != '\0');
+		assert(res->lr->ctx_raw);
+		assert(res->lr->ctx_raw[0] != '\0');
+		assert(strcmp(res->lr->ctx_raw, "<<none>>") != 0);
+		assert(!res->lr->ctx_trans);
+		assert(res->lr->validated);
+		assert(res->prefix_len <= strlen(res->regex_str));
+	}
+
+
+cleanup:
+	free_lookup_result(result);
+	if (fp)
+		fclose(fp);
+	if (sdata.root) {
+		free_spec_node(sdata.root);
+		free(sdata.root);
+	}
+
+	{
+		struct mmap_area *area, *last_area;
+
+		area = sdata.mmap_areas;
+		while (area) {
+			rc = munmap(area->addr, area->len);
+			assert(rc == 0);
+			last_area = area;
+			area = area->next;
+			free(last_area);
+		}
+	}
+
+	free(key);
+	free(fcontext_data);
+
+	/* Non-zero return values are reserved for future use. */
+	return 0;
+}
diff --git a/libselinux/src/label_file.c b/libselinux/src/label_file.c
index 096e5dab..ac349bc5 100644
--- a/libselinux/src/label_file.c
+++ b/libselinux/src/label_file.c
@@ -27,6 +27,13 @@
 #include "label_file.h"
 
 
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+# define FUZZ_EXTERN
+#else
+# define FUZZ_EXTERN static
+#endif  /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */
+
+
 /*
  * Warn about duplicate specifications.
  */
@@ -114,8 +121,8 @@ static int nodups_spec_node(const struct spec_node *node, const char *path)
 	return rc;
 }
 
-static int process_text_file(FILE *fp, const char *prefix,
-			     struct selabel_handle *rec, const char *path)
+FUZZ_EXTERN int process_text_file(FILE *fp, const char *prefix,
+				  struct selabel_handle *rec, const char *path)
 {
 	int rc;
 	size_t line_len;
@@ -721,8 +728,8 @@ static int load_mmap_spec_node(struct mmap_area *mmap_area, const char *path, bo
 	return 0;
 }
 
-static int load_mmap(FILE *fp, const size_t len, struct selabel_handle *rec,
-		     const char *path)
+FUZZ_EXTERN int load_mmap(FILE *fp, const size_t len, struct selabel_handle *rec,
+			  const char *path)
 {
 	struct saved_data *data = rec->data;
 	struct spec_node *root = NULL;
@@ -1443,16 +1450,7 @@ static uint32_t search_literal_spec(const struct literal_spec *array, uint32_t s
 	return (uint32_t)-1;
 }
 
-struct lookup_result {
-	const char *regex_str;
-	struct selabel_lookup_rec *lr;
-	uint16_t prefix_len;
-	uint8_t file_kind;
-	bool has_meta_chars;
-	struct lookup_result *next;
-};
-
-static void free_lookup_result(struct lookup_result *result)
+FUZZ_EXTERN void free_lookup_result(struct lookup_result *result)
 {
 	struct lookup_result *tmp;
 
@@ -1684,11 +1682,11 @@ static uint8_t mode_to_file_kind(int type) {
 // Finds all the matches of |key| in the given context. Returns the result in
 // the allocated array and updates the match count. If match_count is NULL,
 // stops early once the 1st match is found.
-static struct lookup_result *lookup_all(struct selabel_handle *rec,
-					const char *key,
-					int type,
-					bool partial,
-					bool find_all)
+FUZZ_EXTERN struct lookup_result *lookup_all(struct selabel_handle *rec,
+				 const char *key,
+				 int type,
+				 bool partial,
+				 bool find_all)
 {
 	struct saved_data *data = (struct saved_data *)rec->data;
 	struct lookup_result *result = NULL;
@@ -2255,7 +2253,7 @@ static enum selabel_cmp_result spec_node_cmp(const struct spec_node *node1, cons
 	return result;
 }
 
-static enum selabel_cmp_result cmp(const struct selabel_handle *h1, const struct selabel_handle *h2)
+FUZZ_EXTERN enum selabel_cmp_result cmp(const struct selabel_handle *h1, const struct selabel_handle *h2)
 {
 	const struct saved_data *data1, *data2;
 
diff --git a/libselinux/src/label_file.h b/libselinux/src/label_file.h
index 2dc772eb..529a1bd2 100644
--- a/libselinux/src/label_file.h
+++ b/libselinux/src/label_file.h
@@ -50,6 +50,23 @@
 #define LABEL_FILE_KIND_LNK		6
 #define LABEL_FILE_KIND_REG		7
 
+/* Only exported for fuzzing */
+struct lookup_result {
+	const char *regex_str;
+	struct selabel_lookup_rec *lr;
+	uint16_t prefix_len;
+	uint8_t file_kind;
+	bool has_meta_chars;
+	struct lookup_result *next;
+};
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+extern int load_mmap(FILE *fp, const size_t len, struct selabel_handle *rec, const char *path);
+extern int process_text_file(FILE *fp, const char *prefix, struct selabel_handle *rec, const char *path);
+extern void free_lookup_result(struct lookup_result *result);
+extern struct lookup_result *lookup_all(struct selabel_handle *rec, const char *key, int type, bool partial, bool find_all);
+extern enum selabel_cmp_result cmp(const struct selabel_handle *h1, const struct selabel_handle *h2);
+#endif  /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */
+
 struct selabel_sub {
 	char *src;
 	unsigned int slen;
diff --git a/scripts/oss-fuzz.sh b/scripts/oss-fuzz.sh
index 72d275e8..e51efe74 100755
--- a/scripts/oss-fuzz.sh
+++ b/scripts/oss-fuzz.sh
@@ -44,10 +44,13 @@ export LIB_FUZZING_ENGINE=${LIB_FUZZING_ENGINE:--fsanitize=fuzzer}
 
 rm -rf "$DESTDIR"
 make -C libsepol clean
+make -C libselinux clean
 # LIBSO and LIBMAP shouldn't be expanded here because their values are unknown until Makefile
 # has been read by make
 # shellcheck disable=SC2016
 make -C libsepol V=1 LD_SONAME_FLAGS='-soname,$(LIBSO),--version-script=$(LIBMAP)' -j"$(nproc)" install
+# shellcheck disable=SC2016
+make -C libselinux V=1 LD_SONAME_FLAGS='-soname,$(LIBSO),--version-script=libselinux.map' -j"$(nproc)" install
 
 ## secilc fuzzer ##
 
@@ -70,3 +73,25 @@ $CC $CFLAGS -c -o binpolicy-fuzzer.o libsepol/fuzz/binpolicy-fuzzer.c
 $CXX $CXXFLAGS $LIB_FUZZING_ENGINE binpolicy-fuzzer.o "$DESTDIR/usr/lib/libsepol.a" -o "$OUT/binpolicy-fuzzer"
 
 zip -j "$OUT/binpolicy-fuzzer_seed_corpus.zip" libsepol/fuzz/policy.bin
+
+## selabel-file text fcontext based fuzzer ##
+
+# CFLAGS, CXXFLAGS and LIB_FUZZING_ENGINE have to be split to be accepted by
+# the compiler/linker so they shouldn't be quoted
+# shellcheck disable=SC2086
+$CC $CFLAGS -DUSE_PCRE2 -DPCRE2_CODE_UNIT_WIDTH=8 -c -o selabel_file_text-fuzzer.o libselinux/fuzz/selabel_file_text-fuzzer.c
+# shellcheck disable=SC2086
+$CXX $CXXFLAGS $LIB_FUZZING_ENGINE selabel_file_text-fuzzer.o "$DESTDIR/usr/lib/libselinux.a" -lpcre2-8 -o "$OUT/selabel_file_text-fuzzer"
+
+zip -j "$OUT/selabel_file_text-fuzzer_seed_corpus.zip" libselinux/fuzz/input
+
+## selabel-file compiled fcontext based fuzzer ##
+
+# CFLAGS, CXXFLAGS and LIB_FUZZING_ENGINE have to be split to be accepted by
+# the compiler/linker so they shouldn't be quoted
+# shellcheck disable=SC2086
+$CC $CFLAGS -DUSE_PCRE2 -DPCRE2_CODE_UNIT_WIDTH=8 -c -o selabel_file_compiled-fuzzer.o libselinux/fuzz/selabel_file_compiled-fuzzer.c
+# shellcheck disable=SC2086
+$CXX $CXXFLAGS $LIB_FUZZING_ENGINE selabel_file_compiled-fuzzer.o "$DESTDIR/usr/lib/libselinux.a" -lpcre2-8 -o "$OUT/selabel_file_compiled-fuzzer"
+
+zip -j "$OUT/selabel_file_compiled-fuzzer_seed_corpus.zip" libselinux/fuzz/input
-- 
2.43.0


  parent reply	other threads:[~2024-01-31 13:08 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-01-31 13:08 [RFC PATCH v2 0/9] libselinux: rework selabel_file(5) database Christian Göttsche
2024-01-31 13:08 ` [RFC PATCH v2 1/9] policycoreutils: introduce unsetfiles Christian Göttsche
2024-01-31 13:08 ` [RFC PATCH v2 2/9] libselinux/utils: introduce selabel_compare Christian Göttsche
2024-03-07 19:50   ` James Carter
2024-03-11 17:20     ` Christian Göttsche
2024-03-11 20:49       ` James Carter
2024-01-31 13:08 ` [RFC PATCH v2 3/9] libselinux: use more appropriate types in sidtab Christian Göttsche
2024-01-31 13:08 ` [RFC PATCH v2 4/9] libselinux: add unique id to sidtab entries Christian Göttsche
2024-01-31 13:08 ` [RFC PATCH v2 5/9] libselinux: sidtab updates Christian Göttsche
2024-03-07 20:53   ` James Carter
2024-03-11 16:32     ` Christian Göttsche
2024-01-31 13:08 ` [RFC PATCH v2 6/9] libselinux: rework selabel_file(5) database Christian Göttsche
2024-01-31 13:08 ` [RFC PATCH v2 7/9] libselinux: remove unused hashtab code Christian Göttsche
2024-01-31 13:08 ` Christian Göttsche [this message]
2024-01-31 13:08 ` [RFC PATCH v2 9/9] libselinux: support parallel selabel_lookup(3) Christian Göttsche

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240131130840.48155-9-cgzones@googlemail.com \
    --to=cgzones@googlemail.com \
    --cc=evverx@gmail.com \
    --cc=selinux@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.