Merge "Add SELinux policy for storage areas" into main
diff --git a/contexts/plat_file_contexts_test b/contexts/plat_file_contexts_test
index c9c809a..6e9a8a2 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 a965f1f..41a2861 100644
--- a/flagging/Android.bp
+++ b/flagging/Android.bp
@@ -21,6 +21,7 @@
"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 634cc53..30931e4 100644
--- a/private/app.te
+++ b/private/app.te
@@ -242,12 +242,37 @@
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 @@
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 ab8b8d5..bf723c5 100644
--- a/private/app_neverallows.te
+++ b/private/app_neverallows.te
@@ -68,6 +68,21 @@
-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 @@
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 fced92f..ac62b66 100644
--- a/private/crosvm.te
+++ b/private/crosvm.te
@@ -139,6 +139,7 @@
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 da52d5f..60e61a4 100644
--- a/private/domain.te
+++ b/private/domain.te
@@ -1594,7 +1594,20 @@
-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 @@
-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 @@
-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 @@
-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 7b2507c..09aa02a 100644
--- a/private/file.te
+++ b/private/file.te
@@ -194,3 +194,12 @@
# 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 3f5c9ef..c72d752 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 a83e538..96fd5c5 100644
--- a/private/init.te
+++ b/private/init.te
@@ -300,6 +300,11 @@
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 {
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 @@
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 {
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 @@
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 @@
-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 0a50285..af0d62c 100644
--- a/private/installd.te
+++ b/private/installd.te
@@ -225,6 +225,12 @@
# 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 67bd113..8fcc1d4 100644
--- a/private/mlstrustedsubject.te
+++ b/private/mlstrustedsubject.te
@@ -8,13 +8,31 @@
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 @@
-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 4da11da..7716bd1 100644
--- a/private/vold.te
+++ b/private/vold.te
@@ -62,6 +62,27 @@
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 @@
# 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 {
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 4d8c802..1dc00b2 100644
--- a/private/vold_prepare_subdirs.te
+++ b/private/vold_prepare_subdirs.te
@@ -10,6 +10,7 @@
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 @@
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 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