Run throne_tracker() in kthread instead of blocking the caller.
Prevents full lockup during installation and removing the manager.
By default, first run remains synchronous for compatibility purposes
(FDE, FBEv1, FBEv2)
Features:
- looks and waits for manager UID in /data/system/packages.list
- run track_throne() in a kthread after the first synchronous run
- prevent duplicate thread creation with a single-instance check
- spinlock-on-d_lock based polling adressing possible race conditions.
Race conditions adressed
- single instance kthread lock, smp_mb()
- track_throne_function, packages.list, spinlock-on-d_lock based polling
- is_manager_apk, apk, spinlock-on-d_lock based polling
This is a squash of:
https://github.com/tiann/KernelSU/pull/2632
Original skeleton based on:
`kernelsu: move throne_tracker() to kthread`
`kernelsu: check locking before accessing files and dirs during searching manager`
`kernelsu: look for manager UID in /data/system/packages.list, not /data/system/packages.list.tmp`
0b05e927...8783badd
Co-Authored-By: backslashxx <118538522+backslashxx@users.noreply.github.com>
Co-Authored-By: Yaroslav Zviezda <10716792+acroreiser@users.noreply.github.com>
Signed-off-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
`ksu handles devpts with selinux lsm hook` - aviraxp
- no, not yet, but yes we can, thats a good idea.
This change tries to do that, so instead of hooking pts_unix98_lookup or
devpts_get_priv, we just watch security_inode_permission, if its devpts,
pass it along to the original handler.
EDIT: define devpts super magic if its undefined
- yeah I aint gonna include a conditional include of a header just for this
- while we can just fully remove the macro and inline, readability loss is bad
Co-authored-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
Since KernelSU Manager can now be built for 32-bit, theres this problematic
setup where userspace is 32-bit (armeabi-v7a) and kernel is 64bit (aarch64).
On 64-bit kernels with CONFIG_COMPAT=y, 32-bit userspace passes 32-bit pointers.
These values are interpreted as 64-bit pointers without proper casting and that
results in invalid or near-null memory access.
This patch adds proper compat-mode handling with the ff changes:
- introduce a dedicated struct (`sepol_compat_data`) using u32 fields
- use `compat_ptr()` to safely convert 32-bit user pointers to kernel pointers
- adding a runtime `ksu_is_compat` flag to dynamically select between struct layouts
This prevents a near-null pointer dereference when handling SELinux
policy updates from 32-bit ksud in a 64-bit kernel.
Truth table:
kernel 32 + ksud 32, struct is u32, no compat_ptr
kernel 64 + ksud 32, struct is u32, yes compat_ptr
kernel 64 + ksud 64, struct is u64, no compat_ptr
Preprocessor check
64BIT=y COMPAT=y: define both structs, select dynamically
64BIT=y COMPAT=n: struct u64
64BIT=n: struct u32
Co-authored-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
Signed-off-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
This migrates ksud execution decision-making to bprm_check_security.
This requires passing proper argv and envp to a modified _ksud handler
aptly named 'ksu_handle_bprm_ksud'.
Introduces:
int ksu_handle_bprm_ksud(const char *filename, const char *argv1,
const char *envp, size_t envp_len)
which is adapted from:
int ksu_handle_execveat_ksud(int *fd, struct filename **filename_ptr,
struct user_arg_ptr *argv,
struct user_arg_ptr *envp,
int *flags)
ksu_handle_bprm_ksud handles all the decision making, it decides when it is
time to apply_kernelsu_rules depending if it sees "second_stage".
For LSM hook, turns out we can pull out argv and envp from mm_struct.
The code in here explains itself on how to do it.
whole blob exists on arg_start to arg_end, so we just pull it out and grab next
array after the first null terminator.
as for envp, we pass the pointer then hunt for it when needed
My reasoning on adding a fallback on usercopy is that on some devices a fault
happens, and it copies garbled data. On my creation of this, I actually had to lock
that _nofault copy on a spinlock as a way to mimic preempt_disable/enable without
actually doing it. As per user reports, no failed _nofault copies anyway but we
have-to-have a fallback for resilience.
References:
- old version1 6efcd8193e
- old version2 37d5938e66
- bad usercopy #21
This now provides a small helper function, ksu_copy_from_user_retry, which explains
itself. First we attempt a _nofault copy, if that fails, we try plain.
With that, It also provides an inlined copy_from_user_nofault for < 5.8.
While using strncpy_from_user_nofault was considered, this wont do, this will
only copy up to the first \0.
devlog:
16e5dce9e7...16c1f5f52128642e60d7...728de0c571
References:
https://elixir.bootlin.com/linux/v4.14.1/source/include/linux/mm_types.h#L429https://elixir.bootlin.com/linux/v4.14.1/source/include/linux/lsm_hooks.h
Stale: https://github.com/tiann/KernelSU/pull/2653
Signed-off-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
Some kernels (e.g. 5.4 with backports) include proc_ops despite being
older than 5.6.0. Replace hardcoded version check with runtime header
detection to handle these cases.
- Check for "struct proc_ops" in include/linux/proc_fs.h
- Use KSU_COMPAT_HAS_PROC_OPS macro for conditional compilation
- Fixes build failures on kernels with backported proc_ops
Signed-off-by: JackAltman
Prioritize retrieving the application UID from /data/user_de. If this fails, fall back to retrieving it from packages.list.
Fix unstable application UID acquisition
Signed-off-by: ShirkNeko <109797057+ShirkNeko@users.noreply.github.com>
* On newer kernel for some reason -Wno-strict-prototypes still does not fix the errors or warnings.
* To fix it, we just need to add void type.
Signed-off-by: rsuntk <rsuntk@yukiprjkt.my.id>
* kernel: define ksu_core_exit() for <4.1 devices without LSM hooks
Ensure ksu_core_exit() is defined even if CONFIG_KSU_LSM_SECURITY_HOOKS
is disabled, which is mostly relevant for kernels 4.1 and older, preventing
build failures due to missing exit function.
Signed-off-by: Prslc <prslc113@gmail.com>
* kernel: consolidate ksu_core_exit() definition
Move ksu_core_exit() out of the CONFIG_KSU_LSM_SECURITY_HOOKS
conditional branches to remove redundant empty definitions
and ensure the exit function is always available.
Signed-off-by: Prslc <prslc113@gmail.com>
---------
Signed-off-by: Prslc <prslc113@gmail.com>
The 'strip' function is redundant when checking Kconfig variables, as
values from CONFIG options (like CONFIG_KSU_TRACEPOINT_HOOK) are already
trimmed and do not contain leading/trailing whitespace.
Simplify the condition for better readability and maintainability:
- Remove unnecessary $(strip ...)
- Add consistent spacing around the comma
This change aligns with kernel Makefile conventions and improves code clarity
without altering behavior.
Signed-off-by: dabao1955 <dabao1955@163.com>
* The coding format is too messy, reformat to improve readability
and get closer to Linux kernel coding style.
* While at it, update .clang-format file to linux-mainline state.
* path_umount pretty much guaranteed to work as is, so it would not need
much logging.
Unlike sys_umount which is an alternative to path_umount for older kernel, so, sys_umount need constant logging.
Signed-off-by: rsuntk <rsuntk@yukiprjkt.my.id>
upstream used IS_ERR to check for negative return and that is int,
so correct it.
This is one headache for old compilers.
Signed-off-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
* Following the advice that was given by member in rksu group, by replacing ALL to untrusted_app.
$ /system/bin/stat /proc/1
Result:
08-15 14:57:54.370 20062 20062 W stat : type=1400 audit(0.0:9564): avc: denied { getattr } for path="/proc/1" dev="proc" ino=12308 scontext=u:r:untrusted_app_27:s0:c27,c258,c512,c768 tcontext=u:r:init:s0 tclass=dir permissive=0 app=com.termux
(issue
438bd5fd6d (commitcomment-163785768))
Test: Checker pass.
* Any issue? Let me know.
Tested-by: rsuntk <rsuntk@yukiprjkt.my.id>
Signed-off-by: rsuntk <rsuntk@yukiprjkt.my.id>
* Maybe there's much better solution than this.
This reverts commit 438bd5fd6dac74ba63ef627124f0d2f552b1cb31.
Signed-off-by: rsuntk <rsuntk@yukiprjkt.my.id>
* Much cleaner code, although setenforce is not used anymore
* Guard is_ksu_transition only for 4.19 and under.
Signed-off-by: rsuntk <rsuntk@yukiprjkt.my.id>
Tracepoint is a predefined hook point in the kernel, compared to Kprobe,
it is more stable and has lower performance overhead, although compatibility
is relatively poor, it is still worth trying
By the way, we have also included the config definitions related to hook types
in Kconfig, to enhance cleanliness
Improve and merge types that do not require hooks
Introducing the hook type prctl
These patches is based on backslashxx/KernelSU#5
Co-authored-by: Cloud_Yun <1770669041@qq.com>
Co-authored-by: Prslc <prslc113@gmail.com>
Co-authored-by: ShirkNeko <109797057+ShirkNeko@users.noreply.github.com>
Signed-off-by: ShirkNeko <109797057+ShirkNeko@users.noreply.github.com>
Isolated processes can be directly forked from zygote, but current code doesn't handle it well. Fix it by unmounting unconditionally if isolated process is forked from zygote.
Signed-off-by: rsuntk <rsuntk@yukiprjkt.my.id>
get_policydb() uses rcu_dereference() to read pointers to selinux_state.policy.
But in the SELinux implementation, these pointers are assigned once during
initialization and never changed with rcu_assign_pointer(), rendering the
rcu_dereference() call in get_policydb() completely useless. This just adds
unwanted overhead and implies concurrency pattern that is not even present in
the kernel.
Therefore, read the pointers directly since it's safe.
* selinux_state.ss needs more context.
Signed-off-by: Tashfin Shakeer Rhythm <tashfinshakeerrhythm@gmail.com>
Currently, handle_sepolicy() holds an RCU read lock across the entire
function including calls to strncpy_from_user() which can sleep, which
is illegal in RCU semantics.
This triggers the following warning when the kernel is compiled with
CONFIG_DEBUG_ATOMIC_SLEEP enabled:
[ 8.526345] BUG: sleeping function called from invalid context at lib/strncpy_from_user.c:40
[ 8.526349] in_atomic(): 0, irqs_disabled(): 0, non_block: 0, pid: 683, name: ksud
[ 8.526351] preempt_count: 0, expected: 0
[ 8.526352] RCU nest depth: 1, expected: 0
[ 8.526354] 1 lock held by ksud/683:
[ 8.526355] #0: ffffffe013e1b970 (rcu_read_lock){....}, at: handle_sepolicy+0xe4/0xaa0
[ 8.526365] CPU: 6 PID: 683 Comm: ksud Tainted: G W 5.4.289-Scarlet-v2.2-beta2 #1
[ 8.526366] Hardware name: redwood based Qualcomm Technologies, Inc. SM7325 (DT)
[ 8.526367] Call trace:
[ 8.526371] dump_backtrace+0x0/0x1c0
[ 8.526374] dump_stack+0x90/0xcc
[ 8.526376] __might_sleep+0x1a0/0x200
[ 8.526378] __might_fault+0x28/0x40
[ 8.526381] strncpy_from_user+0xac/0x300
[ 8.526383] handle_sepolicy+0x588/0xaa0
[ 8.526385] ksu_handle_prctl+0x368/0xd60
[ 8.526386] ksu_task_prctl+0xc/0x20
[ 8.526389] security_task_prctl+0x5c/0xa0
[ 8.526391] __arm64_sys_prctl+0x58/0x7e0
[ 8.526393] do_el0_svc+0x68/0x120
[ 8.526394] el0_sync_handler+0x11c/0x1c0
[ 8.526395] el0_sync+0x140/0x180
To fix this, replace the rcu_read_lock() with the `ksu_rules` mutex_lock()
introduced with commit 9014c663d1eb4 ("kernel: selinux: rules: Fix illegal RCU
lock usage in apply_kernelsu_rules()") which allows sleeping.
This mutex_lock() ensures mutual exclusion between threads invoking dynamic
policy modifications via handle_sepolicy() and those applying KernelSU rules
via apply_kernelsu_rules(), both of which access the policydb structure through
get_policydb().
Signed-off-by: Tashfin Shakeer Rhythm <tashfinshakeerrhythm@gmail.com>
* We got a splat related to atomic sleep.
* The trace is from strncpy_from_user and might_fault
Same case:
e47115e009
Signed-off-by: rsuntk <rsuntk@yukiprjkt.my.id>