V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
gam2046
V2EX  ›  Android

请教如何正确在 Android 设备上编写 SELinux 规则

  •  
  •   gam2046 · 2021-04-25 16:00:27 +08:00 · 8164 次点击
    这是一个创建于 1314 天前的主题,其中的信息可能已经有所发展或是发生改变。
    • 基于 AOSP 二次开发
    • 设备:Android API: 28 以及上

    在系统启动时,会新增一些自定义的 System Service 以供第三方应用使用一些特权操作。 第三方应用可以通过ServiceManager.getService(...)Context.getService(...)获取到对应的 Binder 对象。

    在测试中发现 SELinux 阻止了普通应用获取

    ELinux: avc: denied { find } for service=test_service_name pid=14827 uid=10144 scontext=u:r:untrusted_app_27:s0:c512,c768 tcontext=u:object_r:default_android_service:s0 tclass=service_manager permissive=0

    我不希望直接关闭 SELinux,尝试添加规则:allow untrusted_app default_android_service service_manager { find }

    依然被 SELinux 阻止,还是上述一样的日志,所以想请问一下各位,是不是我对 SELinux 理解有偏差导致我的规则写错了?

    RikkaW
        1
    RikkaW  
       2021-04-25 21:07:10 +08:00   ❤️ 2
    1. untrusted_app_27 和 untrusted_app 是两个东西
    2. 正常的系统服务是通过 attachApplication/bindApplication 由系统服务发给应用进程的,不需要专门允许应用进程 find service_manager
    RikkaW
        2
    RikkaW  
       2021-04-25 21:08:03 +08:00
    补充一下,从 ContextImpl.getService 往上找就能看到系统服务的 binder 们是怎么进来的
    gam2046
        3
    gam2046  
    OP
       2021-04-26 11:55:14 +08:00
    @RikkaW #1 感谢大佬。

    简单梳理了一下,也为了方便后人,整个流程大概是这样(以 Android 10 代码为例)

    目标 APK 能够获取到的 Service 是在 ActivityThread.bindApplication 方法中获得,此方法中对于应用不应该访问的服务给出了警告,但是没有拒绝访问
    ```
    if (ServiceManager.getService(name) == null) {
    Log.wtf(TAG, "Service " + name + " should be accessible by this app");
    }
    ```
    而该方法中的 services 参数是由 AMS 发过来的,继续往里跟,可以得到 ActivityManagerService.getCommonServicesLocked 方法,在源代码中也可以看到一些注释
    // Add common services.
    // IMPORTANT: Before adding services here, make sure ephemeral apps can access them too.
    // Enable the check in ApplicationThread.bindApplication() to make sure.

    最终方法落到 ActivityManagerService.addServiceToMap,此方法中调用了 ServiceManager.getService

    综上,可以得到,一般应用程序获得的 Service 是由 AMS 获取后通过 Binder 发送给目标应用,此时由于 AMS 本身是有权限获得 Service 的(这也就对应了大佬说不需要专门允许应用进程 find service_manager ),而在目标应用内对获得的 Service 列表有一个权限检查(即 AMS 传递过来的 Service 应用本身是否可以获取),即通过 service name 再次通过 ServiceManager 获取,如果返回 NULL,则输出警告日志,是否影响后续使用需要等待我测试一下。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2793 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 14:41 · PVG 22:41 · LAX 06:41 · JFK 09:41
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.