如何检测Android应用程序中是否启用了SELinux?

时间:2013-09-10 20:13:01

标签: android selinux

我正在尝试使用Google在我的Android应用程序中发布的SecureRandom解决方法: http://android-developers.blogspot.com/2013/08/some-securerandom-thoughts.html

这项工作涉及写入(和读取)/ dev / urandom。但是,看起来三星已经以防止应用程序访问/ dev / urandom的方式启用了SELinux。

我没有这些设备中的任何一个,所以对我来说测试解决方案有点困难,除了推出Android市场上的变通方法尝试,但似乎这不是我能做的错误陷阱与try catch块。看来File.canRead和canWrite也返回true。您可以在以下类的supportedOnThisDevice方法中查看我的变通方法尝试: PRNGFixes.java

我正在寻找一种可靠的方法来检测我是否是这样的设备,如果是这样,请不要应用Google SecureRandom解决方法。

5 个答案:

答案 0 :(得分:3)

这是我检查SELinux是否处于强制模式的方法 - 可以通过任何Shell脚本完成,而不是取决于RootTools:

private static boolean isSELinuxEnforcing() {
    try {
        CommandCapture command = new CommandCapture(1, "getenforce");
        RootTools.getShell(false).add(command).waitForFinish();
        boolean isSELinuxEnforcing = command.toString().trim().equalsIgnoreCase("enforcing");
        return isSELinuxEnforcing;
    } catch (Exception e) {
        // handle exception
    }
    return false;
}

答案 1 :(得分:2)

我听说三星开始将SELinux政策设置为Enforce的设备发货,但我不知道它是否属实。据我所知,4.3上的大多数设备仍然设置为允许。

根据谷歌的说法,"SELinux reinforcement is invisible to users and developers, and adds robustness to the existing Android security model while maintaining compatibility with existing applications."因此,您可能需要检查系统属性或通过shell进行测试,以确定无误。

如果您可以让某人向您发送他们的build.prop,您可以通过System.getProperty("ro.build.selinux")比较他们的ro.build.selinux属性来捕获它, 但是你也需要验证你是否能够更直接地访问它,以防它不可靠或者getProperty()在将来的更新中被破坏。

Root(SELinux上的系统用户)是可用的另一个选项,但无论哪种方式,基于shell的解决方案都可能是您最好的选择。

答案 2 :(得分:1)

System.getProperty("ro.build.selinux")

在Samsung S4 Android 4.3上没有为我工作。所以我写了这个

private static final int JELLY_BEAN_MR2 = 18;

public static boolean isSELinuxSupported() {
        // Didnt' work
        //String selinuxStatus = System.getProperty(PROPERTY_SELINUX_STATUS);
        //return selinuxStatus.equals("1") ? true : false;

        String selinuxFlag = getSelinuxFlag();

        if (!StringUtils.isEmpty(selinuxFlag)) {
            return selinuxFlag.equals("1") ? true : false;
        } else {
            // 4.3 or later ?
            if(Build.VERSION.SDK_INT >= JELLY_BEAN_MR2) {
                return true;
            }
            else {
                return false;
            }
        }       
}

public static String getSelinuxFlag() {
        String selinux = null;

        try {
            Class<?> c = Class.forName("android.os.SystemProperties");
            Method get = c.getMethod("get", String.class);
            selinux = (String) get.invoke(c, "ro.build.selinux");
        } catch (Exception ignored) {
        }

        return selinux;
}

答案 3 :(得分:1)

如果您有权访问框架

import android.os.SELinux;

SELinux.isSELinuxEnforced();

答案 4 :(得分:0)

Jellybean MR2及其后的大多数设备都会在其设备上启用SELinux,但如果您正在与OEM合作或进行平台工作,则可能不一定如此。

我用来验证的方法是使用getenforce shell命令:

public boolean isSeLinuxEnforcing() {
    StringBuffer output = new StringBuffer();
    Process p;
    try {
        p = Runtime.getRuntime().exec("getenforce");
        p.waitFor();
        BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
        String line = "";
        while ((line = reader.readLine())!= null) {
            output.append(line);
        }
    } catch (Exception e) {
        Log.e(TAG, "OS does not support getenforce");
        // If getenforce is not available to the device, assume the device is not enforcing
        e.printStackTrace();
        return false;
    }
    String response = output.toString();
    if ("Enforcing".equals(response)) {
        return true;
    } else if ("Permissive".equals(response)) {
        return false;
    } else {
        Log.e(TAG, "getenforce returned unexpected value, unable to determine selinux!");
        // If getenforce is modified on this device, assume the device is not enforcing
        return false;
    }
}

如果 在执行状态下运行,则大多数设备似乎只为selinux编写系统属性。您还可以检查属性: ro.boot.selinux ,以查看内核是否在当前版本的permissive参数中传递。