Merge "logd: auditd: suppress multiple identical avc: messages to kmsg"
diff --git a/adb/daemon/main.cpp b/adb/daemon/main.cpp
index b0a0162..b54243e 100644
--- a/adb/daemon/main.cpp
+++ b/adb/daemon/main.cpp
@@ -28,8 +28,10 @@
#include <memory>
#include <android-base/logging.h>
+#include <android-base/macros.h>
#include <android-base/stringprintf.h>
#include <libminijail.h>
+#include <scoped_minijail.h>
#include "cutils/properties.h"
#include "debuggerd/client.h"
@@ -99,8 +101,7 @@
}
static void drop_privileges(int server_port) {
- std::unique_ptr<minijail, void (*)(minijail*)> jail(minijail_new(),
- &minijail_destroy);
+ ScopedMinijail jail(minijail_new());
// Add extra groups:
// AID_ADB to access the USB driver
@@ -116,9 +117,7 @@
AID_INET, AID_NET_BT, AID_NET_BT_ADMIN,
AID_SDCARD_R, AID_SDCARD_RW, AID_NET_BW_STATS,
AID_READPROC};
- minijail_set_supplementary_gids(jail.get(),
- sizeof(groups) / sizeof(groups[0]),
- groups);
+ minijail_set_supplementary_gids(jail.get(), arraysize(groups), groups);
// Don't listen on a port (default 5037) if running in secure mode.
// Don't run as root if running in secure mode.
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/include/utils/LruCache.h b/include/utils/LruCache.h
index ed96fe4..f4e225a 100644
--- a/include/utils/LruCache.h
+++ b/include/utils/LruCache.h
@@ -56,36 +56,55 @@
private:
LruCache(const LruCache& that); // disallow copy constructor
- struct Entry {
+ // Super class so that we can have entries having only a key reference, for searches.
+ class KeyedEntry {
+ public:
+ virtual const TKey& getKey() const = 0;
+ // Make sure the right destructor is executed so that keys and values are deleted.
+ virtual ~KeyedEntry() {}
+ };
+
+ class Entry final : public KeyedEntry {
+ public:
TKey key;
TValue value;
Entry* parent;
Entry* child;
- Entry(TKey key_, TValue value_) : key(key_), value(value_), parent(NULL), child(NULL) {
+ Entry(TKey _key, TValue _value) : key(_key), value(_value), parent(NULL), child(NULL) {
}
- const TKey& getKey() const { return key; }
+ const TKey& getKey() const final { return key; }
};
- struct HashForEntry : public std::unary_function<Entry*, hash_t> {
- size_t operator() (const Entry* entry) const {
- return hash_type(entry->key);
+ class EntryForSearch : public KeyedEntry {
+ public:
+ const TKey& key;
+ EntryForSearch(const TKey& key_) : key(key_) {
+ }
+ const TKey& getKey() const final { return key; }
+ };
+
+ struct HashForEntry : public std::unary_function<KeyedEntry*, hash_t> {
+ size_t operator() (const KeyedEntry* entry) const {
+ return hash_type(entry->getKey());
};
};
- struct EqualityForHashedEntries : public std::unary_function<Entry*, hash_t> {
- bool operator() (const Entry* lhs, const Entry* rhs) const {
- return lhs->key == rhs->key;
+ struct EqualityForHashedEntries : public std::unary_function<KeyedEntry*, hash_t> {
+ bool operator() (const KeyedEntry* lhs, const KeyedEntry* rhs) const {
+ return lhs->getKey() == rhs->getKey();
};
};
- typedef std::unordered_set<Entry*, HashForEntry, EqualityForHashedEntries> LruCacheSet;
+ // All entries in the set will be Entry*. Using the weaker KeyedEntry as to allow entries
+ // that have only a key reference, for searching.
+ typedef std::unordered_set<KeyedEntry*, HashForEntry, EqualityForHashedEntries> LruCacheSet;
void attachToCache(Entry& entry);
void detachFromCache(Entry& entry);
typename LruCacheSet::iterator findByKey(const TKey& key) {
- Entry entryForSearch(key, mNullValue);
+ EntryForSearch entryForSearch(key);
typename LruCacheSet::iterator result = mSet->find(&entryForSearch);
return result;
}
@@ -124,11 +143,13 @@
}
const TValue& value() const {
- return (*mIterator)->value;
+ // All the elements in the set are of type Entry. See comment in the definition
+ // of LruCacheSet above.
+ return reinterpret_cast<Entry *>(*mIterator)->value;
}
const TKey& key() const {
- return (*mIterator)->key;
+ return (*mIterator)->getKey();
}
private:
const LruCache<TKey, TValue>& mCache;
@@ -171,7 +192,9 @@
if (find_result == mSet->end()) {
return mNullValue;
}
- Entry *entry = *find_result;
+ // All the elements in the set are of type Entry. See comment in the definition
+ // of LruCacheSet above.
+ Entry *entry = reinterpret_cast<Entry*>(*find_result);
detachFromCache(*entry);
attachToCache(*entry);
return entry->value;
@@ -199,7 +222,9 @@
if (find_result == mSet->end()) {
return false;
}
- Entry* entry = *find_result;
+ // All the elements in the set are of type Entry. See comment in the definition
+ // of LruCacheSet above.
+ Entry* entry = reinterpret_cast<Entry*>(*find_result);
mSet->erase(entry);
if (mListener) {
(*mListener)(entry->key, entry->value);
diff --git a/libcutils/iosched_policy.c b/libcutils/iosched_policy.c
index 71bc94b..13c2ceb 100644
--- a/libcutils/iosched_policy.c
+++ b/libcutils/iosched_policy.c
@@ -24,7 +24,8 @@
#include <cutils/iosched_policy.h>
#if defined(__ANDROID__)
-#include <linux/ioprio.h>
+#define IOPRIO_WHO_PROCESS (1)
+#define IOPRIO_CLASS_SHIFT (13)
#include <sys/syscall.h>
#define __android_unused
#else
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/libpackagelistparser/Android.bp b/libpackagelistparser/Android.bp
new file mode 100644
index 0000000..70ff528
--- /dev/null
+++ b/libpackagelistparser/Android.bp
@@ -0,0 +1,13 @@
+cc_library {
+
+ name: "libpackagelistparser",
+ srcs: ["packagelistparser.c"],
+ shared_libs: ["liblog"],
+ local_include_dirs: ["include"],
+ export_include_dirs: ["include"],
+
+ clang: true,
+ sanitize: {
+ misc_undefined: ["integer"],
+ },
+}
diff --git a/libpackagelistparser/Android.mk b/libpackagelistparser/Android.mk
deleted file mode 100644
index c8be050..0000000
--- a/libpackagelistparser/Android.mk
+++ /dev/null
@@ -1,32 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-
-#########################
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libpackagelistparser
-LOCAL_MODULE_TAGS := optional
-LOCAL_SRC_FILES := packagelistparser.c
-LOCAL_SHARED_LIBRARIES := liblog
-LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
-
-LOCAL_CLANG := true
-LOCAL_SANITIZE := integer
-
-include $(BUILD_SHARED_LIBRARY)
-
-#########################
-include $(CLEAR_VARS)
-
-
-LOCAL_MODULE := libpackagelistparser
-LOCAL_MODULE_TAGS := optional
-LOCAL_SRC_FILES := packagelistparser.c
-LOCAL_STATIC_LIBRARIES := liblog
-LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
-
-LOCAL_CLANG := true
-LOCAL_SANITIZE := integer
-
-include $(BUILD_STATIC_LIBRARY)
diff --git a/libutils/tests/LruCache_test.cpp b/libutils/tests/LruCache_test.cpp
index dd95c57..de440fd 100644
--- a/libutils/tests/LruCache_test.cpp
+++ b/libutils/tests/LruCache_test.cpp
@@ -80,6 +80,14 @@
}
};
+struct KeyFailsOnCopy : public ComplexKey {
+ public:
+ KeyFailsOnCopy(const KeyFailsOnCopy& key) : ComplexKey(key) {
+ ADD_FAILURE();
+ }
+ KeyFailsOnCopy(int key) : ComplexKey(key) { }
+};
+
} // namespace
@@ -95,6 +103,10 @@
return hash_type(*value.ptr);
}
+template<> inline android::hash_t hash_type(const KeyFailsOnCopy& value) {
+ return hash_type<ComplexKey>(value);
+}
+
class EntryRemovedCallback : public OnEntryRemoved<SimpleKey, StringValue> {
public:
EntryRemovedCallback() : callbackCount(0), lastKey(-1), lastValue(NULL) { }
@@ -437,4 +449,10 @@
EXPECT_EQ(std::unordered_set<int>({ 4, 5, 6 }), returnedValues);
}
+TEST_F(LruCacheTest, DontCopyKeyInGet) {
+ LruCache<KeyFailsOnCopy, KeyFailsOnCopy> cache(1);
+ // Check that get doesn't copy the key
+ cache.get(KeyFailsOnCopy(0));
+}
+
}
diff --git a/logd/Android.mk b/logd/Android.mk
index 84ea7a2..3348890 100644
--- a/logd/Android.mk
+++ b/logd/Android.mk
@@ -28,7 +28,8 @@
liblog \
libcutils \
libbase \
- libpackagelistparser
+ libpackagelistparser \
+ libminijail
# This is what we want to do:
# event_logtags = $(shell \
diff --git a/logd/main.cpp b/logd/main.cpp
index 69ba896..b69927d 100644
--- a/logd/main.cpp
+++ b/logd/main.cpp
@@ -36,12 +36,15 @@
#include <cstdbool>
#include <memory>
+#include <android-base/macros.h>
#include <cutils/properties.h>
#include <cutils/sched_policy.h>
#include <cutils/sockets.h>
+#include <libminijail.h>
#include <log/event_tag_map.h>
#include <packagelistparser/packagelistparser.h>
#include <private/android_filesystem_config.h>
+#include <scoped_minijail.h>
#include <utils/threads.h>
#include "CommandListener.h"
@@ -58,14 +61,14 @@
'>'
//
-// The service is designed to be run by init, it does not respond well
+// The service is designed to be run by init, it does not respond well
// to starting up manually. When starting up manually the sockets will
// fail to open typically for one of the following reasons:
// EADDRINUSE if logger is running.
// EACCESS if started without precautions (below)
//
// Here is a cookbook procedure for starting up logd manually assuming
-// init is out of the way, pedantically all permissions and selinux
+// init is out of the way, pedantically all permissions and SELinux
// security is put back in place:
//
// setenforce 0
@@ -102,43 +105,13 @@
return -1;
}
- if (prctl(PR_SET_KEEPCAPS, 1) < 0) {
- return -1;
- }
-
gid_t groups[] = { AID_READPROC };
-
- if (setgroups(sizeof(groups) / sizeof(groups[0]), groups) == -1) {
- return -1;
- }
-
- if (setgid(AID_LOGD) != 0) {
- return -1;
- }
-
- if (setuid(AID_LOGD) != 0) {
- return -1;
- }
-
- struct __user_cap_header_struct capheader;
- struct __user_cap_data_struct capdata[2];
- memset(&capheader, 0, sizeof(capheader));
- memset(&capdata, 0, sizeof(capdata));
- capheader.version = _LINUX_CAPABILITY_VERSION_3;
- capheader.pid = 0;
-
- capdata[CAP_TO_INDEX(CAP_SYSLOG)].permitted = CAP_TO_MASK(CAP_SYSLOG);
- capdata[CAP_TO_INDEX(CAP_AUDIT_CONTROL)].permitted |= CAP_TO_MASK(CAP_AUDIT_CONTROL);
-
- capdata[0].effective = capdata[0].permitted;
- capdata[1].effective = capdata[1].permitted;
- capdata[0].inheritable = 0;
- capdata[1].inheritable = 0;
-
- if (capset(&capheader, &capdata[0]) < 0) {
- return -1;
- }
-
+ ScopedMinijail j(minijail_new());
+ minijail_set_supplementary_gids(j.get(), arraysize(groups), groups);
+ minijail_change_uid(j.get(), AID_LOGD);
+ minijail_change_gid(j.get(), AID_LOGD);
+ minijail_use_caps(j.get(), CAP_TO_MASK(CAP_SYSLOG) | CAP_TO_MASK(CAP_AUDIT_CONTROL));
+ minijail_enter(j.get());
return 0;
}
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 e82f29e..3d7bdc9 100644
--- a/sdcard/sdcard.cpp
+++ b/sdcard/sdcard.cpp
@@ -29,9 +29,9 @@
#include <unistd.h>
#include <android-base/logging.h>
+#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>
@@ -77,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);
@@ -209,7 +190,7 @@
static void drop_privs(uid_t uid, gid_t gid) {
ScopedMinijail j(minijail_new());
- minijail_set_supplementary_gids(j.get(), sizeof(kGroups) / sizeof(kGroups[0]), kGroups);
+ minijail_set_supplementary_gids(j.get(), arraysize(kGroups), kGroups);
minijail_change_gid(j.get(), gid);
minijail_change_uid(j.get(), uid);
/* minijail_enter() will abort if priv-dropping fails. */
@@ -244,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;