kernel: Syncronize upstream changes (#198)

* Cherry-picked range: (kernel)
ebea31daa8..6915b62b9a

* Also merged unmerged pr:
https://github.com/tiann/KernelSU/pull/ 2909

Co-authored-by: Ylarod <me@ylarod.cn>
Co-authored-by: 5ec1cff <56485584+5ec1cff@users.noreply.github.com>
Co-authored-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
Co-authored-by: u9521 <63995396+u9521@users.noreply.github.com>
Co-authored-by: Wang Han <416810799@qq.com>
This commit is contained in:
fc5b87cf
2025-11-17 18:21:29 +07:00
committed by ShirkNeko
parent edeff936ce
commit c93cf58f48
40 changed files with 2550 additions and 2194 deletions

View File

@@ -10,11 +10,9 @@
#include "allowlist.h"
#include "klog.h" // IWYU pragma: keep
#include "ksu.h"
#include "apk_sign.h"
#include "manager.h"
#include "throne_tracker.h"
#include "kernel_compat.h"
#include "apk_sign.h"
#include "dynamic_manager.h"
#include "throne_comm.h"
@@ -40,7 +38,7 @@ static int uid_from_um_list(struct list_head *uid_list)
ssize_t nr;
int cnt = 0;
fp = ksu_filp_open_compat(KSU_UID_LIST_PATH, O_RDONLY, 0);
fp = filp_open(KSU_UID_LIST_PATH, O_RDONLY, 0);
if (IS_ERR(fp))
return -ENOENT;
@@ -57,7 +55,7 @@ static int uid_from_um_list(struct list_head *uid_list)
return -ENOMEM;
}
nr = ksu_kernel_read_compat(fp, buf, size, &pos);
nr = kernel_read(fp, buf, size, &pos);
filp_close(fp, NULL);
if (nr != size) {
pr_err("uid_list: short read %zd/%lld\n", nr, size);
@@ -155,7 +153,7 @@ static void crown_manager(const char *apk, struct list_head *uid_data, int signa
// pkg is `/<real package>`
if (strncmp(pkg, KSU_MANAGER_PACKAGE, sizeof(KSU_MANAGER_PACKAGE))) {
pr_info("manager package is inconsistent with kernel build: %s\n",
KSU_MANAGER_PACKAGE);
KSU_MANAGER_PACKAGE);
return;
}
#endif
@@ -235,10 +233,9 @@ struct my_dir_context {
#define FILLDIR_ACTOR_CONTINUE 0
#define FILLDIR_ACTOR_STOP -EINVAL
#endif
FILLDIR_RETURN_TYPE my_actor(struct dir_context *ctx, const char *name,
int namelen, loff_t off, u64 ino,
unsigned int d_type)
int namelen, loff_t off, u64 ino,
unsigned int d_type)
{
struct my_dir_context *my_ctx =
container_of(ctx, struct my_dir_context, ctx);
@@ -271,7 +268,7 @@ FILLDIR_RETURN_TYPE my_actor(struct dir_context *ctx, const char *name,
if (d_type == DT_DIR && my_ctx->depth > 0 &&
(my_ctx->stop && !*my_ctx->stop)) {
struct data_path *data = kmalloc(sizeof(struct data_path), GFP_ATOMIC);
struct data_path *data = kzalloc(sizeof(struct data_path), GFP_ATOMIC);
if (!data) {
pr_err("Failed to allocate memory for %s\n", dirpath);
@@ -306,29 +303,24 @@ FILLDIR_RETURN_TYPE my_actor(struct dir_context *ctx, const char *name,
// Check for dynamic sign or multi-manager signatures
if (is_multi_manager && (signature_index == DYNAMIC_SIGN_INDEX || signature_index >= 2)) {
crown_manager(dirpath, my_ctx->private_data, signature_index);
struct apk_path_hash *apk_data = kmalloc(sizeof(struct apk_path_hash), GFP_ATOMIC);
if (apk_data) {
apk_data->hash = hash;
apk_data->exists = true;
list_add_tail(&apk_data->list, &apk_path_hash_list);
}
} else if (is_manager_apk(dirpath)) {
crown_manager(dirpath, my_ctx->private_data, 0);
*my_ctx->stop = 1;
}
struct apk_path_hash *apk_data = kzalloc(sizeof(*apk_data), GFP_ATOMIC);
if (apk_data) {
apk_data->hash = hash;
apk_data->exists = true;
list_add_tail(&apk_data->list, &apk_path_hash_list);
}
if (is_manager_apk(dirpath)) {
// Manager found, clear APK cache list
list_for_each_entry_safe(pos, n, &apk_path_hash_list, list) {
list_del(&pos->list);
kfree(pos);
}
} else {
struct apk_path_hash *apk_data = kmalloc(sizeof(struct apk_path_hash), GFP_ATOMIC);
if (apk_data) {
apk_data->hash = hash;
apk_data->exists = true;
list_add_tail(&apk_data->list, &apk_path_hash_list);
}
}
}
}
@@ -345,7 +337,7 @@ void search_manager(const char *path, int depth, struct list_head *uid_data)
// Initialize APK cache list
struct apk_path_hash *pos, *n;
list_for_each_entry(pos, &apk_path_hash_list, list) {
list_for_each_entry (pos, &apk_path_hash_list, list) {
pos->exists = false;
}
@@ -358,36 +350,39 @@ void search_manager(const char *path, int depth, struct list_head *uid_data)
for (i = depth; i >= 0; i--) {
struct data_path *pos, *n;
list_for_each_entry_safe(pos, n, &data_path_list, list) {
list_for_each_entry_safe (pos, n, &data_path_list, list) {
struct my_dir_context ctx = { .ctx.actor = my_actor,
.data_path_list = &data_path_list,
.parent_dir = pos->dirpath,
.private_data = uid_data,
.depth = pos->depth,
.stop = &stop };
.data_path_list = &data_path_list,
.parent_dir = pos->dirpath,
.private_data = uid_data,
.depth = pos->depth,
.stop = &stop };
struct file *file;
if (!stop) {
file = ksu_filp_open_compat(pos->dirpath, O_RDONLY | O_NOFOLLOW, 0);
file = filp_open(pos->dirpath, O_RDONLY | O_NOFOLLOW, 0);
if (IS_ERR(file)) {
pr_err("Failed to open directory: %s, err: %ld\n", pos->dirpath, PTR_ERR(file));
pr_err("Failed to open directory: %s, err: %ld\n",
pos->dirpath, PTR_ERR(file));
goto skip_iterate;
}
// grab magic on first folder, which is /data/app
if (!data_app_magic) {
if (file->f_inode->i_sb->s_magic) {
data_app_magic = file->f_inode->i_sb->s_magic;
pr_info("%s: dir: %s got magic! 0x%lx\n", __func__, pos->dirpath, data_app_magic);
pr_info("%s: dir: %s got magic! 0x%lx\n", __func__,
pos->dirpath, data_app_magic);
} else {
filp_close(file, NULL);
goto skip_iterate;
}
}
if (file->f_inode->i_sb->s_magic != data_app_magic) {
pr_info("%s: skip: %s magic: 0x%lx expected: 0x%lx\n", __func__, pos->dirpath,
file->f_inode->i_sb->s_magic, data_app_magic);
pr_info("%s: skip: %s magic: 0x%lx expected: 0x%lx\n",
__func__, pos->dirpath,
file->f_inode->i_sb->s_magic, data_app_magic);
filp_close(file, NULL);
goto skip_iterate;
}
@@ -395,7 +390,7 @@ void search_manager(const char *path, int depth, struct list_head *uid_data)
iterate_dir(file, &ctx.ctx);
filp_close(file, NULL);
}
skip_iterate:
skip_iterate:
list_del(&pos->list);
if (pos != &data)
kfree(pos);
@@ -403,7 +398,7 @@ skip_iterate:
}
// Remove stale cached APK entries
list_for_each_entry_safe(pos, n, &apk_path_hash_list, list) {
list_for_each_entry_safe (pos, n, &apk_path_hash_list, list) {
if (!pos->exists) {
list_del(&pos->list);
kfree(pos);
@@ -427,11 +422,11 @@ static bool is_uid_exist(uid_t uid, char *package, void *data)
return exist;
}
void track_throne(void)
void track_throne(bool prune_only)
{
struct list_head uid_list;
struct uid_data *np, *n;
struct file *fp;
struct file *fp;
char chr = 0;
loff_t pos = 0;
loff_t line_start = 0;
@@ -456,7 +451,7 @@ void track_throne(void)
}
{
fp = ksu_filp_open_compat(SYSTEM_PACKAGES_LIST_PATH, O_RDONLY, 0);
fp = filp_open(SYSTEM_PACKAGES_LIST_PATH, O_RDONLY, 0);
if (IS_ERR(fp)) {
pr_err("%s: open " SYSTEM_PACKAGES_LIST_PATH " failed: %ld\n", __func__, PTR_ERR(fp));
return;
@@ -464,13 +459,13 @@ void track_throne(void)
for (;;) {
ssize_t count =
ksu_kernel_read_compat(fp, &chr, sizeof(chr), &pos);
kernel_read(fp, &chr, sizeof(chr), &pos);
if (count != sizeof(chr))
break;
if (chr != '\n')
continue;
count = ksu_kernel_read_compat(fp, buf, sizeof(buf),
count = kernel_read(fp, buf, sizeof(buf),
&line_start);
struct uid_data *data =
kzalloc(sizeof(struct uid_data), GFP_ATOMIC);
@@ -504,6 +499,9 @@ void track_throne(void)
}
uid_ready:
if (prune_only)
goto prune;
// first, check if manager_uid exist!
list_for_each_entry(np, &uid_list, list) {
if (np->uid == current_manager_uid) {
@@ -547,6 +545,7 @@ uid_ready:
pr_info("Manager search finished\n");
}
prune:
// then prune the allowlist
ksu_prune_allowlist(is_uid_exist, &uid_list);
out:
@@ -565,4 +564,4 @@ void ksu_throne_tracker_init(void)
void ksu_throne_tracker_exit(void)
{
// nothing to do
}
}