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:
@@ -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
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user