You've already forked KernelSU-Next
mirror of
https://github.com/KernelSU-Next/KernelSU-Next.git
synced 2025-08-27 23:46:34 +00:00
manager | ksud: Add toggle for global mount namespace (#99)
* This is untested, if you facing any issues, open a new issue or comments at our group * and also, this changes maybe reverted if didn't meet the target. Taken from Apatch's implementations:8de6b9d67657d527a846f093d6a633Critics are welcome! Signed-off-by: rsuntk <90097027+rsuntk@users.noreply.github.com>
This commit is contained in:
committed by
Rifat Azad
parent
a917314e84
commit
c6b5440682
@@ -120,6 +120,9 @@ object Natives {
|
|||||||
return version < MINIMAL_SUPPORTED_KERNEL
|
return version < MINIMAL_SUPPORTED_KERNEL
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val KSU_WORK_DIR = "/data/adb/ksu/"
|
||||||
|
val GLOBAL_NAMESPACE_FILE = KSU_WORK_DIR + ".global_mnt"
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
@Parcelize
|
@Parcelize
|
||||||
@Keep
|
@Keep
|
||||||
|
|||||||
@@ -88,6 +88,8 @@ import com.rifsxd.ksunext.ui.component.rememberLoadingDialog
|
|||||||
import com.rifsxd.ksunext.ui.util.LocalSnackbarHost
|
import com.rifsxd.ksunext.ui.util.LocalSnackbarHost
|
||||||
import com.rifsxd.ksunext.ui.util.getBugreportFile
|
import com.rifsxd.ksunext.ui.util.getBugreportFile
|
||||||
import com.rifsxd.ksunext.ui.util.*
|
import com.rifsxd.ksunext.ui.util.*
|
||||||
|
import com.rifsxd.ksunext.ui.util.isGlobalNamespaceEnabled
|
||||||
|
import com.rifsxd.ksunext.ui.util.setGlobalNamespaceEnabled
|
||||||
import java.time.LocalDateTime
|
import java.time.LocalDateTime
|
||||||
import java.time.format.DateTimeFormatter
|
import java.time.format.DateTimeFormatter
|
||||||
|
|
||||||
@@ -101,6 +103,8 @@ import java.time.format.DateTimeFormatter
|
|||||||
fun SettingScreen(navigator: DestinationsNavigator) {
|
fun SettingScreen(navigator: DestinationsNavigator) {
|
||||||
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState())
|
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState())
|
||||||
val snackBarHost = LocalSnackbarHost.current
|
val snackBarHost = LocalSnackbarHost.current
|
||||||
|
var isGlobalNamespaceEnabled by rememberSaveable { mutableStateOf(false) }
|
||||||
|
isGlobalNamespaceEnabled = isGlobalNamespaceEnabled()
|
||||||
|
|
||||||
val isManager = Natives.becomeManager(ksuApp.packageName)
|
val isManager = Natives.becomeManager(ksuApp.packageName)
|
||||||
val ksuVersion = if (isManager) Natives.version else null
|
val ksuVersion = if (isManager) Natives.version else null
|
||||||
@@ -196,6 +200,23 @@ fun SettingScreen(navigator: DestinationsNavigator) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SwitchItem(
|
||||||
|
icon = Icons.Filled.Engineering,
|
||||||
|
title = stringResource(id = R.string.settings_global_namespace_mode),
|
||||||
|
summary = stringResource(id = R.string.settings_global_namespace_mode_summary),
|
||||||
|
checked = isGlobalNamespaceEnabled,
|
||||||
|
onCheckedChange = {
|
||||||
|
setGlobalNamespaceEnabled(
|
||||||
|
if (isGlobalNamespaceEnabled) {
|
||||||
|
"0"
|
||||||
|
} else {
|
||||||
|
"1"
|
||||||
|
}
|
||||||
|
)
|
||||||
|
isGlobalNamespaceEnabled = it
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
val prefs = context.getSharedPreferences("settings", Context.MODE_PRIVATE)
|
val prefs = context.getSharedPreferences("settings", Context.MODE_PRIVATE)
|
||||||
|
|||||||
@@ -103,7 +103,10 @@ fun Uri.getFileName(context: Context): String? {
|
|||||||
|
|
||||||
fun createRootShell(globalMnt: Boolean = false): Shell {
|
fun createRootShell(globalMnt: Boolean = false): Shell {
|
||||||
Shell.enableVerboseLogging = BuildConfig.DEBUG
|
Shell.enableVerboseLogging = BuildConfig.DEBUG
|
||||||
val builder = Shell.Builder.create()
|
val builder = Shell.Builder.create().apply {
|
||||||
|
setFlags(Shell.FLAG_MOUNT_MASTER)
|
||||||
|
}
|
||||||
|
|
||||||
return try {
|
return try {
|
||||||
if (globalMnt) {
|
if (globalMnt) {
|
||||||
builder.build(ksuDaemonMagicPath(), "debug", "su", "-g")
|
builder.build(ksuDaemonMagicPath(), "debug", "su", "-g")
|
||||||
@@ -403,6 +406,22 @@ fun hasMagisk(): Boolean {
|
|||||||
return result.isSuccess
|
return result.isSuccess
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun isGlobalNamespaceEnabled(): Boolean {
|
||||||
|
val shell = getRootShell()
|
||||||
|
val result =
|
||||||
|
ShellUtils.fastCmd(shell, "nsenter --mount=/proc/1/ns/mnt cat ${Natives.GLOBAL_NAMESPACE_FILE}")
|
||||||
|
Log.i(TAG, "is global namespace enabled: $result")
|
||||||
|
return result == "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setGlobalNamespaceEnabled(value: String) {
|
||||||
|
getRootShell().newJob()
|
||||||
|
.add("nsenter --mount=/proc/1/ns/mnt echo $value > ${Natives.GLOBAL_NAMESPACE_FILE}")
|
||||||
|
.submit { result ->
|
||||||
|
Log.i(TAG, "setGlobalNamespaceEnabled result: ${result.isSuccess} [${result.out}]")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun isSepolicyValid(rules: String?): Boolean {
|
fun isSepolicyValid(rules: String?): Boolean {
|
||||||
if (rules == null) {
|
if (rules == null) {
|
||||||
return true
|
return true
|
||||||
|
|||||||
@@ -231,4 +231,6 @@
|
|||||||
<string name="module_sort_enabled_first">Sort (Enabled first)</string>
|
<string name="module_sort_enabled_first">Sort (Enabled first)</string>
|
||||||
<string name="module_sort_action_first">Sort (Action first)</string>
|
<string name="module_sort_action_first">Sort (Action first)</string>
|
||||||
<string name="module_sort_webui_first">Sort (WebUI first)</string>
|
<string name="module_sort_webui_first">Sort (WebUI first)</string>
|
||||||
|
<string name="settings_global_namespace_mode">Global Namespace Mode</string>
|
||||||
|
<string name="settings_global_namespace_mode_summary">All root sessions use the global mount namespace</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -44,3 +44,5 @@ pub const NO_TMPFS_PATH: &str = concatcp!(WORKING_DIR, ".notmpfs");
|
|||||||
pub const NO_MOUNT_PATH: &str = concatcp!(WORKING_DIR, ".nomount");
|
pub const NO_MOUNT_PATH: &str = concatcp!(WORKING_DIR, ".nomount");
|
||||||
|
|
||||||
pub const MOUNT_SYSTEM: &str = "Magic_Mount";
|
pub const MOUNT_SYSTEM: &str = "Magic_Mount";
|
||||||
|
|
||||||
|
pub const GLOBAL_NAMESPACE_FILE: &str = concatcp!(WORKING_DIR, ".global_mnt");
|
||||||
@@ -261,7 +261,10 @@ pub fn root_shell() -> Result<()> {
|
|||||||
|
|
||||||
// switch to global mount namespace
|
// switch to global mount namespace
|
||||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||||
if mount_master {
|
let global_namespace_enable =
|
||||||
|
std::fs::read_to_string(defs::GLOBAL_NAMESPACE_FILE)
|
||||||
|
.unwrap_or("0".to_string());
|
||||||
|
if global_namespace_enable.trim() == "1" || mount_master {
|
||||||
let _ = utils::switch_mnt_ns(1);
|
let _ = utils::switch_mnt_ns(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -47,3 +47,5 @@ pub const KSU_BACKUP_FILE_PREFIX: &str = "ksu_backup_";
|
|||||||
pub const BACKUP_FILENAME: &str = "stock_image.sha1";
|
pub const BACKUP_FILENAME: &str = "stock_image.sha1";
|
||||||
|
|
||||||
pub const MOUNT_SYSTEM: &str = "OverlayFS";
|
pub const MOUNT_SYSTEM: &str = "OverlayFS";
|
||||||
|
|
||||||
|
pub const GLOBAL_NAMESPACE_FILE: &str = concatcp!(WORKING_DIR, ".global_mnt");
|
||||||
|
|||||||
@@ -261,7 +261,10 @@ pub fn root_shell() -> Result<()> {
|
|||||||
|
|
||||||
// switch to global mount namespace
|
// switch to global mount namespace
|
||||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||||
if mount_master {
|
let global_namespace_enable =
|
||||||
|
std::fs::read_to_string(defs::GLOBAL_NAMESPACE_FILE)
|
||||||
|
.unwrap_or("0".to_string());
|
||||||
|
if global_namespace_enable.trim() == "1" || mount_master {
|
||||||
let _ = utils::switch_mnt_ns(1);
|
let _ = utils::switch_mnt_ns(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user