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

问题描述 投票:0回答:6

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

此工作涉及写入(和读取)/dev/urandom。然而,三星似乎已启用 SELinux,以阻止应用程序访问 /dev/urandom。

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

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

android selinux
6个回答
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;
}

2
投票

我听说三星开始发售将 SELinux 策略设置为强制执行的设备,但我不知道这是否属实。据我所知,4.3 上的大多数设备仍然将其设置为宽容。

根据 Google 的说法,“SELinux 强化对于用户和开发人员来说是不可见的,它为现有 Android 安全模型增加了稳健性,同时保持了与现有应用程序的兼容性。” 因此,您可能需要检查系统属性或通过 shell 进行测试确定一下。

如果你能让某人向你发送他们的 build.prop,你也许可以通过

System.getProperty("ro.build.selinux")
比较他们的 ro.build.selinux 属性来捕获它, 但您还需要验证您是否能够更直接地访问它,以防它不可靠或 getProperty() 在未来的更新中被破坏。

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


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;
}

1
投票

如果您有权访问框架

import android.os.SELinux;

SELinux.isSELinuxEnforced();

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以查看内核是否在当前构建上传递了许可参数。


0
投票

public static String getviarefSelinuxFlag(Context ctx) { try { Class<?> cls = Class.forName("android.os.SELinux"); Object newInstance = cls.getConstructor(Context.class).newInstance(ctx); Method method = cls.getMethod("isSELinuxEnforced"); Method method1 = cls.getMethod("isSELinuxEnabled"); Boolean SELinuxEnforced = (Boolean) method.invoke(null); Boolean SELinuxEnabled = (Boolean) method1.invoke(null); return "isSELinuxEnforced : " + SELinuxEnforced + "\nisSELinuxEnabled : " + SELinuxEnabled; } catch (Exception ignored) { return "Method not working"; } }

© www.soinside.com 2019 - 2024. All rights reserved.