From 70f2df11d1a8f5413cf243d1805894de81ada7d7 Mon Sep 17 00:00:00 2001 From: weishu Date: Sat, 1 Jul 2023 18:44:56 +0800 Subject: [PATCH] manager: support setting selinux rules profile --- .../main/java/me/weishu/kernelsu/Natives.kt | 1 + .../ui/component/profile/RootProfileConfig.kt | 15 +++++++++------ .../me/weishu/kernelsu/ui/screen/AppProfile.kt | 17 +++++++++++++++-- .../java/me/weishu/kernelsu/ui/util/KsuCli.kt | 18 +++++++++++++++++- manager/app/src/main/res/values/strings.xml | 1 + 5 files changed, 43 insertions(+), 9 deletions(-) diff --git a/manager/app/src/main/java/me/weishu/kernelsu/Natives.kt b/manager/app/src/main/java/me/weishu/kernelsu/Natives.kt index 218f72d6..164a4018 100644 --- a/manager/app/src/main/java/me/weishu/kernelsu/Natives.kt +++ b/manager/app/src/main/java/me/weishu/kernelsu/Natives.kt @@ -93,6 +93,7 @@ object Natives { val nonRootUseDefault: Boolean = true, val umountModules: Boolean = true, + var rules: String = "", // this field is save in ksud!! ) : Parcelable { enum class Namespace { Inherited, diff --git a/manager/app/src/main/java/me/weishu/kernelsu/ui/component/profile/RootProfileConfig.kt b/manager/app/src/main/java/me/weishu/kernelsu/ui/component/profile/RootProfileConfig.kt index 5072a66d..3ba0b163 100644 --- a/manager/app/src/main/java/me/weishu/kernelsu/ui/component/profile/RootProfileConfig.kt +++ b/manager/app/src/main/java/me/weishu/kernelsu/ui/component/profile/RootProfileConfig.kt @@ -175,6 +175,7 @@ fun RootProfileConfig( onProfileChange( profile.copy( context = domain, + rules = rules, rootUseDefault = false ) ) @@ -357,11 +358,14 @@ private fun UidPanel(uid: Int, label: String, onUidChange: (Int) -> Unit) { } @Composable -private fun SELinuxPanel(profile: Natives.Profile, onSELinuxChange: (domain: String, rules: String) -> Unit) { +private fun SELinuxPanel( + profile: Natives.Profile, + onSELinuxChange: (domain: String, rules: String) -> Unit +) { var showDialog by remember { mutableStateOf(false) } if (showDialog) { var domain by remember { mutableStateOf(profile.context) } - var rules by remember { mutableStateOf("") } + var rules by remember { mutableStateOf(profile.rules) } val inputOptions = listOf( InputTextField( @@ -382,7 +386,7 @@ private fun SELinuxPanel(profile: Natives.Profile, onSELinuxChange: (domain: Str // value can be a-zA-Z0-9_ val regex = Regex("^[a-z_]+:[a-z0-9_]+:[a-z0-9_]+(:[a-z0-9_]+)?$") if (value?.matches(regex) == true) ValidationResult.Valid - else ValidationResult.Invalid("Domain must be valid sepolicy") + else ValidationResult.Invalid("Domain must be in the format of \"user:role:type:level\"") } ), InputTextField( @@ -393,7 +397,6 @@ private fun SELinuxPanel(profile: Natives.Profile, onSELinuxChange: (domain: Str type = InputTextFieldType.OUTLINED, keyboardOptions = KeyboardOptions( keyboardType = KeyboardType.Ascii, - imeAction = ImeAction.Done ), singleLine = false, resultListener = { @@ -401,8 +404,8 @@ private fun SELinuxPanel(profile: Natives.Profile, onSELinuxChange: (domain: Str }, validationListener = { value -> if (isSepolicyValid(value)) ValidationResult.Valid - else ValidationResult.Invalid("Rules must be valid sepolicy") - }, + else ValidationResult.Invalid("SELinux rules is invalid!") + } ) ) diff --git a/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/AppProfile.kt b/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/AppProfile.kt index 89be4c48..1c353e4b 100644 --- a/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/AppProfile.kt +++ b/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/AppProfile.kt @@ -1,6 +1,5 @@ package me.weishu.kernelsu.ui.screen -import android.util.Log import androidx.annotation.StringRes import androidx.compose.animation.Crossfade import androidx.compose.foundation.gestures.detectTapGestures @@ -64,8 +63,10 @@ import me.weishu.kernelsu.ui.component.profile.AppProfileConfig import me.weishu.kernelsu.ui.component.profile.RootProfileConfig import me.weishu.kernelsu.ui.util.LocalSnackbarHost import me.weishu.kernelsu.ui.util.forceStopApp +import me.weishu.kernelsu.ui.util.getSepolicy import me.weishu.kernelsu.ui.util.launchApp import me.weishu.kernelsu.ui.util.restartApp +import me.weishu.kernelsu.ui.util.setSepolicy import me.weishu.kernelsu.ui.viewmodel.SuperUserViewModel /** @@ -83,10 +84,16 @@ fun AppProfileScreen( val scope = rememberCoroutineScope() val failToUpdateAppProfile = stringResource(R.string.failed_to_update_app_profile).format(appInfo.label) + val failToUpdateSepolicy = + stringResource(R.string.failed_to_update_sepolicy).format(appInfo.label) val packageName = appInfo.packageName + val initialProfile = Natives.getAppProfile(packageName, appInfo.uid) + if (initialProfile.allowSu) { + initialProfile.rules = getSepolicy(packageName) + } var profile by rememberSaveable { - mutableStateOf(Natives.getAppProfile(packageName, appInfo.uid)) + mutableStateOf(initialProfile) } Scaffold( @@ -114,6 +121,12 @@ fun AppProfileScreen( profile = profile, onProfileChange = { scope.launch { + if (it.allowSu && !it.rootUseDefault && it.rules.isNotEmpty()) { + if (!setSepolicy(profile.name, it.rules)) { + snackbarHost.showSnackbar(failToUpdateSepolicy) + return@launch + } + } if (!Natives.setAppProfile(it)) { snackbarHost.showSnackbar(failToUpdateAppProfile.format(appInfo.uid)) } else { diff --git a/manager/app/src/main/java/me/weishu/kernelsu/ui/util/KsuCli.kt b/manager/app/src/main/java/me/weishu/kernelsu/ui/util/KsuCli.kt index 784900aa..cfaf9397 100644 --- a/manager/app/src/main/java/me/weishu/kernelsu/ui/util/KsuCli.kt +++ b/manager/app/src/main/java/me/weishu/kernelsu/ui/util/KsuCli.kt @@ -147,7 +147,23 @@ fun isSepolicyValid(rules: String?): Boolean { } val shell = getRootShell() val result = - shell.newJob().add("ksud sepolicy check '$rules'").to(ArrayList(), null).exec() + shell.newJob().add("${getKsuDaemonPath()} sepolicy check '$rules'").to(ArrayList(), null).exec() + return result.isSuccess +} + +fun getSepolicy(pkg: String): String { + val shell = getRootShell() + val result = + shell.newJob().add("${getKsuDaemonPath()} profile get-sepolicy $pkg").to(ArrayList(), null).exec() + Log.i(TAG, "code: ${result.code}, out: ${result.out}, err: ${result.err}") + return result.out.joinToString("\n") +} + +fun setSepolicy(pkg: String, rules: String): Boolean { + val shell = getRootShell() + val result = + shell.newJob().add("${getKsuDaemonPath()} profile set-sepolicy $pkg '$rules'").to(ArrayList(), null).exec() + Log.i(TAG, "set sepolicy result: ${result.code}") return result.isSuccess } diff --git a/manager/app/src/main/res/values/strings.xml b/manager/app/src/main/res/values/strings.xml index 410581c0..cee42a43 100644 --- a/manager/app/src/main/res/values/strings.xml +++ b/manager/app/src/main/res/values/strings.xml @@ -83,4 +83,5 @@ Launch Force Stop Restart + Failed to update SELinux rules for: %s