Android L版本后native process无法使用am pm等命令的说明
时间:10-02
整理:3721RD
点击:
[Description]
android L 版本后native process 无法使用am pm 等命令的说明
[Keyword]
SElinux, Native process, am, pm,
[Android Version]
Version >= android 5.0
[Solution]
在android 5.0 后, 默认启用了Enforcing SELinux. Google 通过SELinux 严禁普通的native
process 执行非system image 中的非exec类型的文件, 如data/dalvik-cache 下面的odex 文件,
从而native process 无法直接执行am, pm 等命令.
//external/sepolicy/domain.te
neverallow {
domain
-appdomain
-dumpstate
-shell
userdebug_or_eng(`-su')
-system_server
-zygote
} { file_type -system_file -exec_type }:file execute;
neverallow {
domain
-appdomain # for oemfs
-recovery # for /tmp/update_binary in tmpfs
} { fs_type -rootfs }:file execute;
通常我们解决的方式是,通过binder 直接使用 activity 等service接口, 直接向AMS 发送指令来
规避这一条。
注意这个同样要求你的process 有操作binder 的SELinux 权限,这个Google 不会限制。
在我们的代码中已经有很多类似的这样案例,大家可以参考:
php?mod=tag&id=6090" target="_blank" class="relatedlink">Frameworks/av/media/libmediaplayerservice/ActivityManager.cpp
/vendor/mediatek/proprietary/external/ds1_utility/ds1_utility.cpp
/vendor/mediatek/proprietary/external/Batterywarning/batterywarning.cpp
/frameworks/av/services/audioflinger/AudioLosslessBTBroADCast.cpp
/vendor/mediatek/proprietary/packages/apps/mtkThermalManager/jni/thermald.cpp
通常首先:
#include <unistd.h>
#include <binder/IBinder.h>
#include <binder/IServiceManager.h>
#include <binder/Parcel.h>
#include <utils/String8.h>
(1). 获取am service
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> am = sm->getService(String16("activity"));
(2). 填充传送参数Parcel data, 准备好Parcel reply
data.writeInterfaceToken(String16("android.app.IActivityManager"));
.....
(3). 执行binder
status_t ret = am->transact(XXXXXX_TRANSACTION, data, &reply);
这些cmd 都定义在/frameworks/base/core/java/android/app/IActivityManager.Java , 可选择查
看.
(4). 解析返回的ret 和 reply.
比如:
if (ret == NO_ERROR) {
int exceptionCode = reply.readExceptionCode();
if (exceptionCode) {
ALOGE("sendBroadcastMessage(%s) caught exception %d\n", action.string(),
exceptionCode);
return false;
}
} else {
return false;
}
Parcel 参数的填充过程可以参考:
/frameworks/base/core/java/android/app/ActivityManagerNative.java
CMD 参数列表可以参考:
/frameworks/base/core/java/android/app/IActivityManager.java
android L 版本后native process 无法使用am pm 等命令的说明
[Keyword]
SElinux, Native process, am, pm,
[Android Version]
Version >= android 5.0
[Solution]
在android 5.0 后, 默认启用了Enforcing SELinux. Google 通过SELinux 严禁普通的native
process 执行非system image 中的非exec类型的文件, 如data/dalvik-cache 下面的odex 文件,
从而native process 无法直接执行am, pm 等命令.
//external/sepolicy/domain.te
neverallow {
domain
-appdomain
-dumpstate
-shell
userdebug_or_eng(`-su')
-system_server
-zygote
} { file_type -system_file -exec_type }:file execute;
neverallow {
domain
-appdomain # for oemfs
-recovery # for /tmp/update_binary in tmpfs
} { fs_type -rootfs }:file execute;
通常我们解决的方式是,通过binder 直接使用 activity 等service接口, 直接向AMS 发送指令来
规避这一条。
注意这个同样要求你的process 有操作binder 的SELinux 权限,这个Google 不会限制。
在我们的代码中已经有很多类似的这样案例,大家可以参考:
php?mod=tag&id=6090" target="_blank" class="relatedlink">Frameworks/av/media/libmediaplayerservice/ActivityManager.cpp
/vendor/mediatek/proprietary/external/ds1_utility/ds1_utility.cpp
/vendor/mediatek/proprietary/external/Batterywarning/batterywarning.cpp
/frameworks/av/services/audioflinger/AudioLosslessBTBroADCast.cpp
/vendor/mediatek/proprietary/packages/apps/mtkThermalManager/jni/thermald.cpp
通常首先:
#include <unistd.h>
#include <binder/IBinder.h>
#include <binder/IServiceManager.h>
#include <binder/Parcel.h>
#include <utils/String8.h>
(1). 获取am service
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> am = sm->getService(String16("activity"));
(2). 填充传送参数Parcel data, 准备好Parcel reply
data.writeInterfaceToken(String16("android.app.IActivityManager"));
.....
(3). 执行binder
status_t ret = am->transact(XXXXXX_TRANSACTION, data, &reply);
这些cmd 都定义在/frameworks/base/core/java/android/app/IActivityManager.Java , 可选择查
看.
(4). 解析返回的ret 和 reply.
比如:
if (ret == NO_ERROR) {
int exceptionCode = reply.readExceptionCode();
if (exceptionCode) {
ALOGE("sendBroadcastMessage(%s) caught exception %d\n", action.string(),
exceptionCode);
return false;
}
} else {
return false;
}
Parcel 参数的填充过程可以参考:
/frameworks/base/core/java/android/app/ActivityManagerNative.java
CMD 参数列表可以参考:
/frameworks/base/core/java/android/app/IActivityManager.java
沙发
谢谢支持V