Merge "Drop shell from having access to dmesg"
diff --git a/access_vectors b/access_vectors
index 4de3463..b039b0b 100644
--- a/access_vectors
+++ b/access_vectors
@@ -871,7 +871,6 @@
 	call
 	set_context_mgr
 	transfer
-	receive
 }
 
 class zygote
diff --git a/app.te b/app.te
index 65d710a..de7b7d0 100644
--- a/app.te
+++ b/app.te
@@ -188,10 +188,8 @@
 binder_use(appdomain)
 # Perform binder IPC to binder services.
 binder_call(appdomain, binderservicedomain)
-binder_transfer(appdomain, binderservicedomain)
 # Perform binder IPC to other apps.
 binder_call(appdomain, appdomain)
-binder_transfer(appdomain, appdomain)
 
 # Appdomain interaction with isolated apps
 r_dir_file(appdomain, isolated_app)
diff --git a/device.te b/device.te
index 7818ce8..ecb7c10 100644
--- a/device.te
+++ b/device.te
@@ -41,6 +41,7 @@
 type ion_device, dev_type;
 type gps_device, dev_type;
 type qtaguid_device, dev_type;
+type watchdog_device, dev_type;
 
 # All devices have a uart for the hci
 # attach service. The uart dev node
diff --git a/file_contexts b/file_contexts
index 3b207c9..c47b44b 100644
--- a/file_contexts
+++ b/file_contexts
@@ -104,6 +104,7 @@
 /dev/urandom		u:object_r:urandom_device:s0
 /dev/vcs[0-9a-z]*	u:object_r:vcs_device:s0
 /dev/video[0-9]*	u:object_r:video_device:s0
+/dev/watchdog		u:object_r:watchdog_device:s0
 /dev/xt_qtaguid	u:object_r:qtaguid_device:s0
 /dev/zero		u:object_r:zero_device:s0
 #############################
diff --git a/mediaserver.te b/mediaserver.te
index f5274d9..f941c6a 100644
--- a/mediaserver.te
+++ b/mediaserver.te
@@ -13,7 +13,6 @@
 binder_use(mediaserver)
 binder_call(mediaserver, binderservicedomain)
 binder_call(mediaserver, appdomain)
-binder_transfer(mediaserver, surfaceflinger)
 binder_service(mediaserver)
 
 allow mediaserver kernel:system module_request;
diff --git a/seapp_contexts b/seapp_contexts
index 258477a..f0cea67 100644
--- a/seapp_contexts
+++ b/seapp_contexts
@@ -24,11 +24,12 @@
 # Outputs:
 #	domain (string)
 #	type (string)
-#	levelFromUid (boolean)
+#	levelFrom (string; one of none, all, app, or user)
 #	level (string)
 # Only entries that specify domain= will be used for app process labeling.
 # Only entries that specify type= will be used for app directory labeling.
-# levelfromUid is only supported for app UIDs presently.
+# levelFrom=user is only supported for _app or _isolated UIDs.
+# levelFrom=app or levelFrom=all is only supported for _app UIDs.
 # level may be used to specify a fixed level for any UID. 
 #
 isSystemServer=true domain=system
@@ -36,7 +37,7 @@
 user=bluetooth domain=bluetooth type=bluetooth_data_file
 user=nfc domain=nfc type=nfc_data_file
 user=radio domain=radio type=radio_data_file
-user=_app domain=untrusted_app type=app_data_file levelFromUid=true
+user=_app domain=untrusted_app type=app_data_file levelFrom=app
 user=_app seinfo=platform domain=platform_app type=platform_app_data_file
 user=_app seinfo=shared domain=shared_app type=platform_app_data_file
 user=_app seinfo=media domain=media_app type=platform_app_data_file
diff --git a/servicemanager.te b/servicemanager.te
index fefbe08..a78a485 100644
--- a/servicemanager.te
+++ b/servicemanager.te
@@ -11,4 +11,4 @@
 # created by other domains.  It never passes its own references
 # or initiates a Binder IPC.
 allow servicemanager self:binder set_context_mgr;
-allow servicemanager domain:binder { receive transfer };
+allow servicemanager domain:binder transfer;
diff --git a/surfaceflinger.te b/surfaceflinger.te
index 10a57ee..30b1816 100644
--- a/surfaceflinger.te
+++ b/surfaceflinger.te
@@ -12,6 +12,7 @@
 binder_use(surfaceflinger)
 binder_call(surfaceflinger, system)
 binder_service(surfaceflinger)
+allow surfaceflinger init:binder transfer;
 
 # Access /dev/graphics/fb0.
 allow surfaceflinger graphics_device:dir search;
