Merge "Get rid of separate download_file type."
diff --git a/clatd.te b/clatd.te
index be0314d..b1bda1e 100644
--- a/clatd.te
+++ b/clatd.te
@@ -7,11 +7,13 @@
 # Access objects inherited from netd.
 allow clatd netd:fd use;
 allow clatd netd:fifo_file { read write };
+# TODO: Check whether some or all of these sockets should be close-on-exec.
 allow clatd netd:netlink_kobject_uevent_socket { read write };
 allow clatd netd:netlink_nflog_socket { read write };
 allow clatd netd:netlink_route_socket { read write };
 allow clatd netd:udp_socket { read write };
 allow clatd netd:unix_stream_socket { read write };
+allow clatd netd:unix_dgram_socket { read write };
 
 allow clatd self:capability { net_admin setuid setgid };
 
diff --git a/dnsmasq.te b/dnsmasq.te
index 9a9882d..2195d1b 100644
--- a/dnsmasq.te
+++ b/dnsmasq.te
@@ -1,6 +1,5 @@
 # DNS, DHCP services
 type dnsmasq, domain;
-permissive_or_unconfined(dnsmasq)
 type dnsmasq_exec, exec_type, file_type;
 
 net_domain(dnsmasq)
diff --git a/gpsd.te b/gpsd.te
index c628631..33b1df6 100644
--- a/gpsd.te
+++ b/gpsd.te
@@ -1,6 +1,5 @@
 # gpsd - GPS daemon
 type gpsd, domain;
-permissive_or_unconfined(gpsd)
 type gpsd_exec, exec_type, file_type;
 
 init_daemon_domain(gpsd)
diff --git a/healthd.te b/healthd.te
index 62a20e8..ba80dad 100644
--- a/healthd.te
+++ b/healthd.te
@@ -8,7 +8,7 @@
 # open fd inherited by healthd.
 allow healthd tmpfs:chr_file { read write };
 
-allow healthd self:capability { net_admin mknod };
+allow healthd self:capability { net_admin mknod sys_tty_config };
 allow healthd self:capability2 block_suspend;
 allow healthd self:netlink_kobject_uevent_socket create_socket_perms;
 binder_use(healthd)
diff --git a/hostapd.te b/hostapd.te
index 90a0314..ad86a3a 100644
--- a/hostapd.te
+++ b/hostapd.te
@@ -1,6 +1,5 @@
 # userspace wifi access points
 type hostapd, domain;
-permissive_or_unconfined(hostapd)
 type hostapd_exec, exec_type, file_type;
 
 net_domain(hostapd)
diff --git a/mdnsd.te b/mdnsd.te
index cfcf873..7e14b52 100644
--- a/mdnsd.te
+++ b/mdnsd.te
@@ -1,6 +1,5 @@
 # mdns daemon
 type mdnsd, domain;
-permissive_or_unconfined(mdnsd)
 type mdnsd_exec, exec_type, file_type;
 
 init_daemon_domain(mdnsd)
diff --git a/rild.te b/rild.te
index 9c315d5..5bc267a 100644
--- a/rild.te
+++ b/rild.te
@@ -1,6 +1,5 @@
 # rild - radio interface layer daemon
 type rild, domain;
-permissive_or_unconfined(rild)
 type rild_exec, exec_type, file_type;
 
 init_daemon_domain(rild)
@@ -24,6 +23,8 @@
 allow rild sdcard_type:dir r_dir_perms;
 allow rild system_data_file:dir create_dir_perms;
 allow rild system_data_file:file create_file_perms;
+auditallow rild system_data_file:dir { create reparent rmdir setattr write add_name remove_name };
+auditallow rild system_data_file:file { create setattr write append link unlink rename };
 allow rild system_file:file x_file_perms;
 dontaudit rild self:capability sys_admin;
 
diff --git a/system_server.te b/system_server.te
index b59f5a3..9938079 100644
--- a/system_server.te
+++ b/system_server.te
@@ -80,6 +80,13 @@
 # Write to /proc/pid/oom_adj_score for apps.
 allow system_server appdomain:file write;
 
