Merge "logd: Use Minijail for privilege dropping."
diff --git a/debuggerd/Android.mk b/debuggerd/Android.mk
index 19c7298..fdedb76 100644
--- a/debuggerd/Android.mk
+++ b/debuggerd/Android.mk
@@ -130,6 +130,9 @@
     -Wno-missing-field-initializers \
     -fno-rtti \
 
+# Bug: http://b/29823425 Disable -Wvarargs for Clang update to r271374
+debuggerd_cpp_flags += -Wno-varargs
+
 # Only build the host tests on linux.
 ifeq ($(HOST_OS),linux)
 
diff --git a/include/cutils/klog.h b/include/cutils/klog.h
index 2078fa2..c837edb 100644
--- a/include/cutils/klog.h
+++ b/include/cutils/klog.h
@@ -23,7 +23,6 @@
 
 __BEGIN_DECLS
 
-void klog_init(void);
 int  klog_get_level(void);
 void klog_set_level(int level);
 
diff --git a/libcutils/klog.cpp b/libcutils/klog.cpp
index 11ebf88..abf643f 100644
--- a/libcutils/klog.cpp
+++ b/libcutils/klog.cpp
@@ -36,9 +36,6 @@
     klog_level = level;
 }
 
-void klog_init(void) {
-}
-
 static int __open_klog(void) {
     int fd = open("/dev/kmsg", O_WRONLY | O_CLOEXEC);
     if (fd == -1) {
diff --git a/run-as/Android.mk b/run-as/Android.mk
index 2e305d7..7111fbe 100644
--- a/run-as/Android.mk
+++ b/run-as/Android.mk
@@ -1,8 +1,8 @@
 LOCAL_PATH:= $(call my-dir)
 
 include $(CLEAR_VARS)
-LOCAL_CFLAGS := -Werror
+LOCAL_CFLAGS := -Wall -Werror
 LOCAL_MODULE := run-as
-LOCAL_SHARED_LIBRARIES := libselinux libpackagelistparser
+LOCAL_SHARED_LIBRARIES := libselinux libpackagelistparser libminijail
 LOCAL_SRC_FILES := run-as.cpp
 include $(BUILD_EXECUTABLE)
diff --git a/run-as/run-as.cpp b/run-as/run-as.cpp
index 50b47b9..aec51f4 100644
--- a/run-as/run-as.cpp
+++ b/run-as/run-as.cpp
@@ -25,6 +25,9 @@
 #include <sys/types.h>
 #include <unistd.h>
 
+#include <libminijail.h>
+#include <scoped_minijail.h>
+
 #include <packagelistparser/packagelistparser.h>
 #include <private/android_filesystem_config.h>
 #include <selinux/android.h>
@@ -136,19 +139,6 @@
     error(1, 0, "only 'shell' or 'root' users can run this program");
   }
 
-  __user_cap_header_struct capheader;
-  __user_cap_data_struct capdata[2];
-  memset(&capheader, 0, sizeof(capheader));
-  memset(&capdata, 0, sizeof(capdata));
-  capheader.version = _LINUX_CAPABILITY_VERSION_3;
-  capdata[CAP_TO_INDEX(CAP_SETUID)].effective |= CAP_TO_MASK(CAP_SETUID);
-  capdata[CAP_TO_INDEX(CAP_SETGID)].effective |= CAP_TO_MASK(CAP_SETGID);
-  capdata[CAP_TO_INDEX(CAP_SETUID)].permitted |= CAP_TO_MASK(CAP_SETUID);
-  capdata[CAP_TO_INDEX(CAP_SETGID)].permitted |= CAP_TO_MASK(CAP_SETGID);
-  if (capset(&capheader, &capdata[0]) == -1) {
-    error(1, errno, "couldn't set capabilities");
-  }
-
   char* pkgname = argv[1];
   int cmd_argv_offset = 2;
 
@@ -201,18 +191,10 @@
   // same time to avoid nasty surprises.
   uid_t uid = userAppId;
   uid_t gid = userAppId;
-  if (setresgid(gid, gid, gid) == -1) {
-    error(1, errno, "setresgid failed");
-  }
-  if (setresuid(uid, uid, uid) == -1) {
-    error(1, errno, "setresuid failed");
-  }
-
-  // Required if caller has uid and gid all non-zero.
-  memset(&capdata, 0, sizeof(capdata));
-  if (capset(&capheader, &capdata[0]) == -1) {
-    error(1, errno, "couldn't clear all capabilities");
-  }
+  ScopedMinijail j(minijail_new());
+  minijail_change_uid(j.get(), uid);
+  minijail_change_gid(j.get(), gid);
+  minijail_enter(j.get());
 
   if (selinux_android_setcontext(uid, 0, info.seinfo, pkgname) < 0) {
     error(1, errno, "couldn't set SELinux security context");
diff --git a/sdcard/fuse.cpp b/sdcard/fuse.cpp
index 1b6a5f1..9b1b190 100644
--- a/sdcard/fuse.cpp
+++ b/sdcard/fuse.cpp
@@ -275,8 +275,9 @@
     case PERM_ANDROID_DATA:
     case PERM_ANDROID_OBB:
     case PERM_ANDROID_MEDIA:
-        appid = (appid_t) (uintptr_t) hashmapGet(fuse->global->package_to_appid, node->name);
-        if (appid != 0) {
+        const auto& iter = fuse->global->package_to_appid->find(node->name);
+        if (iter != fuse->global->package_to_appid->end()) {
+            appid = iter->second;
             node->uid = multiuser_get_uid(parent->userid, appid);
         }
         break;
diff --git a/sdcard/fuse.h b/sdcard/fuse.h
index d76c664..634fbf1 100644
--- a/sdcard/fuse.h
+++ b/sdcard/fuse.h
@@ -30,14 +30,17 @@
 #include <sys/uio.h>
 #include <unistd.h>
 
+#include <map>
+#include <string>
+
 #include <cutils/fs.h>
-#include <cutils/hashmap.h>
 #include <cutils/log.h>
 #include <cutils/multiuser.h>
 #include <packagelistparser/packagelistparser.h>
 
 #include <private/android_filesystem_config.h>
 
+// TODO(b/30222003): Fix compilation with FUSE_TRACE == 1.
 #define FUSE_TRACE 0
 
 #if FUSE_TRACE
@@ -59,6 +62,16 @@
  * the largest possible data payload. */
 #define MAX_REQUEST_SIZE (sizeof(struct fuse_in_header) + sizeof(struct fuse_write_in) + MAX_WRITE)
 
+namespace {
+struct CaseInsensitiveCompare {
+    bool operator()(const std::string& lhs, const std::string& rhs) const {
+        return strcasecmp(lhs.c_str(), rhs.c_str()) < 0;
+    }
+};
+}
+
+using AppIdMap = std::map<std::string, appid_t, CaseInsensitiveCompare>;
+
 /* Permission mode for a specific node. Controls how file permissions
  * are derived for children nodes. */
 typedef enum {
@@ -135,7 +148,7 @@
     char source_path[PATH_MAX];
     char obb_path[PATH_MAX];
 
-    Hashmap* package_to_appid;
+    AppIdMap* package_to_appid;
 
     __u64 next_generation;
     struct node root;
diff --git a/sdcard/sdcard.cpp b/sdcard/sdcard.cpp
index ba63636..3d7bdc9 100644
--- a/sdcard/sdcard.cpp
+++ b/sdcard/sdcard.cpp
@@ -32,7 +32,6 @@
 #include <android-base/macros.h>
 
 #include <cutils/fs.h>
-#include <cutils/hashmap.h>
 #include <cutils/log.h>
 #include <cutils/multiuser.h>
 #include <packagelistparser/packagelistparser.h>
@@ -78,41 +77,22 @@
 /* Supplementary groups to execute with. */
 static const gid_t kGroups[1] = { AID_PACKAGE_INFO };
 
-static int str_hash(void *key) {
-    return hashmapHash(key, strlen(static_cast<const char*>(key)));
-}
-
-/* Tests if two string keys are equal ignoring case. */
-static bool str_icase_equals(void *keyA, void *keyB) {
-    return strcasecmp(static_cast<const char*>(keyA), static_cast<const char*>(keyB)) == 0;
-}
-
-static bool remove_str_to_int(void *key, void *value, void *context) {
-    Hashmap* map = static_cast<Hashmap*>(context);
-    hashmapRemove(map, key);
-    free(key);
-    return true;
-}
-
 static bool package_parse_callback(pkg_info *info, void *userdata) {
     struct fuse_global *global = (struct fuse_global *)userdata;
-
-    char* name = strdup(info->name);
-    hashmapPut(global->package_to_appid, name, (void*) (uintptr_t) info->uid);
+    bool res = global->package_to_appid->emplace(info->name, info->uid).second;
     packagelist_free(info);
-    return true;
+    return res;
 }
 
 static bool read_package_list(struct fuse_global* global) {
     pthread_mutex_lock(&global->lock);
 
-    hashmapForEach(global->package_to_appid, remove_str_to_int, global->package_to_appid);
-
+    global->package_to_appid->clear();
     bool rc = packagelist_parse(package_parse_callback, global);
     TRACE("read_package_list: found %zu packages\n",
-            hashmapSize(global->package_to_appid));
+            global->package_to_appid->size());
 
-    /* Regenerate ownership details using newly loaded mapping */
+    // Regenerate ownership details using newly loaded mapping.
     derive_permissions_recursive_locked(global->fuse_default, &global->root);
 
     pthread_mutex_unlock(&global->lock);
@@ -245,7 +225,7 @@
     memset(&handler_write, 0, sizeof(handler_write));
 
     pthread_mutex_init(&global.lock, NULL);
-    global.package_to_appid = hashmapCreate(256, str_hash, str_icase_equals);
+    global.package_to_appid = new AppIdMap;
     global.uid = uid;
     global.gid = gid;
     global.multi_user = multi_user;