Android 开机时重设 selinux 规则导致系统开机非常慢

2021-12-10 16:40:06 +08:00
 amrnxcdt

最近手机升级了 android 版本(官方支持的 lineageOS17=>18 ),每次开机或者需要 3min 以上,于是打了日志出来看看,发现 Android 在启动的时候,默认重设了 /data 分区所有文件的 selinux 规则,这个操作需要非常非常长的时间,导致开机很慢。

这是另外一台红米(非官方的 lineageOS18 )抓出来的日志,也是开机很慢。截取日志的 1598 行开始

09-09 04:52:04.230 E/selinux (    0):  
09-09 04:52:04.345 I/init    (    0): Command 'restorecon --recursive --skip-ce /data' action=post-fs-data (/system/etc/init/hw/init.rc:770) took 153265ms and succeeded
09-09 04:52:04.346 I/init    (    0): starting service 'exec 6 (/system/bin/tzdatacheck /apex/com.android.tzdata/etc/tz /data/misc/zoneinfo)'...

“restorecon --recursive --skip-ce /data”这个操作用了整整 153265ms 。

这是抓取出来的 logcat 和 dmesg

https://github.com/zeelog/android_device_xiaomi_mido/files/7685368/logcat.log

https://github.com/zeelog/android_device_xiaomi_mido/files/7685361/dmesg.log

这是日志所记录的 /system/etc/init/hw/init.rc 文件

https://github.com/zeelog/android_device_xiaomi_mido/files/7685423/init.rc.txt

在 aosp 上面找到 init.rc 对应的源码文件,看上去是 Android 从 5.0 开始的默认行为

https://cs.android.com/android/_/android/platform/system/core/+/refs/tags/android-11.0.0_r48:rootdir/init.rc;l=770;drc=109a140f6cf20ba0aa1f517999c690f6f4281b42

暂时找到三台不一样的机型,均运行 lineageOS18 ,看开机日志也是发现是一样的问题,“restorecon --recursive --skip-ce /data”运行 100s 以上。

用 google 组合了几个关键字搜索也没找到有用的信息,想看看大家手上的设备有类似的问题吗?

1394 次点击
所在节点    问与答
12 条回复
ysc3839
2021-12-10 16:59:15 +08:00
建议去 LineageOS 的 Discord 询问。我估计 V2EX 很少 AOSP ROM 开发者。
amrnxcdt
2021-12-10 17:09:39 +08:00
@ysc3839 #1 本来我是想向 LineageOS 官方提 issue 的,可是我没找到入口在哪,转而向一个维护非官方版本的作者发了 issue 。

因为在 android 官方上也发现了这个代码, 所以想找大家看看非 lineageOS 的设备上是不是也有同样的问题。
ysc3839
2021-12-10 18:45:42 +08:00
@amrnxcdt 官网有写 Bug Tracker 呀 https://lineageos.org/community/
ReVanTis
2021-12-10 19:07:32 +08:00
有看 kernel log 吗?
抓抓 dmesg 看看 restorecon 到底干嘛了?
amrnxcdt
2021-12-10 19:13:03 +08:00
@ysc3839 #3 thx 我用一台官方支持的设备提了一个 issue
amrnxcdt
2021-12-10 19:23:21 +08:00
@ReVanTis #4 有的,在主贴靠中部的位置有 logcat 和 dmesg 。
amrnxcdt
2021-12-10 19:33:26 +08:00
@ReVanTis #4 看 dmesg 只有最后的几秒里面,restorecon 试图重设 /data/mise 下的文件但是没成功

在 dmesg 的 1469 行开始
````
[ 22.832478] init: Service 'apexd-snapshotde' (pid 482) exited with status 0 waiting took 0.022000 seconds
[ 22.832502] init: Sending signal 9 to service 'apexd-snapshotde' (pid 482) process group...
[ 22.832651] libprocessgroup: Successfully killed process cgroup uid 0 pid 482 in 0ms
[ 167.837700] selinux: SELinux: Skipping restorecon on directory(/data/vendor_ce/0)
[ 167.837710] selinux:
[ 170.188237] selinux: SELinux: Skipping restorecon on directory(/data/misc/apexdata/com.android.wifi)
[ 170.188253] selinux:
[ 170.262342] type=1400 audit(21675118.499:4): avc: denied { getattr } for comm="init" path="/data/misc/iorapd/sqlite.db" dev="mmcblk0p49" ino=541854 scontext=u:r:init:s0 tcontext=u:object_r:iorapd_data_file:s0 tclass=file permissive=0
[ 170.262883] selinux: SELinux: Could not stat /data/misc/iorapd/sqlite.db: Permission denied.
[ 170.262897] selinux:
````
下面连续多条都是 SELinux: Could not stat Permission denied.

感觉是已经枚举完整个 /data 下的文件了。
ReysC
2021-12-10 21:58:39 +08:00
自编 ROM ,如果没计划公布出去,直接关闭 selinux 即可,看起来所谓重设后的原始规则么又包括 iorapd 的读写编写,也可直接编写个。

PS: 难得见到个 ROM 编制者
ReVanTis
2021-12-10 22:02:52 +08:00
@amrnxcdt
感觉这个 log 22 - 167 之间应该丢了不少...
你看到开机是在 kernel time 170 秒以后的事情?
所以主要耗时是在 22 - 170 没 log 的这段时间?
amrnxcdt
2021-12-10 22:13:03 +08:00
@ReysC #8 见笑了,我不是 ROM 作者,只是一个普通的 android 用户。
amrnxcdt
2021-12-10 22:23:30 +08:00
@ReVanTis #9 是的,交叉对比 dmesg 的 1470 行附近:

````
[ 22.832502] init: Sending signal 9 to service 'apexd-snapshotde' (pid 482) process group...
[ 22.832651] libprocessgroup: Successfully killed process cgroup uid 0 pid 482 in 0ms
[ 167.837700] selinux: SELinux: Skipping restorecon on directory(/data/vendor_ce/0)
[ 167.837710] selinux:
[ 170.188237] selinux: SELinux: Skipping restorecon on directory(/data/misc/apexdata/com.android.wifi)
````


对应的 logcat 应该是 1214 行附近:

````
09-09 04:49:31.078 I/init ( 0): Service 'apexd-snapshotde' (pid 482) exited with status 0 waiting took 0.022000 seconds
09-09 04:49:31.078 I/init ( 0): Sending signal 9 to service 'apexd-snapshotde' (pid 482) process group...
09-09 04:51:56.084 I/selinux ( 0): SELinux: Skipping restorecon on directory(/data/vendor_ce/0)
09-09 04:51:56.084 I/selinux ( 0):
09-09 04:51:58.434 I/selinux ( 0): SELinux: Skipping restorecon on directory(/data/misc/apexdata/com.android.wifi)
````

可以看到两个日志输出都是跳过了一段时间。

下面是我的推测,restorecon --recursive 需要递归 /data 下每个文件产生的 io 开销非常大,所以导致系统启动过程卡在这里了。

参考这个 chmod -R 大量文件耗时的问题: https://unix.stackexchange.com/questions/79868/chmod-recursive-permission-on-thousands-of-files
Buges
2021-12-10 22:48:35 +08:00
@ReysC 除非你没打算运行任何第三方的代码。因为如果你这么做了,任何 app 都可以轻易 setuid 0 。
https://www.reddit.com/r/Android/comments/lfye5r/selinux_permissive_romskernels_are_very_bad/gmoi05a/

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/821370

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX