自定义AOSP系统服务调用特权方法的实现问题咨询
问题解答
报错原因
你遇到的异常是因为Android Binder机制会自动携带原始调用方的身份标识(UID/PID),你在自定义系统服务中调用DevicePolicyManager.lockNow()时,系统校验的是发起请求的普通应用UID(10136),而非你自定义系统服务的UID(1000),普通应用没有激活设备管理员权限,因此触发安全异常。
核心疑问解答
完全可以在自定义AOSP系统服务中封装特权操作,再暴露给普通应用调用,这是定制ROM时非常常用的「权限封装降级」方案,不需要普通应用持有特权权限或设备管理员身份。
修复方案
你只需要在调用特权操作前,清除Binder调用上下文里的原始调用者身份,操作完成后再恢复身份即可,修改后的PocService代码如下:
public class PocService extends IPocServiceManagerAidlInterface.Stub { private final static String LOG_TAG = "PocService"; private final Context mContext; PocService(Context context) { mContext = context; } @Override public void lock() throws RemoteException { Slog.i(LOG_TAG,"PocService UID: " + android.os.Process.myUid()); // 保存原始调用者身份标识 final long identityToken = Binder.clearCallingIdentity(); try { DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(DevicePolicyManager.class); dpm.lockNow(); } finally { // 恢复原始调用者身份,避免后续逻辑出现权限校验错误 Binder.restoreCallingIdentity(identityToken); } } }
额外注意事项
- 你自定义的系统服务运行在system_server进程,UID为1000,默认已经持有调用
lockNow()所需的特权权限,不需要额外声明权限即可正常执行。 - 为了避免任意普通应用都能调用你暴露的特权接口,建议新增自定义权限,在
PocService的接口入口处校验调用方是否持有你定义的权限,避免能力被滥用。 - 如果后续封装其他需要特定权限的特权操作,只需要确保system_server进程已持有对应权限,再按上述方案清除调用者身份即可正常调用。
内容的提问来源于stack exchange,提问作者Gabe
相关产品推荐
相关产品推荐

