diff --git a/kernel/Kconfig b/kernel/Kconfig index 67f177f4..1f3802f6 100644 --- a/kernel/Kconfig +++ b/kernel/Kconfig @@ -16,4 +16,12 @@ config KSU_DEBUG help Enable KernelSU debug mode. +config KSU_ALLOWLIST_WORKAROUND + bool "KernelSU Session Keyring Init workaround" + depends on KSU + default n + help + Enable session keyring init workaround for problematic devices. + Useful for situations where the SU allowlist is not kept after a reboot. + endmenu diff --git a/kernel/core_hook.c b/kernel/core_hook.c index e3ffa820..ebe95923 100644 --- a/kernel/core_hook.c +++ b/kernel/core_hook.c @@ -627,7 +627,7 @@ static int ksu_task_prctl(int option, unsigned long arg2, unsigned long arg3, } // kernel 4.4 and 4.9 -#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) || defined(CONFIG_IS_HW_HISI) +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) || defined(CONFIG_IS_HW_HISI) || defined(CONFIG_KSU_ALLOWLIST_WORKAROUND) static int ksu_key_permission(key_ref_t key_ref, const struct cred *cred, unsigned perm) { @@ -661,7 +661,7 @@ static struct security_hook_list ksu_hooks[] = { LSM_HOOK_INIT(task_prctl, ksu_task_prctl), LSM_HOOK_INIT(inode_rename, ksu_inode_rename), LSM_HOOK_INIT(task_fix_setuid, ksu_task_fix_setuid), -#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) || defined(CONFIG_IS_HW_HISI) +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) || defined(CONFIG_IS_HW_HISI) || defined(CONFIG_KSU_ALLOWLIST_WORKAROUND) LSM_HOOK_INIT(key_permission, ksu_key_permission) #endif }; diff --git a/kernel/kernel_compat.c b/kernel/kernel_compat.c index a80b6ffc..eb6e8b22 100644 --- a/kernel/kernel_compat.c +++ b/kernel/kernel_compat.c @@ -9,7 +9,7 @@ #include #include "klog.h" // IWYU pragma: keep #include "kernel_compat.h" // Add check Huawei Device -#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) || defined(CONFIG_IS_HW_HISI) +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) || defined(CONFIG_IS_HW_HISI) || defined(CONFIG_KSU_ALLOWLIST_WORKAROUND) #include #include #include @@ -84,7 +84,7 @@ int ksu_access_ok(const void *addr, unsigned long size) { struct file *ksu_filp_open_compat(const char *filename, int flags, umode_t mode) { -#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) || defined(CONFIG_IS_HW_HISI) +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) || defined(CONFIG_IS_HW_HISI) || defined(CONFIG_KSU_ALLOWLIST_WORKAROUND) if (init_session_keyring != NULL && !current_cred()->session_keyring && (current->flags & PF_WQ_WORKER)) { pr_info("installing init session keyring for older kernel\n"); diff --git a/kernel/kernel_compat.h b/kernel/kernel_compat.h index 34050e73..b0d664a9 100644 --- a/kernel/kernel_compat.h +++ b/kernel/kernel_compat.h @@ -24,7 +24,7 @@ extern long ksu_strncpy_from_user_nofault(char *dst, const void __user *unsafe_addr, long count); -#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) || defined(CONFIG_IS_HW_HISI) +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) || defined(CONFIG_IS_HW_HISI) || defined(CONFIG_KSU_ALLOWLIST_WORKAROUND) extern struct key *init_session_keyring; #endif