Android 8.0 system app加载so Permission denied 解决

在预置包含react native 的Android app 预置到mtk 6739的系统中,此app 具体 platform 签名。此app启动会加载一些 facebook的so库
在这里插入图片描述
发现此app 如果预置到system/app下,启动会报错。开始以为是没有把相关的so库 放到 system/app/xx/lib 下。在Android 6.0我都是可以正常启动的。发现在8.0 仍然会报错。
报错如下

2010-01-01 08:27:30.951 1887-1887/xxx W/Thread-2: type=1400 audit(0.0:19): avc: denied { execute } for path="/data/data/xxx/lib-main/libgnustl_shared.so" dev="dm-0" ino=1733 scontext=u:r:system_app:s0 tcontext=u:object_r:system_app_data_file:s0 tclass=file permissive=0
2010-01-01 08:27:30.957 1887-1915/xxx E/AndroidRuntime: FATAL EXCEPTION: Thread-2
    Process: xxx, PID: 1887
    java.lang.UnsatisfiedLinkError: dlopen failed: couldn't map "/data/data/xxx/lib-main/libgnustl_shared.so" segment 2: Permission denied
        at java.lang.Runtime.load0(Runtime.java:928)
        at java.lang.System.load(System.java:1621)
        at com.facebook.soloader.DirectorySoSource.loadLibraryFrom(DirectorySoSource.java:71)
        at com.facebook.soloader.DirectorySoSource.loadLibrary(DirectorySoSource.java:42)
        at com.facebook.soloader.SoLoader.loadLibraryBySoName(SoLoader.java:299)
        at com.facebook.soloader.DirectorySoSource.loadLibraryFrom(DirectorySoSource.java:65)
        at com.facebook.soloader.DirectorySoSource.loadLibrary(DirectorySoSource.java:42)
        at com.facebook.soloader.SoLoader.loadLibraryBySoName(SoLoader.java:299)
        at com.facebook.soloader.DirectorySoSource.loadLibraryFrom(DirectorySoSource.java:65)
        at com.facebook.soloader.DirectorySoSource.loadLibrary(DirectorySoSource.java:42)
        at com.facebook.soloader.SoLoader.loadLibraryBySoName(SoLoader.java:299)
        at com.facebook.soloader.DirectorySoSource.loadLibraryFrom(DirectorySoSource.java:65)
        at com.facebook.soloader.DirectorySoSource.loadLibrary(DirectorySoSource.java:42)
        at com.facebook.soloader.SoLoader.loadLibraryBySoName(SoLoader.java:299)
        at com.facebook.soloader.SoLoader.loadLibrary(SoLoader.java:247)
        at com.facebook.react.bridge.ReactBridge.staticInit(ReactBridge.java:18)
        at com.facebook.react.bridge.NativeMap.<clinit>(NativeMap.java:19)
        at com.facebook.react.bridge.JSCJavaScriptExecutorFactory.create(JSCJavaScriptExecutorFactory.java:21)
        at com.facebook.react.ReactInstanceManager$5.run(ReactInstanceManager.java:912)
        at java.lang.Thread.run(Thread.java:764)
2010-01-01 08:27:30.958 1887-1887/xxx D/Surface: Surface::allocateBuffers(this=0x9820a800)
2010-01-01 08:27:30.962 651-673/system_process I/WindowManager: Focus moving from null to Window{52abab1 u0 xxx/xxx.MainActivity}
2010-01-01 08:27:30.964 651-662/system_process W/ActivityManager:   Force finishing activity xxx/.MainActivity
2010-01-01 08:27:30.970 651-1917/system_process W/AES: Exception Log handling...

之后把libgnustl_shared.so 放到 /system/lib下。这个错误仍然出现。
通过报错的log可以知道 react 不是通过System.loadLibrary加载libgnustl_shared.so,而是动态的通过dlopen 加载so。如果通过System.loadLibrary 加载 ,我已经把libgnustl_shared.so 放到 /system/lib下,就不会报这个错误。
System.loadLibrary()装载一个库是在Dalvik虚拟机中,而dlopen()只在你的本地进程中装载库
个人猜测 包含react native的app 在安装的时候会把 相关的so解压到/data/data/xxx/lib/下,然后dlopen("/data/data/xxx/lib")
通过adb 进入到/data/data/xxx/lib/下 发现 so文件都存在。

