Android 7.1 SElinux权限问题解决方案——编写APP,通过暗码读取TP fw版本

1.在底层,创建节点并给予访问节点的权限
2.在顶层添加暗码和调用的函数
3.编写app ReadHwid
4.编写app完后,发现通过电话拨号键 暗码*#850208# 显示:TP SW Version hello world!
5.权限解决方案
附加知识点

1、在底层,创建节点并给予访问节点的权限

kernel/msm-3.18/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_core.c

	__ATTR(buildid, (S_IRUGO | S_IWUSR | S_IWGRP),
			synaptics_rmi4_f01_buildid_show,
			synaptics_rmi4_store_error),
static ssize_t synaptics_rmi4_f01_buildid_show(struct device *dev,struct device_attribute *attr, char *buf)
{
	struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev);
	return snprintf(buf, PAGE_SIZE, "firmware_id:%u\n",
			rmi4_data->firmware_id);
}
static inline ssize_t synaptics_rmi4_store_error(struct device *dev,struct device_attribute *attr, const char *buf, size_t count)
{
	dev_warn(dev, "%s Attempted to write to read-only attribute %s\n",
			__func__, attr->attr.name);
	return -EPERM;
}

解析:buildid // 为节点名
S_IRUGO | S_IWUSR | S_IWGRP //用户可读|用户可写|小组用户可读可写权限
synaptics_rmi4_f01_buildid_show //显示函数,cat该文件时,此函数被调用
synaptics_rmi4_store_error //写函数,echo内容到该文件时,此函数被调用

通过adb可以查看到节点和TP FW的版本号:
在这里插入图片描述

2、在顶层添加暗码和调用的函数 /Halo/packages/apps/Dialer/src/com/android/dialer/SpecialCharSequenceMgr.java

@@ -81,6 +81,7 @@public class SpecialCharSequenceMgr {
     private static final String PRL_VERSION_DISPLAY = "*#0000#";
 
     private static final int IMEI_14_DIGIT = 14;
+    private static final String HWVESION = "*#850208#";
@@ -159,7 +160,8 @@ public class SpecialCharSequenceMgr {
                 || handleQSensorTest(context,dialString)
                 || handleEngineerTest(context, dialString)
                 || handleDeadCode(context, dialString)
-                || handleSecretCode(context, dialString)) {
+                || handleSecretCode(context, dialString)
+                               || handleRead_hwid(context, dialString)) {
             return true;
         }
@@ -459,24 +461,40 @@public class SpecialCharSequenceMgr {
         }
         return false;
     }
+       private static boolean handleRead_hwid(Context context, String input) {
+               if (input.equals(HWVESION)) {
+                       Log.d(TAG, "handleRead_hwid() sending intent to handleRead_hwid app");
+                       Intent handleRead_hwid = new Intent();
+                       try {
+                               ComponentName mComponentName = new ComponentName(
+                                               "com.android.ReadHwid",
+                                               "com.android.ReadHwid.ReadHwid");
+                               handleRead_hwid.setComponent(mComponentName);
+                               context.startActivity(handleRead_hwid);
+                       } catch (ActivityNotFoundException e) {
+                               Log.e(TAG, "startActivity() failed: " + e);
+                       }
+                       return true;
+               }
+               return false;
+       }

3、编写app ReadHwid

Halo/packages/apps/ReadHwid

--- a/Android.mk
+++ b/Android.mk
@@ -7,7 +7,7 @@ LOCAL_SRC_FILES := $(call all-java-files-under, src)
 LOCAL_PACKAGE_NAME := ReadHwid
-
+LOCAL_CERTIFICATE := platform
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -1,6 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.android.ReadHwid"
+    android:sharedUserId="android.uid.system"
--- a/src/com/android/ReadHwid/ReadHwid.java
+++ b/src/com/android/ReadHwid/ReadHwid.java
@@ -22,12 +22,11 @@ public class ReadHwid extends Activity {
         FileReader fr ;
         
         try {
-            File readFile = new File("/sys/bus/i2c/devices/12-004a/plugin_tag");
+            File readFile = new File("/sys/bus/i2c/devices/12-004b/input/input3/buildid");
            if (!readFile.exists()) {
                readFile = new File("/proc/gt1x_cfg");
-               if (!readFile.exists()) {
-                   readFile = new File("/sys/bus/i2c/devices/12-0038/ftstpfwver");
-               }
+       
+       
            }

4.编写完后,发现通过电话拨号键 暗码*#850208# 显示:TP SW Version hello world!

显然没有读出来buildid 。
cmdline 查看,adb临时赋予权限,adb 中设置selinux为permission模式:
在这里插入图片描述
再拨号*#850208# 界面显示 :TP SW Version firmware_id : 2810726
在这里插入图片描述
从而知道是因为ansroid selinux权限问题。

C:\Users\550134>adb shell
G0335D:/ # dmesg | grep avc
出现错误的kernel log:
[  476.686110] type=1400 audit(4216828.505:1596): avc: denied { read } for pid=4240 comm="ndroid.ReadHwid" name="buildid" dev="sysfs" ino=38920 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:sysfs:s0 tclass=file permissive=0
查看logcat log:
02-17 04:04:08.399  4715  4715 W ndroid.ReadHwid: type=1400 audit(0.0:1600): avc: denied { read } for name="buildid" dev="sysfs" ino=38920 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:sysfs:s0 tclass=file permissive=0
02-17 04:04:08.405  4715  4715 W System.err: java.io.FileNotFoundException: /sys/bus/i2c/devices/12-004b/input/input3/buildid (Permission denied)

也可以使用命令ps -Z 查看进程的安全上下文,结果com.android.ReadHwid 是untrusted app
在这里插入图片描述
我们要做就是赋予用户能访问com.android.ReadHwid 的读写权限。有两种方案,1)将untrusted app变为系统app,然后赋予读写权限 1)直接给这个untrusted app, com.android.ReadHwid 给读写权限