+# Silently deny access to any /proc/pid files other than
+# the ones allowed via allow rule.  Avoids filling the logs
+# with noise from /proc/pid traversals by ActivityManager,
+# CpuTracker, and possibly other system_server components.
+dontaudit system_server domain:dir r_dir_perms;
+dontaudit system_server domain:{ file lnk_file } r_file_perms;
+
 # Read/Write to /proc/net/xt_qtaguid/ctrl and and /dev/xt_qtaguid.
 allow system_server qtaguid_proc:file rw_file_perms;
 allow system_server qtaguid_device:chr_file rw_file_perms;
@@ -257,6 +264,9 @@
 # (urge is to deprecate this long term)
 allow system_server zygote:unix_dgram_socket write;
 
+# Read from log daemon.
+read_logd(system_server)
+
 # Be consistent with DAC permissions. Allow system_server to write to
 # /sys/module/lowmemorykiller/parameters/adj
 # /sys/module/lowmemorykiller/parameters/minfree
diff --git a/tools/post_process_mac_perms b/tools/post_process_mac_perms
new file mode 100755
index 0000000..47f43a0
--- /dev/null
+++ b/tools/post_process_mac_perms
@@ -0,0 +1,106 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2013 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""
+Tool to help modify an existing mac_permissions.xml with additional app
+certs not already found in that policy. This becomes useful when a directory
+containing apps is searched and the certs from those apps are added to the
+policy not already explicitly listed.
+"""
+
+import sys
+import os
+import argparse
+from base64 import b16encode, b64decode
+import fileinput
+import re
+import subprocess
+import zipfile
+
+PEM_CERT_RE = """-----BEGIN CERTIFICATE-----
+(.+?)
+-----END CERTIFICATE-----
+"""
+def collect_certs_for_app(filename):
+  app_certs = set()
+  with zipfile.ZipFile(filename, 'r') as apkzip:
+    for info in apkzip.infolist():
+      name = info.filename
+      if name.startswith('META-INF/') and name.endswith(('.DSA', '.RSA')):
+        cmd = ['openssl', 'pkcs7', '-inform', 'DER',
+               '-outform', 'PEM', '-print_certs']
+        p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
+                             stderr=subprocess.PIPE)
+        pem_string, err = p.communicate(apkzip.read(name))
+        if err and err.strip():
+          raise RuntimeError('Problem running openssl on %s (%s)' % (filename, e))
+
+        # turn multiline base64 to single line base16
+        transform = lambda x: b16encode(b64decode(x.replace('\n', ''))).lower()
+        results = re.findall(PEM_CERT_RE, pem_string, re.DOTALL)
+        certs = [transform(i) for i in results]
+
+        app_certs.update(certs)
+
+  return app_certs
+
+def add_leftover_certs(args):
+  all_app_certs = set()
+  for dirpath, _, files in os.walk(args.dir):
+    transform = lambda x: os.path.join(dirpath, x)
+    condition = lambda x: x.endswith('.apk')
+    apps = [transform(i) for i in files if condition(i)]
+
+    # Collect certs for each app found
+    for app in apps:
+      app_certs = collect_certs_for_app(app)
+      all_app_certs.update(app_certs)
+
+  if all_app_certs:
+    policy_certs = set()
+    with open(args.policy, 'r') as f:
+      cert_pattern = 'signature="([a-fA-F0-9]+)"'
+      policy_certs = re.findall(cert_pattern, f.read())
+
+    cert_diff = all_app_certs.difference(policy_certs)
+
+    # Build xml stanzas
+    inner_tag = '<seinfo value="%s"/>' % args.seinfo
+    stanza = '<signer signature="%s">%s</signer>'
+    new_stanzas = [stanza % (cert, inner_tag) for cert in cert_diff]
+    mac_perms_string = ''.join(new_stanzas)
+    mac_perms_string += '</policy>'
+
+    # Inline replace with new policy stanzas
+    for line in fileinput.input(args.policy, inplace=True):
+      print line.replace('</policy>', mac_perms_string)
+
+def main(argv):
+  parser = argparse.ArgumentParser(description=__doc__)
+
+  parser.add_argument('-s', '--seinfo', dest='seinfo', required=True,
+                      help='seinfo tag for each generated stanza')
+  parser.add_argument('-d', '--dir', dest='dir', required=True,
+                      help='Directory to search for apks')
+  parser.add_argument('-f', '--file', dest='policy', required=True,
+                      help='mac_permissions.xml policy file')
+
+  parser.set_defaults(func=add_leftover_certs)
+  args = parser.parse_args()
+  args.func(args)
+
+if __name__ == '__main__':
+  main(sys.argv)