Add priv_app domain to global seapp_context
Assign priviliged apps not signed with the platform key to the priv_app
domain.
Bug: 22033466
Change-Id: Idf7fbe7adbdc326835a179b554f96951b69395bc
diff --git a/domain.te b/domain.te
index a317050..f5078c0 100644
--- a/domain.te
+++ b/domain.te
@@ -304,6 +304,7 @@
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 0000000..ff47f8e
--- /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 b0c61cf..d8d2240 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=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 ae4f7e3..5a03b7f 100644
--- a/tools/check_seapp.c
+++ b/tools/check_seapp.c
@@ -209,6 +209,7 @@
{ .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 },