On 2/4/20 2:46 PM, Petr Lautrbach wrote:
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 <plautrba@xxxxxxxxxx>
---
<snip>
After:
selinux.get_ordered_context_list("staff_u", "system_u:system_r:crond_t:s0-s0:c0.c1023")
['staff_u:staff_r:staff_t:s0-s0:c0.c1023', 'staff_u:staff_r:cronjob_t:s0-s0:c0.c1023', 'staff_u:staff_r:staff_t:s0-s0:c0.c1023', 'staff_u:sysadm_r:sysadm_t:s0-s0:c0.c1023', 'staff_u:unconfined_r:unconfined_t:s0-s0:c0.c1023', 'staff_u:staff_r:cronjob_t:s0-s0:c0.c1023', 'staff_u:sysadm_r:cronjob_t:s0-s0:c0.c1023', 'staff_u:system_r:system_cronjob_t:s0-s0:c0.c1023', 'staff_u:unconfined_r:unconfined_cronjob_t:s0-s0:c0.c1023']
We should likely de-duplicate the list; I think that was being handled
previously by virtue of using the reachable contexts as our baseline and
just re-ordering them. Here we just need to check whether we already
have a context in the list before inserting a new one.
diff --git a/libselinux/src/get_context_list.c b/libselinux/src/get_context_list.c
index 689e46589f30..a3dcaea2ffc4 100644
--- a/libselinux/src/get_context_list.c
+++ b/libselinux/src/get_context_list.c
@@ -114,61 +115,25 @@ int get_default_context(const char *user,
<snip>
@@ -243,23 +209,66 @@ static int get_context_order(FILE * fp,
<snip>
+ context_range_set(usercon, fromlevel);
+ usercon_str = context_str(usercon);
Both context_range_set() and context_str() could fail on an allocation
failure, returning 1 or NULL respectively.