| From bc0dc0d86f86265db7b07f1b4f3a8766efec454d Mon Sep 17 00:00:00 2001 |
| From: Ondrej Mosnacek <omosnace@redhat.com> |
| Date: Thu, 3 Oct 2019 15:59:22 +0200 |
| Subject: [PATCH] selinux: fix context string corruption in convert_context() |
| |
| commit 2a5243937c700ffe6a28e6557a4562a9ab0a17a4 upstream. |
| |
| string_to_context_struct() may garble the context string, so we need to |
| copy back the contents again from the old context struct to avoid |
| storing the corrupted context. |
| |
| Since string_to_context_struct() tokenizes (and therefore truncates) the |
| context string and we are later potentially copying it with kstrdup(), |
| this may eventually cause pieces of uninitialized kernel memory to be |
| disclosed to userspace (when copying to userspace based on the stored |
| length and not the null character). |
| |
| How to reproduce on Fedora and similar: |
| # dnf install -y memcached |
| # systemctl start memcached |
| # semodule -d memcached |
| # load_policy |
| # load_policy |
| # systemctl stop memcached |
| # ausearch -m AVC |
| type=AVC msg=audit(1570090572.648:313): avc: denied { signal } for pid=1 comm="systemd" scontext=system_u:system_r:init_t:s0 tcontext=system_u:object_r:unlabeled_t:s0 tclass=process permissive=0 trawcon=73797374656D5F75007400000000000070BE6E847296FFFF726F6D000096FFFF76 |
| |
| Cc: stable@vger.kernel.org |
| Reported-by: Milos Malik <mmalik@redhat.com> |
| Fixes: ee1a84fdfeed ("selinux: overhaul sidtab to fix bug and improve performance") |
| Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com> |
| Acked-by: Stephen Smalley <sds@tycho.nsa.gov> |
| Signed-off-by: Paul Moore <paul@paul-moore.com> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c |
| index d3f5568c1f60..3585ef8c4836 100644 |
| --- a/security/selinux/ss/services.c |
| +++ b/security/selinux/ss/services.c |
| @@ -1947,7 +1947,14 @@ static int convert_context(struct context *oldc, struct context *newc, void *p) |
| rc = string_to_context_struct(args->newp, NULL, s, |
| newc, SECSID_NULL); |
| if (rc == -EINVAL) { |
| - /* Retain string representation for later mapping. */ |
| + /* |
| + * Retain string representation for later mapping. |
| + * |
| + * IMPORTANT: We need to copy the contents of oldc->str |
| + * back into s again because string_to_context_struct() |
| + * may have garbled it. |
| + */ |
| + memcpy(s, oldc->str, oldc->len); |
| context_init(newc); |
| newc->str = s; |
| newc->len = oldc->len; |
| -- |
| 2.7.4 |
| |