【问题标题】:My custom selinux policies seem to be ignored by android system我的自定义 selinux 策略似乎被 android 系统忽略了
【发布时间】:2017-08-04 14:42:49
【问题描述】:

在基于 AOSP 的 Android 7.1.2(更准确地说是基于 Sony 开放设备树)上让自定义 selinux 策略正常运行时遇到了一些麻烦。

我的问题是审核日志不断告诉我缺少我实际添加的文件访问规则。我还将 audit2allow 创建的规则复制到我的策略文件中,但即使这些规则也无法正常工作。

那么,让我们深入了解一下细节:

我创建了一个名为 vendor_app 的自定义域。此域根据其签名分配给应用程序。我在 mac_permissions.xml 中添加了一个条目来分配 seinfo 字段 vendor。在 seapp_contexts 我这样分配 vendor_app 域:

user=_app seinfo=vendor domain=vendor_app type=app_data_file levelFrom=user

我的应用在 vendor_app 上下文中正确启动:

# ps -Z | grep permissiontest
u:r:vendor_app:s0:c512,c768    u0_a109   4110  508   1620732 79584 SyS_epoll_ 0000000000 S com.vendor.android.permissiontest

所以,现在对于根本不起作用的部分。在 vendor_app 上下文中运行的应用程序将获得对 /persist/vendor 中文件的读/写访问权限。为了创建必要的规则,我在设备目录中的 sepolicy 文件夹中添加了一个名为 vendor.te 的文件,其内容如下:

type vendor_app, domain;
type vendor_file, file_type, data_file_type;
# permissive vendor_app;

app_domain(vendor_app)
net_domain(vendor_app)
bluetooth_domain(vendor_app)

allow vendor_app persist_file:dir r_dir_perms;
allow vendor_app vendor_file:dir create_dir_perms;
allow vendor_app vendor_file:file create_file_perms;

allow vendor_app audioserver_service:service_manager find;
allow vendor_app cameraserver_service:service_manager find;
allow vendor_app drmserver_service:service_manager find;
allow vendor_app mediaserver_service:service_manager find;
allow vendor_app mediaextractor_service:service_manager find;
allow vendor_app mediacodec_service:service_manager find;
allow vendor_app mediadrmserver_service:service_manager find;
allow vendor_app persistent_data_block_service:service_manager find;
allow vendor_app radio_service:service_manager find;
allow vendor_app surfaceflinger_service:service_manager find;
allow vendor_app app_api_service:service_manager find;
allow vendor_app system_api_service:service_manager find;
allow vendor_app vr_manager_service:service_manager find;

并且我在 file_contexts 配置中添加了一项:

###################################
# persist files
#
/persist(/.*)?                                                      u:object_r:persist_file:s0
/persist/vendor(/.*)?                                               u:object_r:vendor_file:s0

在 /persist 分区上,我创建了一些目录结构,让具有适当权限的文件夹可以在其中添加一些文件。

# ls -Zal /persist/vendor/                                            
total 56
drwxrwxrwx  5 persist   persist   u:object_r:vendor_file:s0  4096 2017-08-03 22:27 .
drwxrwx--x 16 system    system    u:object_r:persist_file:s0 4096 2017-08-01 16:24 ..
drwxrwxrwx  2 profile   profile   u:object_r:vendor_file:s0  4096 2017-08-04 13:34 profile
drwxrwxrwx  2 provision provision u:object_r:vendor_file:s0  4096 2017-08-04 13:34 provisioning
drwxrwxrwx  2 updater   updater   u:object_r:vendor_file:s0  4096 2017-08-04 13:34 updater

我知道服务的 find 规则正在运行,因为我可以在强制模式下启动我的应用程序,并且没有收到任何投诉。我还可以访问 { search } 的 /persist 目录,这是关于 persist_file:dir 的规则所允许的。

当我尝试将 /persist/vendor/updater/test 之类的新文件写入 /persist 目录时,我会收到来自 auditd 的错误消息:

