From 75e2ef92601c485348c40cc8884839fba27046ba Mon Sep 17 00:00:00 2001
From: Stephen Smalley <sds@tycho.nsa.gov>
Date: Mon, 16 Jun 2014 13:05:38 -0400
Subject: [PATCH] Restrict use of context= mount options.

Prior to this change, the init and recovery domains were
allowed unrestricted use of context= mount options to force
all files within a given filesystem to be treated as having a
security context specified at mount time.  The context= mount
option can be used in device-specific fstab.<board> files
to assign a context to filesystems that do not support labeling
such as vfat where the default label of sdcard_external is not
appropriate (e.g. /firmware on hammerhead).

Restrict the use of context= mount options to types marked with the
contextmount_type attribute, and then remove write access from
such types from unconfineddomain and prohibit write access to such
types via neverallow.  This ensures that the no write to /system
restriction cannot be bypassed via context= mount.

Change-Id: I4e773fadc9e11328d13a0acec164124ad6e840c1
Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
---
 domain.te     | 10 ++++++++++
 init.te       | 13 +++++++++++--
 recovery.te   |  5 +++--
 unconfined.te | 12 ++++++++++--
 4 files changed, 34 insertions(+), 6 deletions(-)

diff --git a/domain.te b/domain.te
index b161467c2..6c800ab71 100644
--- a/domain.te
+++ b/domain.te
@@ -259,3 +259,13 @@ neverallow { domain -init } property_data_file:file { create setattr relabelfrom
 # Only recovery should be doing writes to /system
 neverallow { domain -recovery } { system_file exec_type }:dir_file_class_set
     { create write setattr relabelfrom relabelto append unlink link rename };
+
+# Restrict context mounts to specific types marked with
+# the contextmount_type attribute.
+neverallow domain {fs_type -contextmount_type}:filesystem relabelto;
+
+# Ensure that context mount types are not writable, to ensure that
+# the write to /system restriction above is not bypassed via context=
+# mount to another type.
+neverallow { domain -recovery } contextmount_type:dir_file_class_set
+    { create write setattr relabelfrom relabelto append unlink link rename };
diff --git a/init.te b/init.te
index 8421fa3d6..e4d1f88aa 100644
--- a/init.te
+++ b/init.te
@@ -10,8 +10,17 @@ allow init self:capability { sys_rawio mknod };
 allow init dev_type:blk_file rw_file_perms;
 
 # Mounting filesystems.
-allow init fs_type:filesystem *;
-allow init unlabeled:filesystem *;
+# Only allow relabelto for types used in context= mount options,
+# which should all be assigned the contextmount_type attribute.
+# This can be done in device-specific policy via type or typeattribute
+# declarations.
+allow init fs_type:filesystem ~relabelto;
+allow init unlabeled:filesystem ~relabelto;
+allow init contextmount_type:filesystem relabelto;
+
+# Allow read-only access to context= mounted filesystems.
+allow init contextmount_type:dir r_dir_perms;
+allow init contextmount_type:notdevfile_class_set r_file_perms;
 
 # restorecon and restorecon_recursive calls from init.rc files.
 # system/core/init.rc requires at least cache_file and data_file_type.
diff --git a/recovery.te b/recovery.te
index df1e60d4a..c6c5417df 100644
--- a/recovery.te
+++ b/recovery.te
@@ -17,8 +17,9 @@ recovery_only(`
 
   # Mount filesystems.
   allow recovery rootfs:dir mounton;
-  allow recovery fs_type:filesystem *;
-  allow recovery unlabeled:filesystem *;
+  allow recovery fs_type:filesystem ~relabelto;
+  allow recovery unlabeled:filesystem ~relabelto;
+  allow recovery contextmount_type:filesystem relabelto;
 
   # Create and relabel files and directories under /system.
   allow recovery exec_type:{ file lnk_file } { create_file_perms relabelfrom relabelto };
diff --git a/unconfined.te b/unconfined.te
index 4dc30dbf4..8e40b063e 100644
--- a/unconfined.te
+++ b/unconfined.te
@@ -48,7 +48,8 @@ allow unconfineddomain domain:{ fifo_file file } rw_file_perms;
 allow unconfineddomain domain:socket_class_set *;
 allow unconfineddomain domain:ipc_class_set *;
 allow unconfineddomain domain:key *;
-allow unconfineddomain {fs_type dev_type}:{ dir lnk_file sock_file fifo_file } ~relabelto;
+allow unconfineddomain {fs_type -contextmount_type}:{ dir lnk_file sock_file fifo_file } ~relabelto;
+allow unconfineddomain dev_type:{ dir lnk_file sock_file fifo_file } ~relabelto;
 allow unconfineddomain {
     file_type
     -keystore_data_file
@@ -61,7 +62,12 @@ allow unconfineddomain {
 allow unconfineddomain exec_type:{ file dir lnk_file } ~{ create write setattr relabelfrom relabelto append unlink link rename };
 allow unconfineddomain system_file:{ dir lnk_file } ~{ create write setattr relabelfrom relabelto append unlink link rename };
 allow unconfineddomain system_file:file ~{ create write setattr relabelfrom relabelto append unlink link rename entrypoint };
-allow unconfineddomain {fs_type -usermodehelper -proc_security}:{ chr_file file } ~{entrypoint execmod execute relabelto};
+allow unconfineddomain {
+    fs_type
+    -usermodehelper
+    -proc_security
+    -contextmount_type
+}:{ chr_file file } ~{entrypoint execmod execute relabelto};
 allow unconfineddomain {dev_type -kmem_device}:{ chr_file file } ~{entrypoint execmod execute relabelto};
 allow unconfineddomain {
     file_type
@@ -73,6 +79,8 @@ allow unconfineddomain {
     -shell_data_file
 }:{ chr_file file } ~{entrypoint execmod execute relabelto};
 allow unconfineddomain { rootfs system_file exec_type }:file execute;
+allow unconfineddomain contextmount_type:dir r_dir_perms;
+allow unconfineddomain contextmount_type:notdevfile_class_set r_file_perms;
 allow unconfineddomain node_type:node *;
 allow unconfineddomain node_type:{ tcp_socket udp_socket rawip_socket } node_bind;
 allow unconfineddomain netif_type:netif *;
-- 
GitLab