如何解决错误Given calling package android does not match caller‘s uid-学员提问

171 阅读2分钟

背景:

近来有学员反馈说wms课程中讲解的借壳Shell帮忙执行一些shell命令有问题,具体啥问题呢? 在ShellProvider的call方法加入如下代码: 在这里插入图片描述目的就是想让shell帮我们执行一下settings值的写入,这里其实可以更加简单的settings put命令既可以,但学员就想知道为这样是不是也可以执行,其实也肯定是可以的哈。 但他发现如果在system_server中调用会报错如下:

08-26 15:21:35.004 19922 19922 E AndroidRuntime: Process: com.example.injectmotion, PID: 19922 08-26 15:21:35.004 19922 19922 E AndroidRuntime: java.lang.SecurityException: Given calling package android does not match caller's uid 10189 在这里插入图片描述

原因分析

先看看这个源码是怎么写的 在这里插入图片描述 直接在wms的relayout中调用了Shell的provider的call方法,想让Shell帮我们执行代码。 但是报错核心堆栈如下:

E AndroidRuntime: 	at com.android.server.am.ContentProviderHelper.getContentProvider(ContentProviderHelper.java:141)
E AndroidRuntime: 	at com.android.server.am.ActivityManagerService.getContentProvider(ActivityManagerService.java:6782)

可以看到这里是acquireProvider就已经报错了,根本没有到达Shell的Provider的call方法,属于压根连Provider获取时候就有校验报错。

具体看看报错代码日志:

日志

Given calling package android does not match caller's uid 10189

这个大概意思是包名 android和uid 没有匹配到一起

这里看看报错具体代码 在这里插入图片描述 可以看到这里的uid明显是通过 Binder.getCallingUid(),即谁发起的跨进程调用获取的就是谁的uid,所以这个uid明显就是我们app包名为com.example.injectmotion的uid,但是这里的callingPackage明显是android即我们的systemserver,因为这个获取Provider明显是在systemserver进程发起的,不是在app端发起的。 所以这里当然就会报错因为com.example.injectmotion的uid个android包名对应uid不一样,从而导致安全报错。

解决方法

方法其实这个在前面的blog都是有讲解,还有相关模拟面试也有多次提到,那就是 Binder.clearCallingIdentity()方法来清除一下binder相关的调用记录。 具体修改如下: 在这里插入图片描述 这样后续的Binder.getCallingUid()就是获取的system_server进程的,就不会有这个安全报错,具体原理可以看这个blog blog.csdn.net/learnframew…

更多framework技术干货,请关注公众号“千里马学框架”