Make dlext_namespaces.h available to users of libnativeloader
am: b75d82b42a
Change-Id: I6d662f190349fb12043e726672673eb6a3b0c7b1
diff --git a/adb/client/usb_dispatch.cpp b/adb/client/usb_dispatch.cpp
index 597e66e..f02dccf 100644
--- a/adb/client/usb_dispatch.cpp
+++ b/adb/client/usb_dispatch.cpp
@@ -24,10 +24,10 @@
void usb_init() {
if (should_use_libusb()) {
- LOG(INFO) << "using libusb backend";
+ LOG(DEBUG) << "using libusb backend";
libusb::usb_init();
} else {
- LOG(INFO) << "using native backend";
+ LOG(DEBUG) << "using native backend";
native::usb_init();
}
}
diff --git a/debuggerd/Android.bp b/debuggerd/Android.bp
index 6dc6675..ca881aa 100644
--- a/debuggerd/Android.bp
+++ b/debuggerd/Android.bp
@@ -195,3 +195,7 @@
init_rc: ["tombstoned/tombstoned.rc"]
}
+
+subdirs = [
+ "crasher",
+]
diff --git a/debuggerd/crasher/Android.bp b/debuggerd/crasher/Android.bp
new file mode 100644
index 0000000..4727894
--- /dev/null
+++ b/debuggerd/crasher/Android.bp
@@ -0,0 +1,81 @@
+cc_defaults {
+ name: "crasher-defaults",
+
+ cppflags: [
+ "-std=gnu++14",
+ "-W",
+ "-Wall",
+ "-Wextra",
+ "-Wunused",
+ "-Werror",
+ "-O0",
+ "-fstack-protector-all",
+ "-Wno-free-nonheap-object",
+ "-Wno-date-time",
+ ],
+ srcs: ["crasher.cpp"],
+ arch: {
+ arm: {
+ srcs: ["arm/crashglue.S"],
+
+ armv7_a_neon: {
+ asflags: ["-DHAS_VFP_D32"],
+ },
+ },
+ arm64: {
+ srcs: ["arm64/crashglue.S"],
+ },
+ mips: {
+ srcs: ["mips/crashglue.S"],
+ },
+ mips64: {
+ srcs: ["mips64/crashglue.S"],
+ },
+ x86: {
+ srcs: ["x86/crashglue.S"],
+ },
+ x86_64: {
+ srcs: ["x86_64/crashglue.S"],
+ },
+ },
+ compile_multilib: "both",
+}
+
+cc_binary {
+ name: "crasher",
+
+ defaults: ["crasher-defaults"],
+ shared_libs: [
+ "libbase",
+ "liblog",
+ ],
+ multilib: {
+ lib32: {
+ stem: "crasher",
+ },
+ lib64: {
+ stem: "crasher64",
+ },
+ },
+}
+
+cc_binary {
+ name: "static_crasher",
+
+ defaults: ["crasher-defaults"],
+ cppflags: ["-DSTATIC_CRASHER"],
+ static_executable: true,
+ static_libs: [
+ "libdebuggerd_handler",
+ "libbase",
+ "liblog",
+ ],
+ multilib: {
+ lib32: {
+ stem: "static_crasher",
+ },
+ lib64: {
+ stem: "static_crasher64",
+ },
+ },
+}
diff --git a/debuggerd/crasher/Android.mk b/debuggerd/crasher/Android.mk
deleted file mode 100644
index b8b786b..0000000
--- a/debuggerd/crasher/Android.mk
+++ /dev/null
@@ -1,66 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-crasher_cppflags := \
- -std=gnu++14 \
- -W \
- -Wall \
- -Wextra \
- -Wunused \
- -Werror \
- -O0 \
- -fstack-protector-all \
- -Wno-free-nonheap-object \
- -Wno-date-time
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := crasher.cpp
-LOCAL_SRC_FILES_arm := arm/crashglue.S
-LOCAL_SRC_FILES_arm64 := arm64/crashglue.S
-LOCAL_SRC_FILES_mips := mips/crashglue.S
-LOCAL_SRC_FILES_mips64 := mips64/crashglue.S
-LOCAL_SRC_FILES_x86 := x86/crashglue.S
-LOCAL_SRC_FILES_x86_64 := x86_64/crashglue.S
-LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
-LOCAL_MODULE_TAGS := optional
-LOCAL_CPPFLAGS := $(crasher_cppflags)
-LOCAL_SHARED_LIBRARIES := libbase liblog
-
-# The arm emulator has VFP but not VFPv3-D32.
-ifeq ($(ARCH_ARM_HAVE_VFP_D32),true)
-LOCAL_ASFLAGS_arm += -DHAS_VFP_D32
-endif
-
-LOCAL_MODULE := crasher
-LOCAL_MODULE_STEM_32 := crasher
-LOCAL_MODULE_STEM_64 := crasher64
-LOCAL_MULTILIB := both
-
-include $(BUILD_EXECUTABLE)
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := crasher.cpp
-LOCAL_SRC_FILES_arm := arm/crashglue.S
-LOCAL_SRC_FILES_arm64 := arm64/crashglue.S
-LOCAL_SRC_FILES_mips := mips/crashglue.S
-LOCAL_SRC_FILES_mips64 := mips64/crashglue.S
-LOCAL_SRC_FILES_x86 := x86/crashglue.S
-LOCAL_SRC_FILES_x86_64 := x86_64/crashglue.S
-LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
-LOCAL_MODULE_TAGS := optional
-LOCAL_CPPFLAGS := $(crasher_cppflags) -DSTATIC_CRASHER
-LOCAL_FORCE_STATIC_EXECUTABLE := true
-LOCAL_SHARED_LIBRARIES := libbase liblog
-
-# The arm emulator has VFP but not VFPv3-D32.
-ifeq ($(ARCH_ARM_HAVE_VFP_D32),true)
-LOCAL_ASFLAGS_arm += -DHAS_VFP_D32
-endif
-
-LOCAL_MODULE := static_crasher
-LOCAL_MODULE_STEM_32 := static_crasher
-LOCAL_MODULE_STEM_64 := static_crasher64
-LOCAL_MULTILIB := both
-
-LOCAL_STATIC_LIBRARIES := libdebuggerd_handler libbase liblog
-
-include $(BUILD_EXECUTABLE)
diff --git a/debuggerd/crasher/crasher.cpp b/debuggerd/crasher/crasher.cpp
index 288f116..64a38dd 100644
--- a/debuggerd/crasher/crasher.cpp
+++ b/debuggerd/crasher/crasher.cpp
@@ -36,6 +36,19 @@
#include "debuggerd/handler.h"
#endif
+#if defined(__arm__)
+// See https://www.kernel.org/doc/Documentation/arm/kernel_user_helpers.txt for details.
+#define __kuser_helper_version (*(int32_t*) 0xffff0ffc)
+typedef void * (__kuser_get_tls_t)(void);
+#define __kuser_get_tls (*(__kuser_get_tls_t*) 0xffff0fe0)
+typedef int (__kuser_cmpxchg_t)(int oldval, int newval, volatile int *ptr);
+#define __kuser_cmpxchg (*(__kuser_cmpxchg_t*) 0xffff0fc0)
+typedef void (__kuser_dmb_t)(void);
+#define __kuser_dmb (*(__kuser_dmb_t*) 0xffff0fa0)
+typedef int (__kuser_cmpxchg64_t)(const int64_t*, const int64_t*, volatile int64_t*);
+#define __kuser_cmpxchg64 (*(__kuser_cmpxchg64_t*) 0xffff0f60)
+#endif
+
#define noinline __attribute__((__noinline__))
// Avoid name mangling so that stacks are more readable.
@@ -142,22 +155,36 @@
fprintf(stderr, "where KIND is:\n");
fprintf(stderr, " smash-stack overwrite a -fstack-protector guard\n");
fprintf(stderr, " stack-overflow recurse until the stack overflows\n");
+ fprintf(stderr, " nostack crash with a NULL stack pointer\n");
+ fprintf(stderr, "\n");
fprintf(stderr, " heap-corruption cause a libc abort by corrupting the heap\n");
fprintf(stderr, " heap-usage cause a libc abort by abusing a heap function\n");
- fprintf(stderr, " nostack crash with a NULL stack pointer\n");
+ fprintf(stderr, "\n");
fprintf(stderr, " abort call abort()\n");
fprintf(stderr, " assert call assert() without a function\n");
fprintf(stderr, " assert2 call assert() with a function\n");
fprintf(stderr, " exit call exit(1)\n");
+ fprintf(stderr, "\n");
fprintf(stderr, " fortify fail a _FORTIFY_SOURCE check\n");
+ fprintf(stderr, " seccomp fail a seccomp check\n");
+#if defined(__arm__)
+ fprintf(stderr, " kuser_helper_version call kuser_helper_version\n");
+ fprintf(stderr, " kuser_get_tls call kuser_get_tls\n");
+ fprintf(stderr, " kuser_cmpxchg call kuser_cmpxchg\n");
+ fprintf(stderr, " kuser_memory_barrier call kuser_memory_barrier\n");
+ fprintf(stderr, " kuser_cmpxchg64 call kuser_cmpxchg64\n");
+#endif
+ fprintf(stderr, "\n");
fprintf(stderr, " LOG_ALWAYS_FATAL call liblog LOG_ALWAYS_FATAL\n");
fprintf(stderr, " LOG_ALWAYS_FATAL_IF call liblog LOG_ALWAYS_FATAL_IF\n");
fprintf(stderr, " LOG-FATAL call libbase LOG(FATAL)\n");
+ fprintf(stderr, "\n");
fprintf(stderr, " SIGFPE cause a SIGFPE\n");
fprintf(stderr, " SIGSEGV cause a SIGSEGV at address 0x0 (synonym: crash)\n");
fprintf(stderr, " SIGSEGV-non-null cause a SIGSEGV at a non-zero address\n");
fprintf(stderr, " SIGSEGV-unmapped mmap/munmap a region of memory and then attempt to access it\n");
fprintf(stderr, " SIGTRAP cause a SIGTRAP\n");
+ fprintf(stderr, "\n");
fprintf(stderr, " fprintf-NULL pass a null pointer to fprintf\n");
fprintf(stderr, " readdir-NULL pass a null pointer to readdir\n");
fprintf(stderr, " strlen-NULL pass a null pointer to strlen\n");
@@ -235,6 +262,20 @@
MAP_SHARED | MAP_ANONYMOUS, -1, 0));
munmap(map, sizeof(int));
map[0] = '8';
+ } else if (!strcasecmp(arg, "seccomp")) {
+ syscall(99999);
+#if defined(__arm__)
+ } else if (!strcasecmp(arg, "kuser_helper_version")) {
+ return __kuser_helper_version;
+ } else if (!strcasecmp(arg, "kuser_get_tls")) {
+ return !__kuser_get_tls();
+ } else if (!strcasecmp(arg, "kuser_cmpxchg")) {
+ return __kuser_cmpxchg(0, 0, 0);
+ } else if (!strcasecmp(arg, "kuser_memory_barrier")) {
+ __kuser_dmb();
+ } else if (!strcasecmp(arg, "kuser_cmpxchg64")) {
+ return __kuser_cmpxchg64(0, 0, 0);
+#endif
} else {
return usage();
}
diff --git a/debuggerd/handler/debuggerd_handler.cpp b/debuggerd/handler/debuggerd_handler.cpp
index cd491d6..9469bbd 100644
--- a/debuggerd/handler/debuggerd_handler.cpp
+++ b/debuggerd/handler/debuggerd_handler.cpp
@@ -67,11 +67,22 @@
static pthread_mutex_t crash_mutex = PTHREAD_MUTEX_INITIALIZER;
// Don't use __libc_fatal because it exits via abort, which might put us back into a signal handler.
-#define fatal(...) \
- do { \
- __libc_format_log(ANDROID_LOG_FATAL, "libc", __VA_ARGS__); \
- _exit(1); \
- } while (0)
+static void __noreturn __printflike(1, 2) fatal(const char* fmt, ...) {
+ va_list args;
+ va_start(args, fmt);
+ __libc_format_log_va_list(ANDROID_LOG_FATAL, "libc", fmt, args);
+ _exit(1);
+}
+
+static void __noreturn __printflike(1, 2) fatal_errno(const char* fmt, ...) {
+ int err = errno;
+ va_list args;
+ va_start(args, fmt);
+
+ char buf[4096];
+ vsnprintf(buf, sizeof(buf), fmt, args);
+ fatal("%s: %s", buf, strerror(err));
+}
/*
* Writes a summary of the signal to the log file. We do this so that, if
@@ -192,7 +203,7 @@
int pipefds[2];
if (pipe(pipefds) != 0) {
- fatal("failed to create pipe");
+ fatal_errno("failed to create pipe");
}
// Don't use fork(2) to avoid calling pthread_atfork handlers.
@@ -209,7 +220,7 @@
snprintf(buf, sizeof(buf), "%d", thread_info->crashing_tid);
execl(CRASH_DUMP_PATH, CRASH_DUMP_NAME, buf, nullptr);
- fatal("exec failed: %s", strerror(errno));
+ fatal_errno("exec failed");
} else {
close(pipefds[1]);
char buf[4];
@@ -264,7 +275,7 @@
if (crash_dump_started || info->si_signo != DEBUGGER_SIGNAL) {
int rc = syscall(SYS_rt_tgsigqueueinfo, getpid(), gettid(), info->si_signo, info);
if (rc != 0) {
- fatal("failed to resend signal during crash: %s", strerror(errno));
+ fatal_errno("failed to resend signal during crash");
}
}
@@ -336,7 +347,7 @@
CLONE_THREAD | CLONE_SIGHAND | CLONE_VM | CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID,
&thread_info, nullptr, nullptr, &thread_info.pseudothread_tid);
if (child_pid == -1) {
- fatal("failed to spawn debuggerd dispatch thread: %s", strerror(errno));
+ fatal_errno("failed to spawn debuggerd dispatch thread");
}
// Wait for the child to start...
@@ -366,12 +377,12 @@
void* thread_stack_allocation =
mmap(nullptr, PAGE_SIZE * 3, PROT_NONE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
if (thread_stack_allocation == MAP_FAILED) {
- fatal("failed to allocate debuggerd thread stack");
+ fatal_errno("failed to allocate debuggerd thread stack");
}
char* stack = static_cast<char*>(thread_stack_allocation) + PAGE_SIZE;
if (mprotect(stack, PAGE_SIZE, PROT_READ | PROT_WRITE) != 0) {
- fatal("failed to mprotect debuggerd thread stack");
+ fatal_errno("failed to mprotect debuggerd thread stack");
}
// Stack grows negatively, set it to the last byte in the page...
diff --git a/debuggerd/libdebuggerd/tombstone.cpp b/debuggerd/libdebuggerd/tombstone.cpp
index 01e9cf6..ac2c0b6 100644
--- a/debuggerd/libdebuggerd/tombstone.cpp
+++ b/debuggerd/libdebuggerd/tombstone.cpp
@@ -49,6 +49,8 @@
#include "open_files_list.h"
#include "tombstone.h"
+using android::base::StringPrintf;
+
#define STACK_WORDS 16
#define MAX_TOMBSTONES 10
@@ -74,7 +76,7 @@
}
static const char* get_signame(int sig) {
- switch(sig) {
+ switch (sig) {
case SIGABRT: return "SIGABRT";
case SIGBUS: return "SIGBUS";
case SIGFPE: return "SIGFPE";
@@ -195,6 +197,29 @@
_LOG(log, logtype::HEADER, "ABI: '%s'\n", ABI_STRING);
}
+static void dump_probable_cause(log_t* log, const siginfo_t& si) {
+ std::string cause;
+ if (si.si_signo == SIGSEGV && si.si_code == SEGV_MAPERR) {
+ if (si.si_addr < reinterpret_cast<void*>(4096)) {
+ cause = StringPrintf("null pointer dereference");
+ } else if (si.si_addr == reinterpret_cast<void*>(0xffff0ffc)) {
+ cause = "call to kuser_helper_version";
+ } else if (si.si_addr == reinterpret_cast<void*>(0xffff0fe0)) {
+ cause = "call to kuser_get_tls";
+ } else if (si.si_addr == reinterpret_cast<void*>(0xffff0fc0)) {
+ cause = "call to kuser_cmpxchg";
+ } else if (si.si_addr == reinterpret_cast<void*>(0xffff0fa0)) {
+ cause = "call to kuser_memory_barrier";
+ } else if (si.si_addr == reinterpret_cast<void*>(0xffff0f60)) {
+ cause = "call to kuser_cmpxchg64";
+ }
+ } else if (si.si_signo == SIGSYS && si.si_code == SYS_SECCOMP) {
+ cause = StringPrintf("seccomp prevented call to disallowed system call %d", si.si_syscall);
+ }
+
+ if (!cause.empty()) _LOG(log, logtype::HEADER, "Cause: %s\n", cause.c_str());
+}
+
static void dump_signal_info(log_t* log, pid_t tid) {
siginfo_t si;
memset(&si, 0, sizeof(si));
@@ -212,6 +237,8 @@
_LOG(log, logtype::HEADER, "signal %d (%s), code %d (%s), fault addr %s\n", si.si_signo,
get_signame(si.si_signo), si.si_code, get_sigcode(si.si_signo, si.si_code), addr_desc);
+
+ dump_probable_cause(log, si);
}
static void dump_thread_info(log_t* log, pid_t pid, pid_t tid) {
@@ -262,11 +289,11 @@
line = " ";
if (i == 0 && label >= 0) {
// Print the label once.
- line += android::base::StringPrintf("#%02d ", label);
+ line += StringPrintf("#%02d ", label);
} else {
line += " ";
}
- line += android::base::StringPrintf("%" PRIPTR " %" PRIPTR, *sp, stack_data[i]);
+ line += StringPrintf("%" PRIPTR " %" PRIPTR, *sp, stack_data[i]);
backtrace_map_t map;
backtrace->FillInMap(stack_data[i], &map);
@@ -277,7 +304,7 @@
if (!func_name.empty()) {
line += " (" + func_name;
if (offset) {
- line += android::base::StringPrintf("+%" PRIuPTR, offset);
+ line += StringPrintf("+%" PRIuPTR, offset);
}
line += ')';
}
@@ -336,11 +363,11 @@
static std::string get_addr_string(uintptr_t addr) {
std::string addr_str;
#if defined(__LP64__)
- addr_str = android::base::StringPrintf("%08x'%08x",
- static_cast<uint32_t>(addr >> 32),
- static_cast<uint32_t>(addr & 0xffffffff));
+ addr_str = StringPrintf("%08x'%08x",
+ static_cast<uint32_t>(addr >> 32),
+ static_cast<uint32_t>(addr & 0xffffffff));
#else
- addr_str = android::base::StringPrintf("%08x", addr);
+ addr_str = StringPrintf("%08x", addr);
#endif
return addr_str;
}
@@ -426,8 +453,7 @@
} else {
line += '-';
}
- line += android::base::StringPrintf(" %8" PRIxPTR " %8" PRIxPTR,
- it->offset, it->end - it->start);
+ line += StringPrintf(" %8" PRIxPTR " %8" PRIxPTR, it->offset, it->end - it->start);
bool space_needed = true;
if (it->name.length() > 0) {
space_needed = false;
@@ -441,7 +467,7 @@
if (space_needed) {
line += ' ';
}
- line += android::base::StringPrintf(" (load base 0x%" PRIxPTR ")", it->load_base);
+ line += StringPrintf(" (load base 0x%" PRIxPTR ")", it->load_base);
}
_LOG(log, logtype::MAPS, "%s\n", line.c_str());
}
diff --git a/init/Android.mk b/init/Android.mk
index 759be52..9e61fb2 100644
--- a/init/Android.mk
+++ b/init/Android.mk
@@ -70,7 +70,6 @@
init.cpp \
keychords.cpp \
property_service.cpp \
- seccomp.cpp \
signal_handler.cpp \
ueventd.cpp \
ueventd_parser.cpp \
@@ -97,7 +96,6 @@
libbase \
libc \
libselinux \
- libseccomp_policy \
liblog \
libcrypto_utils \
libcrypto \
diff --git a/init/README.md b/init/README.md
index cef0dbc..c76a33b 100644
--- a/init/README.md
+++ b/init/README.md
@@ -298,7 +298,8 @@
> Fork and execute command with the given arguments. The command starts
after "--" so that an optional security context, user, and supplementary
groups can be provided. No other commands will be run until this one
- finishes. _seclabel_ can be a - to denote default.
+ finishes. _seclabel_ can be a - to denote default. Properties are expanded
+ within _argument_.
`export <name> <value>`
> Set the environment variable _name_ equal to _value_ in the
@@ -412,6 +413,11 @@
or the timeout has been reached. If timeout is not specified it
currently defaults to five seconds.
+`wait_for_prop <name> <value>`
+> Wait for system property _name_ to be _value_. Properties are expanded
+ within _value_. If property _name_ is already set to _value_, continue
+ immediately.
+
`write <path> <content>`
> Open the file at _path_ and write a string to it with write(2).
If the file does not exist, it will be created. If it does exist,
diff --git a/init/builtins.cpp b/init/builtins.cpp
index 1186e9d..965a81f 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -1003,6 +1003,29 @@
return -1;
}
+static int do_wait_for_prop(const std::vector<std::string>& args) {
+ const char* name = args[1].c_str();
+ const char* value = args[2].c_str();
+ size_t value_len = strlen(value);
+
+ if (!is_legal_property_name(name)) {
+ LOG(ERROR) << "do_wait_for_prop(\"" << name << "\", \"" << value
+ << "\") failed: bad name";
+ return -1;
+ }
+ if (value_len >= PROP_VALUE_MAX) {
+ LOG(ERROR) << "do_wait_for_prop(\"" << name << "\", \"" << value
+ << "\") failed: value too long";
+ return -1;
+ }
+ if (!wait_property(name, value)) {
+ LOG(ERROR) << "do_wait_for_prop(\"" << name << "\", \"" << value
+ << "\") failed: init already in waiting";
+ return -1;
+ }
+ return 0;
+}
+
/*
* Callback to make a directory from the ext4 code
*/
@@ -1074,6 +1097,7 @@
{"verity_load_state", {0, 0, do_verity_load_state}},
{"verity_update_state", {0, 0, do_verity_update_state}},
{"wait", {1, 2, do_wait}},
+ {"wait_for_prop", {2, 2, do_wait_for_prop}},
{"write", {2, 2, do_write}},
};
return builtin_functions;
diff --git a/init/init.cpp b/init/init.cpp
index 850a904..c8c18d2 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -62,7 +62,6 @@
#include "keychords.h"
#include "log.h"
#include "property_service.h"
-#include "seccomp.h"
#include "service.h"
#include "signal_handler.h"
#include "ueventd.h"
@@ -87,6 +86,10 @@
static int epoll_fd = -1;
+static std::unique_ptr<Timer> waiting_for_prop(nullptr);
+static std::string wait_prop_name;
+static std::string wait_prop_value;
+
void register_epoll_handler(int fd, void (*fn)()) {
epoll_event ev;
ev.events = EPOLLIN;
@@ -128,10 +131,34 @@
return -1;
}
+bool wait_property(const char *name, const char *value)
+{
+ if (waiting_for_prop) {
+ return false;
+ }
+ if (property_get(name) != value) {
+ // Current property value is not equal to expected value
+ wait_prop_name = name;
+ wait_prop_value = value;
+ waiting_for_prop.reset(new Timer());
+ } else {
+ LOG(INFO) << "wait_property(\"" << name << "\", \"" << value << "\"): already set";
+ }
+ return true;
+}
+
void property_changed(const char *name, const char *value)
{
if (property_triggers_enabled)
ActionManager::GetInstance().QueuePropertyTrigger(name, value);
+ if (waiting_for_prop) {
+ if (wait_prop_name == name && wait_prop_value == value) {
+ wait_prop_name.clear();
+ wait_prop_value.clear();
+ LOG(INFO) << "Wait for property took " << *waiting_for_prop;
+ waiting_for_prop.reset();
+ }
+ }
}
static void restart_processes()
@@ -793,12 +820,6 @@
// Now set up SELinux for second stage.
selinux_initialize(false);
-
- // Install system-wide seccomp filter
- if (!set_seccomp_filter()) {
- LOG(ERROR) << "Failed to set seccomp policy";
- security_failure();
- }
}
// These directories were necessarily created before initial policy load
@@ -876,7 +897,7 @@
am.QueueBuiltinAction(queue_property_triggers_action, "queue_property_triggers");
while (true) {
- if (!waiting_for_exec) {
+ if (!(waiting_for_exec || waiting_for_prop)) {
am.ExecuteOneCommand();
restart_processes();
}
diff --git a/init/init.h b/init/init.h
index cfb3139..4e4da32 100644
--- a/init/init.h
+++ b/init/init.h
@@ -36,4 +36,6 @@
int add_environment(const char* key, const char* val);
+bool wait_property(const char *name, const char *value);
+
#endif /* _INIT_INIT_H */
diff --git a/init/seccomp.cpp b/init/seccomp.cpp
deleted file mode 100644
index b0688f3..0000000
--- a/init/seccomp.cpp
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * Copyright (C) 2016 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.
- */
-
-#include "seccomp.h"
-
-#include <vector>
-
-#include <sys/prctl.h>
-
-#include <linux/unistd.h>
-#include <linux/audit.h>
-#include <linux/filter.h>
-#include <linux/seccomp.h>
-
-#include "log.h"
-#include "seccomp_policy.h"
-
-#define syscall_nr (offsetof(struct seccomp_data, nr))
-#define arch_nr (offsetof(struct seccomp_data, arch))
-
-#if defined __arm__
-#define AUDIT_ARCH_NR AUDIT_ARCH_ARM
-#elif defined __aarch64__
-#define AUDIT_ARCH_NR AUDIT_ARCH_AARCH64
-#define AUDIT_ARCH_NR32 AUDIT_ARCH_ARM
-#elif defined __i386__
-#define AUDIT_ARCH_NR AUDIT_ARCH_I386
-#elif defined __x86_64__
-#define AUDIT_ARCH_NR AUDIT_ARCH_X86_64
-#define AUDIT_ARCH_NR32 AUDIT_ARCH_I386
-#elif defined __mips64__
-#define AUDIT_ARCH_NR AUDIT_ARCH_MIPS64
-#define AUDIT_ARCH_NR32 AUDIT_ARCH_MIPS
-#elif defined __mips__ && !defined __mips64__
-#define AUDIT_ARCH_NR AUDIT_ARCH_MIPS
-#else
-#error "Could not determine AUDIT_ARCH_NR for this architecture"
-#endif
-
-typedef std::vector<sock_filter> filter;
-
-// We want to keep the below inline functions for debugging and future
-// development even though they are not used currently.
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wunused-function"
-
-static inline void Kill(filter& f) {
- f.push_back(BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_KILL));
-}
-
-static inline void Trap(filter& f) {
- f.push_back(BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_TRAP));
-}
-
-static inline void Error(filter& f, __u16 retcode) {
- f.push_back(BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ERRNO + retcode));
-}
-
-inline static void Trace(filter& f) {
- f.push_back(BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_TRACE));
-}
-
-inline static void Allow(filter& f) {
- f.push_back(BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW));
-}
-
-inline static void AllowSyscall(filter& f, __u32 num) {
- f.push_back(BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, num, 0, 1));
- f.push_back(BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW));
-}
-
-inline static void ExamineSyscall(filter& f) {
- f.push_back(BPF_STMT(BPF_LD|BPF_W|BPF_ABS, syscall_nr));
-}
-
-#ifdef AUDIT_ARCH_NR32
-inline static int SetValidateArchitectureJumpTarget(size_t offset, filter& f) {
- auto jump_length = f.size() - offset - 1;
- auto u8_jump_length = (__u8) jump_length;
- if (u8_jump_length != jump_length) {
- LOG(ERROR) << "Can't set jump greater than 255 - actual jump is " << jump_length;
- return -1;
- }
- f[offset] = BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, AUDIT_ARCH_NR32, u8_jump_length, 0);
- return 0;
-}
-#endif
-
-inline static size_t ValidateArchitectureAndJumpIfNeeded(filter& f) {
- f.push_back(BPF_STMT(BPF_LD|BPF_W|BPF_ABS, arch_nr));
-
-#ifdef AUDIT_ARCH_NR32
- f.push_back(BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, AUDIT_ARCH_NR, 2, 0));
- f.push_back(BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, AUDIT_ARCH_NR32, 1, 0));
- Kill(f);
- return f.size() - 2;
-#else
- f.push_back(BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, AUDIT_ARCH_NR, 1, 0));
- Kill(f);
- return 0;
-#endif
-}
-
-#pragma clang diagnostic pop
-
-static bool install_filter(filter const& f) {
- struct sock_fprog prog = {
- (unsigned short) f.size(),
- (struct sock_filter*) &f[0],
- };
-
- if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) < 0) {
- PLOG(ERROR) << "SECCOMP: Could not set seccomp filter";
- return false;
- }
-
- LOG(INFO) << "SECCOMP: Global filter installed";
- return true;
-}
-
-bool set_seccomp_filter() {
- filter f;
-
- // Note that for mixed 64/32 bit architectures, ValidateArchitecture inserts a
- // jump that must be changed to point to the start of the 32-bit policy
- // 32 bit syscalls will not hit the policy between here and the call to SetJump
-#ifdef AUDIT_ARCH_NR32
- auto offset_to_32bit_filter =
-#endif
- ValidateArchitectureAndJumpIfNeeded(f);
-
- // Native filter
- ExamineSyscall(f);
-
-#ifdef __aarch64__
- // Syscalls needed to boot Android
- AllowSyscall(f, __NR_pivot_root);
- AllowSyscall(f, __NR_ioprio_get);
- AllowSyscall(f, __NR_ioprio_set);
- AllowSyscall(f, __NR_gettid);
- AllowSyscall(f, __NR_futex);
- AllowSyscall(f, __NR_clone);
- AllowSyscall(f, __NR_rt_sigreturn);
- AllowSyscall(f, __NR_rt_tgsigqueueinfo);
- AllowSyscall(f, __NR_add_key);
- AllowSyscall(f, __NR_request_key);
- AllowSyscall(f, __NR_keyctl);
- AllowSyscall(f, __NR_restart_syscall);
- AllowSyscall(f, __NR_getrandom);
-
- // Needed for performance tools
- AllowSyscall(f, __NR_perf_event_open);
-
- // Needed for treble
- AllowSyscall(f, __NR_finit_module);
-
- // Needed for trusty
- AllowSyscall(f, __NR_syncfs);
-
- // Needed for strace
- AllowSyscall(f, __NR_tkill); // __NR_tkill
-
- // Needed for kernel to restart syscalls
- AllowSyscall(f, __NR_restart_syscall);
-
- // arm64-only filter - autogenerated from bionic syscall usage
- for (size_t i = 0; i < arm64_filter_size; ++i)
- f.push_back(arm64_filter[i]);
-#else
- // Generic policy
- Allow(f);
-#endif
-
-#ifdef AUDIT_ARCH_NR32
- if (SetValidateArchitectureJumpTarget(offset_to_32bit_filter, f) != 0)
- return -1;
-
- // 32-bit filter for 64-bit platforms
- ExamineSyscall(f);
-
-#ifdef __aarch64__
- // Syscalls needed to boot android
- AllowSyscall(f, 120); // __NR_clone
- AllowSyscall(f, 240); // __NR_futex
- AllowSyscall(f, 119); // __NR_sigreturn
- AllowSyscall(f, 173); // __NR_rt_sigreturn
- AllowSyscall(f, 363); // __NR_rt_tgsigqueueinfo
- AllowSyscall(f, 224); // __NR_gettid
-
- // Syscalls needed to run Chrome
- AllowSyscall(f, 383); // __NR_seccomp - needed to start Chrome
- AllowSyscall(f, 384); // __NR_getrandom - needed to start Chrome
-
- // Syscalls needed to run GFXBenchmark
- AllowSyscall(f, 190); // __NR_vfork
-
- // Needed for strace
- AllowSyscall(f, 238); // __NR_tkill
-
- // Needed for kernel to restart syscalls
- AllowSyscall(f, 0); // __NR_restart_syscall
-
- // Needed for debugging 32-bit Chrome
- AllowSyscall(f, 42); // __NR_pipe
-
- // b/34732712
- AllowSyscall(f, 364); // __NR_perf_event_open
-
- // b/34651972
- AllowSyscall(f, 33); // __NR_access
- AllowSyscall(f, 195); // __NR_stat64
-
- // b/34813887
- AllowSyscall(f, 5); // __NR_open
- AllowSyscall(f, 141); // __NR_getdents
- AllowSyscall(f, 217); // __NR_getdents64
-
- // b/34719286
- AllowSyscall(f, 351); // __NR_eventfd
-
- // b/34817266
- AllowSyscall(f, 252); // __NR_epoll_wait
-
- // arm32-on-arm64 only filter - autogenerated from bionic syscall usage
- for (size_t i = 0; i < arm_filter_size; ++i)
- f.push_back(arm_filter[i]);
-#else
- // Generic policy
- Allow(f);
-#endif
-#endif
- return install_filter(f);
-}
diff --git a/init/seccomp.h b/init/seccomp.h
deleted file mode 100644
index cda7a89..0000000
--- a/init/seccomp.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2016 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.
- */
-
-#ifndef SECCOMP_H
-#define SECCOMP_H
-
-bool set_seccomp_filter();
-
-#endif