From 487e8355598920ac41390b2a6586c6d4a5d14e21 Mon Sep 17 00:00:00 2001 From: JingMatrix Date: Sat, 8 Nov 2025 20:13:53 +0100 Subject: [PATCH] Properly set SELinux context after reboot After reboot, the SELinux context labels for files located in `/data/adb` are reset to `u:object_r:adb_data_file:s0`. To fully address the issue in ed1f61d2, we should always compare the SELinux context and reset it when necessary. --- .../lspd/service/ConfigFileManager.java | 37 ++++++++++++++----- .../src/main/java/android/os/SELinux.java | 4 ++ 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/daemon/src/main/java/org/lsposed/lspd/service/ConfigFileManager.java b/daemon/src/main/java/org/lsposed/lspd/service/ConfigFileManager.java index e8e6943d..6e72014f 100644 --- a/daemon/src/main/java/org/lsposed/lspd/service/ConfigFileManager.java +++ b/daemon/src/main/java/org/lsposed/lspd/service/ConfigFileManager.java @@ -70,6 +70,7 @@ import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Locale; +import java.util.stream.Stream; import java.util.zip.Deflater; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; @@ -454,20 +455,38 @@ public class ConfigFileManager { static Path resolveModuleDir(String packageName, String dir, int userId, int uid) throws IOException { var path = modulePath.resolve(String.valueOf(userId)).resolve(packageName).resolve(dir).normalize(); - if (uid != -1) { - if (path.toFile().mkdirs()) { - try { - SELinux.setFileContext(path.toString(), "u:object_r:xposed_data:s0"); - Os.chown(path.toString(), uid, uid); - Os.chmod(path.toString(), 0755); - } catch (ErrnoException e) { - throw new IOException(e); - } + // Ensure the directory and any necessary parent directories exist. + path.toFile().mkdirs(); + + if (SELinux.getFileContext(path.toString()) != "u:object_r:xposed_data:s0") { + // SELinux label could be reset after a reboot. + try { + setSelinuxContextRecursive(path, "u:object_r:xposed_data:s0"); + Os.chown(path.toString(), uid, uid); + Os.chmod(path.toString(), 0755); + } catch (ErrnoException e) { + throw new IOException(e); } } return path; } + private static void setSelinuxContextRecursive(Path path, String context) throws IOException { + try { + SELinux.setFileContext(path.toString(), context); + + if (Files.isDirectory(path)) { + try (Stream stream = Files.list(path)) { + for (Path entry : (Iterable) stream::iterator) { + setSelinuxContextRecursive(entry, context); + } + } + } + } catch (Exception e) { + throw new IOException("Failed to recursively set SELinux context for " + path, e); + } + } + private static class FileLocker { private final FileChannel lockChannel; private final FileLock locker; diff --git a/hiddenapi/stubs/src/main/java/android/os/SELinux.java b/hiddenapi/stubs/src/main/java/android/os/SELinux.java index 991a84fe..2119bd29 100644 --- a/hiddenapi/stubs/src/main/java/android/os/SELinux.java +++ b/hiddenapi/stubs/src/main/java/android/os/SELinux.java @@ -9,6 +9,10 @@ public class SELinux { throw new UnsupportedOperationException("Stub"); } + public static String getFileContext(String path) { + throw new UnsupportedOperationException("Stub"); + } + public static boolean setFSCreateContext(String context){ throw new UnsupportedOperationException("Stub"); }