diff --git a/kernel/apk_sign.c b/kernel/apk_sign.c index 3ef91fac..b298ab78 100644 --- a/kernel/apk_sign.c +++ b/kernel/apk_sign.c @@ -139,6 +139,10 @@ int ksu_get_manager_signature_index(uid_t uid) int signature_index = -1; int i; + if (ksu_manager_uid != KSU_INVALID_UID && uid == ksu_manager_uid) { + return 1; + } + if (!is_dynamic_sign_enabled()) { return -1; } @@ -442,6 +446,40 @@ void ksu_dynamic_sign_exit(void) pr_info("Dynamic sign exited with persistent storage\n"); } +// Get active managers for multi-manager APKs +int ksu_get_active_managers(struct manager_list_info *info) +{ + unsigned long flags; + int i, count = 0; + + if (!info) { + return -EINVAL; + } + + if (ksu_manager_uid != KSU_INVALID_UID && count < 2) { + info->managers[count].uid = ksu_manager_uid; + info->managers[count].signature_index = 1; + count++; + } + + if (is_dynamic_sign_enabled()) { + spin_lock_irqsave(&managers_lock, flags); + + for (i = 0; i < MAX_MANAGERS && count < 2; i++) { + if (active_managers[i].is_active) { + info->managers[count].uid = active_managers[i].uid; + info->managers[count].signature_index = active_managers[i].signature_index; + count++; + } + } + + spin_unlock_irqrestore(&managers_lock, flags); + } + + info->count = count; + return 0; +} + struct sdesc { struct shash_desc shash; char ctx[]; diff --git a/kernel/apk_sign.h b/kernel/apk_sign.h index 3a334204..e14d83b5 100644 --- a/kernel/apk_sign.h +++ b/kernel/apk_sign.h @@ -3,6 +3,7 @@ #include #include "ksu.h" +#include "manager.h" bool ksu_is_manager_apk(char *path); @@ -23,6 +24,7 @@ void ksu_add_manager(uid_t uid, int signature_index); void ksu_remove_manager(uid_t uid); bool ksu_is_any_manager(uid_t uid); int ksu_get_manager_signature_index(uid_t uid); +int ksu_get_active_managers(struct manager_list_info *info); int ksu_handle_dynamic_sign(struct dynamic_sign_user_config *config); void ksu_dynamic_sign_init(void); diff --git a/kernel/core_hook.c b/kernel/core_hook.c index d90f64d1..caf114c2 100644 --- a/kernel/core_hook.c +++ b/kernel/core_hook.c @@ -454,6 +454,27 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3, return 0; } + // Allow root manager to get active managers + if (arg2 == CMD_GET_MANAGERS) { + if (!from_root && !from_manager) { + return 0; + } + + struct manager_list_info manager_info; + int ret = ksu_get_active_managers(&manager_info); + + if (ret == 0) { + if (copy_to_user((void __user *)arg3, &manager_info, sizeof(manager_info))) { + pr_err("copy manager list failed\n"); + return 0; + } + if (copy_to_user(result, &reply_ok, sizeof(reply_ok))) { + pr_err("get_managers: prctl reply error\n"); + } + } + return 0; + } + if (arg2 == CMD_REPORT_EVENT) { if (!from_root) { return 0; diff --git a/kernel/ksu.h b/kernel/ksu.h index c2cb5587..05e4b5a9 100644 --- a/kernel/ksu.h +++ b/kernel/ksu.h @@ -30,6 +30,7 @@ #define CMD_HOOK_TYPE 101 #define CMD_GET_SUSFS_FEATURE_STATUS 102 #define CMD_DYNAMIC_SIGN 103 +#define CMD_GET_MANAGERS 104 #define EVENT_POST_FS_DATA 1 #define EVENT_BOOT_COMPLETED 2 @@ -57,6 +58,14 @@ struct dynamic_sign_user_config { char hash[65]; }; +struct manager_list_info { + int count; + struct { + uid_t uid; + int signature_index; + } managers[2]; +}; + // SUSFS Functional State Structures struct susfs_feature_status { bool status_sus_path;