无法调用android.os.SystemProperties.set方法设置系统属性的问题研究

com.test.testservice 无法调用android.os.SystemProperties.set方法的问题研究

error log:
E AndroidRuntime: java.lang.RuntimeException: Unable to create service com.test.testservice.testService: java.lang.RuntimeException: Can not invoke android.os.SystemProperties.set method

crash log:
--------- beginning of crash
 23927 23927 E AndroidRuntime: FATAL EXCEPTION: main
 23927 23927 E AndroidRuntime: Process: com.test.testservice, PID: 23927
 23927 23927 E AndroidRuntime: java.lang.RuntimeException: Unable to create service com.test.testservice.testService: java.lang.RuntimeException: Can not invoke android.os.SystemProperties.set method
 23927 23927 E AndroidRuntime:     at android.app.ActivityThread.handleCreateService(ActivityThread.java:4134)
 23927 23927 E AndroidRuntime:     at android.app.ActivityThread.access$1800(ActivityThread.java:229)
 23927 23927 E AndroidRuntime:     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1993)
 23927 23927 E AndroidRuntime:     at android.os.Handler.dispatchMessage(Handler.java:107)
 23927 23927 E AndroidRuntime:     at android.os.Looper.loop(Looper.java:214)
 23927 23927 E AndroidRuntime:     at android.app.ActivityThread.main(ActivityThread.java:7582)
 23927 23927 E AndroidRuntime:     at java.lang.reflect.Method.invoke(Native Method)
 23927 23927 E AndroidRuntime:     at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
 23927 23927 E AndroidRuntime:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:960)
 23927 23927 E AndroidRuntime: Caused by: java.lang.RuntimeException: Can not invoke android.os.SystemProperties.set method
 23927 23927 E AndroidRuntime:     at com.test.testservice.SystemProperties.set(SystemProperties.java:32)
 23927 23927 E AndroidRuntime:     at com.test.testservice.testService.onCreate(testService.java:593)
 23927 23927 E AndroidRuntime:     at android.app.ActivityThread.handleCreateService(ActivityThread.java:4122)
 23927 23927 E AndroidRuntime:     ... 8 more
 23927 23927 E AndroidRuntime: Caused by: java.lang.reflect.InvocationTargetException
 23927 23927 E AndroidRuntime:     at java.lang.reflect.Method.invoke(Native Method)
 23927 23927 E AndroidRuntime:     at com.test.testservice.SystemProperties.set(SystemProperties.java:28)
 23927 23927 E AndroidRuntime:     ... 10 more
 23927 23927 E AndroidRuntime: Caused by: java.lang.RuntimeException: failed to set system property
 23927 23927 E AndroidRuntime:     at android.os.SystemProperties.native_set(Native Method)
 23927 23927 E AndroidRuntime:     at android.os.SystemProperties.set(SystemProperties.java:196)
 23927 23927 E AndroidRuntime:     ... 12 more
  1496  6228 V RescueParty: Disabled because of active USB connection
  1496  6228 W ActivityManager: Process com.test.testservice has crashed too many times: killing!
 23927 23927 I Process : Sending signal. PID: 23927 SIG: 9
  1496  6227 I ActivityManager: Process com.test.testservice (pid 23927) has died: pers PER 
======

SystemProperties.set()调查:
在对Android操作系统进行开发的过程中,经常需要使用到Android的隐藏API SystemProperties.set(String key, String value) 这个接口,写入一些属性值存放到系统共享内存,配合SystemProperties.get(String key) 这个接口可以很方便的实现某些功能。由于是android:sharedUserId=“android.uid.system” 的系统级应用,有权限操作类似的隐藏接口。比如可以定义一个persist.test.meid 的属性来保存系统的MEID号,以方便第三方应用开发者获取。
在Android5.0之前,系统级应用可以很方便的写入规范(比如属性key、value的长度有一定限制等)的属性,在这之后,Android系统引入了SELinux,所有的操作都有相应的权限组,任意写入一个属性也会抛出错误,即使是系统级应用.

