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

如何检测android应用程序中是否启用了SELinux?,android,selinux,Android,Selinux,我正在尝试使用谷歌在我的android应用程序中发布的SecureRandom解决方案: 这项工作包括向/dev/uradom写信(并从中阅读)。然而,三星似乎以阻止应用程序访问/dev/uradom的方式启用了SELinux 我没有这些设备,所以除了在Android市场上推出解决方案之外,测试解决方案对我来说有点困难,但这似乎不是一个我可以用try-catch块捕获的错误。看起来File.canRead和canWrite也返回true。您可以在以下类中的supportedOnThisDevi

我正在尝试使用谷歌在我的android应用程序中发布的SecureRandom解决方案:

这项工作包括向/dev/uradom写信(并从中阅读)。然而,三星似乎以阻止应用程序访问/dev/uradom的方式启用了SELinux

我没有这些设备,所以除了在Android市场上推出解决方案之外,测试解决方案对我来说有点困难,但这似乎不是一个我可以用try-catch块捕获的错误。看起来File.canRead和canWrite也返回true。您可以在以下类中的supportedOnThisDevice方法中看到我的解决方法尝试:


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

我听说三星已经开始发布设置了SELinux策略的设备,但我不知道这是真是假。据我所知,4.3上的大多数设备仍将其设置为“允许”

根据谷歌的说法,因此你可能需要检查系统属性或通过shell进行测试以确定答案

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

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

System.getProperty("ro.build.selinux")
在三星S4安卓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;
}
private static final int JELLY\u BEAN\u MR2=18;
公共静态布尔值isSELinuxSupported(){
//他没有工作
//字符串selinuxStatus=System.getProperty(属性\u SELINUX\u状态);
//返回selinuxStatus.equals(“1”)?true:false;
字符串selinuxFlag=getSelinuxFlag();
如果(!StringUtils.isEmpty(selinux-xflag)){
返回selinuxFlag.equals(“1”)?true:false;
}否则{
//4.3或更高版本?
if(Build.VERSION.SDK\u INT>=JELLY\u BEAN\u MR2){
返回true;
}
否则{
返回false;
}
}       
}
公共静态字符串getSelinuxFlag(){
字符串selinux=null;
试一试{
Class c=Class.forName(“android.os.SystemProperties”);
方法get=c.getMethod(“get”,String.class);
selinux=(String)get.invoke(c,“ro.build.selinux”);
}捕获(忽略异常){
}
返回selinux;
}

这是我检查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;
}

自Jellybean MR2及以后的大多数设备都将在其设备上启用SELinux,但如果您与OEM合作或从事平台工作,这可能不一定是真的

我用于验证的方法是使用getEnforceShell命令:

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,查看内核是否在当前版本中传递了许可参数。

如果您有权访问框架

import android.os.SELinux;

SELinux.isSELinuxEnforced();

此方法的返回值是什么?isSELinuxSupported返回true(如果存在SELinux)或FALSE在我的一些设备上强制执行SELinux,但
ro.build.SELinux
没有值,因此不可靠。