Skip to content

Commit 61d2d63

Browse files
committed
Merge remote-tracking branch 'upstream/main'
2 parents f2cec9b + 5f9cada commit 61d2d63

266 files changed

Lines changed: 23704 additions & 8395 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
.idea
22
.vscode
33
CLAUDE.md
4-
AGENTS.md
4+
AGENTS.md
5+
.DS_Store

docs/README_PT-BR.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,10 @@ O KernelSU oferece suporte oficial a dispositivos Android GKI 2.0 (kernel 5.10+)
2424

2525
Com isso, WSA, ChromeOS e Android baseado em contêiner são todos suportados.
2626

27-
Atualmente, apenas as arquiteturas `arm64-v8a` e `x86_64` são compatíveis.
27+
Atualmente, as arquiteturas `arm64-v8a` e `x86_64` são suportadas.
28+
29+
> [!CAUTION]
30+
> Versões recentes do kernel implementaram uma mudança que quebra a compatibilidade, fazendo com que o KernelSU falhe e potencialmente cause um kernel panic no `x86_64`! Verifique o site para mais informações!
2831
2932
## Uso
3033

kernel/.clang-format

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ BreakConstructorInitializersBeforeComma: false
5252
#BreakConstructorInitializers: BeforeComma # Unknown to clang-format-4.0
5353
BreakAfterJavaFieldAnnotations: false
5454
BreakStringLiterals: false
55-
ColumnLimit: 80
55+
ColumnLimit: 120
5656
CommentPragmas: '^ IWYU pragma:'
5757
#CompactNamespaces: false # Unknown to clang-format-4.0
5858
ConstructorInitializerAllOnOneLineOrOnePerLine: false

kernel/.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ compile_commands.json
1212
*.mod.c
1313
*.symvers*
1414
*.order
15-
.*.ko.cmd
15+
.*.cmd
1616
.tmp_versions/
1717
libs/
1818
obj/

kernel/Kbuild

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ kernelsu-objs += app_profile.o
44
kernelsu-objs += apk_sign.o
55
kernelsu-objs += sucompat.o
66
kernelsu-objs += syscall_hook_manager.o
7+
kernelsu-objs += tp_marker.o
78
kernelsu-objs += throne_tracker.o
89
kernelsu-objs += pkg_observer.o
910
kernelsu-objs += setuid_hook.o
@@ -14,7 +15,13 @@ kernelsu-objs += feature.o
1415
kernelsu-objs += ksud.o
1516
kernelsu-objs += seccomp_cache.o
1617
kernelsu-objs += file_wrapper.o
17-
kernelsu-objs += util.o
18+
ifeq ($(CONFIG_ARM64),y)
19+
kernelsu-objs += hook/arm64/patch_memory.o
20+
kernelsu-objs += hook/arm64/syscall_hook.o
21+
else ifeq ($(CONFIG_X86_64),y)
22+
kernelsu-objs += hook/x86_64/patch_memory.o
23+
kernelsu-objs += hook/x86_64/syscall_hook.o
24+
endif
1825