源代码中关于testservice的权限设置如下:
1. 定义服务名称和属性

sepolicy/property_contexts:    test.                  u:object_r:test_prop:s0
sepolicy/property.te:          type test_prop, property_type;
sepolicy/system_app.te:       #set_prop(system_app, test_prop)

2. 在代码文件sepolicy/system_app.te中做如下修改尝试解决问题

diff --git a/sepolicy/system_app.te b/common/sepolicy/system_app.te
 # test_START
+set_prop(system_app, test_prop)
 # test_END
 
diff --git a/sepolicy/system_server.te b/sepolicy/system_server.te
 # test_START
+set_prop(system_server, test_prop)
 # test_END
//set_prop(system_server, test_prop) 和 allow system_server test_prop:property_service set;意义相等

但是这个方法在android Q上会有编译错误,如下:
[ 21% 1176/5556] build out/target/×/precompiled_sepolicy_intermediates/precompiled_sepolicy
FAILED: out/target/×/precompiled_sepolicy_intermediates/precompiled_sepolicy
/bin/bash -c "out/host/linux-x86/bin/secilc -m -M true -G -c 30          out/target/×/plat_sepolicy.cil_intermediates/plat_sepolicy.cil out/target/×/plat_mapping_file_intermediates/29.0.cil out/target/×/plat_pub_versioned.cil_intermediates/plat_pub_versioned.cil out/target/×/vendor_sepolicy.cil_intermediates/vendor_sepolicy.cil -o out/target/×/precompiled_sepolicy_intermediates/precompiled_sepolicy -f /dev/null"
neverallow check failed at out/target/×/plat_pub_versioned.cil_intermediates/plat_pub_versioned.cil
  (neverallow base_typeattr_470_29_0 base_typeattr_471_29_0 (property_service (set)))
    <root>
    allow at out/target/×/vendor_sepolicy.cil_intermediates/vendor_sepolicy.cil:8995
      (allow system_app_29_0 test_prop (property_service (set)))

neverallow check failed at out/target/×/plat_sepolicy.cil_intermediates/plat_sepolicy.cil:11946 from system/sepolicy/public/property.te
  (neverallow base_typeattr_470 base_typeattr_471 (property_service (set)))
    <root>
    allow at out/target/×/vendor_sepolicy.cil_intermediates/vendor_sepolicy.cil:8995
      (allow system_app_29_0 test_prop (property_service (set)))

Failed to generate binary
Failed to build policydb
ninja: build stopped: subcommand failed.


3. 最终的解决方法:  添加exported_system_prop到property_contexts文件

diff --git a/sepolicy/property_contexts
 # test_START
+test.                  u:object_r:exported_system_prop:s0 exact string
 # test_END
 //关于exported_system_prop目前的资料较少,有待进行深入研究

4.SELinux的基本介绍
SELinux非常繁杂,8.0开始的Treble Project后,为了实现system、vendor分区的隔离,selinux的机制变的更加繁琐。

语法:rule_name source_type target_type : class perm_set
allow system_app misc_user_data_file:file create_file_perms;
get_prop(system_app, system_prop) 其实是一个宏,展开如下:
allow system_app system_prop:file r_file_perms; #/dev/__properties__/system_prop

ROM:
selinux编译生成的策略文件sepolicy,8.0之前在boot.img中,8.0由于treble的原因,system和vendor分区各放置一部分,加载的时候会进行合并。8.0之后单刷userdebug版本的boot不再能获取root权限,要刷userdebug版的system.img才行。
/system/etc/selinux:
plat_file_contexts
plat_property_contexts
plat_sepolicy.cil
/vendor/etc/selinux:
vendor_file_contexts
vendor_property_contexts
vendor_sepolicy.cil

猜你喜欢

转载自blog.csdn.net/sinat_37343534/article/details/102630554
今日推荐