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