1926
kernelsu-objs += selinux/selinux.o
2027
kernelsu-objs += selinux/sepolicy.o
@@ -60,6 +67,10 @@ $(warning "KSU_GIT_VERSION not defined! It is better to make KernelSU a git repo
6067
ccflags-y += -DKSU_VERSION=16
6168
endif
6269

70+
KSU_NEW_DCACHE_FLUSH := $(shell grep -q __flush_dcache_area $(srctree)/arch/arm64/include/asm/cacheflush.h ; echo $$?)
71+
$(info -- KSU_NEW_DCACHE_FLUSH: $(KSU_NEW_DCACHE_FLUSH))
72+
73+
6374
ifndef KSU_EXPECTED_SIZE
6475
KSU_EXPECTED_SIZE := 0x033b
6576
endif
@@ -79,6 +90,18 @@ $(info -- KernelSU Manager signature hash: $(KSU_EXPECTED_HASH))
7990
ccflags-y += -DEXPECTED_SIZE=$(KSU_EXPECTED_SIZE)
8091
ccflags-y += -DEXPECTED_HASH=\"$(KSU_EXPECTED_HASH)\"
8192

93+
ifdef KSU_EXPECTED_SIZE2
94+
ifndef KSU_EXPECTED_HASH2
95+
$(error KSU_EXPECTED_HASH2 must be set when KSU_EXPECTED_SIZE2 is set)
96+
endif
97+
ccflags-y += -DEXPECTED_SIZE2=$(KSU_EXPECTED_SIZE2)
98+
ccflags-y += -DEXPECTED_HASH2=\"$(KSU_EXPECTED_HASH2)\"
99+
$(info -- KernelSU Manager signature size2: $(KSU_EXPECTED_SIZE2))
100+
$(info -- KernelSU Manager signature hash2: $(KSU_EXPECTED_HASH2))
101+
endif
102+
103+
ccflags-y += -DKSU_NEW_DCACHE_FLUSH=$(KSU_NEW_DCACHE_FLUSH)
104+
82105
ccflags-y += -Wno-strict-prototypes -Wno-int-conversion -Wno-gcc-compat -Wno-missing-prototypes
83106
ccflags-y += -Wno-declaration-after-statement -Wno-unused-function
84107

kernel/Kconfig

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@ menu "KernelSU"
22

33
config KSU
44
tristate "KernelSU function support"
5-
depends on KPROBES
5+
depends on KPROBES && EXT4_FS
66
default y
77
help
88
Enable kernel-level root privileges on Android System.
99
Requires CONFIG_KPROBES for kernel hooking support.
10+
Requires CONFIG_EXT4_FS for `ext4_unregister_sysfs`.
1011
To compile as a module, choose M here: the
1112
module will be called kernelsu.
1213

kernel/allowlist.c

Lines changed: 34 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,7 @@ static DEFINE_MUTEX(allowlist_mutex);
3535
static struct root_profile default_root_profile;
3636
static struct non_root_profile default_non_root_profile;
3737

38-
static int allow_list_arr[PAGE_SIZE / sizeof(int)] __read_mostly
39-
__aligned(PAGE_SIZE);
38+
static int allow_list_arr[PAGE_SIZE / sizeof(int)] __read_mostly __aligned(PAGE_SIZE);
4039
static int allow_list_pointer __read_mostly = 0;
4140

4241
static void remove_uid_from_arr(uid_t uid)
@@ -46,8 +45,7 @@ static void remove_uid_from_arr(uid_t uid)
4645
if (allow_list_arr[i] == uid) {
4746
int remaining = allow_list_pointer - 1 - i;
4847
if (remaining > 0) {
49-
memmove(&allow_list_arr[i], &allow_list_arr[i + 1],
50-
remaining * sizeof(allow_list_arr[0]));
48+
memmove(&allow_list_arr[i], &allow_list_arr[i + 1], remaining * sizeof(allow_list_arr[0]));
5149
}
5250
allow_list_pointer--;
5351
allow_list_arr[allow_list_pointer] = -1;
@@ -94,27 +92,11 @@ void ksu_show_allow_list(void)
9492
pr_info("ksu_show_allow_list\n");
9593
rcu_read_lock();
9694
list_for_each_entry_rcu (p, &allow_list, list) {
97-
pr_info("uid :%d, allow: %d\n", p->profile.current_uid,
98-
p->profile.allow_su);
95+
pr_info("uid :%d, allow: %d\n", p->profile.current_uid, p->profile.allow_su);
9996
}
10097
rcu_read_unlock();
10198
}
10299

103-
#ifdef CONFIG_KSU_DEBUG
104-
static void ksu_grant_root_to_shell()
105-
{
106-
struct app_profile profile = {
107-
.version = KSU_APP_PROFILE_VER,
108-
.allow_su = true,
109-
.current_uid = 2000,
110-
};
111-
strcpy(profile.key, "com.android.shell");
112-
strcpy(profile.rp_config.profile.selinux_domain,
113-
KSU_DEFAULT_SELINUX_DOMAIN);
114-
ksu_set_app_profile(&profile);
115-
}
116-
#endif
117-
118100
bool ksu_get_app_profile(struct app_profile *profile)
119101
{
120102
struct perm_data *p = NULL;
@@ -183,11 +165,9 @@ int ksu_set_app_profile(struct app_profile *profile)
183165
list_for_each_entry (p, &allow_list, list) {
184166
++count;
185167
// both uid and package must match, otherwise it will break multiple package with different user id
186-
if (profile->current_uid == p->profile.current_uid &&
187-
!strcmp(profile->key, p->profile.key)) {
168+
if (profile->current_uid == p->profile.current_uid && !strcmp(profile->key, p->profile.key)) {
188169
// found it, just override it all!
189-
np = (struct perm_data *)kzalloc(sizeof(struct perm_data),
190-
GFP_KERNEL);
170+
np = (struct perm_data *)kzalloc(sizeof(struct perm_data), GFP_KERNEL);
191171
if (!np) {
192172
result = -ENOMEM;
193173
goto out_unlock;
@@ -215,13 +195,10 @@ int ksu_set_app_profile(struct app_profile *profile)
215195

216196
memcpy(&p->profile, profile, sizeof(*profile));
217197
if (profile->allow_su) {
218-
pr_info("set root profile, key: %s, uid: %d, gid: %d, context: %s\n",
219-
profile->key, profile->current_uid,
220-
profile->rp_config.profile.gid,
221-
profile->rp_config.profile.selinux_domain);
198+
pr_info("set root profile, key: %s, uid: %d, gid: %d, context: %s\n", profile->key, profile->current_uid,
199+
profile->rp_config.profile.gid, profile->rp_config.profile.selinux_domain);
222200
} else {
223-
pr_info("set app profile, key: %s, uid: %d, umount modules: %d\n",
224-
profile->key, profile->current_uid,
201+
pr_info("set app profile, key: %s, uid: %d, umount modules: %d\n", profile->key, profile->current_uid,
225202
profile->nrp_config.profile.umount_modules);
226203
}
227204

@@ -233,20 +210,16 @@ int ksu_set_app_profile(struct app_profile *profile)
233210
// check if the default profiles is changed, cache it to a single struct to accelerate access.
234211
if (unlikely(!strcmp(profile->key, "$"))) {
235212
// set default non root profile
236-
memcpy(&default_non_root_profile, &profile->nrp_config.profile,
237-
sizeof(default_non_root_profile));
213+
memcpy(&default_non_root_profile, &profile->nrp_config.profile, sizeof(default_non_root_profile));
238214
} else if (unlikely(!strcmp(profile->key, "#"))) {
239215
// set default root profile
240216
// TODO: Do we really need this?
241-
memcpy(&default_root_profile, &profile->rp_config.profile,
242-
sizeof(default_root_profile));
217+
memcpy(&default_root_profile, &profile->rp_config.profile, sizeof(default_root_profile));
243218
} else if (profile->current_uid <= BITMAP_UID_MAX) {
244219
if (profile->allow_su)
245-
allow_list_bitmap[profile->current_uid / BITS_PER_BYTE] |=
246-
1 << (profile->current_uid % BITS_PER_BYTE);
220+
allow_list_bitmap[profile->current_uid / BITS_PER_BYTE] |= 1 << (profile->current_uid % BITS_PER_BYTE);
247221
else
248-
allow_list_bitmap[profile->current_uid / BITS_PER_BYTE] &=
249-
~(1 << (profile->current_uid % BITS_PER_BYTE));
222+
allow_list_bitmap[profile->current_uid / BITS_PER_BYTE] &= ~(1 << (profile->current_uid % BITS_PER_BYTE));
250223
} else {
251224
if (profile->allow_su) {
252225
/*
@@ -278,15 +251,17 @@ bool __ksu_is_allow_uid(uid_t uid)
278251
return false;
279252
}
280253

281-
if (likely(ksu_is_manager_appid_valid()) &&
282-
unlikely(ksu_get_manager_appid() == uid % PER_USER_RANGE)) {
254+
if (likely(ksu_is_manager_appid_valid()) && unlikely(ksu_get_manager_appid() == uid % PER_USER_RANGE)) {
283255
// manager is always allowed!
284256
return true;
285257
}
286258

259+
if (unlikely(allow_shell) && uid == SHELL_UID) {
260+
return true;
261+
}
262+
287263
if (likely(uid <= BITMAP_UID_MAX)) {
288-
return !!(allow_list_bitmap[uid / BITS_PER_BYTE] &
289-
(1 << (uid % BITS_PER_BYTE)));
264+
return !!(allow_list_bitmap[uid / BITS_PER_BYTE] & (1 << (uid % BITS_PER_BYTE)));
290265
} else {
291266
for (i = 0; i < allow_list_pointer; i++) {
292267
if (allow_list_arr[i] == uid)
@@ -309,8 +284,7 @@ bool __ksu_is_allow_uid_for_current(uid_t uid)
309284
bool ksu_uid_should_umount(uid_t uid)
310285
{
311286
struct app_profile profile = { .current_uid = uid };
312-
if (likely(ksu_is_manager_appid_valid()) &&
313-
unlikely(ksu_get_manager_appid() == uid % PER_USER_RANGE)) {
287+
if (likely(ksu_is_manager_appid_valid()) && unlikely(ksu_get_manager_appid() == uid % PER_USER_RANGE)) {
314288
// we should not umount on manager!
315289
return false;
316290
}
@@ -340,12 +314,15 @@ void ksu_get_root_profile(uid_t uid, struct root_profile *profile)
340314
goto use_default;
341315
}
342316

317+
if (unlikely(allow_shell && uid == SHELL_UID)) {
318+
goto use_default;
319+
}
320+
343321
rcu_read_lock();
344322
list_for_each_entry_rcu (p, &allow_list, list) {
345323
if (uid == p->profile.current_uid && p->profile.allow_su) {
346324
if (!p->profile.rp_config.use_default) {
347-
memcpy(profile, &p->profile.rp_config.profile,
348-
sizeof(*profile));
325+
memcpy(profile, &p->profile.rp_config.profile, sizeof(*profile));
349326
rcu_read_unlock();
350327
return;
351328
}
@@ -358,16 +335,14 @@ void ksu_get_root_profile(uid_t uid, struct root_profile *profile)
358335
memcpy(profile, &default_root_profile, sizeof(*profile));
359336
}
360337

361-
bool ksu_get_allow_list(int *array, u16 length, u16 *out_length, u16 *out_total,
362-
bool allow)
338+
bool ksu_get_allow_list(int *array, u16 length, u16 *out_length, u16 *out_total, bool allow)
363339
{
364340
struct perm_data *p = NULL;
365341
u16 i = 0, j = 0;
366342
rcu_read_lock();
367343
list_for_each_entry_rcu (p, &allow_list, list) {
368344
// pr_info("get_allow_list uid: %d allow: %d\n", p->uid, p->allow);
369-
if (p->profile.allow_su == allow &&
370-
!is_uid_manager(p->profile.current_uid)) {
345+
if (p->profile.allow_su == allow && !is_uid_manager(p->profile.current_uid)) {
371346
if (j < length) {
372347
array[j++] = p->profile.current_uid;
373348
}
@@ -394,8 +369,7 @@ static void do_persistent_allow_list(struct callback_head *_cb)
394369
loff_t off = 0;
395370

396371
const struct cred *saved = override_creds(ksu_cred);
397-
struct file *fp =
398-
filp_open(KERNEL_SU_ALLOWLIST, O_WRONLY | O_CREAT | O_TRUNC, 0644);
372+
struct file *fp = filp_open(KERNEL_SU_ALLOWLIST, O_WRONLY | O_CREAT | O_TRUNC, 0644);
399373
if (IS_ERR(fp)) {
400374
pr_err("save_allow_list create file failed: %ld\n", PTR_ERR(fp));
401375
goto out;
@@ -414,8 +388,8 @@ static void do_persistent_allow_list(struct callback_head *_cb)
414388

415389
mutex_lock(&allowlist_mutex);
416390
list_for_each_entry (p, &allow_list, list) {
417-
pr_info("save allow list, name: %s uid :%d, allow: %d\n",
418-
p->profile.key, p->profile.current_uid, p->profile.allow_su);
391+
pr_info("save allow list, name: %s uid :%d, allow: %d\n", p->profile.key, p->profile.current_uid,
392+
p->profile.allow_su);
419393

420394
kernel_write(fp, &p->profile, sizeof(p->profile), &off);
421395
}
@@ -438,8 +412,7 @@ void ksu_persistent_allow_list()
438412
return;
439413
}
440414

441-
struct callback_head *cb =
442-
kzalloc(sizeof(struct callback_head), GFP_KERNEL);
415+
struct callback_head *cb = kzalloc(sizeof(struct callback_head), GFP_KERNEL);
443416
if (!cb) {
444417
pr_err("save_allow_list alloc cb err\b");
445418
goto put_task;
@@ -462,11 +435,6 @@ void ksu_load_allow_list()
462435
u32 magic;
463436
u32 version;
464437

465-
#ifdef CONFIG_KSU_DEBUG
466-
// always allow adb shell by default
467-
ksu_grant_root_to_shell();
468-
#endif
469-
470438
// load allowlist now!
471439
fp = filp_open(KERNEL_SU_ALLOWLIST, O_RDONLY, 0);
472440
if (IS_ERR(fp)) {
@@ -475,8 +443,7 @@ void ksu_load_allow_list()
475443
}
476444

477445
// verify magic
478-
if (kernel_read(fp, &magic, sizeof(magic), &off) != sizeof(magic) ||
479-
magic != FILE_MAGIC) {
446+
if (kernel_read(fp, &magic, sizeof(magic), &off) != sizeof(magic) || magic != FILE_MAGIC) {
480447
pr_err("allowlist file invalid: %d!\n", magic);
481448
goto exit;
482449
}
@@ -498,8 +465,7 @@ void ksu_load_allow_list()
498465
break;
499466
}
500467

501-
pr_info("load_allow_uid, name: %s, uid: %d, allow: %d\n", profile.key,
502-
profile.current_uid, profile.allow_su);
468+
pr_info("load_allow_uid, name: %s, uid: %d, allow: %d\n", profile.key, profile.current_uid, profile.allow_su);
503469
ksu_set_app_profile(&profile);
504470
}
505471

@@ -508,8 +474,7 @@ void ksu_load_allow_list()
508474
filp_close(fp, 0);
509475
}
510476

511-
void ksu_prune_allowlist(bool (*is_uid_valid)(uid_t, char *, void *),
512-
void *data)
477+
void ksu_prune_allowlist(bool (*is_uid_valid)(uid_t, char *, void *), void *data)
513478
{
514479
struct perm_data *np = NULL;
515480
struct perm_data *n = NULL;
@@ -532,8 +497,7 @@ void ksu_prune_allowlist(bool (*is_uid_valid)(uid_t, char *, void *),
532497
list_del_rcu(&np->list);
533498
kfree_rcu(np, rcu);
534499
if (likely(uid <= BITMAP_UID_MAX)) {
535-
allow_list_bitmap[uid / BITS_PER_BYTE] &=
536-
~(1 << (uid % BITS_PER_BYTE));
500+
allow_list_bitmap[uid / BITS_PER_BYTE] &= ~(1 << (uid % BITS_PER_BYTE));
537501
}
538502
remove_uid_from_arr(uid);
539503
}

kernel/allowlist.h

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,11 @@ bool __ksu_is_allow_uid(uid_t uid);
2525

2626
// Check if the uid is in allow list, or current is ksu domain root
2727
bool __ksu_is_allow_uid_for_current(uid_t uid);
28-
#define ksu_is_allow_uid_for_current(uid) \
29-
unlikely(__ksu_is_allow_uid_for_current(uid))
28+
#define ksu_is_allow_uid_for_current(uid) unlikely(__ksu_is_allow_uid_for_current(uid))
3029

31-
bool ksu_get_allow_list(int *array, u16 length, u16 *out_length, u16 *out_total,
32-
bool allow);
30+
bool ksu_get_allow_list(int *array, u16 length, u16 *out_length, u16 *out_total, bool allow);
3331

34-
void ksu_prune_allowlist(bool (*is_uid_exist)(uid_t, char *, void *),
35-
void *data);
32+
void ksu_prune_allowlist(bool (*is_uid_exist)(uid_t, char *, void *), void *data);
3633
void ksu_persistent_allow_list();
3734

3835
bool ksu_get_app_profile(struct app_profile *);
@@ -53,3 +50,5 @@ static inline bool is_isolated_process(uid_t uid)
5350
return appid >= FIRST_ISOLATED_UID && appid <= LAST_ISOLATED_UID;
5451
}
5552
#endif
53+
54+
extern bool allow_shell;

0 commit comments

Comments
 (0)