reorder ksu_handle_prctl checks a bit to allow non-manager to use CMD 15
this allows us to piggyback a small su to KernelSU's permission system after
disabling kernel sucompat
from:
Relax prctl perm check
- 95125c32f9
Allow prctl only for root or manager or su binary
- fa7af67d94
Refine prctl access check, allow /product/bin/su
- dd466dc1b6
Refine prctl check a little bit more
- e7c5b24efa
Signed-off-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
* ksud: Address pagefault in ksu_handle_execveat_ksud
As pointed out by @backslashxx, when strncpy pagefaults, it causes
the first_arg to be completely NULL in some systems. This causes
second_stage initialization to fail hence causing SU to be
non-functional.
This patch copies ksu_strncpy_from_user_retry from @backslashxx's
commit:
e2fe25e485
This adds a fallback to perform a normal strncpy_from_user when nofault
fails which allows us to get the first_arg in such cases.
Co-authored-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
Signed-off-by: Edrick Sinsuan <evcsinsuan@gmail.com>
* Revert "ksud: Add second_stage init variant (#653)"
This reverts commit c6b60a24e8.
---------
Signed-off-by: Edrick Sinsuan <evcsinsuan@gmail.com>
Co-authored-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
There are some ROMs based on AOSP that calls on second stage init
with argc: 2 but with first_arg: "". This causes KSU to not work
properly on those systems.
Signed-off-by: Edrick Sinsuan <evcsinsuan@gmail.com>
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: https://github.com/tiann/KernelSU/issues/2637
Signed-off-by: Tashfin Shakeer Rhythm <tashfinshakeerrhythm@gmail.com>
This reverts commit a37f398cc7.
- this is a very flawed logic for when we try to build with release tags or specific commit hashes instead of latest commit, the online logic will always append latest version instead of the actual version of code (i.e release tags or commit hashes)
throne_tracker, cross-fs avoidance:
f_inode is f_path.dentry->d_inode
so file->f_inode->i_sb->s_magic is file->f_path.dentry->d_inode->i_sb->s_magic
Signed-off-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
strscpy requires 4.3
strscpy on this usage can be replaced with strncpy + null term.
kernel gives us an option though.
strlcpy is fast af, hotrod fast. It’s just memcpy + null term, so lets go with that.
it got dropped in 6.8 due to risk concerns, so for those, lets use og strscpy.
Signed-off-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
this probably wont happen, but just to make sure, we dont block the rename now
so there is really a chance that this does not exist yet when the kthread runs.
Signed-off-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
context: this is known by many as `selinux hook`, `4.9 hook`
add is_ksu_transition check which allows ksud execution under nosuid.
it also eases up integration on 3.X kernels that does not have check_nnp_nosuid.
Usage:
if (is_ksu_transition(old_tsec, new_tsec))
return 0;
on either check_nnp_nosuid or selinux_bprm_set_creds (after execve sid reset)
reference: dfe003c9fd
taken from:
`allow init exec ksud under nosuid`
- 3df9df42a6
- https://github.com/tiann/KernelSU/pull/166#issue-1565872173
250611-edit:
- remove ksu_execveat_hook entry check
- turns out some devices needs the transition for multiple times
Reported-by: edenadversary <143865198+edenadversary@users.noreply.github.com>
Signed-off-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
Skip directories that does NOT have the same magic as /data/app.
This is to avoid scanning incfs and any other stacked filesystems.
While this is way dumber, it's way cheaper.
no kern_path(), no missable path_put(), no ref handling.
This supercedes
`throne_tracker: avoid cross fs access
(https://github.com/tiann/KernelSU/pull/2626)`
- upstream
0b6998b474
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.
Signed-off-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
Co-authored-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
Safe Ultra-Legacy changes that don't deserve their own commit
d_is_reg requires 4.0
- e36cb0b89c
IS_REG is still there on 6.15 so I do NOT see any issues forcing it for all.
strscpy requires 4.3
strscpy on this usage can be replaced with strncpy + null term.
kernel gives us an option though.
strlcpy is fast af, hotrod fast. It’s just memcpy + null term, so lets go with that.
it got dropped in 6.8 due to risk concerns, so for those, lets use og strscpy.
ref: openwrt/packages #26453
Signed-off-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
Runs throne_tracker() in kthread instead of blocking the caller.
Prevents full lockup during installation and removing the manager.
This also looks for manager UID in /data/system/packages.list, not
/data/system/packages.list.tmp
Nice additional side effect is a faster booting.
Signed-off-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
Co-Authored-By: backslashxx <118538522+backslashxx@users.noreply.github.com>
On plain ARMv8.0 devices (A53,A57,A73), strncpy_from_user_nofault() sometimes
fails to copy `filename_user` string correctly. This breaks su ofc, breaking
some apps like Termux (Play Store ver), ZArchiver and Root Explorer.
This does NOT seem to affect newer ARMv8.2+ CPUs (A75/A76 and newer)
My speculation? ARMv8.0 has weak speculation :)
here we replace `strncpy_from_user_nofault()` with another routine:
- access_ok() to validate the pointer
- strncpy_from_user() to copy and validate string
- manual null-termination just in case, as strncpy_from_user_nofault also does it
- remove that memset, seems useless as it is an strncpy, not strncat
Kind of mimicking _nofault, but yes with this one we allow pagefaults.
Tested on:
- ARMv8.0 A73.a53, A57.a53, A53.a53
- ARMv8.2 A76.a55
Tested-by: iDead XD <rafifirdaus12bb@gmail.com>
Signed-off-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
we move the folder out of system if it exists in real filesystem and it
is not a symlink.
this is already supported on init_event.rs so only handle_partition
logic was needed to make it happen
since KernelSU is using overlayfs, we need to move these out.
Signed-off-by: backslashxx
<118538522+backslashxx@users.noreply.github.com>
---------
Signed-off-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
disabling this removes the need for LSM_HOOK_INIT, security_add_hooks and such,.
furthermore, this will also allow easier integration on pre-4.1 kernels.
Expose this and make it a configurable option.
Signed-off-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
When the manager UID disappears from packages.list, we correctly
invalidate it — good. But, in the very next breath, we start scanning
/data/app hoping to find it again?
This event is just unnecessary I/O, exactly when we should be doing less.
Apparently this causes hangups and stuckups which is REALLY noticeable
on Ultra-Legacy devices.
Skip the scan — we’ll catch the reinstall next time packages.list updates.
Signed-off-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
Signed-off-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
kernel: sucompat: sucompat toggle support for non-kp
This is done like how vfs_read_hook, input_hook and execve_hook is disabled.
While this is not exactly the same thing, this CAN achieve the same results.
The complete disabling of all KernelSU hooks.
While this is likely unneeded, It keeps feature parity to non-kprobe builds.
adapted from upstream:
kernel: Allow to re-enable sucompat - 4593ae81c7
Rejected: https://github.com/tiann/KernelSU/pull/2506
Signed-off-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
kernel: sucompat: fix compile issue on kprobe builds, unused variable
When the manager is already running, if other programs / kernel toggle
the sucompat enable status,
The manager "Disable SU Compat" toggle button can not work, kmesg print
"cmd enable su but no need to change."
I think we should still return reply_ok when the syscall value is
consistent with the kernel, which would fix the issue.