diff --git a/contexts/plat_file_contexts_test b/contexts/plat_file_contexts_test index c9c809a48..6e9a8a28f 100644 --- a/contexts/plat_file_contexts_test +++ b/contexts/plat_file_contexts_test @@ -911,6 +911,8 @@ /data/system_de system_userdir_file /data/user system_userdir_file /data/user_de system_userdir_file +/data/storage_area system_userdir_file +/data/misc_ce/0/storage_area_keys storage_area_key_file /data/misc/adb adb_keys_file /data/misc/adb/test adb_keys_file diff --git a/flagging/Android.bp b/flagging/Android.bp index a965f1f67..41a286162 100644 --- a/flagging/Android.bp +++ b/flagging/Android.bp @@ -21,6 +21,7 @@ se_flags { "RELEASE_AVF_ENABLE_DEVICE_ASSIGNMENT", "RELEASE_AVF_ENABLE_LLPVM_CHANGES", "RELEASE_HARDWARE_BLUETOOTH_RANGING_SERVICE", + "RELEASE_UNLOCKED_STORAGE_API", ], export_to: ["all_selinux_flags"], } diff --git a/private/app.te b/private/app.te index 634cc5368..30931e464 100644 --- a/private/app.te +++ b/private/app.te @@ -242,12 +242,37 @@ allow appdomain appdomain:fifo_file rw_file_perms; allow appdomain surfaceflinger:unix_stream_socket { read write setopt getattr getopt shutdown }; # App sandbox file accesses. -allow { appdomain -isolated_app_all -mlstrustedsubject -sdk_sandbox_all } { app_data_file privapp_data_file }:dir create_dir_perms; -allow { appdomain -isolated_app_all -mlstrustedsubject -sdk_sandbox_all } { app_data_file privapp_data_file }:file create_file_perms; -allowxperm { appdomain -isolated_app_all -mlstrustedsubject -sdk_sandbox_all } { app_data_file privapp_data_file }:file ioctl FS_IOC_MEASURE_VERITY; +allow { appdomain -isolated_app_all -mlstrustedsubject -sdk_sandbox_all } { + app_data_file + privapp_data_file + is_flag_enabled(RELEASE_UNLOCKED_STORAGE_API, `storage_area_content_file') +}:dir create_dir_perms; +allow { appdomain -isolated_app_all -mlstrustedsubject -sdk_sandbox_all } { + app_data_file + privapp_data_file + is_flag_enabled(RELEASE_UNLOCKED_STORAGE_API, `storage_area_content_file') +}:file create_file_perms; + +is_flag_enabled(RELEASE_UNLOCKED_STORAGE_API, ` + # an app can read but cannot write to its own directory of storage areas + allow { appdomain -isolated_app_all -mlstrustedsubject -sdk_sandbox_all } storage_area_app_dir:dir r_dir_perms; + # an app can write to its storage areas + allow { appdomain -isolated_app_all -mlstrustedsubject -sdk_sandbox_all } storage_area_dir:dir rw_dir_perms; +') + +allowxperm { appdomain -isolated_app_all -mlstrustedsubject -sdk_sandbox_all } { + app_data_file + privapp_data_file + is_flag_enabled(RELEASE_UNLOCKED_STORAGE_API, `storage_area_content_file') +}:file ioctl FS_IOC_MEASURE_VERITY; # Access via already open fds is ok even for mlstrustedsubject. -allow { appdomain -isolated_app_all -sdk_sandbox_all } { app_data_file privapp_data_file system_app_data_file }:file { getattr map read write }; +allow { appdomain -isolated_app_all -sdk_sandbox_all } { + app_data_file + privapp_data_file + system_app_data_file + is_flag_enabled(RELEASE_UNLOCKED_STORAGE_API, `storage_area_content_file') +}:file { getattr map read write }; # Access open fds from SDK sandbox allow appdomain sdk_sandbox_data_file:file { getattr read }; @@ -777,3 +802,13 @@ dontaudit appdomain system_font_fallback_file:file no_rw_file_perms; neverallow appdomain system_font_fallback_file:file no_rw_file_perms; neverallow { appdomain -shell } tombstone_data_file:file ~{ getattr read }; +is_flag_enabled(RELEASE_UNLOCKED_STORAGE_API, ` + # Files and directories that apps write to their storage areas + # should have type storage_area_content_file + type_transition { + appdomain + -isolated_app_all + -ephemeral_app + -sdk_sandbox_all + } storage_area_dir:{ notdevfile_class_set dir } storage_area_content_file; +') diff --git a/private/app_neverallows.te b/private/app_neverallows.te index ab8b8d530..bf723c5be 100644 --- a/private/app_neverallows.te +++ b/private/app_neverallows.te @@ -68,6 +68,21 @@ neverallow { -runas_app } { app_data_file privapp_data_file }:file execute_no_trans; +is_flag_enabled(RELEASE_UNLOCKED_STORAGE_API, ` + # block apps from executing files in their storage areas + # this is a stronger and more desirable guarantee than blocking execute_no_trans, but + # execute cannot be blocked on all of app_data_file without causing + # backwards compatibility issues (see b/237289679) + neverallow appdomain storage_area_content_file:file execute; +') + +is_flag_enabled(RELEASE_UNLOCKED_STORAGE_API, ` + # dont allow apps to modify their own directories of storage areas + neverallow appdomain storage_area_app_dir:dir_file_class_set { + create write setattr relabelfrom relabelto append unlink link rename + }; +') + # Do not allow untrusted apps to invoke dex2oat. This was historically required # by ART for compiling secondary dex files but has been removed in Q. # Exempt legacy apps (targetApi<=28) for compatibility. @@ -156,6 +171,7 @@ neverallow { all_untrusted_apps -mediaprovider } { file_type -app_data_file # The apps sandbox itself -privapp_data_file + is_flag_enabled(RELEASE_UNLOCKED_STORAGE_API, `-storage_area_content_file') -app_exec_data_file # stored within the app sandbox directory -media_rw_data_file # Internal storage. Known that apps can # leave artfacts here after uninstall. diff --git a/private/crosvm.te b/private/crosvm.te index fced92fef..ac62b666c 100644 --- a/private/crosvm.te +++ b/private/crosvm.te @@ -139,6 +139,7 @@ neverallow crosvm { apk_data_file app_data_file privapp_data_file + is_flag_enabled(RELEASE_UNLOCKED_STORAGE_API, `storage_area_content_file') userdebug_or_eng(`-shell_data_file') }:file open; diff --git a/private/domain.te b/private/domain.te index da52d5fbc..60e61a49b 100644 --- a/private/domain.te +++ b/private/domain.te @@ -1594,7 +1594,20 @@ neverallow { -appdomain -artd # compile secondary dex files -installd # creation of sandbox -} { privapp_data_file app_data_file }:dir_file_class_set { create unlink }; +} { + privapp_data_file + app_data_file + is_flag_enabled(RELEASE_UNLOCKED_STORAGE_API, `storage_area_content_file') +}:dir_file_class_set { create unlink }; + +is_flag_enabled(RELEASE_UNLOCKED_STORAGE_API, ` + neverallow { + domain + -artd # compile secondary dex files + -installd # creation of sandbox + -vold_prepare_subdirs # creation of storage area directories + } {storage_area_app_dir storage_area_dir }:dir { create unlink }; +') # Only the following processes should be directly accessing private app # directories. @@ -1611,7 +1624,38 @@ neverallow { -runas -system_server -zygote -} { privapp_data_file app_data_file }:dir *; +} { + privapp_data_file + app_data_file + is_flag_enabled(RELEASE_UNLOCKED_STORAGE_API, `storage_area_content_file') +}:dir *; + +is_flag_enabled(RELEASE_UNLOCKED_STORAGE_API, ` + neverallow { + domain + -appdomain + -app_zygote + -artd # compile secondary dex files + -installd + -rs # spawned by appdomain, so carryover the exception above + -system_server + -vold # encryption of storage area directories + -vold_prepare_subdirs # creation of storage area directories + -zygote + } { storage_area_dir storage_area_app_dir }:dir *; +') + +is_flag_enabled(RELEASE_UNLOCKED_STORAGE_API, ` + # only vold and installd can access the storage area key files + # (and init, in case of a recursive restorecon) + neverallow { + domain + -init + -vold + -vold_prepare_subdirs + -installd + } { storage_area_key_file }:dir_file_class_set *; +') # Only apps should be modifying app data. installd is exempted for # restorecon and package install/uninstall. @@ -1621,7 +1665,22 @@ neverallow { -artd # compile secondary dex files -installd -rs # spawned by appdomain, so carryover the exception above -} { privapp_data_file app_data_file }:dir ~r_dir_perms; +} { + privapp_data_file + app_data_file + is_flag_enabled(RELEASE_UNLOCKED_STORAGE_API, `storage_area_content_file') +}:dir ~r_dir_perms; + +is_flag_enabled(RELEASE_UNLOCKED_STORAGE_API, ` + neverallow { + domain + -appdomain + -artd # compile secondary dex files + -installd + -rs # spawned by appdomain, so carryover the exception above + -vold_prepare_subdirs # creation of storage area directories + } { storage_area_dir storage_area_app_dir }:dir ~r_dir_perms; +') neverallow { domain @@ -1630,20 +1689,41 @@ neverallow { -artd # compile secondary dex files -installd -rs # spawned by appdomain, so carryover the exception above -} { privapp_data_file app_data_file }:file_class_set open; +} { + privapp_data_file + app_data_file + is_flag_enabled(RELEASE_UNLOCKED_STORAGE_API, `storage_area_content_file') +}:file_class_set open; neverallow { domain -appdomain -artd # compile secondary dex files -installd # creation of sandbox -} { privapp_data_file app_data_file }:dir_file_class_set { create unlink }; +} { + privapp_data_file + app_data_file + is_flag_enabled(RELEASE_UNLOCKED_STORAGE_API, `storage_area_content_file') +}:dir_file_class_set { create unlink }; neverallow { domain -artd # compile secondary dex files -installd -} { privapp_data_file app_data_file }:dir_file_class_set { relabelfrom relabelto }; +} { + privapp_data_file + app_data_file + is_flag_enabled(RELEASE_UNLOCKED_STORAGE_API, `storage_area_content_file') +}:dir_file_class_set { relabelfrom relabelto }; + +is_flag_enabled(RELEASE_UNLOCKED_STORAGE_API, ` + neverallow { + domain + -artd # compile secondary dex files + -installd + -vold_prepare_subdirs + } { storage_area_dir storage_area_app_dir }:dir { relabelfrom relabelto }; +') # The staging directory contains APEX and APK files. It is important to ensure # that these files cannot be accessed by other domains to ensure that the files diff --git a/private/file.te b/private/file.te index 7b2507cbd..09aa02aa5 100644 --- a/private/file.te +++ b/private/file.te @@ -194,3 +194,12 @@ allow proc_net proc:filesystem associate; # Should be: # type apk_data_file, file_type, data_file_type; neverallow fs_type file_type:filesystem associate; +# app directories of storage areas: /data/storage_area/userId/pkgName -- apps cannot write to it +type storage_area_app_dir, file_type, data_file_type, core_data_file_type, app_data_file_type; +# app storage areas: /data/storage_area/userId/pkgName/storageAreaName +type storage_area_dir, file_type, data_file_type, core_data_file_type, app_data_file_type; +# contents of app storage areas: /data/storage_area/userId/pkgName/storageAreaName/* +type storage_area_content_file, file_type, data_file_type, core_data_file_type, app_data_file_type; + +# /data/misc_ce/userId/storage_area_keys +type storage_area_key_file, file_type, data_file_type, core_data_file_type; \ No newline at end of file diff --git a/private/file_contexts b/private/file_contexts index 3f5c9ef3d..c72d752bc 100644 --- a/private/file_contexts +++ b/private/file_contexts @@ -624,6 +624,7 @@ /data/system_de u:object_r:system_userdir_file:s0 /data/user u:object_r:system_userdir_file:s0 /data/user_de u:object_r:system_userdir_file:s0 +/data/storage_area u:object_r:system_userdir_file:s0 # Misc data /data/misc/adb(/.*)? u:object_r:adb_keys_file:s0 @@ -819,6 +820,9 @@ /data/misc_de/[0-9]+/vold(/.*)? u:object_r:vold_data_file:s0 /data/misc_ce/[0-9]+/vold(/.*)? u:object_r:vold_data_file:s0 +# storage area keys +/data/misc_ce/[0-9]+/storage_area_keys(/.*)? u:object_r:storage_area_key_file:s0 + # Backup service persistent per-user bookkeeping /data/system_ce/[0-9]+/backup(/.*)? u:object_r:backup_data_file:s0 # Backup service temporary per-user data for inter-change with apps diff --git a/private/init.te b/private/init.te index a83e538e3..96fd5c55c 100644 --- a/private/init.te +++ b/private/init.te @@ -300,6 +300,11 @@ allow init self:global_capability_class_set { chown fowner fsetid }; allow init { file_type -app_data_file + is_flag_enabled(RELEASE_UNLOCKED_STORAGE_API, ` + -storage_area_dir + -storage_area_app_dir + -storage_area_content_file + ') -bpffs_type -exec_type -misc_logd_file @@ -314,6 +319,11 @@ allow init { allow init { file_type -app_data_file + is_flag_enabled(RELEASE_UNLOCKED_STORAGE_API, ` + -storage_area_dir + -storage_area_app_dir + -storage_area_content_file + ') -bpffs_type -credstore_data_file -exec_type @@ -336,6 +346,11 @@ allow init { file_type -apex_info_file -app_data_file + is_flag_enabled(RELEASE_UNLOCKED_STORAGE_API, ` + -storage_area_dir + -storage_area_app_dir + -storage_area_content_file + ') -bpffs_type -exec_type -gsi_data_file @@ -363,6 +378,11 @@ allow init apex_info_file:file r_file_perms; allow init { file_type -app_data_file + is_flag_enabled(RELEASE_UNLOCKED_STORAGE_API, ` + -storage_area_dir + -storage_area_app_dir + -storage_area_content_file + ') -bpffs_type -exec_type -gsi_data_file @@ -383,6 +403,11 @@ allow init { file_type -apex_mnt_dir -app_data_file + is_flag_enabled(RELEASE_UNLOCKED_STORAGE_API, ` + -storage_area_dir + -storage_area_app_dir + -storage_area_content_file + ') -bpffs_type -exec_type -gsi_data_file @@ -409,6 +434,11 @@ allow init { -vendor_file_type -exec_type -app_data_file + is_flag_enabled(RELEASE_UNLOCKED_STORAGE_API, ` + -storage_area_dir + -storage_area_app_dir + -storage_area_content_file + ') -privapp_data_file }:dir_file_class_set relabelto; diff --git a/private/installd.te b/private/installd.te index 0a5028576..af0d62cd2 100644 --- a/private/installd.te +++ b/private/installd.te @@ -225,6 +225,12 @@ get_prop(installd, storage_config_prop) # Accessing files on the Incremental File System uses fds opened in the context of vold. allow installd vold:fd use; +# on app uninstall, installd deletes the storage area keys for the app +is_flag_enabled(RELEASE_UNLOCKED_STORAGE_API, ` + allow installd storage_area_key_file:dir { open search write remove_name lock }; + allow installd storage_area_key_file:file unlink; +') + ### ### Neverallow rules ### diff --git a/private/mlstrustedsubject.te b/private/mlstrustedsubject.te index 67bd1137c..8fcc1d403 100644 --- a/private/mlstrustedsubject.te +++ b/private/mlstrustedsubject.te @@ -8,13 +8,31 @@ neverallow { mlstrustedsubject -artd # compile secondary dex files -installd -} { app_data_file privapp_data_file }:file ~{ read write map getattr ioctl lock append }; +} { + app_data_file + privapp_data_file + is_flag_enabled(RELEASE_UNLOCKED_STORAGE_API, `storage_area_content_file') +}:file ~{ read write map getattr ioctl lock append }; neverallow { mlstrustedsubject -artd # compile secondary dex files -installd -} { app_data_file privapp_data_file }:dir ~{ read getattr search }; +} { + app_data_file + privapp_data_file + is_flag_enabled(RELEASE_UNLOCKED_STORAGE_API, `storage_area_content_file') +}:dir ~{ read getattr search }; + +is_flag_enabled(RELEASE_UNLOCKED_STORAGE_API, ` + neverallow { + mlstrustedsubject + -artd # compile secondary dex files + -installd + -vold # encryption of storage areas + -vold_prepare_subdirs # creation of storage area directories + } { storage_area_dir storage_area_app_dir }:dir ~{ read getattr search }; +') neverallow { mlstrustedsubject @@ -24,4 +42,22 @@ neverallow { -adbd -runas -zygote -} { app_data_file privapp_data_file }:dir { read getattr search }; +} { + app_data_file + privapp_data_file + is_flag_enabled(RELEASE_UNLOCKED_STORAGE_API, `storage_area_content_file') +}:dir { read getattr search }; + +is_flag_enabled(RELEASE_UNLOCKED_STORAGE_API, ` + neverallow { + mlstrustedsubject + -artd # compile secondary dex files + -installd + -system_server + -adbd + -runas + -vold # encryption of storage area directories + -vold_prepare_subdirs # creation of storage area directories + -zygote + } { storage_area_dir storage_area_app_dir }:dir { read getattr search }; +') diff --git a/private/vold.te b/private/vold.te index 4da11da06..7716bd1c4 100644 --- a/private/vold.te +++ b/private/vold.te @@ -62,6 +62,27 @@ allow vold keystore_maintenance_service:service_manager find; allow vold keystore:keystore2 early_boot_ended; allow vold keystore:keystore2 delete_all_keys; +is_flag_enabled(RELEASE_UNLOCKED_STORAGE_API, ` + # Allow vold to encrypt storage area directories on behalf of apps. + allow vold { + storage_area_dir + storage_area_app_dir + }:dir { + getattr + ioctl # for FS_IOC_SET_ENCRYPTION_POLICY + open + read # for open(O_RDONLY) for ioctl + search + }; +') + +# when a storage area is created (with `openStorageArea`), vold creates the key +# and when a storage area is deleted (with `deleteStorageArea`), vold deletes the key +is_flag_enabled(RELEASE_UNLOCKED_STORAGE_API, ` + allow vold storage_area_key_file:file create_file_perms; + allow vold storage_area_key_file:dir create_dir_perms; +') + # Allow vold to create and delete per-user directories like /data/user/$userId. allow vold { media_userdir_file @@ -119,6 +140,7 @@ allowxperm vold { fs_type file_type }:dir ioctl FITRIM; # and add/remove file-based encryption keys. allowxperm vold data_file_type:dir ioctl { FS_IOC_GET_ENCRYPTION_POLICY + FS_IOC_GET_ENCRYPTION_POLICY_EX FS_IOC_SET_ENCRYPTION_POLICY FS_IOC_ADD_ENCRYPTION_KEY FS_IOC_REMOVE_ENCRYPTION_KEY @@ -131,6 +153,7 @@ allowxperm vold data_file_type:dir ioctl { allowxperm vold { vold_data_file vold_metadata_file + is_flag_enabled(RELEASE_UNLOCKED_STORAGE_API, `storage_area_key_file') }:file ioctl { F2FS_IOC_SEC_TRIM_FILE FS_IOC_FIEMAP diff --git a/private/vold_prepare_subdirs.te b/private/vold_prepare_subdirs.te index 4d8c80266..1dc00b252 100644 --- a/private/vold_prepare_subdirs.te +++ b/private/vold_prepare_subdirs.te @@ -10,6 +10,7 @@ allow vold_prepare_subdirs devpts:chr_file rw_file_perms; allow vold_prepare_subdirs vold:fd use; allow vold_prepare_subdirs vold:fifo_file { read write }; allow vold_prepare_subdirs file_contexts_file:file r_file_perms; +allow vold_prepare_subdirs seapp_contexts_file:file r_file_perms; allow vold_prepare_subdirs self:global_capability_class_set { chown dac_override dac_read_search fowner }; allow vold_prepare_subdirs self:process setfscreate; allow vold_prepare_subdirs { @@ -27,6 +28,7 @@ allow vold_prepare_subdirs { fingerprint_vendor_data_file iris_vendor_data_file rollback_data_file + is_flag_enabled(RELEASE_UNLOCKED_STORAGE_API, `storage_area_key_file') storaged_data_file sdk_sandbox_data_file sdk_sandbox_system_data_file @@ -54,6 +56,27 @@ allow vold_prepare_subdirs mnt_expand_file:dir search; allow vold_prepare_subdirs user_profile_data_file:dir { search getattr relabelfrom }; allow vold_prepare_subdirs user_profile_root_file:dir { search getattr relabelfrom relabelto }; +# Allow vold_prepare_subdirs to create storage area directories on behalf of apps. +is_flag_enabled(RELEASE_UNLOCKED_STORAGE_API, ` + allow vold_prepare_subdirs { + storage_area_dir + storage_area_app_dir + }:dir { + rw_dir_perms + create + setattr # for chown() and chmod() + rmdir + unlink + relabelfrom # setfilecon + relabelto # setfilecon + }; + + # The storage area directories should have type storage_area_dir + type_transition vold_prepare_subdirs storage_area_app_dir:dir storage_area_dir; + + selinux_check_context(vold_prepare_subdirs) +') + # Migrate legacy labels to apex_system_server_data_file (b/217581286) allow vold_prepare_subdirs { apex_appsearch_data_file