我在使自定义selinux策略在基于AOSP的Android 7.1.2(更精确地基于sony开放设备树)上正确运行时遇到了一些麻烦。

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

因此,让我们深入研究细节:

我创建了一个名为vendor_app的自定义域。该域根据其签名分配给应用。我已经在mac_permissions.xml中添加了一个条目来分配seinfo字段供应商。在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

我知道该服务的查找规则正在运行,因为我能够以强制模式启动我的应用程序,而不会对此提出任何投诉。我也可以按照persist_file:dir的规则访问/persist目录进行{search}。

一旦我尝试将/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;

由于write是create_dir_perms的成员,因此实际上应该在该位置。我还尝试将audit2allow创建的行添加到我的vendor.te,但没有成功。

请注意,写入更新程序还涉及搜索persist_file和vendor_file,两者似乎都可以正常工作。

有没有人有任何建议,如何正确调试它,甚至可能对此问题有任何解决方案?我已经研究了两天了,这让我发疯了。

编辑:

啊。/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 };

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

最佳答案

好吧,经过更多的挖掘,看来我终于找到了答案。为了避免某人在脑筋急转弯的日子里遇到相同的问题,这里提供了解决方案:

除了MAC (Mandatory Access Control)之外,android上的SElinux也是MLS (Multi-Level Security)

尽管在Android SELinux concepts中以某种方式描述了MAC,但是关于MLS的信息只是非常简短和隐含地提及:



因此,发生的事情是我的Android应用程序以MLS级别运行(由c512,c768表示),该级别可以读取/persist上的文件,但不能写入它们。因此,需要做的是,我的应用获得了MLS级别才能正确访问这些文件。

我(暂时)将自定义标签更改为

type vendor_app, domain, mlstrustedsubject;

这使我的应用程序值得信赖。这可以解决问题,但可以授予对我的应用程序的大量访问权限。因此,更好的选择是将目标的安全级别设置为可以授予对我的应用程序的读写访问权限的级别。

因此,到目前为止,这基本上是解决此问题的解决方案(尽管尚未完成)。

关于android - 我的自定义selinux策略似乎被android系统忽略,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45509643/

10-09 20:00