From 5785c2a9c02c507819f15cf95403f3e8c5984b32 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Mar 30 2021 14:44:03 +0000 Subject: import libselinux-2.9-5.el8 --- diff --git a/SOURCES/0009-libselinux-Eliminate-use-of-security_compute_user.patch b/SOURCES/0009-libselinux-Eliminate-use-of-security_compute_user.patch new file mode 100644 index 0000000..68085cf --- /dev/null +++ b/SOURCES/0009-libselinux-Eliminate-use-of-security_compute_user.patch @@ -0,0 +1,354 @@ +From bfee1a3131580a7b9d8a7366764b8e78d99a9f1b Mon Sep 17 00:00:00 2001 +From: Petr Lautrbach +Date: Mon, 17 Feb 2020 21:47:35 +0100 +Subject: [PATCH] libselinux: Eliminate use of security_compute_user() + +get_ordered_context_list() code used to ask the kernel to compute the complete +set of reachable contexts using /sys/fs/selinux/user aka +security_compute_user(). This set can be so huge so that it doesn't fit into a +kernel page and security_compute_user() fails. Even if it doesn't fail, +get_ordered_context_list() throws away the vast majority of the returned +contexts because they don't match anything in +/etc/selinux/targeted/contexts/default_contexts or +/etc/selinux/targeted/contexts/users/ + +get_ordered_context_list() is rewritten to compute set of contexts based on +/etc/selinux/targeted/contexts/users/ and +/etc/selinux/targeted/contexts/default_contexts files and to return only valid +contexts, using security_check_context(), from this set. + +Fixes: https://github.com/SELinuxProject/selinux/issues/28 + +Signed-off-by: Petr Lautrbach +--- + libselinux/src/get_context_list.c | 212 +++++++++++++----------------- + 1 file changed, 93 insertions(+), 119 deletions(-) + +diff --git a/libselinux/src/get_context_list.c b/libselinux/src/get_context_list.c +index 689e4658..26d7b3b9 100644 +--- a/libselinux/src/get_context_list.c ++++ b/libselinux/src/get_context_list.c +@@ -2,6 +2,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -114,64 +115,41 @@ int get_default_context(const char *user, + return 0; + } + +-static int find_partialcon(char ** list, +- unsigned int nreach, char *part) ++static int is_in_reachable(char **reachable, const char *usercon_str) + { +- const char *conrole, *contype; +- char *partrole, *parttype, *ptr; +- context_t con; +- unsigned int i; ++ if (!reachable) ++ return 0; + +- partrole = part; +- ptr = part; +- while (*ptr && !isspace(*ptr) && *ptr != ':') +- ptr++; +- if (*ptr != ':') +- return -1; +- *ptr++ = 0; +- parttype = ptr; +- while (*ptr && !isspace(*ptr) && *ptr != ':') +- ptr++; +- *ptr = 0; +- +- for (i = 0; i < nreach; i++) { +- con = context_new(list[i]); +- if (!con) +- return -1; +- conrole = context_role_get(con); +- contype = context_type_get(con); +- if (!conrole || !contype) { +- context_free(con); +- return -1; +- } +- if (!strcmp(conrole, partrole) && !strcmp(contype, parttype)) { +- context_free(con); +- return i; ++ for (; *reachable != NULL; reachable++) { ++ if (strcmp(*reachable, usercon_str) == 0) { ++ return 1; + } +- context_free(con); + } +- +- return -1; ++ return 0; + } + +-static int get_context_order(FILE * fp, ++static int get_context_user(FILE * fp, + char * fromcon, +- char ** reachable, +- unsigned int nreach, +- unsigned int *ordering, unsigned int *nordered) ++ const char * user, ++ char ***reachable, ++ unsigned int *nreachable) + { + char *start, *end = NULL; + char *line = NULL; +- size_t line_len = 0; ++ size_t line_len = 0, usercon_len; ++ size_t user_len = strlen(user); + ssize_t len; + int found = 0; +- const char *fromrole, *fromtype; ++ const char *fromrole, *fromtype, *fromlevel; + char *linerole, *linetype; +- unsigned int i; ++ char **new_reachable = NULL; ++ char *usercon_str; + context_t con; ++ context_t usercon; ++ + int rc; + +- errno = -EINVAL; ++ errno = EINVAL; + + /* Extract the role and type of the fromcon for matching. + User identity and MLS range can be variable. */ +@@ -180,6 +158,7 @@ static int get_context_order(FILE * fp, + return -1; + fromrole = context_role_get(con); + fromtype = context_type_get(con); ++ fromlevel = context_range_get(con); + if (!fromrole || !fromtype) { + context_free(con); + return -1; +@@ -243,23 +222,75 @@ static int get_context_order(FILE * fp, + if (*end) + *end++ = 0; + +- /* Check for a match in the reachable list. */ +- rc = find_partialcon(reachable, nreach, start); +- if (rc < 0) { +- /* No match, skip it. */ ++ /* Check whether a new context is valid */ ++ if (SIZE_MAX - user_len < strlen(start) + 2) { ++ fprintf(stderr, "%s: one of partial contexts is too big\n", __FUNCTION__); ++ errno = EINVAL; ++ rc = -1; ++ goto out; ++ } ++ usercon_len = user_len + strlen(start) + 2; ++ usercon_str = malloc(usercon_len); ++ if (!usercon_str) { ++ rc = -1; ++ goto out; ++ } ++ ++ /* set range from fromcon in the new usercon */ ++ snprintf(usercon_str, usercon_len, "%s:%s", user, start); ++ usercon = context_new(usercon_str); ++ if (!usercon) { ++ if (errno != EINVAL) { ++ free(usercon_str); ++ rc = -1; ++ goto out; ++ } ++ fprintf(stderr, ++ "%s: can't create a context from %s, skipping\n", ++ __FUNCTION__, usercon_str); ++ free(usercon_str); + start = end; + continue; + } ++ free(usercon_str); ++ if (context_range_set(usercon, fromlevel) != 0) { ++ context_free(usercon); ++ rc = -1; ++ goto out; ++ } ++ usercon_str = context_str(usercon); ++ if (!usercon_str) { ++ context_free(usercon); ++ rc = -1; ++ goto out; ++ } + +- /* If a match is found and the entry is not already ordered +- (e.g. due to prior match in prior config file), then set +- the ordering for it. */ +- i = rc; +- if (ordering[i] == nreach) +- ordering[i] = (*nordered)++; ++ /* check whether usercon is already in reachable */ ++ if (is_in_reachable(*reachable, usercon_str)) { ++ context_free(usercon); ++ start = end; ++ continue; ++ } ++ if (security_check_context(usercon_str) == 0) { ++ new_reachable = realloc(*reachable, (*nreachable + 2) * sizeof(char *)); ++ if (!new_reachable) { ++ context_free(usercon); ++ rc = -1; ++ goto out; ++ } ++ *reachable = new_reachable; ++ new_reachable[*nreachable] = strdup(usercon_str); ++ if (new_reachable[*nreachable] == NULL) { ++ context_free(usercon); ++ rc = -1; ++ goto out; ++ } ++ new_reachable[*nreachable + 1] = 0; ++ *nreachable += 1; ++ } ++ context_free(usercon); + start = end; + } +- + rc = 0; + + out: +@@ -313,21 +344,6 @@ static int get_failsafe_context(const char *user, char ** newcon) + return 0; + } + +-struct context_order { +- char * con; +- unsigned int order; +-}; +- +-static int order_compare(const void *A, const void *B) +-{ +- const struct context_order *c1 = A, *c2 = B; +- if (c1->order < c2->order) +- return -1; +- else if (c1->order > c2->order) +- return 1; +- return strcmp(c1->con, c2->con); +-} +- + int get_ordered_context_list_with_level(const char *user, + const char *level, + char * fromcon, +@@ -395,11 +411,8 @@ int get_ordered_context_list(const char *user, + char *** list) + { + char **reachable = NULL; +- unsigned int *ordering = NULL; +- struct context_order *co = NULL; +- char **ptr; + int rc = 0; +- unsigned int nreach = 0, nordered = 0, freefrom = 0, i; ++ unsigned nreachable = 0, freefrom = 0; + FILE *fp; + char *fname = NULL; + size_t fname_len; +@@ -413,23 +426,6 @@ int get_ordered_context_list(const char *user, + freefrom = 1; + } + +- /* Determine the set of reachable contexts for the user. */ +- rc = security_compute_user(fromcon, user, &reachable); +- if (rc < 0) +- goto failsafe; +- nreach = 0; +- for (ptr = reachable; *ptr; ptr++) +- nreach++; +- if (!nreach) +- goto failsafe; +- +- /* Initialize ordering array. */ +- ordering = malloc(nreach * sizeof(unsigned int)); +- if (!ordering) +- goto failsafe; +- for (i = 0; i < nreach; i++) +- ordering[i] = nreach; +- + /* Determine the ordering to apply from the optional per-user config + and from the global config. */ + fname_len = strlen(user_contexts_path) + strlen(user) + 2; +@@ -440,8 +436,8 @@ int get_ordered_context_list(const char *user, + fp = fopen(fname, "re"); + if (fp) { + __fsetlocking(fp, FSETLOCKING_BYCALLER); +- rc = get_context_order(fp, fromcon, reachable, nreach, ordering, +- &nordered); ++ rc = get_context_user(fp, fromcon, user, &reachable, &nreachable); ++ + fclose(fp); + if (rc < 0 && errno != ENOENT) { + fprintf(stderr, +@@ -454,8 +450,7 @@ int get_ordered_context_list(const char *user, + fp = fopen(selinux_default_context_path(), "re"); + if (fp) { + __fsetlocking(fp, FSETLOCKING_BYCALLER); +- rc = get_context_order(fp, fromcon, reachable, nreach, ordering, +- &nordered); ++ rc = get_context_user(fp, fromcon, user, &reachable, &nreachable); + fclose(fp); + if (rc < 0 && errno != ENOENT) { + fprintf(stderr, +@@ -463,40 +458,19 @@ int get_ordered_context_list(const char *user, + __FUNCTION__, selinux_default_context_path()); + /* Fall through */ + } +- rc = 0; + } + +- if (!nordered) ++ if (!nreachable) + goto failsafe; + +- /* Apply the ordering. */ +- co = malloc(nreach * sizeof(struct context_order)); +- if (!co) +- goto failsafe; +- for (i = 0; i < nreach; i++) { +- co[i].con = reachable[i]; +- co[i].order = ordering[i]; +- } +- qsort(co, nreach, sizeof(struct context_order), order_compare); +- for (i = 0; i < nreach; i++) +- reachable[i] = co[i].con; +- free(co); +- +- /* Only report the ordered entries to the caller. */ +- if (nordered <= nreach) { +- for (i = nordered; i < nreach; i++) +- free(reachable[i]); +- reachable[nordered] = NULL; +- rc = nordered; +- } +- + out: +- if (rc > 0) ++ if (nreachable > 0) { + *list = reachable; ++ rc = nreachable; ++ } + else + freeconary(reachable); + +- free(ordering); + if (freefrom) + freecon(fromcon); + +@@ -519,7 +493,7 @@ int get_ordered_context_list(const char *user, + reachable = NULL; + goto out; + } +- rc = 1; /* one context in the list */ ++ nreachable = 1; /* one context in the list */ + goto out; + } + +-- +2.25.4 + diff --git a/SOURCES/0010-libselinux-deprecate-security_compute_user-update-ma.patch b/SOURCES/0010-libselinux-deprecate-security_compute_user-update-ma.patch new file mode 100644 index 0000000..7e782b4 --- /dev/null +++ b/SOURCES/0010-libselinux-deprecate-security_compute_user-update-ma.patch @@ -0,0 +1,168 @@ +From d4c22fcd5943fe35db648dee971f631d40b3eb94 Mon Sep 17 00:00:00 2001 +From: Stephen Smalley +Date: Thu, 20 Feb 2020 10:40:19 -0500 +Subject: [PATCH] libselinux: deprecate security_compute_user(), update man + pages + +commit 1f89c4e7879fcf6da5d8d1b025dcc03371f30fc9 ("libselinux: Eliminate +use of security_compute_user()") eliminated the use of +security_compute_user() by get_ordered_context_list(). Deprecate +all use of security_compute_user() by updating the headers and man +pages and logging a warning message on any calls to it. Remove +the example utility that called the interface. While here, also +fix the documentation of correct usage of the user argument to these +interfaces. + +Fixes: https://github.com/SELinuxProject/selinux/issues/70 +Signed-off-by: Stephen Smalley +Acked-by: Petr Lautrbach +--- + libselinux/include/selinux/selinux.h | 8 +++- + .../man/man3/get_ordered_context_list.3 | 24 +++++++++--- + libselinux/man/man3/security_compute_av.3 | 5 ++- + libselinux/src/compute_user.c | 3 ++ + libselinux/utils/compute_user.c | 38 ------------------- + 5 files changed, 31 insertions(+), 47 deletions(-) + delete mode 100644 libselinux/utils/compute_user.c + +diff --git a/libselinux/include/selinux/selinux.h b/libselinux/include/selinux/selinux.h +index a34d54fc..a5ada324 100644 +--- a/libselinux/include/selinux/selinux.h ++++ b/libselinux/include/selinux/selinux.h +@@ -246,8 +246,12 @@ extern int security_compute_member_raw(const char * scon, + security_class_t tclass, + char ** newcon); + +-/* Compute the set of reachable user contexts and set *con to refer to +- the NULL-terminated array of contexts. Caller must free via freeconary. */ ++/* ++ * Compute the set of reachable user contexts and set *con to refer to ++ * the NULL-terminated array of contexts. Caller must free via freeconary. ++ * These interfaces are deprecated. Use get_ordered_context_list() or ++ * one of its variant interfaces instead. ++ */ + extern int security_compute_user(const char * scon, + const char *username, + char *** con); +diff --git a/libselinux/man/man3/get_ordered_context_list.3 b/libselinux/man/man3/get_ordered_context_list.3 +index e084da40..3ed14a96 100644 +--- a/libselinux/man/man3/get_ordered_context_list.3 ++++ b/libselinux/man/man3/get_ordered_context_list.3 +@@ -26,14 +26,28 @@ get_ordered_context_list, get_ordered_context_list_with_level, get_default_conte + .BI "int get_default_type(const char *" role ", char **" type ); + . + .SH "DESCRIPTION" ++ ++This family of functions can be used to obtain either a prioritized list of ++all reachable security contexts for a given SELinux user or a single default ++(highest priority) context for a given SELinux user for use by login-like ++programs. These functions takes a SELinux user identity that must ++be defined in the SELinux policy as their input, not a Linux username. ++Most callers should typically first call ++.BR getseuserbyname(3) ++to look up the SELinux user identity and level for a given ++Linux username and then invoke one of ++.BR get_ordered_context_list_with_level () ++or ++.BR get_default_context_with_level () ++with the returned SELinux user and level as inputs. ++ + .BR get_ordered_context_list () +-invokes the +-.BR security_compute_user (3) +-function to obtain the list of contexts for the specified ++obtains the list of contexts for the specified ++SELinux + .I user +-that are reachable from the specified ++identity that are reachable from the specified + .I fromcon +-context. The function then orders the resulting list based on the global ++context based on the global + .I \%/etc/selinux/{SELINUXTYPE}/contexts/default_contexts + file and the per-user + .I \%/etc/selinux/{SELINUXTYPE}/contexts/users/ +diff --git a/libselinux/man/man3/security_compute_av.3 b/libselinux/man/man3/security_compute_av.3 +index 2aade5fe..8e1f746a 100644 +--- a/libselinux/man/man3/security_compute_av.3 ++++ b/libselinux/man/man3/security_compute_av.3 +@@ -97,8 +97,9 @@ instance. + + .BR security_compute_user () + is used to determine the set of user contexts that can be reached from a +-source context. It is mainly used by +-.BR get_ordered_context_list (). ++source context. This function is deprecated; use ++.BR get_ordered_context_list (3) ++instead. + + .BR security_get_initial_context () + is used to get the context of a kernel initial security identifier specified by +diff --git a/libselinux/src/compute_user.c b/libselinux/src/compute_user.c +index 401fd107..0f55de84 100644 +--- a/libselinux/src/compute_user.c ++++ b/libselinux/src/compute_user.c +@@ -8,6 +8,7 @@ + #include "selinux_internal.h" + #include "policy.h" + #include ++#include "callbacks.h" + + int security_compute_user_raw(const char * scon, + const char *user, char *** con) +@@ -24,6 +25,8 @@ int security_compute_user_raw(const char * scon, + return -1; + } + ++ selinux_log(SELINUX_WARNING, "Direct use of security_compute_user() is deprecated, switch to get_ordered_context_list()\n"); ++ + if (! scon) { + errno=EINVAL; + return -1; +diff --git a/libselinux/utils/compute_user.c b/libselinux/utils/compute_user.c +deleted file mode 100644 +index cae62b26..00000000 +--- a/libselinux/utils/compute_user.c ++++ /dev/null +@@ -1,38 +0,0 @@ +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-int main(int argc, char **argv) +-{ +- char **buf, **ptr; +- int ret; +- +- if (argc != 3) { +- fprintf(stderr, "usage: %s context user\n", argv[0]); +- exit(1); +- } +- +- ret = security_compute_user(argv[1], argv[2], &buf); +- if (ret < 0) { +- fprintf(stderr, "%s: security_compute_user(%s,%s) failed\n", +- argv[0], argv[1], argv[2]); +- exit(2); +- } +- +- if (!buf[0]) { +- printf("none\n"); +- exit(0); +- } +- +- for (ptr = buf; *ptr; ptr++) { +- printf("%s\n", *ptr); +- } +- freeconary(buf); +- exit(0); +-} +-- +2.25.4 + diff --git a/SPECS/libselinux.spec b/SPECS/libselinux.spec index 83af24c..5c649a9 100644 --- a/SPECS/libselinux.spec +++ b/SPECS/libselinux.spec @@ -6,7 +6,7 @@ %endif %define libsepolver 2.9-1 -%define libselinuxrelease 3 +%define libselinuxrelease 5 Summary: SELinux library and simple utilities Name: libselinux @@ -27,6 +27,8 @@ Patch0005: 0005-libselinux-add-missing-av_permission-values.patch Patch0006: 0006-libselinux-Use-Python-distutils-to-install-SELinux-p.patch Patch0007: 0007-libselinux-Do-not-use-SWIG_CFLAGS-when-Python-bindin.patch Patch0008: 0008-Fix-mcstrans-secolor-examples.patch +Patch0009: 0009-libselinux-Eliminate-use-of-security_compute_user.patch +Patch0010: 0010-libselinux-deprecate-security_compute_user-update-ma.patch BuildRequires: gcc %if 0%{?with_ruby} @@ -274,6 +276,12 @@ rm -f %{buildroot}%{_mandir}/man8/togglesebool* %endif %changelog +* Tue Oct 20 2020 Vit Mojzis - 2.9-5 +- Deprecate security_compute_user(), update man pages (#1879368) + +* Thu Sep 24 2020 Vit Mojzis - 2.9-4 +- Eliminate use of security_compute_user() (#1879368) + * Fri Nov 08 2019 Vit Mojzis - 2.9-3 - Fix mcstrans secolor examples in secolor.conf man page (#1770270)