couldn't map "/data/data/xxx/lib-main/libgnustl_shared.so" segment 2: Permission denied

报错的意思并不是文件不存在。而是load加载失败,失败原因是Permission denied。
那为什么Permission denied ?

avc: denied { execute } for path="/data/data/xxx/lib-main/libgnustl_shared.so" dev="dm-0" ino=1733 scontext=u:r:system_app:s0 tcontext=u:object_r:system_app_data_file:s0 tclass=file permissive=0

因为 libgnustl_shared.so 在system_app_data_file域目录下。system_app 对system_app_data_file 是没有execute 权限。
system_app_data_file 是什么鬼,
在external/sepolicy/file.te 下

type system_app_data_file, file_type, data_file_type, mlstrustedobject;

data_file_type 就是data分区下文件。
说白了就是 system权限的app 无法执行data分区下文件。读写应该没有问题。应该是防止有些流氓软件在data分区下隐藏可以执行文件。
所以给systemapp加可执行权限

device/mediatek/sepolicy/basic/non_plat/system_app.te
allow system_app system_app_data_file:dir {getattr search };
allow system_app system_app_data_file:file {read getattr execute };

加完之后编译发现报错,原因是

libsepol.report_failure: neverallow on line 528 of system/sepolicy/private/app.te (or line 21726 of policy.conf) violated by allow system_app system_app_data_file:file { execute };

//system_data_file
/system/sepolicy/private/app.te

neverallow {
  bluetooth
  isolated_app
  nfc
  radio
  shared_relro
  system_app
} {
  data_file_type
  -dalvikcache_data_file
  -system_data_file # shared libs in apks
  -apk_data_file
}:file no_x_file_perms;

禁止system_app no_x_file_perms(执行) data_file_type(system_app_data_file)下的文件。
所以我修改app.te文件中的system_app去掉

neverallow {
  bluetooth
  isolated_app
  nfc
  radio
  shared_relro
} {
  data_file_type
  -dalvikcache_data_file
  -system_data_file # shared libs in apks
  -apk_data_file
}:file no_x_file_perms;

这个存在一个问题就是过不了谷歌cts测试。另外还有一种方法绕过这种过不了谷歌测试cts问题,我不想写了,修改system_app_data_file的type,这个 type就是本篇文章中,有谁知道的可以把这个方法列出来?

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
当你在操作系统中遇到"Permission denied"错误时,这意味着你没有足够的权限执行特定的操作。这通常发生在以下几种情况下: 1. 文件或目录权限不足:你可能没有读取、写入或执行特定文件或目录的权限。解决方法是使用chmod命令更改文件或目录的权限,例如使用"chmod 755 filename"将文件的权限更改为755。 2. 用户权限不足:你可能没有足够的权限执行特定操作,例如安装软件或修改系统设置。解决方法是使用管理员权限登录或使用sudo命令来执行需要特权的操作。 3. 文件或目录所属用户/组不匹配:如果文件或目录的所有者是其他用户或组,而你没有相应的权限,你将无法访问或执行它们。解决方法是使用chown命令更改文件或目录的所有者,例如使用"chown username:groupname filename"将文件的所有者更改为指定的用户和组。 4. SELinux或AppArmor限制:某些Linux发行版使用SELinux或AppArmor等安全模块来限制进程的访问权限。如果你遇到"Permission denied"错误,可能是由于这些安全模块的限制。解决方法是修改安全模块的策略,以允许特定操作。 5. 磁盘空间不足:如果磁盘空间不足,你可能无法创建新文件或写入数据。解决方法是释放磁盘空间或扩展磁盘容量。 这些是常见的"Permission denied"错误解决办法。如果你遇到特定的问题,请提供更多详细信息,以便我能够给出更具体的建议。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

九霄的爸爸

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值