kernel/manager/ksud: Add switch functionality to sulog
Signed-off-by: ShirkNeko <109797057+ShirkNeko@users.noreply.github.com>
This commit is contained in:
@@ -7,6 +7,7 @@ enum ksu_feature_id {
|
|||||||
KSU_FEATURE_SU_COMPAT = 0,
|
KSU_FEATURE_SU_COMPAT = 0,
|
||||||
KSU_FEATURE_KERNEL_UMOUNT = 1,
|
KSU_FEATURE_KERNEL_UMOUNT = 1,
|
||||||
KSU_FEATURE_ENHANCED_SECURITY = 2,
|
KSU_FEATURE_ENHANCED_SECURITY = 2,
|
||||||
|
KSU_FEATURE_SULOG = 3,
|
||||||
|
|
||||||
KSU_FEATURE_MAX
|
KSU_FEATURE_MAX
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#include <linux/mm.h>
|
#include <linux/mm.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/binfmts.h>
|
#include <linux/binfmts.h>
|
||||||
|
|
||||||
#include "manual_su.h"
|
#include "manual_su.h"
|
||||||
#include "ksu.h"
|
#include "ksu.h"
|
||||||
#include "allowlist.h"
|
#include "allowlist.h"
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
#include "sulog.h"
|
#include "sulog.h"
|
||||||
#include "ksu.h"
|
#include "ksu.h"
|
||||||
|
#include "feature.h"
|
||||||
|
|
||||||
#if __SULOG_GATE
|
#if __SULOG_GATE
|
||||||
|
|
||||||
@@ -25,7 +26,28 @@ static DEFINE_SPINLOCK(dedup_lock);
|
|||||||
static LIST_HEAD(sulog_queue);
|
static LIST_HEAD(sulog_queue);
|
||||||
static struct workqueue_struct *sulog_workqueue;
|
static struct workqueue_struct *sulog_workqueue;
|
||||||
static struct work_struct sulog_work;
|
static struct work_struct sulog_work;
|
||||||
static bool sulog_enabled = true;
|
static bool sulog_enabled __read_mostly = true;
|
||||||
|
|
||||||
|
static int sulog_feature_get(u64 *value)
|
||||||
|
{
|
||||||
|
*value = sulog_enabled ? 1 : 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int sulog_feature_set(u64 value)
|
||||||
|
{
|
||||||
|
bool enable = value != 0;
|
||||||
|
sulog_enabled = enable;
|
||||||
|
pr_info("sulog: set to %d\n", enable);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct ksu_feature_handler sulog_handler = {
|
||||||
|
.feature_id = KSU_FEATURE_SULOG,
|
||||||
|
.name = "sulog",
|
||||||
|
.get_handler = sulog_feature_get,
|
||||||
|
.set_handler = sulog_feature_set,
|
||||||
|
};
|
||||||
|
|
||||||
static void get_timestamp(char *buf, size_t len)
|
static void get_timestamp(char *buf, size_t len)
|
||||||
{
|
{
|
||||||
@@ -304,6 +326,10 @@ void ksu_sulog_report_syscall(uid_t uid, const char *comm, const char *syscall,
|
|||||||
|
|
||||||
int ksu_sulog_init(void)
|
int ksu_sulog_init(void)
|
||||||
{
|
{
|
||||||
|
if (ksu_register_feature_handler(&sulog_handler)) {
|
||||||
|
pr_err("Failed to register su_compat feature handler\n");
|
||||||
|
}
|
||||||
|
|
||||||
sulog_workqueue = alloc_workqueue("ksu_sulog", WQ_UNBOUND | WQ_HIGHPRI, 1);
|
sulog_workqueue = alloc_workqueue("ksu_sulog", WQ_UNBOUND | WQ_HIGHPRI, 1);
|
||||||
if (!sulog_workqueue) {
|
if (!sulog_workqueue) {
|
||||||
pr_err("sulog: failed to create workqueue\n");
|
pr_err("sulog: failed to create workqueue\n");
|
||||||
@@ -320,6 +346,8 @@ void ksu_sulog_exit(void)
|
|||||||
struct sulog_entry *entry, *tmp;
|
struct sulog_entry *entry, *tmp;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
|
ksu_unregister_feature_handler(KSU_FEATURE_SULOG);
|
||||||
|
|
||||||
sulog_enabled = false;
|
sulog_enabled = false;
|
||||||
|
|
||||||
if (sulog_workqueue) {
|
if (sulog_workqueue) {
|
||||||
|
|||||||
@@ -319,6 +319,14 @@ NativeBridge(setEnhancedSecurityEnabled, jboolean, jboolean enabled) {
|
|||||||
return set_enhanced_security_enabled(enabled);
|
return set_enhanced_security_enabled(enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NativeBridgeNP(isSuLogEnabled, jboolean) {
|
||||||
|
return is_sulog_enabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
NativeBridge(setSuLogEnabled, jboolean, jboolean enabled) {
|
||||||
|
return set_sulog_enabled(enabled);
|
||||||
|
}
|
||||||
|
|
||||||
NativeBridge(getUserName, jstring, jint uid) {
|
NativeBridge(getUserName, jstring, jint uid) {
|
||||||
struct passwd *pw = getpwuid((uid_t) uid);
|
struct passwd *pw = getpwuid((uid_t) uid);
|
||||||
if (pw && pw->pw_name && pw->pw_name[0] != '\0') {
|
if (pw && pw->pw_name && pw->pw_name[0] != '\0') {
|
||||||
|
|||||||
@@ -231,6 +231,22 @@ bool is_enhanced_security_enabled() {
|
|||||||
return value != 0;
|
return value != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool set_sulog_enabled(bool enabled) {
|
||||||
|
return set_feature(KSU_FEATURE_SULOG, enabled ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_sulog_enabled() {
|
||||||
|
uint64_t value = 0;
|
||||||
|
bool supported = false;
|
||||||
|
if (!get_feature(KSU_FEATURE_SULOG, &value, &supported)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!supported) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return value != 0;
|
||||||
|
}
|
||||||
|
|
||||||
void get_full_version(char* buff) {
|
void get_full_version(char* buff) {
|
||||||
struct ksu_get_full_version_cmd cmd = {0};
|
struct ksu_get_full_version_cmd cmd = {0};
|
||||||
if (ksuctl(KSU_IOCTL_GET_FULL_VERSION, &cmd) == 0) {
|
if (ksuctl(KSU_IOCTL_GET_FULL_VERSION, &cmd) == 0) {
|
||||||
|
|||||||
@@ -132,6 +132,7 @@ enum ksu_feature_id {
|
|||||||
KSU_FEATURE_SU_COMPAT = 0,
|
KSU_FEATURE_SU_COMPAT = 0,
|
||||||
KSU_FEATURE_KERNEL_UMOUNT = 1,
|
KSU_FEATURE_KERNEL_UMOUNT = 1,
|
||||||
KSU_FEATURE_ENHANCED_SECURITY = 2,
|
KSU_FEATURE_ENHANCED_SECURITY = 2,
|
||||||
|
KSU_FEATURE_SULOG = 3,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Generic feature API
|
// Generic feature API
|
||||||
@@ -211,9 +212,12 @@ bool is_kernel_umount_enabled();
|
|||||||
|
|
||||||
// Enhanced security
|
// Enhanced security
|
||||||
bool set_enhanced_security_enabled(bool enabled);
|
bool set_enhanced_security_enabled(bool enabled);
|
||||||
|
|
||||||
bool is_enhanced_security_enabled();
|
bool is_enhanced_security_enabled();
|
||||||
|
|
||||||
|
// Su log
|
||||||
|
bool set_sulog_enabled(bool enabled);
|
||||||
|
bool is_sulog_enabled();
|
||||||
|
|
||||||
// Other command structures
|
// Other command structures
|
||||||
struct ksu_get_full_version_cmd {
|
struct ksu_get_full_version_cmd {
|
||||||
char version_full[KSU_FULL_VERSION_STRING]; // Output: full version string
|
char version_full[KSU_FULL_VERSION_STRING]; // Output: full version string
|
||||||
|
|||||||
@@ -118,6 +118,15 @@ object Natives {
|
|||||||
external fun isEnhancedSecurityEnabled(): Boolean
|
external fun isEnhancedSecurityEnabled(): Boolean
|
||||||
external fun setEnhancedSecurityEnabled(enabled: Boolean): Boolean
|
external fun setEnhancedSecurityEnabled(enabled: Boolean): Boolean
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Su Log can be enabled/disabled.
|
||||||
|
* 0: disabled
|
||||||
|
* 1: enabled
|
||||||
|
* negative : error
|
||||||
|
*/
|
||||||
|
external fun isSuLogEnabled(): Boolean
|
||||||
|
external fun setSuLogEnabled(enabled: Boolean): Boolean
|
||||||
|
|
||||||
external fun isKPMEnabled(): Boolean
|
external fun isKPMEnabled(): Boolean
|
||||||
external fun getHookType(): String
|
external fun getHookType(): String
|
||||||
|
|
||||||
|
|||||||
@@ -270,6 +270,49 @@ fun SettingScreen(navigator: DestinationsNavigator) {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var kernelSuLogMode by rememberSaveable {
|
||||||
|
mutableIntStateOf(
|
||||||
|
run {
|
||||||
|
val currentEnabled = Natives.isSuLogEnabled()
|
||||||
|
val savedPersist = prefs.getInt("kernel_sulog_mode", 0)
|
||||||
|
if (savedPersist == 2) 2 else if (!currentEnabled) 1 else 0
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
SuperDropdown(
|
||||||
|
icon = Icons.Rounded.RemoveCircle,
|
||||||
|
title = stringResource(id = R.string.settings_disable_sulog),
|
||||||
|
summary = stringResource(id = R.string.settings_disable_sulog_summary),
|
||||||
|
items = modeItems,
|
||||||
|
selectedIndex = kernelSuLogMode,
|
||||||
|
onSelectedIndexChange = { index ->
|
||||||
|
when (index) {
|
||||||
|
// Default: enable and save to persist
|
||||||
|
0 -> if (Natives.setSuLogEnabled(true)) {
|
||||||
|
execKsud("feature save", true)
|
||||||
|
prefs.edit { putInt("kernel_sulog_mode", 0) }
|
||||||
|
kernelSuLogMode = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// Temporarily disable: save enabled state first, then disable
|
||||||
|
1 -> if (Natives.setSuLogEnabled(true)) {
|
||||||
|
execKsud("feature save", true)
|
||||||
|
if (Natives.setSuLogEnabled(false)) {
|
||||||
|
prefs.edit { putInt("kernel_sulog_mode", 0) }
|
||||||
|
kernelSuLogMode = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Permanently disable: disable and save
|
||||||
|
2 -> if (Natives.setSuLogEnabled(false)) {
|
||||||
|
execKsud("feature save", true)
|
||||||
|
prefs.edit { putInt("kernel_sulog_mode", 2) }
|
||||||
|
kernelSuLogMode = 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
// 卸载模块开关
|
// 卸载模块开关
|
||||||
var umountChecked by rememberSaveable { mutableStateOf(Natives.isDefaultUmountModules()) }
|
var umountChecked by rememberSaveable { mutableStateOf(Natives.isDefaultUmountModules()) }
|
||||||
SwitchItem(
|
SwitchItem(
|
||||||
@@ -284,7 +327,6 @@ fun SettingScreen(navigator: DestinationsNavigator) {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
// 强制签名验证开关
|
// 强制签名验证开关
|
||||||
var forceSignatureVerification by rememberSaveable {
|
var forceSignatureVerification by rememberSaveable {
|
||||||
mutableStateOf(prefs.getBoolean("force_signature_verification", false))
|
mutableStateOf(prefs.getBoolean("force_signature_verification", false))
|
||||||
@@ -403,6 +445,7 @@ fun SettingScreen(navigator: DestinationsNavigator) {
|
|||||||
|
|
||||||
// 查看使用日志
|
// 查看使用日志
|
||||||
KsuIsValid {
|
KsuIsValid {
|
||||||
|
if (Natives.isSuLogEnabled()) {
|
||||||
SettingItem(
|
SettingItem(
|
||||||
icon = Icons.Filled.Visibility,
|
icon = Icons.Filled.Visibility,
|
||||||
title = stringResource(R.string.log_viewer_view_logs),
|
title = stringResource(R.string.log_viewer_view_logs),
|
||||||
@@ -412,6 +455,7 @@ fun SettingScreen(navigator: DestinationsNavigator) {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
val lkmMode = Natives.isLkmMode
|
val lkmMode = Natives.isLkmMode
|
||||||
KsuIsValid {
|
KsuIsValid {
|
||||||
if (lkmMode) {
|
if (lkmMode) {
|
||||||
|
|||||||
@@ -751,4 +751,6 @@
|
|||||||
<string name="apply_config">应用配置</string>
|
<string name="apply_config">应用配置</string>
|
||||||
<string name="config_applied">配置已应用到内核</string>
|
<string name="config_applied">配置已应用到内核</string>
|
||||||
<string name="group_contains_apps">包含 %1$d 个应用</string>
|
<string name="group_contains_apps">包含 %1$d 个应用</string>
|
||||||
|
<string name="settings_disable_sulog">禁用 KernelSU 超级用户访问日志记录</string>
|
||||||
|
<string name="settings_disable_sulog_summary">禁用超级用户日志记录功能</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -761,4 +761,6 @@ Important Note:\n
|
|||||||
<string name="config_applied">Configuration applied to kernel</string>
|
<string name="config_applied">Configuration applied to kernel</string>
|
||||||
<string name="mnt_detach">MNT_DETACH</string>
|
<string name="mnt_detach">MNT_DETACH</string>
|
||||||
<string name="group_contains_apps">Contains %d apps</string>
|
<string name="group_contains_apps">Contains %d apps</string>
|
||||||
|
<string name="settings_disable_sulog">Disable KernelSU superuser access logging</string>
|
||||||
|
<string name="settings_disable_sulog_summary">Disable superuser logging functionality</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ pub enum FeatureId {
|
|||||||
SuCompat = 0,
|
SuCompat = 0,
|
||||||
KernelUmount = 1,
|
KernelUmount = 1,
|
||||||
EnhancedSecurity = 2,
|
EnhancedSecurity = 2,
|
||||||
|
SuLog = 3,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FeatureId {
|
impl FeatureId {
|
||||||
@@ -25,6 +26,7 @@ impl FeatureId {
|
|||||||
0 => Some(FeatureId::SuCompat),
|
0 => Some(FeatureId::SuCompat),
|
||||||
1 => Some(FeatureId::KernelUmount),
|
1 => Some(FeatureId::KernelUmount),
|
||||||
2 => Some(FeatureId::EnhancedSecurity),
|
2 => Some(FeatureId::EnhancedSecurity),
|
||||||
|
3 => Some(FeatureId::SuLog),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -34,6 +36,7 @@ impl FeatureId {
|
|||||||
FeatureId::SuCompat => "su_compat",
|
FeatureId::SuCompat => "su_compat",
|
||||||
FeatureId::KernelUmount => "kernel_umount",
|
FeatureId::KernelUmount => "kernel_umount",
|
||||||
FeatureId::EnhancedSecurity => "enhanced_security",
|
FeatureId::EnhancedSecurity => "enhanced_security",
|
||||||
|
FeatureId::SuLog => "sulog",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,6 +51,9 @@ impl FeatureId {
|
|||||||
FeatureId::EnhancedSecurity => {
|
FeatureId::EnhancedSecurity => {
|
||||||
"Enhanced Security - disable non‑KSU root elevation and unauthorized UID downgrades"
|
"Enhanced Security - disable non‑KSU root elevation and unauthorized UID downgrades"
|
||||||
}
|
}
|
||||||
|
FeatureId::SuLog => {
|
||||||
|
"SU Log - enables logging of SU command usage to kernel log for auditing purposes"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -57,6 +63,7 @@ fn parse_feature_id(name: &str) -> Result<FeatureId> {
|
|||||||
"su_compat" | "0" => Ok(FeatureId::SuCompat),
|
"su_compat" | "0" => Ok(FeatureId::SuCompat),
|
||||||
"kernel_umount" | "1" => Ok(FeatureId::KernelUmount),
|
"kernel_umount" | "1" => Ok(FeatureId::KernelUmount),
|
||||||
"enhanced_security" | "2" => Ok(FeatureId::EnhancedSecurity),
|
"enhanced_security" | "2" => Ok(FeatureId::EnhancedSecurity),
|
||||||
|
"sulog" | "3" => Ok(FeatureId::SuLog),
|
||||||
_ => bail!("Unknown feature: {}", name),
|
_ => bail!("Unknown feature: {}", name),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -234,6 +241,7 @@ pub fn list_features() -> Result<()> {
|
|||||||
FeatureId::SuCompat,
|
FeatureId::SuCompat,
|
||||||
FeatureId::KernelUmount,
|
FeatureId::KernelUmount,
|
||||||
FeatureId::EnhancedSecurity,
|
FeatureId::EnhancedSecurity,
|
||||||
|
FeatureId::SuLog,
|
||||||
];
|
];
|
||||||
|
|
||||||
for feature_id in all_features.iter() {
|
for feature_id in all_features.iter() {
|
||||||
@@ -297,6 +305,7 @@ pub fn save_config() -> Result<()> {
|
|||||||
FeatureId::SuCompat,
|
FeatureId::SuCompat,
|
||||||
FeatureId::KernelUmount,
|
FeatureId::KernelUmount,
|
||||||
FeatureId::EnhancedSecurity,
|
FeatureId::EnhancedSecurity,
|
||||||
|
FeatureId::SuLog,
|
||||||
];
|
];
|
||||||
|
|
||||||
for feature_id in all_features.iter() {
|
for feature_id in all_features.iter() {
|
||||||
|
|||||||
Reference in New Issue
Block a user