解析:
setenforce 0 //设置SELinux 成为permissive模式(SELinux开启,但对违反selinux规则的行为只记录,不会阻止)
setenforce 1 //设置SELinux 成为enforcing模式 (SELinux开启)
getenforce //获取SELinux状态(permissive,enforcing,disabled)

avc: denied { read } //表示没有读权限
comm=“ndroid.ReadHwid” //进程名
scontext=u:r:untrusted_app //源类型为 不信任的app
tcontext=u:object_r:sysfs //目标类型为sysfs
tclass=file //访问类型

5、权限解决方案:

方案一:要将untrusted app 变为system app 需要进行两处修改

1)、在AndroidMainefest.xml中配置,添加语句:android:sharedUserId=”android.uid.system”; //将untrusted APP 配置为系统APP 。G0335D_2/Halo/packages/app/ReadHwid/AndroidManifest.xml
2)、LOCAL_CERTIFICATE := platform //使用platform实现签名 。G0335D_2/Halo/packages/app/ReadHwid/Android.mk
变为系统app,adb 查看:
在这里插入图片描述
补充:SELinux(或SEAndroid)将app划分为主要三种类型(根据user不同,也有其他的domain类型):
(1)untrusted_app 第三方app,没有Android平台签名,没有system权限
(2)platform_app有Android平台签名,没有system权限
(3)system_app有Android平台签名和system权限
系统应用使用platform密钥进行签名,默认情况下,在Android源码中一共有四种密钥:platform、share、media、testkey。
platform:核心平台上的所有包(e.g: System UI、Setting、Phone、Bluetooth等)使用platform密钥签名。
share:搜索和联系人相关的包使用shared密钥签名。
media:图库和媒体相关的包使用media密钥签名。
testkey(releasekey):没有显示在自身makefile文件中指定密钥的包使用testkey(releasekey)密钥签名。
3)、添加读写权限,需要修改以下四个文件

(1)device/qcom/sepolicy/common/file.te
+#for TP FW id
+type sysfs_buildid, fs_type, sysfs_type;

(2)device/qcom/sepolicy/common/file_contexts
+# for TP fw id
+/sys/devices/soc/75ba000.i2c/i2c-12/12-004b/input/input3/buildid u:object_r:sysfs_buildid:s0

(3)device/qcom/sepolicy/common/system_app.te
+allow system_app sysfs_buildid:file rw_file_perms;

(4)system/core/rootdir/init.rc
+#for TP FW id
+chown system system /sys/devices/soc/75ba000.i2c/i2c-12/12-004b/input/input3/buildid

解析:allow 源类型 目标类型:访问类型 {操作权限};
file.te //定义目标类型sysfs_buildid 否则会出现sysfs_buildid无法识别。
file_contexts // 文件上下文,将实际节点和目标类型绑定
system_app.te //系统应用,system_app进程能够拥有对sysfs_buildid的这个字符设备的读写权限
system_server.te //系统应用服务,使得目标类型(type)和 源类型(domain) 绑定,并赋予目标类型读写权限
init.rc //赋予系统进程可以访问节点的权限

补充点:app 对应的te文件修改
system_app -> device/qcom/sepolicy/common/system_app.te
untrusted_app ->device/qcom/sepolicy/common/
platform_app ->device/qcom/sepolicy/common/platform_app.te

方案二:直接给这个untrusted app, com.android.ReadHwid 给读写权限

(1)device/qcom/sepolicy/common/file.te
+#for TP FW id
+type sysfs_buildid, fs_type, sysfs_type;
(2)device/qcom/sepolicy/common/file_contexts
+# for TP fw id
+/sys/devices/soc/75ba000.i2c/i2c-12/12-004b/input/input3/buildid u:object_r:sysfs_buildid:s0
(3)device/qcom/sepolicy/common/untrusted_app.te
+#for TP FW id
+allow untrusted_app sysfs_buildid:file rw_file_perms;
(5)system/core/rootdir/init.rc
+#for TP FW id
+chown system system /sys/devices/soc/75ba000.i2c/i2c-12/12-004b/input/input3/buildid

附加知识点

TP synaptics 节点路径是相等的
在这里插入图片描述
该路径下所有节点
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_42352255/article/details/85127209