0c3049ec03a8950d5c34755673a69ea97fb1f273
When kernel is compiled with CONFIG_DEBUG_ATOMIC_SLEEP enabled, it prints the following splat in dmesg during post boot: [ 6.739169] init: Opening SELinux policy [ 6.751520] init: Loading SELinux policy [ 6.894684] SELinux: policy capability network_peer_controls=1 [ 6.894688] SELinux: policy capability open_perms=1 [ 6.894690] SELinux: policy capability extended_socket_class=1 [ 6.894691] SELinux: policy capability always_check_network=0 [ 6.894693] SELinux: policy capability cgroup_seclabel=0 [ 6.894695] SELinux: policy capability nnp_nosuid_transition=1 [ 7.214323] selinux: SELinux: Loaded file context from: [ 7.214332] selinux: /system/etc/selinux/plat_file_contexts [ 7.214339] selinux: /system_ext/etc/selinux/system_ext_file_contexts [ 7.214345] selinux: /product/etc/selinux/product_file_contexts [ 7.214350] selinux: /vendor/etc/selinux/vendor_file_contexts [ 7.214356] selinux: /odm/etc/selinux/odm_file_contexts [ 7.216398] KernelSU: /system/bin/init argc: 2 [ 7.216401] KernelSU: /system/bin/init first arg: second_stage [ 7.216403] KernelSU: /system/bin/init second_stage executed [ 7.216506] BUG: sleeping function called from invalid context at security/selinux/ss/hashtab.c:47 [ 7.216512] in_atomic(): 0, irqs_disabled(): 0, non_block: 0, pid: 1, name: init [ 7.216516] preempt_count: 0, expected: 0 [ 7.216518] RCU nest depth: 1, expected: 0 [ 7.216524] CPU: 6 PID: 1 Comm: init Not tainted 5.4.289-Scarlet-v2.0-beta3 #1 [ 7.216526] Hardware name: redwood based Qualcomm Technologies, Inc. SM7325 (DT) [ 7.216528] Call trace: [ 7.216536] dump_backtrace+0x0/0x210 [ 7.216539] show_stack+0x14/0x20 [ 7.216544] dump_stack+0x9c/0xec [ 7.216548] __might_resched+0x1f0/0x210 [ 7.216552] hashtab_insert+0x38/0x230 [ 7.216557] add_type+0xd4/0x2e0 [ 7.216559] ksu_type+0x24/0x60 [ 7.216562] apply_kernelsu_rules+0xa8/0x650 [ 7.216565] ksu_handle_execveat_ksud+0x2a8/0x460 [ 7.216568] ksu_handle_execveat+0x2c/0x60 [ 7.216571] __arm64_sys_execve+0xe8/0xf0 [ 7.216574] el0_svc_common+0xf4/0x1a0 [ 7.216577] do_el0_svc+0x2c/0x40 [ 7.216579] el0_sync_handler+0x18c/0x200 [ 7.216582] el0_sync+0x140/0x180 This is because apply_kernelsu_rules() uses rcu_read_lock() to protect SELinux policy modifications. However, cond_resched() from hashtab_insert() at security/selinux/ss/hashtab.c is internally called and it sleeps which is illegal under an RCU read-side critical section. While replacing it with a spinlock would suppress the warning, this is fundamentally incorrect because sleeping is illegal while holding a spinlock and spinlock would turn off preemption which isn't an ideal solution since it intentionally turns off rescheduling, and can lead to deadlocks. Instead, replace the RCU lock with a mutex lock. Mutex lock allows sleeping when necessary, which is appropriate here because apply_kernelsu_rules() runs in process context, not in atomic or interrupt context. As apply_kernelsu_rules() is invoked only once during post boot (SYSTEM_RUNNING), the mutex lock does not introduce any major runtime performance regression and provides correct synchronization. Fixes: tiann#2637 Signed-off-by: Tashfin Shakeer Rhythm <tashfinshakeerrhythm@gmail.com>
Description
Languages
Kotlin
67.1%
C
20%
Rust
11.1%
Shell
0.9%
Makefile
0.4%
Other
0.4%