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