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 節點路徑是相等的
該路徑下所有節點