diff --git a/system.te b/system.te
index 192b14f..7e207c3 100644
--- a/system.te
+++ b/system.te
@@ -8,7 +8,6 @@
 
 # Perform binder IPC to any app domain.
 binder_call(system_app, appdomain)
-binder_transfer(system_app, appdomain)
 
 # Read and write system data files.
 # May want to split into separate types.
@@ -121,9 +120,6 @@
 binder_call(system, binderservicedomain)
 binder_call(system, appdomain)
 binder_service(system)
-# Transfer other Binder references.
-binder_transfer(system, binderservicedomain)
-binder_transfer(system, appdomain)
 
 # Read /proc/pid files for Binder clients.
 r_dir_file(system, appdomain)
diff --git a/te_macros b/te_macros
index 6354496..7883c40 100644
--- a/te_macros
+++ b/te_macros
@@ -152,10 +152,8 @@
 # binder_use(domain)
 # Allow domain to use Binder IPC.
 define(`binder_use', `
-# Get Binder references from the servicemanager.
-allow $1 servicemanager:binder call;
-# Transfer and receive own Binder references.
-allow $1 self:binder { transfer receive };
+# Call the servicemanager and transfer references to it.
+allow $1 servicemanager:binder { call transfer };
 # Map /dev/ashmem with PROT_EXEC.
 allow $1 ashmem_device:chr_file execute;
 # rw access to /dev/binder and /dev/ashmem is presently granted to
@@ -166,20 +164,15 @@
 # binder_call(clientdomain, serverdomain)
 # Allow clientdomain to perform binder IPC to serverdomain.
 define(`binder_call', `
-# First we receive a Binder ref to the server, then we call it.
-allow $1 $2:binder { receive call };
+# Call the server domain and optionally transfer references to it.
+allow $1 $2:binder { call transfer };
+# Allow the serverdomain to transfer references to the client on the reply.
+allow $2 $1:binder transfer;
 # Receive and use open files from the server.
 allow $1 $2:fd use;
 ')
 
 #####################################
-# binder_transfer(clientdomain, serverdomain)
-# Allow clientdomain to transfer Binder references created by serverdomain.
-define(`binder_transfer', `
-allow $1 $2:binder transfer;
-')
-
-#####################################
 # binder_service(domain)
 # Mark a domain as being a Binder service domain.
 # Used to allow binder IPC to the various system services.
diff --git a/tools/check_seapp.c b/tools/check_seapp.c
index 8001cea..482d060 100644
--- a/tools/check_seapp.c
+++ b/tools/check_seapp.c
@@ -162,6 +162,7 @@
                 { .name = "domain",         .type = dt_string, .dir = dir_out, .data = NULL },
                 { .name = "type",           .type = dt_string, .dir = dir_out, .data = NULL },
                 { .name = "levelFromUid",   .type = dt_bool,   .dir = dir_out, .data = NULL },
+                { .name = "levelFrom",      .type = dt_string,   .dir = dir_out, .data = NULL },
                 { .name = "level",          .type = dt_string, .dir = dir_out, .data = NULL },
 };
 
@@ -256,6 +257,15 @@
 		goto out;
 	}
 
+	if (!strcasecmp(key, "levelFrom") &&
+	    (strcasecmp(value, "none") && strcasecmp(value, "all") &&
+	     strcasecmp(value, "app") && strcasecmp(value, "user"))) {
+		log_error("Unknown levelFrom=%s on line: %d in file: %s\n",
+			  value, lineno, out_file_name);
+		rc = 0;
+		goto out;
+	}
+
 	/*
 	 * If their is no policy file present,
 	 * then it is not in strict mode so just return.
diff --git a/unconfined.te b/unconfined.te
index ff53595..e016584 100644
--- a/unconfined.te
+++ b/unconfined.te
@@ -20,5 +20,5 @@
 allow unconfineddomain port_type:socket_class_set name_bind;
 allow unconfineddomain port_type:{ tcp_socket dccp_socket } name_connect;
 allow unconfineddomain domain:peer recv;
-allow unconfineddomain domain:binder { call transfer receive };
+allow unconfineddomain domain:binder { call transfer };
 allow unconfineddomain property_type:property_service set;
diff --git a/watchdogd.te b/watchdogd.te
new file mode 100644
index 0000000..18824cc
--- /dev/null
+++ b/watchdogd.te
@@ -0,0 +1,8 @@
+# watchdogd seclabel is specified in init.<board>.rc
+type watchdogd, domain;
+allow watchdogd rootfs:file { entrypoint r_file_perms };
+allow watchdogd self:capability mknod;
+allow watchdogd device:dir { add_name write remove_name };
+allow watchdogd watchdog_device:chr_file rw_file_perms;
+# because of /dev/__kmsg__ and /dev/__null__
+allow watchdogd device:chr_file create_file_perms;