diff --git a/kernel/allowlist.c b/kernel/allowlist.c index 4c8abe196b64..2cd47dfcc7a6 100644 --- a/kernel/allowlist.c +++ b/kernel/allowlist.c @@ -153,11 +153,6 @@ static bool profile_valid(struct app_profile *profile) return false; } - if (forbid_system_uid(profile->current_uid)) { - pr_err("uid lower than 2000 is unsupported: %d\n", profile->current_uid); - return false; - } - if (profile->version < KSU_APP_PROFILE_VER) { pr_info("Unsupported profile version: %d\n", profile->version); return false; 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 30e96e97aac3..278bfc0f88bb 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 @@ -95,6 +95,7 @@ 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 suNotAllowed = stringResource(R.string.su_not_allowed).format(appInfo.label) val packageName = appInfo.packageName val initialProfile = Natives.getAppProfile(packageName, appInfo.uid) @@ -143,8 +144,13 @@ fun AppProfileScreen( }, onProfileChange = { scope.launch { - if (it.allowSu && !it.rootUseDefault && it.rules.isNotEmpty()) { - if (!setSepolicy(profile.name, it.rules)) { + if (it.allowSu) { + // sync with allowlist.c - forbid_system_uid + if (appInfo.uid < 2000 && appInfo.uid != 1000) { + snackBarHost.showSnackbar(suNotAllowed) + return@launch + } + if (!it.rootUseDefault && it.rules.isNotEmpty() && !setSepolicy(profile.name, it.rules)) { snackBarHost.showSnackbar(failToUpdateSepolicy) return@launch } diff --git a/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/Flash.kt b/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/Flash.kt index c8bd8c861056..4719004e2dea 100644 --- a/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/Flash.kt +++ b/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/Flash.kt @@ -53,9 +53,10 @@ import kotlinx.coroutines.withContext import kotlinx.parcelize.Parcelize import me.weishu.kernelsu.R import me.weishu.kernelsu.ui.component.KeyEventBlocker +import me.weishu.kernelsu.ui.util.FlashResult import me.weishu.kernelsu.ui.util.LkmSelection import me.weishu.kernelsu.ui.util.LocalSnackbarHost -import me.weishu.kernelsu.ui.util.flashModule +import me.weishu.kernelsu.ui.util.flashModules import me.weishu.kernelsu.ui.util.installBoot import me.weishu.kernelsu.ui.util.reboot import me.weishu.kernelsu.ui.util.restoreBoot @@ -81,7 +82,7 @@ enum class FlashingStatus { fun FlashScreen(navigator: DestinationsNavigator, flashIt: FlashIt) { var text by rememberSaveable { mutableStateOf("") } - var tempText : String + var tempText: String val logContent = rememberSaveable { StringBuilder() } var showFloatAction by rememberSaveable { mutableStateOf(false) } @@ -98,16 +99,7 @@ fun FlashScreen(navigator: DestinationsNavigator, flashIt: FlashIt) { return@LaunchedEffect } withContext(Dispatchers.IO) { - flashIt(flashIt, onFinish = { showReboot, code -> - if (code != 0) { - text += "Error: exit code = $code.\nPlease save and check the log.\n" - } - if (showReboot) { - text += "\n\n\n" - showFloatAction = true - } - flashing = if (code == 0) FlashingStatus.SUCCESS else FlashingStatus.FAILED - }, onStdout = { + flashIt(flashIt, onStdout = { tempText = "$it\n" if (tempText.startsWith("")) { // clear command text = tempText.substring(6) @@ -117,7 +109,16 @@ fun FlashScreen(navigator: DestinationsNavigator, flashIt: FlashIt) { logContent.append(it).append("\n") }, onStderr = { logContent.append(it).append("\n") - }) + }).apply { + if (code != 0) { + text += "Error code: $code.\n $err Please save and check the log.\n" + } + if (showReboot) { + text += "\n\n\n" + showFloatAction = true + } + flashing = if (code == 0) FlashingStatus.SUCCESS else FlashingStatus.FAILED + } } } @@ -191,7 +192,7 @@ sealed class FlashIt : Parcelable { data class FlashBoot(val boot: Uri? = null, val lkm: LkmSelection, val ota: Boolean) : FlashIt() - data class FlashModule(val uri: Uri) : FlashIt() + data class FlashModules(val uri: List) : FlashIt() data object FlashRestore : FlashIt() @@ -199,25 +200,24 @@ sealed class FlashIt : Parcelable { } fun flashIt( - flashIt: FlashIt, onFinish: (Boolean, Int) -> Unit, + flashIt: FlashIt, onStdout: (String) -> Unit, onStderr: (String) -> Unit -) { - when (flashIt) { +): FlashResult { + return when (flashIt) { is FlashIt.FlashBoot -> installBoot( flashIt.boot, flashIt.lkm, flashIt.ota, - onFinish, onStdout, onStderr ) - is FlashIt.FlashModule -> flashModule(flashIt.uri, onFinish, onStdout, onStderr) + is FlashIt.FlashModules -> flashModules(flashIt.uri, onStdout, onStderr) - FlashIt.FlashRestore -> restoreBoot(onFinish, onStdout, onStderr) + FlashIt.FlashRestore -> restoreBoot(onStdout, onStderr) - FlashIt.FlashUninstall -> uninstallPermanently(onFinish, onStdout, onStderr) + FlashIt.FlashUninstall -> uninstallPermanently(onStdout, onStderr) } } diff --git a/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/Module.kt b/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/Module.kt index 9463d9449a69..beddc887b881 100644 --- a/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/Module.kt +++ b/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/Module.kt @@ -209,7 +209,7 @@ fun ModuleScreen(navigator: DestinationsNavigator) { val data = it.data ?: return@rememberLauncherForActivityResult val uri = data.data ?: return@rememberLauncherForActivityResult - navigator.navigate(FlashScreenDestination(FlashIt.FlashModule(uri))) + navigator.navigate(FlashScreenDestination(FlashIt.FlashModules(listOf(uri)))) viewModel.markNeedRefresh() @@ -254,7 +254,7 @@ fun ModuleScreen(navigator: DestinationsNavigator) { modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection), boxModifier = Modifier.padding(innerPadding), onInstallModule = { - navigator.navigate(FlashScreenDestination(FlashIt.FlashModule(it))) + navigator.navigate(FlashScreenDestination(FlashIt.FlashModules(listOf(it)))) }, onClickModule = { id, name, hasWebUi -> if (hasWebUi) { 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 8b325848405f..7ab5a1b56f67 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 @@ -33,6 +33,11 @@ private fun getKsuDaemonPath(): String { return ksuApp.applicationInfo.nativeLibraryDir + File.separator + "libksud.so" } +data class FlashResult(val code: Int, val err: String, val showReboot: Boolean) { + constructor(result: Shell.Result, showReboot: Boolean) : this(result.code, result.err.joinToString("\n"), showReboot) + constructor(result: Shell.Result) : this(result, result.isSuccess) +} + object KsuCli { val SHELL: Shell = createRootShell() val GLOBAL_MNT_SHELL: Shell = createRootShell(true) @@ -167,10 +172,9 @@ private fun flashWithIO( fun flashModule( uri: Uri, - onFinish: (Boolean, Int) -> Unit, onStdout: (String) -> Unit, onStderr: (String) -> Unit -): Boolean { +): FlashResult { val resolver = ksuApp.contentResolver with(resolver.openInputStream(uri)) { val file = File(ksuApp.cacheDir, "module.zip") @@ -183,11 +187,24 @@ fun flashModule( file.delete() - onFinish(result.isSuccess, result.code) - return result.isSuccess + return FlashResult(result) } } +fun flashModules( + uris: List, + onStdout: (String) -> Unit, + onStderr: (String) -> Unit +): FlashResult { + for (uri in uris) { + val result = flashModule(uri, onStdout, onStderr) + if (result.code != 0) { + return result + } + } + return FlashResult(0, "", true) +} + fun runModuleAction( moduleId: String, onStdout: (String) -> Unit, onStderr: (String) -> Unit ): Boolean { @@ -213,21 +230,19 @@ fun runModuleAction( } fun restoreBoot( - onFinish: (Boolean, Int) -> Unit, onStdout: (String) -> Unit, onStderr: (String) -> Unit -): Boolean { + onStdout: (String) -> Unit, onStderr: (String) -> Unit +): FlashResult { val magiskboot = File(ksuApp.applicationInfo.nativeLibraryDir, "libmagiskboot.so") val result = flashWithIO("${getKsuDaemonPath()} boot-restore -f --magiskboot $magiskboot", onStdout, onStderr) - onFinish(result.isSuccess, result.code) - return result.isSuccess + return FlashResult(result) } fun uninstallPermanently( - onFinish: (Boolean, Int) -> Unit, onStdout: (String) -> Unit, onStderr: (String) -> Unit -): Boolean { + onStdout: (String) -> Unit, onStderr: (String) -> Unit +): FlashResult { val magiskboot = File(ksuApp.applicationInfo.nativeLibraryDir, "libmagiskboot.so") val result = flashWithIO("${getKsuDaemonPath()} uninstall --magiskboot $magiskboot", onStdout, onStderr) - onFinish(result.isSuccess, result.code) - return result.isSuccess + return FlashResult(result) } suspend fun shrinkModules(): Boolean = withContext(Dispatchers.IO) { @@ -245,10 +260,9 @@ fun installBoot( bootUri: Uri?, lkm: LkmSelection, ota: Boolean, - onFinish: (Boolean, Int) -> Unit, onStdout: (String) -> Unit, onStderr: (String) -> Unit, -): Boolean { +): FlashResult { val resolver = ksuApp.contentResolver val bootFile = bootUri?.let { uri -> @@ -311,8 +325,7 @@ fun installBoot( lkmFile?.delete() // if boot uri is empty, it is direct install, when success, we should show reboot button - onFinish(bootUri == null && result.isSuccess, result.code) - return result.isSuccess + return FlashResult(result, bootUri == null && result.isSuccess) } fun reboot(reason: String = "") { diff --git a/manager/app/src/main/res/values-zh-rCN/strings.xml b/manager/app/src/main/res/values-zh-rCN/strings.xml index d22b434d5d6f..f29662697e62 100644 --- a/manager/app/src/main/res/values-zh-rCN/strings.xml +++ b/manager/app/src/main/res/values-zh-rCN/strings.xml @@ -81,6 +81,7 @@ 强制停止 重新启动 为 %s 更新 SELinux 策略失败 + 不允许授予:%s 超级用户权限 更新日志 App Profile 模版 管理本地和在线的 App Profile 模版 diff --git a/manager/app/src/main/res/values/strings.xml b/manager/app/src/main/res/values/strings.xml index 55f8d1e3b13e..ef226c92fbf8 100644 --- a/manager/app/src/main/res/values/strings.xml +++ b/manager/app/src/main/res/values/strings.xml @@ -83,6 +83,7 @@ Force stop Restart Failed to update SELinux rules for %s + Granting superuser to %s is not allowed Changelog App Profile Template Manage local and online template of App Profile