I have some trouble on getting custom selinux policies running properly on an AOSP based Android 7.1.2 (more precisely based on sony open devices tree).
My problem is that the audit logs keep telling me about missing file access rules that I actually added. I also copied rules that audit2allow has created to my policy files, but even those do not properly work.
So, let's dig into the details:
I created a custom domain called vendor_app. This domain is assigned to an app based on its signature. I have added an entry to the mac_permissions.xml to assign the seinfo field vendor. In seapp_contexts I assign the vendor_app domain like this:
user=_app seinfo=vendor domain=vendor_app type=app_data_file levelFrom=user
My app is properly started in the vendor_app context:
# 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
So, now for the part that does not work at all. An app running in the vendor_app context shall get read/write access to files in /persist/vendor. To create the nessesary rules, I added a file called vendor.te to the sepolicy folder in the device directory with the followin content:
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;
And I have added one entry in the file_contexts configuration:
###################################
# persist files
#
/persist(/.*)? u:object_r:persist_file:s0
/persist/vendor(/.*)? u:object_r:vendor_file:s0
On the /persist partition, I created some directory structure to have folders with appropriate permissions to add some files there.
# 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
I know that the find-rules for the services are working, as I am able to start my app in enforcing mode and do not get any complaints about that. I am also able to access the /persist directory for { search } as allowed by the rule regarding persist_file:dir.
As soon as I try writing a new file like /persist/vendor/updater/test to the /persist directory, I get error messages from 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
That error is of course converted by audit2allow to the following rule:
#============= vendor_app ==============
allow vendor_app vendor_file:dir write;
As write is a member of create_dir_perms, it actually should be there. I have also tried adding the line created by audit2allow to my vendor.te without any success.
Please notice that writing to updater also involves search on persist_file and search on vendor_file which both seem to work without any problems.
Has anyone any advice, how to debug that properly or maybe even any solution for this problem? I have been digging on this for two days now and it's driving me nuts.
EDIT:
Ah. /persist is of course mounted writable:
# mount | grep persist
/dev/block/bootdevice/by-name/persist on /persist type ext4 (rw,seclabel,nosuid,nodev,relatime,nodelalloc,errors=panic,data=ordered)
EDIT 2:
As Paul Ratazzi has asked, I have scanned the sepolicy file and the version actually loaded into the kernel for the presence of my rules as well.
$ 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 };
So they are infact deployed to the device properly.