Restrict access to ro.serialno and ro.boot.serialno

This restricts access to ro.serialno and ro.boot.serialno, the two
system properties which contain the device's serial number, to a
select few SELinux domains which need the access. In particular, this
removes access to these properties from Android apps. Apps can access
the serial number via the public android.os.Build API. System
properties are not public API for apps.

The reason for the restriction is that serial number is a globally
unique identifier which cannot be reset by the user. Thus, it can be
used as a super-cookie by apps. Apps need to wean themselves off of
identifiers not resettable by the user.

Test: Set up fresh GMS device, install some apps via Play, update some apps, use Chrome
Test: Access the device via ADB (ADBD exposes serial number)
Test: Enable MTP over USB, use mtp-detect to confirm that serial number is reported in MTP DeviceInfo
Bug: 31402365
Bug: 33700679
Change-Id: I4713133b8d78dbc63d8272503e80cd2ffd63a2a7
diff --git a/private/property_contexts b/private/property_contexts
index 3407560..a27b756 100644
--- a/private/property_contexts
+++ b/private/property_contexts
@@ -59,6 +59,8 @@
 persist.vendor.overlay.  u:object_r:overlay_prop:s0
 ro.boot.vendor.overlay.  u:object_r:overlay_prop:s0
 ro.boottime.             u:object_r:boottime_prop:s0
+ro.serialno             u:object_r:serialno_prop:s0
+ro.boot.serialno        u:object_r:serialno_prop:s0
 
 # Boolean property set by system server upon boot indicating
 # if device owner is provisioned.
diff --git a/public/adbd.te b/public/adbd.te
index 675219a..59ee3e1 100644
--- a/public/adbd.te
+++ b/public/adbd.te
@@ -55,6 +55,9 @@
 # Access device logging gating property
 get_prop(adbd, device_logging_prop)
 
+# Read device's serial number from system properties
+get_prop(adbd, serialno_prop)
+
 # Run /system/bin/bu
 allow adbd system_file:file rx_file_perms;
 
diff --git a/public/domain.te b/public/domain.te
index c9f7f6f..47b3e5a 100644
--- a/public/domain.te
+++ b/public/domain.te
@@ -374,6 +374,18 @@
 neverallow { domain -init } default_prop:property_service set;
 neverallow { domain -init } mmc_prop:property_service set;
 
+# Do not allow reading device's serial number from system properties except form
+# a few whitelisted domains.
+neverallow {
+  domain
+  -adbd
+  -dumpstate
+  -init
+  -mediadrmserver
+  -recovery
+  -system_server
+} serialno_prop:file r_file_perms;
+
 neverallow {
   domain
   -init
diff --git a/public/dumpstate.te b/public/dumpstate.te
index 08d24ae..ee617e5 100644
--- a/public/dumpstate.te
+++ b/public/dumpstate.te
@@ -187,6 +187,9 @@
 # dumpstate_options_prop is used to pass extra command-line args.
 set_prop(dumpstate, dumpstate_options_prop)
 
+# Read device's serial number from system properties
+get_prop(dumpstate, serialno_prop)
+
 # Access to /data/media.
 # This should be removed if sdcardfs is modified to alter the secontext for its
 # accesses to the underlying FS.
diff --git a/public/mediadrmserver.te b/public/mediadrmserver.te
index b08664f..c9e28d7 100644
--- a/public/mediadrmserver.te
+++ b/public/mediadrmserver.te
@@ -55,6 +55,9 @@
 allowxperm mediadrmserver self:{ rawip_socket tcp_socket udp_socket }
   ioctl { unpriv_sock_ioctls unpriv_tty_ioctls };
 
+# Permit reading device's serial number from system properties
+get_prop(mediadrmserver, serialno_prop)
+
 ###
 ### neverallow rules
 ###
diff --git a/public/property.te b/public/property.te
index 731eee5..0bba50d 100644
--- a/public/property.te
+++ b/public/property.te
@@ -36,6 +36,7 @@
 type radio_prop, property_type, core_property_type;
 type restorecon_prop, property_type, core_property_type;
 type safemode_prop, property_type;
+type serialno_prop, property_type;
 type shell_prop, property_type, core_property_type;
 type system_prop, property_type, core_property_type;
 type system_radio_prop, property_type, core_property_type;
diff --git a/public/recovery.te b/public/recovery.te
index 32601e3..bbee928 100644
--- a/public/recovery.te
+++ b/public/recovery.te
@@ -92,6 +92,9 @@
   # Start/stop adbd via ctl.start adbd
   set_prop(recovery, ctl_default_prop)
 
+  # Read device's serial number from system properties
+  get_prop(recovery, serialno_prop)
+
   # Use setfscreatecon() to label files for OTA updates.
   allow recovery self:process setfscreate;
 
diff --git a/public/system_server.te b/public/system_server.te
index 6bbe991..bc1dd9f 100644
--- a/public/system_server.te
+++ b/public/system_server.te
@@ -388,6 +388,9 @@
 # Collect metrics on boot time created by init
 get_prop(system_server, boottime_prop)
 
+# Read device's serial number from system properties
+get_prop(system_server, serialno_prop)
+
 # Create a socket for receiving info from wpa.
 allow system_server wpa_socket:dir rw_dir_perms;
 allow system_server system_wpa_socket:sock_file create_file_perms;