tgoop.com/qianqianzhuang/18
Last Update:
Magisk 27.0 正式版发布后,我们收到了一些报告,称 WiFi 无法打开(如[1])。调查后发现,这与 Magisk 近期修复的一个安全问题有关。
众所周知,Magisk 有一个基础功能,就是自定义 sepolicy 规则。为了实现这个功能,Magisk 需要劫持 sepolicy 加载过程,读取设备上原本的 sepolicy,修补后将其手动加载进内核。这个步骤很复杂,需要调用 SELinux Project 提供的 libsepol 库。由于 Android 自带的 libsepol 缺少某些导出函数,且对规则的检查过于严格,Magisk 一直以来使用的都是自行编译的 libsepol。
问题就出在这里。直到去年年底,Magisk 使用的 libsepol 都是从上游 SELinux Project fork 的。AOSP 使用的 libsepol 也同样是从上游 fork 的,在 Android 11 前变动不大;但从 Android 11 开始,为了能够限制应用读取 MAC 地址[2],谷歌对内核、libsepol、内置 selinux 规则做了一些小小的修改,使系统能够识别 RTM_GETLINK 消息,并针对性加以限制[3]。这些修改并未进入上游。
篇幅原因,具体技术细节不再详述,只需要知道大致流程:libsepol 在向内核写入规则时,传递一个标记,告知内核需要对 RTM_GETLINK 消息进行特殊的权限控制。由于 Magisk 直接使用从上游 fork 的 libsepol,因此在安装了 Magisk 的设备上,内核压根不知道要对 RTM_GETLINK 消息进行拦截。后果就是,所有应用都可以读取设备 MAC 地址。这个漏洞从 Android 11 发布的那天起就一直存在,直到近期才被发现。
Magisk 27.0 通过从 AOSP fork libsepol 修复了这个问题。但另一个问题随之而来:为了支持 Project Treble,谷歌将相应的内核提交同步到了 common kernel 的 Android 9 分支,导致部分 Android 9 设备的内核也有限制读取 MAC 地址的能力。在正常情况下,这毫无问题:用户空间的 libsepol 并不会传递相应标记,因此该功能不会启用。但是,如果用户安装了修复安全问题后的 Magisk,内核中的功能会被启用,但 Android 9 系统并没有相应的 selinux 规则来告知内核,不需要限制系统应用读取 MAC 地址。从而,在这部分设备上,WiFi 根本无法打开。
我目前想到的修复方法有两种,一是根据设备原有 libsepol 实现,判断是否应该向内核传递 flag,或者为不同 Android 版本编译不同的 libsepol;二是干脆直接向内核写入相匹配的 sepolicy 规则,允许系统应用获取 MAC 地址。具体怎么修,还要看项目维护者的选择。
[1] https://github.com/topjohnwu/Magisk/issues/7764
[2] https://developer.android.com/training/articles/user-data-ids#mac-11-plus
[3] https://android-review.googlesource.com/c/platform/external/selinux/+/1229615; https://android-review.googlesource.com/c/kernel/common/+/1214053; https://android-review.googlesource.com/c/platform/system/sepolicy/+/1214045
BY 钱庄
Share with your friend now:
tgoop.com/qianqianzhuang/18