From 1adbdc5f45dab11853340ceb23cc5b286cb88846 Mon Sep 17 00:00:00 2001 From: fly_fzc <2385803914@qq.com> Date: Wed, 6 Dec 2023 15:44:04 +0800 Subject: [PATCH] backport upstream patches (cherry picked from commit 0327677f388cddd541515ad3c502b705258fbffc) --- ...void-regex-serialization-truncations.patch | 33 ++ ...to-unsigned-char-for-character-handl.patch | 332 ++++++++++++++++++ ...x-logic-for-building-android-backend.patch | 39 ++ ...elements-on-read_spec_entries-failur.patch | 33 ++ ...-libselinux-introduce-reallocarray-3.patch | 129 +++++++ backport-libselinux-introduce-strlcpy.patch | 77 ++++ ...linux-use-DJB2a-string-hash-function.patch | 53 +++ ...x-utils-update-selabel_partial_match.patch | 56 +++ libselinux.spec | 13 +- 9 files changed, 764 insertions(+), 1 deletion(-) create mode 100644 backport-libselinux-avoid-regex-serialization-truncations.patch create mode 100644 backport-libselinux-cast-to-unsigned-char-for-character-handl.patch create mode 100644 backport-libselinux-fix-logic-for-building-android-backend.patch create mode 100644 backport-libselinux-free-elements-on-read_spec_entries-failur.patch create mode 100644 backport-libselinux-introduce-reallocarray-3.patch create mode 100644 backport-libselinux-introduce-strlcpy.patch create mode 100644 backport-libselinux-use-DJB2a-string-hash-function.patch create mode 100644 backport-libselinux-utils-update-selabel_partial_match.patch diff --git a/backport-libselinux-avoid-regex-serialization-truncations.patch b/backport-libselinux-avoid-regex-serialization-truncations.patch new file mode 100644 index 0000000..fa4d740 --- /dev/null +++ b/backport-libselinux-avoid-regex-serialization-truncations.patch @@ -0,0 +1,33 @@ +From 4eea9948d3cca9729fac693a06c554468ca1dc8c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= +Date: Wed, 9 Aug 2023 19:55:17 +0200 +Subject: [PATCH] libselinux: avoid regex serialization truncations +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Check (for the probably impossible) case the serialized data is longer +than the compiled fcontext format supports. + +Signed-off-by: Christian Göttsche +Acked-by: James Carter +--- + libselinux/src/regex.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/regex.c b/src/regex.c +index 16df6790..88d82fed 100644 +--- a/src/regex.c ++++ b/src/regex.c +@@ -176,7 +176,7 @@ int regex_writef(struct regex_data *regex, FILE *fp, int do_write_precompregex) + /* encode the patter for serialization */ + rc = pcre2_serialize_encode((const pcre2_code **)®ex->regex, + 1, &bytes, &serialized_size, NULL); +- if (rc != 1) { ++ if (rc != 1 || serialized_size >= UINT32_MAX) { + rc = -1; + goto out; + } +-- +2.27.0 + diff --git a/backport-libselinux-cast-to-unsigned-char-for-character-handl.patch b/backport-libselinux-cast-to-unsigned-char-for-character-handl.patch new file mode 100644 index 0000000..363b519 --- /dev/null +++ b/backport-libselinux-cast-to-unsigned-char-for-character-handl.patch @@ -0,0 +1,332 @@ +From 3dad44a1a963fc6f9dffd67402a18cb445e8d7b0 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= +Date: Wed, 1 Nov 2023 17:56:35 +0100 +Subject: [PATCH] libselinux: cast to unsigned char for character handling + function +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Character handling functions, like isspace(3), expect a value +representable as unsigned char or equal to EOF. Otherwise the behavior +is undefined. + +See https://wiki.sei.cmu.edu/confluence/display/c/STR37-C.+Arguments+to+character-handling+functions+must+be+representable+as+an+unsigned+char + +Signed-off-by: Christian Göttsche +Acked-by: James Carter +--- + libselinux/src/booleans.c | 8 ++++---- + libselinux/src/compute_create.c | 2 +- + libselinux/src/get_context_list.c | 12 ++++++------ + libselinux/src/get_default_type.c | 2 +- + libselinux/src/label_file.c | 8 ++++---- + libselinux/src/label_media.c | 2 +- + libselinux/src/label_support.c | 8 ++++---- + libselinux/src/label_x.c | 2 +- + libselinux/src/load_policy.c | 2 +- + libselinux/src/matchmediacon.c | 6 +++--- + libselinux/src/selinux_check_securetty_context.c | 4 ++-- + libselinux/src/selinux_config.c | 12 ++++++------ + libselinux/src/seusers.c | 6 +++--- + 13 files changed, 37 insertions(+), 37 deletions(-) + +diff --git a/src/booleans.c b/src/booleans.c +index e34b39ff..c557df65 100644 +--- a/src/booleans.c ++++ b/src/booleans.c +@@ -107,7 +107,7 @@ char *selinux_boolean_sub(const char *name) + char *ptr; + char *src = line_buf; + char *dst; +- while (*src && isspace(*src)) ++ while (*src && isspace((unsigned char)*src)) + src++; + if (!*src) + continue; +@@ -115,19 +115,19 @@ char *selinux_boolean_sub(const char *name) + continue; + + ptr = src; +- while (*ptr && !isspace(*ptr)) ++ while (*ptr && !isspace((unsigned char)*ptr)) + ptr++; + *ptr++ = '\0'; + if (strcmp(src, name) != 0) + continue; + + dst = ptr; +- while (*dst && isspace(*dst)) ++ while (*dst && isspace((unsigned char)*dst)) + dst++; + if (!*dst) + continue; + ptr = dst; +- while (*ptr && !isspace(*ptr)) ++ while (*ptr && !isspace((unsigned char)*ptr)) + ptr++; + *ptr = '\0'; + +diff --git a/src/compute_create.c b/src/compute_create.c +index e9f3c96a..d19baa0b 100644 +--- a/src/compute_create.c ++++ b/src/compute_create.c +@@ -13,7 +13,7 @@ + + static int object_name_encode(const char *objname, char *buffer, size_t buflen) + { +- int code; ++ unsigned char code; + size_t offset = 0; + + if (buflen - offset < 1) +diff --git a/src/get_context_list.c b/src/get_context_list.c +index d774b9cf..0342823c 100644 +--- a/src/get_context_list.c ++++ b/src/get_context_list.c +@@ -170,27 +170,27 @@ static int get_context_user(FILE * fp, + + /* Skip leading whitespace. */ + start = line; +- while (*start && isspace(*start)) ++ while (*start && isspace((unsigned char)*start)) + start++; + if (!(*start)) + continue; + + /* Find the end of the (partial) fromcon in the line. */ + end = start; +- while (*end && !isspace(*end)) ++ while (*end && !isspace((unsigned char)*end)) + end++; + if (!(*end)) + continue; + + /* Check for a match. */ + linerole = start; +- while (*start && !isspace(*start) && *start != ':') ++ while (*start && !isspace((unsigned char)*start) && *start != ':') + start++; + if (*start != ':') + continue; + *start = 0; + linetype = ++start; +- while (*start && !isspace(*start) && *start != ':') ++ while (*start && !isspace((unsigned char)*start) && *start != ':') + start++; + if (!(*start)) + continue; +@@ -210,14 +210,14 @@ static int get_context_user(FILE * fp, + start = ++end; + while (*start) { + /* Skip leading whitespace */ +- while (*start && isspace(*start)) ++ while (*start && isspace((unsigned char)*start)) + start++; + if (!(*start)) + break; + + /* Find the end of this partial context. */ + end = start; +- while (*end && !isspace(*end)) ++ while (*end && !isspace((unsigned char)*end)) + end++; + if (*end) + *end++ = 0; +diff --git a/src/get_default_type.c b/src/get_default_type.c +index 766ea4b7..87e9c72c 100644 +--- a/src/get_default_type.c ++++ b/src/get_default_type.c +@@ -42,7 +42,7 @@ static int find_default_type(FILE * fp, const char *role, char **type) + buf[strlen(buf) - 1] = 0; + + ptr = buf; +- while (*ptr && isspace(*ptr)) ++ while (*ptr && isspace((unsigned char)*ptr)) + ptr++; + if (!(*ptr)) + continue; +diff --git a/src/label_file.c b/src/label_file.c +index a665c9b4..4778f8f8 100644 +--- a/src/label_file.c ++++ b/src/label_file.c +@@ -708,20 +708,20 @@ static int selabel_subs_init(const char *path, struct selabel_digest *digest, + char *src = buf; + char *dst = NULL; + +- while (*src && isspace(*src)) ++ while (*src && isspace((unsigned char)*src)) + src++; + if (src[0] == '#') continue; + ptr = src; +- while (*ptr && ! isspace(*ptr)) ++ while (*ptr && ! isspace((unsigned char)*ptr)) + ptr++; + *ptr++ = '\0'; + if (! *src) continue; + + dst = ptr; +- while (*dst && isspace(*dst)) ++ while (*dst && isspace((unsigned char)*dst)) + dst++; + ptr = dst; +- while (*ptr && ! isspace(*ptr)) ++ while (*ptr && ! isspace((unsigned char)*ptr)) + ptr++; + *ptr = '\0'; + if (! *dst) +diff --git a/src/label_media.c b/src/label_media.c +index d33b614a..b3443b47 100644 +--- a/src/label_media.c ++++ b/src/label_media.c +@@ -39,7 +39,7 @@ static int process_line(const char *path, char *line_buf, int pass, + char *key, *context; + + buf_p = line_buf; +- while (isspace(*buf_p)) ++ while (isspace((unsigned char)*buf_p)) + buf_p++; + /* Skip comment lines and empty lines. */ + if (*buf_p == '#' || *buf_p == 0) +diff --git a/src/label_support.c b/src/label_support.c +index 49f72b1c..f7ab9292 100644 +--- a/src/label_support.c ++++ b/src/label_support.c +@@ -26,14 +26,14 @@ static inline int read_spec_entry(char **entry, char **ptr, int *len, const char + *entry = NULL; + char *tmp_buf = NULL; + +- while (isspace(**ptr) && **ptr != '\0') ++ while (isspace((unsigned char)**ptr) && **ptr != '\0') + (*ptr)++; + + tmp_buf = *ptr; + *len = 0; + +- while (!isspace(**ptr) && **ptr != '\0') { +- if (!isascii(**ptr)) { ++ while (!isspace((unsigned char)**ptr) && **ptr != '\0') { ++ if (!isascii((unsigned char)**ptr)) { + errno = EINVAL; + *errbuf = "Non-ASCII characters found"; + return -1; +@@ -80,7 +80,7 @@ int read_spec_entries(char *line_buf, const char **errbuf, int num_args, ...) + len++; + + buf_p = line_buf; +- while (isspace(*buf_p)) ++ while (isspace((unsigned char)*buf_p)) + buf_p++; + + /* Skip comment lines and empty lines. */ +diff --git a/src/label_x.c b/src/label_x.c +index 4b8f524f..e15190ca 100644 +--- a/src/label_x.c ++++ b/src/label_x.c +@@ -41,7 +41,7 @@ static int process_line(const char *path, char *line_buf, int pass, + char *type, *key, *context; + + buf_p = line_buf; +- while (isspace(*buf_p)) ++ while (isspace((unsigned char)*buf_p)) + buf_p++; + /* Skip comment lines and empty lines. */ + if (*buf_p == '#' || *buf_p == 0) +diff --git a/src/load_policy.c b/src/load_policy.c +index 17918e8b..57d7aaef 100644 +--- a/src/load_policy.c ++++ b/src/load_policy.c +@@ -252,7 +252,7 @@ int selinux_init_load_policy(int *enforce) + } + if (fgets(buf, selinux_page_size, cfg) && + (tmp = strstr(buf, "enforcing="))) { +- if (tmp == buf || isspace(*(tmp - 1))) { ++ if (tmp == buf || isspace((unsigned char)*(tmp - 1))) { + secmdline = + atoi(tmp + sizeof("enforcing=") - 1); + } +diff --git a/src/matchmediacon.c b/src/matchmediacon.c +index d3d95043..6ba87b99 100644 +--- a/src/matchmediacon.c ++++ b/src/matchmediacon.c +@@ -29,7 +29,7 @@ int matchmediacon(const char *media, char ** con) + current_line[strlen(current_line) - 1] = 0; + /* Skip leading whitespace before the partial context. */ + ptr = current_line; +- while (*ptr && isspace(*ptr)) ++ while (*ptr && isspace((unsigned char)*ptr)) + ptr++; + + if (!(*ptr)) +@@ -37,7 +37,7 @@ int matchmediacon(const char *media, char ** con) + + /* Find the end of the media context. */ + ptr2 = ptr; +- while (*ptr2 && !isspace(*ptr2)) ++ while (*ptr2 && !isspace((unsigned char)*ptr2)) + ptr2++; + if (!(*ptr2)) + continue; +@@ -53,7 +53,7 @@ int matchmediacon(const char *media, char ** con) + return -1; + + /* Skip whitespace. */ +- while (*ptr2 && isspace(*ptr2)) ++ while (*ptr2 && isspace((unsigned char)*ptr2)) + ptr2++; + if (!(*ptr2)) { + return -1; +diff --git a/src/selinux_check_securetty_context.c b/src/selinux_check_securetty_context.c +index c5c557fd..7609752e 100644 +--- a/src/selinux_check_securetty_context.c ++++ b/src/selinux_check_securetty_context.c +@@ -26,13 +26,13 @@ int selinux_check_securetty_context(const char * tty_context) + + /* Skip leading whitespace. */ + start = line; +- while (*start && isspace(*start)) ++ while (*start && isspace((unsigned char)*start)) + start++; + if (!(*start)) + continue; + + end = start; +- while (*end && !isspace(*end)) ++ while (*end && !isspace((unsigned char)*end)) + end++; + if (*end) + *end++ = 0; +diff --git a/src/seusers.c b/src/seusers.c +index fff80c1a..6da8c318 100644 +--- a/src/seusers.c ++++ b/src/seusers.c +@@ -25,7 +25,7 @@ static int process_seusers(const char *buffer, + goto err; + + start = newbuf; +- while (isspace(*start)) ++ while (isspace((unsigned char)*start)) + start++; + if (*start == '#' || *start == 0) { + free(newbuf); +@@ -46,7 +46,7 @@ static int process_seusers(const char *buffer, + mls_found = 0; + + end = start; +- while (*end && !isspace(*end)) ++ while (*end && !isspace((unsigned char)*end)) + end++; + } + *end = 0; +@@ -63,7 +63,7 @@ static int process_seusers(const char *buffer, + goto out; + + start = ++end; +- while (*end && !isspace(*end)) ++ while (*end && !isspace((unsigned char)*end)) + end++; + *end = 0; + +-- +2.27.0 + diff --git a/backport-libselinux-fix-logic-for-building-android-backend.patch b/backport-libselinux-fix-logic-for-building-android-backend.patch new file mode 100644 index 0000000..547454d --- /dev/null +++ b/backport-libselinux-fix-logic-for-building-android-backend.patch @@ -0,0 +1,39 @@ +From 25a18110871487ecb861aa8fd37cb20067b5a5ac Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= +Date: Wed, 9 Aug 2023 19:56:51 +0200 +Subject: [PATCH] libselinux: fix logic for building android backend +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Fix the typo and adjust the logic accordingly so the android backend is +not build by default, but if either ANDROID_HOST or +LABEL_BACKEND_ANDROID is set to y. + +Fixes: c2a58cc52574 ("libselinux: LABEL_BACKEND_ANDROID add option to enable") +Signed-off-by: Christian Göttsche +Acked-by: James Carter +--- + libselinux/src/Makefile | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/src/Makefile b/src/Makefile +index 20d79312..cf830046 100644 +--- a/src/Makefile ++++ b/src/Makefile +@@ -125,11 +125,10 @@ DISABLE_FLAGS+= -DNO_MEDIA_BACKEND -DNO_DB_BACKEND -DNO_X_BACKEND \ + SRCS= callbacks.c freecon.c label.c label_file.c \ + label_backends_android.c regex.c label_support.c \ + matchpathcon.c setrans_client.c sha1.c booleans.c +-else + LABEL_BACKEND_ANDROID=y + endif + +-ifneq ($(LABEL_BACKEND_ANDROIDT),y) ++ifneq ($(LABEL_BACKEND_ANDROID),y) + SRCS:= $(filter-out label_backends_android.c, $(SRCS)) + DISABLE_FLAGS+= -DNO_ANDROID_BACKEND + endif +-- +2.27.0 + diff --git a/backport-libselinux-free-elements-on-read_spec_entries-failur.patch b/backport-libselinux-free-elements-on-read_spec_entries-failur.patch new file mode 100644 index 0000000..918e56e --- /dev/null +++ b/backport-libselinux-free-elements-on-read_spec_entries-failur.patch @@ -0,0 +1,33 @@ +From 168edd1ca279cc786e0949a9bd43b647c66bd0c8 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= +Date: Mon, 14 Aug 2023 14:08:55 +0200 +Subject: [PATCH] libselinux: free elements on read_spec_entries() failure +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Some entries might have been already parsed and allocated. + +Signed-off-by: Christian Göttsche +Acked-by: James Carter +--- + libselinux/src/label_file.h | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/label_file.h b/src/label_file.h +index 1363c83c..ea02cd5e 100644 +--- a/src/label_file.h ++++ b/src/label_file.h +@@ -446,6 +446,9 @@ static inline int process_line(struct selabel_handle *rec, + "%s: line %u error due to: %m\n", path, + lineno); + } ++ free(regex); ++ free(type); ++ free(context); + errno = rc; + return -1; + } +-- +2.27.0 + diff --git a/backport-libselinux-introduce-reallocarray-3.patch b/backport-libselinux-introduce-reallocarray-3.patch new file mode 100644 index 0000000..14273ae --- /dev/null +++ b/backport-libselinux-introduce-reallocarray-3.patch @@ -0,0 +1,129 @@ +From cb8289c2b237e5f66e4a7608ecc6c68abeaeaf55 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= +Date: Wed, 1 Nov 2023 17:56:36 +0100 +Subject: [PATCH] libselinux: introduce reallocarray(3) +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Introduce reallocarray(3), a realloc(3) wrapper incorporating a +multiplication overflow check. + +Add private implementation in case the function is not provided by the +standard C library. + +Use in appropriate locations. + +Signed-off-by: Christian Göttsche +Acked-by: James Carter +--- + libselinux/src/Makefile | 6 ++++++ + libselinux/src/get_context_list.c | 2 +- + libselinux/src/matchpathcon.c | 4 ++-- + libselinux/src/selinux_internal.c | 14 ++++++++++++++ + libselinux/src/selinux_internal.h | 4 ++++ + libselinux/src/selinux_restorecon.c | 3 +-- + 6 files changed, 28 insertions(+), 5 deletions(-) + +diff --git a/src/Makefile b/src/Makefile +index cf830046..7aadb822 100644 +--- a/src/Makefile ++++ b/src/Makefile +@@ -108,6 +108,12 @@ ifeq (yes,$(shell printf '${H}include \nint main(void){char*d,*s;strlc + override CFLAGS += -DHAVE_STRLCPY + endif + ++# check for reallocarray(3) availability ++H := \# ++ifeq (yes,$(shell printf '${H}include \nint main(void){reallocarray(NULL, 0, 0);return 0;}' | $(CC) -x c -o /dev/null - >/dev/null 2>&1 && echo yes)) ++override CFLAGS += -DHAVE_REALLOCARRAY ++endif ++ + SWIG_CFLAGS += -Wno-error -Wno-unused-variable -Wno-unused-but-set-variable -Wno-unused-parameter \ + -Wno-shadow -Wno-uninitialized -Wno-missing-prototypes -Wno-missing-declarations \ + -Wno-deprecated-declarations +diff --git a/src/get_context_list.c b/src/get_context_list.c +index 0342823c..9dafa519 100644 +--- a/src/get_context_list.c ++++ b/src/get_context_list.c +@@ -272,7 +272,7 @@ static int get_context_user(FILE * fp, + continue; + } + if (security_check_context(usercon_str) == 0) { +- new_reachable = realloc(*reachable, (*nreachable + 2) * sizeof(char *)); ++ new_reachable = reallocarray(*reachable, *nreachable + 2, sizeof(char *)); + if (!new_reachable) { + context_free(usercon); + rc = -1; +diff --git a/src/matchpathcon.c b/src/matchpathcon.c +index b98849d9..e44734c3 100644 +--- a/src/matchpathcon.c ++++ b/src/matchpathcon.c +@@ -96,8 +96,8 @@ static int add_array_elt(char *con) + if (con_array_size) { + while (con_array_used >= con_array_size) { + con_array_size *= 2; +- tmp = (char **)realloc(con_array, sizeof(char*) * +- con_array_size); ++ tmp = (char **)reallocarray(con_array, con_array_size, ++ sizeof(char*)); + if (!tmp) { + free_array_elts(); + return -1; +diff --git a/src/selinux_internal.c b/src/selinux_internal.c +index c2be7c0a..06852359 100644 +--- a/src/selinux_internal.c ++++ b/src/selinux_internal.c +@@ -1,5 +1,7 @@ + #include "selinux_internal.h" + ++#include ++#include + #include + + +@@ -16,3 +18,15 @@ size_t strlcpy(char *dest, const char *src, size_t size) + return ret; + } + #endif /* HAVE_STRLCPY */ ++ ++#ifndef HAVE_REALLOCARRAY ++void *reallocarray(void *ptr, size_t nmemb, size_t size) ++{ ++ if (size && nmemb > SIZE_MAX / size) { ++ errno = ENOMEM; ++ return NULL; ++ } ++ ++ return realloc(ptr, nmemb * size); ++} ++#endif /* HAVE_REALLOCARRAY */ +diff --git a/src/selinux_internal.h b/src/selinux_internal.h +index 06f2c038..af69ff04 100644 +--- a/src/selinux_internal.h ++++ b/src/selinux_internal.h +@@ -79,3 +79,7 @@ extern int has_selinux_config ; + size_t strlcpy(char *dest, const char *src, size_t size); + #endif + ++#ifndef HAVE_REALLOCARRAY ++void *reallocarray(void *ptr, size_t nmemb, size_t size); ++#endif ++ +diff --git a/src/selinux_restorecon.c b/src/selinux_restorecon.c +index 7ef2d45d..38f10f1c 100644 +--- a/src/selinux_restorecon.c ++++ b/src/selinux_restorecon.c +@@ -175,8 +175,7 @@ static int add_exclude(const char *directory, bool who) + return -1; + } + +- tmp_list = realloc(exclude_lst, +- sizeof(struct edir) * (exclude_count + 1)); ++ tmp_list = reallocarray(exclude_lst, exclude_count + 1, sizeof(struct edir)); + if (!tmp_list) + goto oom; + +-- +2.27.0 + diff --git a/backport-libselinux-introduce-strlcpy.patch b/backport-libselinux-introduce-strlcpy.patch new file mode 100644 index 0000000..778b8ac --- /dev/null +++ b/backport-libselinux-introduce-strlcpy.patch @@ -0,0 +1,77 @@ +From 7d5a89314be88b3085cfdf6083837045a5e44aa9 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= +Date: Tue, 10 May 2022 20:20:38 +0200 +Subject: [PATCH] libselinux: introduce strlcpy +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +To copy string safely, by always NULL-terminating them, and provide an +easy way to check for truncation introduce the nonstandard function +strlcpy(3). Use the system implementation if available. + +Signed-off-by: Christian Göttsche +--- + libselinux/src/Makefile | 6 ++++++ + libselinux/src/selinux_internal.c | 18 ++++++++++++++++++ + libselinux/src/selinux_internal.h | 4 ++++ + 3 files changed, 28 insertions(+) + create mode 100644 libselinux/src/selinux_internal.c + +diff --git a/src/Makefile b/src/Makefile +index 04bf4f24..88aa32f8 100644 +--- a/src/Makefile ++++ b/src/Makefile +@@ -103,6 +103,12 @@ FTS_LDLIBS ?= + + override CFLAGS += -I../include -D_GNU_SOURCE $(DISABLE_FLAGS) $(PCRE_CFLAGS) + ++# check for strlcpy(3) availability ++H := \# ++ifeq (yes,$(shell printf '${H}include \nint main(void){char*d,*s;strlcpy(d, s, 0);return 0;}' | $(CC) -x c -o /dev/null - >/dev/null 2>&1 && echo yes)) ++override CFLAGS += -DHAVE_STRLCPY ++endif ++ + SWIG_CFLAGS += -Wno-error -Wno-unused-variable -Wno-unused-but-set-variable -Wno-unused-parameter \ + -Wno-shadow -Wno-uninitialized -Wno-missing-prototypes -Wno-missing-declarations \ + -Wno-deprecated-declarations +diff --git a/src/selinux_internal.c b/src/selinux_internal.c +new file mode 100644 +index 00000000..c2be7c0a +--- /dev/null ++++ b/src/selinux_internal.c +@@ -0,0 +1,18 @@ ++#include "selinux_internal.h" ++ ++#include ++ ++ ++#ifndef HAVE_STRLCPY ++size_t strlcpy(char *dest, const char *src, size_t size) ++{ ++ size_t ret = strlen(src); ++ ++ if (size) { ++ size_t len = (ret >= size) ? size - 1 : ret; ++ memcpy(dest, src, len); ++ dest[len] = '\0'; ++ } ++ return ret; ++} ++#endif /* HAVE_STRLCPY */ +diff --git a/src/selinux_internal.h b/src/selinux_internal.h +index 9f4c9073..06f2c038 100644 +--- a/src/selinux_internal.h ++++ b/src/selinux_internal.h +@@ -74,3 +74,8 @@ extern int selinux_page_size ; + #define SELINUXCONFIG SELINUXDIR "config" + + extern int has_selinux_config ; ++ ++#ifndef HAVE_STRLCPY ++size_t strlcpy(char *dest, const char *src, size_t size); ++#endif ++ +-- +2.27.0 + diff --git a/backport-libselinux-use-DJB2a-string-hash-function.patch b/backport-libselinux-use-DJB2a-string-hash-function.patch new file mode 100644 index 0000000..660ddd5 --- /dev/null +++ b/backport-libselinux-use-DJB2a-string-hash-function.patch @@ -0,0 +1,53 @@ +From f1178a13dc8bc9e750cf59de1db8fc48867f9293 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= +Date: Wed, 16 Aug 2023 14:38:44 +0200 +Subject: [PATCH] libselinux: use DJB2a string hash function +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The hash table implementation uses `& (SIDTAB_SIZE - 1)` to truncate +generated hashes to the number of buckets. This operation is equal to +`% SIDTAB_SIZE` if and only if the size is a power of two (which seems +to be always the case). One property of the binary and with a power of +two (and probably a small one <=2048) is all higher bits are discarded. +Thus a hash function is needed with a good avalanche effect, which the +current one is not. + +Signed-off-by: Christian Göttsche +Acked-by: James Carter +--- + libselinux/src/avc_sidtab.c | 17 +++++++---------- + 1 file changed, 7 insertions(+), 10 deletions(-) + +diff --git a/src/avc_sidtab.c b/src/avc_sidtab.c +index f179d855..e396a938 100644 +--- a/src/avc_sidtab.c ++++ b/src/avc_sidtab.c +@@ -15,16 +15,13 @@ + + static inline unsigned sidtab_hash(const char * key) + { +- const char *p; +- unsigned int size; +- unsigned int val; +- +- val = 0; +- size = strlen(key); +- for (p = key; (unsigned int)(p - key) < size; p++) +- val = +- (val << 4 | (val >> (8 * sizeof(unsigned int) - 4))) ^ (*p); +- return val & (SIDTAB_SIZE - 1); ++ unsigned int hash = 5381; ++ unsigned char c; ++ ++ while ((c = *(unsigned const char *)key++)) ++ hash = ((hash << 5) + hash) ^ c; ++ ++ return hash & (SIDTAB_SIZE - 1); + } + + int sidtab_init(struct sidtab *s) +-- +2.27.0 + diff --git a/backport-libselinux-utils-update-selabel_partial_match.patch b/backport-libselinux-utils-update-selabel_partial_match.patch new file mode 100644 index 0000000..c12e9f9 --- /dev/null +++ b/backport-libselinux-utils-update-selabel_partial_match.patch @@ -0,0 +1,56 @@ +From 3459dfd92e466f72442dbeb34d1f235bbbe52cc0 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= +Date: Thu, 3 Aug 2023 17:59:43 +0200 +Subject: [PATCH] libselinux/utils: update selabel_partial_match +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Print usage information and exit if required path option is not given +or superfluous arguments are given. + +Constify read-only variables assigned command line arguments. + +Simplify bool evaluation. + +Signed-off-by: Christian Göttsche +Acked-by: James Carter +--- + libselinux/utils/selabel_partial_match.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/utils/selabel_partial_match.c b/utils/selabel_partial_match.c +index 7bbd5777..0df2627a 100644 +--- a/utils/selabel_partial_match.c ++++ b/utils/selabel_partial_match.c +@@ -28,7 +28,7 @@ int main(int argc, char **argv) + { + int opt; + bool partial_match; +- char *validate = NULL, *path = NULL, *file = NULL; ++ const char *validate = NULL, *path = NULL, *file = NULL; + + struct selabel_handle *hnd; + struct selinux_opt selabel_option[] = { +@@ -55,6 +55,9 @@ int main(int argc, char **argv) + } + } + ++ if (!path || optind != argc) ++ usage(argv[0]); ++ + selabel_option[0].value = file; + selabel_option[1].value = validate; + +@@ -69,7 +72,7 @@ int main(int argc, char **argv) + partial_match = selabel_partial_match(hnd, path); + + printf("Match or Partial match: %s\n", +- partial_match == 1 ? "TRUE" : "FALSE"); ++ partial_match ? "TRUE" : "FALSE"); + + selabel_close(hnd); + return partial_match; +-- +2.27.0 + diff --git a/libselinux.spec b/libselinux.spec index 0c66289..26dd5f8 100644 --- a/libselinux.spec +++ b/libselinux.spec @@ -3,7 +3,7 @@ Name: libselinux Version: 3.3 -Release: 4 +Release: 5 License: Public Domain Summary: SELinux library and simple utilities Url: https://github.com/SELinuxProject/selinux/wiki @@ -27,6 +27,14 @@ Patch6014: backport-libselinux-fix-some-memory-issues-in-db_init.patch Patch6015: backport-libselinux-add-check-for-malloc.patch Patch6016: backport-libselinux-restore-use-fixed-sized-integer-for-hash-index.patch Patch6017: backport-libselinux-add-check-for-calloc-in-check_booleans.patch +Patch6018: backport-libselinux-utils-update-selabel_partial_match.patch +Patch6019: backport-libselinux-avoid-regex-serialization-truncations.patch +Patch6020: backport-libselinux-fix-logic-for-building-android-backend.patch +Patch6021: backport-libselinux-free-elements-on-read_spec_entries-failur.patch +Patch6022: backport-libselinux-cast-to-unsigned-char-for-character-handl.patch +Patch6023: backport-libselinux-introduce-strlcpy.patch +Patch6024: backport-libselinux-introduce-reallocarray-3.patch +Patch6025: backport-libselinux-use-DJB2a-string-hash-function.patch Patch9000: do-malloc-trim-after-load-policy.patch @@ -147,6 +155,9 @@ mv %{buildroot}%{_sbindir}/getconlist %{buildroot}%{_sbindir}/selinuxconlist %{_mandir}/ru/man8/* %changelog +* Wed Dec 6 2023 fuanan - 3.3-5 +- backport upstream patches + * Mon Sep 11 2023 zhangguangzhi - 3.3-4 - backport upstream patch -- Gitee