From 575941110956b0c32723da73b739663d06d42459 Mon Sep 17 00:00:00 2001 From: agnostic-apollo Date: Sat, 11 Jun 2022 14:10:34 +0500 Subject: [PATCH] Added: Add `SELinuxUtils` to get process and file paths security contexts --- .../termux/shared/android/SELinuxUtils.java | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 termux-shared/src/main/java/com/termux/shared/android/SELinuxUtils.java diff --git a/termux-shared/src/main/java/com/termux/shared/android/SELinuxUtils.java b/termux-shared/src/main/java/com/termux/shared/android/SELinuxUtils.java new file mode 100644 index 00000000..13810eb7 --- /dev/null +++ b/termux-shared/src/main/java/com/termux/shared/android/SELinuxUtils.java @@ -0,0 +1,96 @@ +package com.termux.shared.android; + +import android.annotation.SuppressLint; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.termux.shared.logger.Logger; +import com.termux.shared.reflection.ReflectionUtils; + +import java.lang.reflect.Method; + +public class SELinuxUtils { + + public static final String ANDROID_OS_SELINUX_CLASS = "android.os.SELinux"; + + private static final String LOG_TAG = "SELinuxUtils"; + + /** + * Gets the security context of the current process. + * + * @return Returns a {@link String} representing the security context of the current process. + * This will be {@code null} if an exception is raised. + */ + @Nullable + public static String getContext() { + ReflectionUtils.bypassHiddenAPIReflectionRestrictions(); + String methodName = "getContext"; + try { + @SuppressLint("PrivateApi") Class clazz = Class.forName(ANDROID_OS_SELINUX_CLASS); + Method method = ReflectionUtils.getDeclaredMethod(clazz, methodName); + if (method == null) { + Logger.logError(LOG_TAG, "Failed to get " + methodName + "() method of " + ANDROID_OS_SELINUX_CLASS + " class"); + return null; + } + + return (String) ReflectionUtils.invokeMethod(method, null).value; + } catch (Exception e) { + Logger.logStackTraceWithMessage(LOG_TAG, "Failed to call " + methodName + "() method of " + ANDROID_OS_SELINUX_CLASS + " class", e); + return null; + } + } + + /** + * Get the security context of a given process id. + * + * @param pid The pid of process. + * @return Returns a {@link String} representing the security context of the given pid. + * This will be {@code null} if an exception is raised. + */ + @Nullable + public static String getPidContext(int pid) { + ReflectionUtils.bypassHiddenAPIReflectionRestrictions(); + String methodName = "getPidContext"; + try { + @SuppressLint("PrivateApi") Class clazz = Class.forName(ANDROID_OS_SELINUX_CLASS); + Method method = ReflectionUtils.getDeclaredMethod(clazz, methodName, int.class); + if (method == null) { + Logger.logError(LOG_TAG, "Failed to get " + methodName + "() method of " + ANDROID_OS_SELINUX_CLASS + " class"); + return null; + } + + return (String) ReflectionUtils.invokeMethod(method, null, pid).value; + } catch (Exception e) { + Logger.logStackTraceWithMessage(LOG_TAG, "Failed to call " + methodName + "() method of " + ANDROID_OS_SELINUX_CLASS + " class", e); + return null; + } + } + + /** + * Get the security context of a file object. + * + * @param path The pathname of the file object. + * @return Returns a {@link String} representing the security context of the file. + * This will be {@code null} if an exception is raised. + */ + @Nullable + public static String getFileContext(@NonNull String path) { + ReflectionUtils.bypassHiddenAPIReflectionRestrictions(); + String methodName = "getFileContext"; + try { + @SuppressLint("PrivateApi") Class clazz = Class.forName(ANDROID_OS_SELINUX_CLASS); + Method method = ReflectionUtils.getDeclaredMethod(clazz, methodName, String.class); + if (method == null) { + Logger.logError(LOG_TAG, "Failed to get " + methodName + "() method of " + ANDROID_OS_SELINUX_CLASS + " class"); + return null; + } + + return (String) ReflectionUtils.invokeMethod(method, null, path).value; + } catch (Exception e) { + Logger.logStackTraceWithMessage(LOG_TAG, "Failed to call " + methodName + "() method of " + ANDROID_OS_SELINUX_CLASS + " class", e); + return null; + } + } + +}