kernel_optimize_test/security/selinux/include
Ondrej Mosnacek 19c9967e49 selinux: fix variable scope issue in live sidtab conversion
commit 6406887a12ee5dcdaffff1a8508d91113d545559 upstream.

Commit 02a52c5c8c ("selinux: move policy commit after updating
selinuxfs") moved the selinux_policy_commit() call out of
security_load_policy() into sel_write_load(), which caused a subtle yet
rather serious bug.

The problem is that security_load_policy() passes a reference to the
convert_params local variable to sidtab_convert(), which stores it in
the sidtab, where it may be accessed until the policy is swapped over
and RCU synchronized. Before 02a52c5c8c, selinux_policy_commit() was
called directly from security_load_policy(), so the convert_params
pointer remained valid all the way until the old sidtab was destroyed,
but now that's no longer the case and calls to sidtab_context_to_sid()
on the old sidtab after security_load_policy() returns may cause invalid
memory accesses.

This can be easily triggered using the stress test from commit
ee1a84fdfe ("selinux: overhaul sidtab to fix bug and improve
performance"):
```
function rand_cat() {
	echo $(( $RANDOM % 1024 ))
}

function do_work() {
	while true; do
		echo -n "system_u:system_r:kernel_t:s0:c$(rand_cat),c$(rand_cat)" \
			>/sys/fs/selinux/context 2>/dev/null || true
	done
}

do_work >/dev/null &
do_work >/dev/null &
do_work >/dev/null &

while load_policy; do echo -n .; sleep 0.1; done

kill %1
kill %2
kill %3
```

Fix this by allocating the temporary sidtab convert structures
dynamically and passing them among the
selinux_policy_{load,cancel,commit} functions.

Fixes: 02a52c5c8c ("selinux: move policy commit after updating selinuxfs")
Cc: stable@vger.kernel.org
Tested-by: Tyler Hicks <tyhicks@linux.microsoft.com>
Reviewed-by: Tyler Hicks <tyhicks@linux.microsoft.com>
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
[PM: merge fuzz in security.h and services.c]
Signed-off-by: Paul Moore <paul@paul-moore.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2021-03-30 14:31:53 +02:00
..
audit.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 500 2019-06-19 17:09:55 +02:00
avc_ss.h selinux: wrap AVC state 2018-03-20 16:58:17 -04:00
avc.h selinux: fall back to ref-walk if audit is required 2019-12-09 18:37:47 -05:00
classmap.h capabilities: Introduce CAP_CHECKPOINT_RESTORE 2020-07-19 20:14:42 +02:00
conditional.h selinux: move policy commit after updating selinuxfs 2020-08-17 20:50:22 -04:00
ibpkey.h selinux: move ibpkeys code under CONFIG_SECURITY_INFINIBAND. 2020-01-10 11:56:37 -05:00
initial_sid_to_string.h selinux: remove unused initial SIDs and improve handling 2020-02-27 19:34:24 -05:00
netif.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 500 2019-06-19 17:09:55 +02:00
netlabel.h selinux: netlabel: Remove unused inline function 2020-05-12 20:16:33 -04:00
netnode.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 295 2019-06-05 17:36:38 +02:00
netport.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 295 2019-06-05 17:36:38 +02:00
objsec.h selinux: randomize layout of key structures 2019-12-18 21:26:06 -05:00
policycap_names.h scripts/selinux,selinux: update mdp to enable policy capabilities 2020-08-17 20:42:00 -04:00
policycap.h scripts/selinux,selinux: update mdp to enable policy capabilities 2020-08-17 20:42:00 -04:00
security.h selinux: fix variable scope issue in live sidtab conversion 2021-03-30 14:31:53 +02:00
xfrm.h security: Remove rtnl_lock() in selinux_xfrm_notify_policyload() 2018-03-29 13:47:53 -04:00