diff --git a/domain.te b/domain.te index a317050842b901f8cc6e340398f03045031eead6..f5078c0a5847eabc6b5f1860b7edd26aa995b02d 100644 --- a/domain.te +++ b/domain.te @@ -304,6 +304,7 @@ neverallow domain { cache_file cache_backup_file }:file execute; neverallow { domain -untrusted_app + -priv_app -shell } { data_file_type diff --git a/priv_app.te b/priv_app.te new file mode 100644 index 0000000000000000000000000000000000000000..ff47f8e8f4eb481a5b5846b5cd2847873ff1fed4 --- /dev/null +++ b/priv_app.te @@ -0,0 +1,93 @@ +### +### A domain for further sandboxing privileged apps. +### +type priv_app, domain; +app_domain(priv_app) +# Access the network. +net_domain(priv_app) +# Access bluetooth. +bluetooth_domain(priv_app) + +# Some apps ship with shared libraries and binaries that they write out +# to their sandbox directory and then execute. +allow priv_app app_data_file:file rx_file_perms; + +# Allow the allocation and use of ptys +# Used by: https://play.privileged.com/store/apps/details?id=jackpal.androidterm +create_pty(priv_app) + +allow priv_app drmserver_service:service_manager find; +allow priv_app mediaserver_service:service_manager find; +allow priv_app nfc_service:service_manager find; +allow priv_app radio_service:service_manager find; +allow priv_app surfaceflinger_service:service_manager find; +allow priv_app app_api_service:service_manager find; +allow priv_app system_api_service:service_manager find; +allow priv_app persistent_data_block_service:service_manager find; + +# Traverse into /mnt/media_rw for bypassing FUSE daemon +# TODO: narrow this to just MediaProvider +allow priv_app mnt_media_rw_file:dir search; + +# Access to /data/media. +allow priv_app media_rw_data_file:dir create_dir_perms; +allow priv_app media_rw_data_file:file create_file_perms; + +# Used by Finsky / Android "Verify Apps" functionality when +# running "adb install foo.apk". +allow priv_app shell_data_file:file r_file_perms; +allow priv_app shell_data_file:dir r_dir_perms; + +# b/18504118: Allow reads from /data/anr/traces.txt +allow priv_app anr_data_file:file r_file_perms; + +# Allow GMS core to access perfprofd output, which is stored +# in /data/misc/perfprofd/. GMS core will need to list all +# data stored in that directory to process them one by one. +userdebug_or_eng(` + allow priv_app perfprofd_data_file:file r_file_perms; + allow priv_app perfprofd_data_file:dir r_dir_perms; +') + +### +### neverallow rules +### + +# Receive or send uevent messages. +neverallow priv_app domain:netlink_kobject_uevent_socket *; + +# Receive or send generic netlink messages +neverallow priv_app domain:netlink_socket *; + +# Too much leaky information in debugfs. It's a security +# best practice to ensure these files aren't readable. +neverallow priv_app debugfs:file read; + +# Do not allow privileged apps to register services. +# Only trusted components of Android should be registering +# services. +neverallow priv_app service_manager_type:service_manager add; + +# Do not allow privileged apps to connect to the property service +# or set properties. b/10243159 +neverallow priv_app property_socket:sock_file write; +neverallow priv_app init:unix_stream_socket connectto; +neverallow priv_app property_type:property_service set; + +# Do not allow priv_app to be assigned mlstrustedsubject. +# This would undermine the per-user isolation model being +# enforced via levelFrom=user in seapp_contexts and the mls +# constraints. As there is no direct way to specify a neverallow +# on attribute assignment, this relies on the fact that fork +# permission only makes sense within a domain (hence should +# never be granted to any other domain within mlstrustedsubject) +# and priv_app is allowed fork permission to itself. +neverallow priv_app mlstrustedsubject:process fork; + +# Do not allow priv_app to hard link to any files. +# In particular, if priv_app links to other app data +# files, installd will not be able to guarantee the deletion +# of the linked to file. Hard links also contribute to security +# bugs, so we want to ensure priv_app never has this +# capability. +neverallow priv_app file_type:file link; diff --git a/seapp_contexts b/seapp_contexts index b0c61cfed7864165042071fb971e783f06fc28fc..d8d224038188409bd36c9b21e14ff86e73dc9063 100644 --- a/seapp_contexts +++ b/seapp_contexts @@ -5,6 +5,7 @@ # seinfo (string) # name (string) # path (string) +# isPrivApp (boolean) # isSystemServer=true can only be used once. # An unspecified isSystemServer defaults to false. # isOwner=true will only match for the owner/primary user. @@ -14,6 +15,8 @@ # A user string selector that ends in * will perform a prefix match. # user=_app will match any regular app UID. # user=_isolated will match any isolated service UID. +# isPrivApp=true will only match for applications preinstalled in +# /system/priv-app. # All specified input selectors in an entry must match (i.e. logical AND). # Matching is case-insensitive. # @@ -24,8 +27,10 @@ # (4) Fixed user= string before user= prefix (i.e. ending in *). # (5) Longer user= prefix before shorter user= prefix. # (6) Specified seinfo= string before unspecified seinfo= string. +# ':' character is reserved and may not be used. # (7) Specified name= string before unspecified name= string. # (8) Specified path= string before unspecified path= string. +# (9) Specified isPrivApp= before unspecified isPrivApp= boolean. # # Outputs: # domain (string) @@ -83,4 +88,5 @@ user=shared_relro domain=shared_relro user=shell seinfo=platform domain=shell type=shell_data_file user=_isolated domain=isolated_app levelFrom=user user=_app seinfo=platform domain=platform_app type=app_data_file levelFrom=user +user=_app isPrivApp=true domain=priv_app type=app_data_file levelFrom=user user=_app domain=untrusted_app type=app_data_file levelFrom=user diff --git a/tools/check_seapp.c b/tools/check_seapp.c index ae4f7e3e03d9b4c9641e02029c6b1235f33a91f9..5a03b7f365884a379dfb944f71db3eb7b9152cba 100644 --- a/tools/check_seapp.c +++ b/tools/check_seapp.c @@ -209,6 +209,7 @@ key_map rules[] = { { .name = "seinfo", .type = dt_string, .dir = dir_in, .data = NULL }, { .name = "name", .type = dt_string, .dir = dir_in, .data = NULL }, { .name = "path", .type = dt_string, .dir = dir_in, .data = NULL }, + { .name = "isPrivApp", .type = dt_bool, .dir = dir_in, .data = NULL }, /*Outputs*/ { .name = "domain", .type = dt_string, .dir = dir_out, .data = NULL }, { .name = "type", .type = dt_string, .dir = dir_out, .data = NULL },