| # gsid - Manager for GSI Installation |
| |
| type gsid, domain; |
| type gsid_exec, exec_type, file_type, system_file_type; |
| typeattribute gsid coredomain; |
| |
| init_daemon_domain(gsid) |
| |
| binder_use(gsid) |
| binder_service(gsid) |
| add_service(gsid, gsi_service) |
| |
| # Manage DSU metadata encryption key through vold. |
| allow gsid vold_service:service_manager find; |
| binder_call(gsid, vold) |
| |
| set_prop(gsid, gsid_prop) |
| |
| # Needed to create/delete device-mapper nodes, and read/write to them. |
| allow gsid dm_device:chr_file rw_file_perms; |
| allow gsid dm_device:blk_file rw_file_perms; |
| allow gsid self:global_capability_class_set sys_admin; |
| dontaudit gsid self:global_capability_class_set dac_override; |
| |
| # On FBE devices (not using dm-default-key), gsid will use loop devices to map |
| # images rather than device-mapper. |
| allow gsid loop_control_device:chr_file rw_file_perms; |
| allow gsid loop_device:blk_file rw_file_perms; |
| allowxperm gsid loop_device:blk_file ioctl { |
| LOOP_GET_STATUS64 |
| LOOP_SET_STATUS64 |
| LOOP_SET_FD |
| LOOP_SET_BLOCK_SIZE |
| LOOP_SET_DIRECT_IO |
| LOOP_CLR_FD |
| BLKFLSBUF |
| }; |
| |
| # libfiemap_writer uses sysfs to derive the bottom of a device-mapper stacking. |
| # This requires traversing /sys/block/dm-N/slaves/* and reading the list of |
| # file names. |
| r_dir_file(gsid, sysfs_dm) |
| |
| # libfiemap_writer needs to read /sys/fs/f2fs/<dev>/features to determine |
| # whether pin_file support is enabled. |
| r_dir_file(gsid, sysfs_fs_f2fs) |
| |
| # Needed to read fstab, which is used to validate that system verity does not |
| # use check_once_at_most for sdcard installs. (Note: proc_cmdline is needed |
| # to get the A/B slot suffix). |
| read_fstab(gsid) |
| allow gsid sysfs_dt_firmware_android:dir r_dir_perms; |
| allow gsid sysfs_dt_firmware_android:file r_file_perms; |
| |
| # Needed to stat /data/gsi/* and realpath on /dev/block/by-name/* |
| allow gsid block_device:dir r_dir_perms; |
| |
| # Allow querying the size of super_block_device_type. |
| allow gsid super_block_device_type:blk_file r_file_perms; |
| |
| # liblp queries these block alignment properties. |
| allowxperm gsid { |
| userdata_block_device |
| sdcard_block_device |
| super_block_device_type |
| }:blk_file ioctl { |
| BLKIOMIN |
| BLKALIGNOFF |
| }; |
| |
| # When installing images to an sdcard, gsid needs to be able to stat() the |
| # block device. gsid also calls realpath() to remove symlinks. |
| allow gsid mnt_media_rw_file:dir r_dir_perms; |
| allow gsid mnt_media_rw_stub_file:dir r_dir_perms; |
| |
| # When installing images to an sdcard, gsid must bypass sdcardfs and install |
| # directly to vfat, which supports the FIBMAP ioctl. |
| allow gsid vfat:dir create_dir_perms; |
| allow gsid vfat:file create_file_perms; |
| allow gsid sdcard_block_device:blk_file r_file_perms; |
| # This is needed for FIBMAP unfortunately. Oddly FIEMAP does not carry this |
| # requirement, but the kernel does not implement FIEMAP support for VFAT. |
| allow gsid self:global_capability_class_set sys_rawio; |
| |
| # Allow rules for gsi_tool. |
| userdebug_or_eng(` |
| # gsi_tool passes the system image over the adb connection, via stdin. |
| allow gsid adbd:fd use; |
| # Needed when running gsi_tool through "su root" rather than adb root. |
| allow gsid adbd:unix_stream_socket rw_socket_perms; |
| # gsi_tool passes a FIFO to gsid if invoked with pipe redirection. |
| allow gsid { shell su }:fifo_file r_file_perms; |
| # Allow installing images from /storage/emulated/... |
| allow gsid { sdcard_type fuse }:file r_file_perms; |
| ') |
| |
| neverallow { |
| domain |
| -gsid |
| -init |
| -update_engine_common |
| -recovery |
| -fastbootd |
| } gsid_prop:property_service set; |
| |
| # gsid needs to store images on /data, but cannot use file I/O. If it did, the |
| # underlying blocks would be encrypted, and we couldn't mount the GSI image in |
| # first-stage init. So instead of directly writing to /data, we: |
| # |
| # 1. fallocate a file large enough to hold the signed GSI |
| # 2. extract its block layout with FIEMAP |
| # 3. create a dm-linear device using the FIEMAP, targeting /dev/block/by-name/userdata |
| # 4. write system_gsi into that dm device |
| # |
| # To make this process work, we need to unwrap the device-mapper stacking for |
| # userdata to reach the underlying block device. To verify the result we use |
| # stat(), which requires read access. |
| allow gsid userdata_block_device:blk_file r_file_perms; |
| |
| # gsid uses /metadata/gsi to communicate GSI boot information to first-stage |
| # init. It cannot use userdata since data cannot be decrypted during this |
| # stage. |
| # |
| # gsid uses /metadata/gsi to store three files: |
| # install_status - A short string indicating whether a GSI image is bootable. |
| # lp_metadata - LpMetadata blob describing the block ranges on userdata |
| # where system_gsi resides. |
| # booted - An empty file that, if exists, indicates that a GSI is |
| # currently running. |
| # |
| allow gsid metadata_file:dir { search getattr }; |
| allow gsid { |
| gsi_metadata_file_type |
| }:dir create_dir_perms; |
| |
| allow gsid { |
| ota_metadata_file |
| }:dir rw_dir_perms; |
| |
| allow gsid { |
| gsi_metadata_file_type |
| ota_metadata_file |
| }:file create_file_perms; |
| |
| # Allow restorecon to fix context of gsi_public_metadata_file. |
| allow gsid file_contexts_file:file r_file_perms; |
| allow gsid gsi_metadata_file:file relabelfrom; |
| allow gsid gsi_public_metadata_file:file relabelto; |
| |
| allow gsid { |
| gsi_data_file |
| ota_image_data_file |
| }:dir create_dir_perms; |
| allow gsid { |
| gsi_data_file |
| ota_image_data_file |
| }:file create_file_perms; |
| allowxperm gsid { |
| gsi_data_file |
| ota_image_data_file |
| }:file ioctl { |
| FS_IOC_FIEMAP |
| FS_IOC_GETFLAGS |
| }; |
| |
| allow gsid system_server:binder call; |
| |
| # Prevent most processes from writing to gsi_metadata_file_type, but allow |
| # adding rules for path resolution of gsi_public_metadata_file and reading |
| # gsi_public_metadata_file. |
| neverallow { |
| domain |
| -init |
| -gsid |
| -fastbootd |
| } gsi_metadata_file_type:dir no_w_dir_perms; |
| |
| neverallow { |
| domain |
| -init |
| -gsid |
| -fastbootd |
| } { gsi_metadata_file_type -gsi_public_metadata_file }:file_class_set *; |
| |
| neverallow { |
| domain |
| -init |
| -gsid |
| -fastbootd |
| } gsi_public_metadata_file:file_class_set ~{ r_file_perms }; |
| |
| # Prevent apps from accessing gsi_metadata_file_type. |
| neverallow { |
| appdomain |
| -shell |
| } gsi_metadata_file_type:dir_file_class_set *; |
| |
| neverallow { |
| domain |
| -init |
| -gsid |
| } gsi_data_file:dir_file_class_set *; |
| |
| neverallow { |
| domain |
| -gsid |
| } gsi_data_file:file_class_set ~{ relabelto getattr }; |