08-04 16:34:29.269  4108  4108 W .permissiontest: type=1400 audit(0.0:27): avc: denied { write } for name="updater" dev="mmcblk0p44" ino=55 scontext=u:r:vendor_app:s0:c512,c768 tcontext=u:object_r:vendor_file:s0 tclass=dir permissive=0

该错误当然会被 audit2allow 转换为以下规则:

#============= vendor_app ==============
allow vendor_app vendor_file:dir write;

由于writecreate_dir_perms 的成员,它实际上应该在那里。我还尝试将 audit2allow 创建的行添加到我的 vendor.te 中,但没有成功。

请注意,写入更新程序还涉及 persist_file 上的 searchvendor_file 上的 search ,这两者似乎工作没有任何问题。

有没有人有任何建议,如何正确调试或者甚至解决这个问题?我已经研究了两天了,这让我发疯了。

编辑:

啊。 /persist 当然是挂载可写的:

# mount | grep persist
/dev/block/bootdevice/by-name/persist on /persist type ext4 (rw,seclabel,nosuid,nodev,relatime,nodelalloc,errors=panic,data=ordered)

编辑 2:

正如 Paul Ratazzi 所问,我已经扫描了 sepolicy 文件和实际加载到内核中的版本,以了解我的规则是否存在。

$ sesearch -A -s vendor_app -t vendor_file policy 
allow vendor_app vendor_file:dir { rename search setattr read lock create reparent getattr write ioctl rmdir remove_name open add_name };
allow vendor_app vendor_file:file { rename setattr read lock create getattr write ioctl unlink open append };

因此它们实际上已正确部署到设备上。

【问题讨论】:

  • 如果您还没有,请尝试从正在运行的设备中提取“/sepolicy”,将其加载到“apol”并检查您的所有规则实际上是否已编译到策略二进制文件中并显示如你所料。这可能有助于将其缩小到构建与运行时问题。
  • 感谢您的提示。事实上,apol 确实 (afaik) 不适用于 android 的 selinux 策略,因为 google 使用的是 settools 不支持的自定义版本 (v30) 策略文件。但是他们提供了自己的工具来解析和搜索策略文件。这些工具表明规则存在于设备上。我将编辑帖子并将输出放在那里。

标签: android selinux m4 seandroid


【解决方案1】:

好吧,经过更多的挖掘,看起来我终于找到了答案。为了避免某些人在一些伤脑筋的日子里遇到同样的问题,这里是解决方案:

除了MAC (Mandatory Access Control) android 上的SElinux 还有MLS (Multi-Level Security)

虽然在Android SELinux concepts 中以某种方式描述了 MAC,但有关 MLS 的信息只是非常简短且含蓄地提及:

在 SELinux 中,标签采用以下形式:user:role:type:mls_level,其中类型是访问决策的主要组成部分,可以由其他部分组件修改贴上标签。

所以,我的 Android 应用程序运行在 MLS 级别(由 c512、c768 表示),可以读取 /persist 上的文件但不能写入它们。所以需要做的是让我的应用获得 MLS 级别以正确访问这些文件。

我(目前)已通过将自定义标签更改为来存档此内容

type vendor_app, domain, mlstrustedsubject;

这使我的应用程序受到信任。这解决了问题,但授予对我的应用程序的大量访问权限。因此,更好的选择是将目标的安全级别设置为允许对我的应用程序进行读写访问的级别。

所以到目前为止,这基本上是这个问题的解决方案(虽然还没有完成)。

【讨论】:

  • 您是否能够降低应用程序的安全级别而不是使用 mlstrustedobject?
  • 我想我从 seaapp_contexts 中删除了“levelFrom=user”,但我终于能够消除 mlstrustedobject,是的。
  • 感谢您的回答。花一个晚上试图弄清楚为什么我的 i2c_device:chr_file 写入被拒绝。没有任何错误,但即使特别允许,它也会否认这一点。原来需要 mlstrustedsubject
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-10-28
  • 2016-09-30
  • 2012-03-11
  • 1970-01-01
  • 1970-01-01
  • 2016-02-20
  • 2017-12-05
相关资源
最近更新 更多