linux/security/selinux/ss
Ondrej Mosnacek 9ad6e9cb39 selinux: fix race between old and new sidtab
Since commit 1b8b31a2e6 ("selinux: convert policy read-write lock to
RCU"), there is a small window during policy load where the new policy
pointer has already been installed, but some threads may still be
holding the old policy pointer in their read-side RCU critical sections.
This means that there may be conflicting attempts to add a new SID entry
to both tables via sidtab_context_to_sid().

See also (and the rest of the thread):
https://lore.kernel.org/selinux/CAFqZXNvfux46_f8gnvVvRYMKoes24nwm2n3sPbMjrB8vKTW00g@mail.gmail.com/

Fix this by installing the new policy pointer under the old sidtab's
spinlock along with marking the old sidtab as "frozen". Then, if an
attempt to add new entry to a "frozen" sidtab is detected, make
sidtab_context_to_sid() return -ESTALE to indicate that a new policy
has been installed and that the caller will have to abort the policy
transaction and try again after re-taking the policy pointer (which is
guaranteed to be a newer policy). This requires adding a retry-on-ESTALE
logic to all callers of sidtab_context_to_sid(), but fortunately these
are easy to determine and aren't that many.

This seems to be the simplest solution for this problem, even if it
looks somewhat ugly. Note that other places in the kernel (e.g.
do_mknodat() in fs/namei.c) use similar stale-retry patterns, so I think
it's reasonable.

Cc: stable@vger.kernel.org
Fixes: 1b8b31a2e6 ("selinux: convert policy read-write lock to RCU")
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
Signed-off-by: Paul Moore <paul@paul-moore.com>
2021-04-07 20:42:56 -04:00
..
avtab.c selinux: fix cond_list corruption when changing booleans 2021-04-02 11:46:55 -04:00
avtab.h selinux: fix cond_list corruption when changing booleans 2021-04-02 11:46:55 -04:00
conditional.c selinux: fix cond_list corruption when changing booleans 2021-04-02 11:46:55 -04:00
conditional.h selinux: refactor changing booleans 2020-08-17 21:00:33 -04:00
constraint.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
context.c selinux: hash context structure directly 2020-04-17 16:04:34 -04:00
context.h selinux: move context hashing under sidtab 2020-04-17 16:04:38 -04:00
ebitmap.c selinux: mark some global variables __ro_after_init 2021-01-12 10:08:55 -05:00
ebitmap.h selinux: hash context structure directly 2020-04-17 16:04:34 -04:00
hashtab.c selinux: mark some global variables __ro_after_init 2021-01-12 10:08:55 -05:00
hashtab.h selinux: refactor changing booleans 2020-08-17 21:00:33 -04:00
mls_types.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
mls.c treewide: Use fallthrough pseudo-keyword 2020-08-23 17:36:59 -05:00
mls.h selinux: hash context structure directly 2020-04-17 16:04:34 -04:00
policydb.c selinux: prepare for inlining of hashtab functions 2020-07-09 19:05:36 -04:00
policydb.h selinux: prepare for inlining of hashtab functions 2020-07-09 19:05:36 -04:00
services.c selinux: fix race between old and new sidtab 2021-04-07 20:42:56 -04:00
services.h selinux: convert policy read-write lock to RCU 2020-08-25 08:34:47 -04:00
sidtab.c selinux: fix race between old and new sidtab 2021-04-07 20:42:56 -04:00
sidtab.h selinux: fix race between old and new sidtab 2021-04-07 20:42:56 -04:00
symtab.c selinux: prepare for inlining of hashtab functions 2020-07-09 19:05:36 -04:00
symtab.h selinux: specialize symtab insert and search functions 2020-07-08 20:21:43 -04:00