Merge "Fix x86 system calls made from ELF preinit."
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index 125b469..7b533a4 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -1,3 +1,2 @@
[Hook Scripts]
-versioner = tools/versioner/preupload.sh
notice = tools/update_notice.sh
diff --git a/libc/Android.bp b/libc/Android.bp
index 5d0e8c7..9bba776 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -2036,15 +2036,12 @@
defaults: ["crt_defaults"],
}
-// The following module lives in prebuilts/ndk because we need to preprocess the
-// headers to include ifdef guards for __ANDROID_API__. Update with
-// bionic/tools/update_headers.sh.
-// ndk_headers {
-// name: "common_libc",
-// from: "include",
-// to: "",
-// srcs: ["include/**/*.h"],
-// }
+preprocessed_ndk_headers {
+ name: "common_libc",
+ from: "include",
+ to: "",
+ license: "NOTICE",
+}
ndk_headers {
name: "libc_uapi",
diff --git a/libc/SECCOMP_WHITELIST.TXT b/libc/SECCOMP_WHITELIST.TXT
index 7cae1e1..f0e99e3 100644
--- a/libc/SECCOMP_WHITELIST.TXT
+++ b/libc/SECCOMP_WHITELIST.TXT
@@ -94,3 +94,9 @@
# b/35906875. Note mips already has getuid from SYSCALLS.TXT
int inotify_init() arm,x86,mips
uid_t getuid() arm,x86
+
+# b/36435222
+int remap_file_pages(void *addr, size_t size, int prot, size_t pgoff, int flags) arm,x86,mips
+
+# b/36449658
+int rename(const char *oldpath, const char *newpath) arm,x86,mips
diff --git a/libc/arch-arm64/generic/bionic/strcmp.S b/libc/arch-arm64/generic/bionic/strcmp.S
index 3cce478..271452d 100644
--- a/libc/arch-arm64/generic/bionic/strcmp.S
+++ b/libc/arch-arm64/generic/bionic/strcmp.S
@@ -57,6 +57,7 @@
/* Start of performance-critical section -- one 64B cache line. */
ENTRY(strcmp)
+.p2align 6
eor tmp1, src1, src2
mov zeroones, #REP8_01
tst tmp1, #7
diff --git a/libc/bionic/bionic_systrace.cpp b/libc/bionic/bionic_systrace.cpp
index b522b10..8e8ff76 100644
--- a/libc/bionic/bionic_systrace.cpp
+++ b/libc/bionic/bionic_systrace.cpp
@@ -48,10 +48,11 @@
// case an audit will be logged, and during boot before the property server has
// been started, in which case we store the global property_area serial to prevent
// the costly find operation until we see a changed property_area.
- if (!g_pinfo && g_property_area_serial != __system_property_area_serial()) {
+ if (g_pinfo == nullptr && g_property_area_serial != __system_property_area_serial()) {
g_property_area_serial = __system_property_area_serial();
g_pinfo = __system_property_find(SYSTRACE_PROPERTY_NAME);
}
+
if (g_pinfo) {
// Find out which tags have been enabled on the command line and set
// the value of tags accordingly. If the value of the property changes,
@@ -61,10 +62,11 @@
// not to move.
uint32_t cur_serial = __system_property_serial(g_pinfo);
if (cur_serial != g_property_serial) {
- g_property_serial = cur_serial;
- char value[PROP_VALUE_MAX];
- __system_property_read(g_pinfo, 0, value);
- g_tags = strtoull(value, nullptr, 0);
+ __system_property_read_callback(g_pinfo,
+ [] (void*, const char*, const char* value, uint32_t serial) {
+ g_property_serial = serial;
+ g_tags = strtoull(value, nullptr, 0);
+ }, nullptr);
}
result = ((g_tags & ATRACE_TAG_BIONIC) != 0);
}
@@ -81,7 +83,7 @@
return g_trace_marker_fd;
}
-ScopedTrace::ScopedTrace(const char* message) {
+void bionic_trace_begin(const char* message) {
if (!should_trace()) {
return;
}
@@ -102,7 +104,7 @@
TEMP_FAILURE_RETRY(write(trace_marker_fd, buf, len));
}
-ScopedTrace::~ScopedTrace() {
+void bionic_trace_end() {
if (!should_trace()) {
return;
}
@@ -114,3 +116,18 @@
TEMP_FAILURE_RETRY(write(trace_marker_fd, "E", 1));
}
+
+ScopedTrace::ScopedTrace(const char* message) : called_end_(false) {
+ bionic_trace_begin(message);
+}
+
+ScopedTrace::~ScopedTrace() {
+ End();
+}
+
+void ScopedTrace::End() {
+ if (!called_end_) {
+ bionic_trace_end();
+ called_end_ = true;
+ }
+}
diff --git a/libc/include/bits/posix_limits.h b/libc/include/bits/posix_limits.h
index c498c69..db09bd7 100644
--- a/libc/include/bits/posix_limits.h
+++ b/libc/include/bits/posix_limits.h
@@ -31,20 +31,22 @@
#include <sys/cdefs.h>
+#define __BIONIC_POSIX_FEATURE_SINCE(level) (((__ANDROID_API__) >= level) ? 200809L : -1)
+
/* Any constant values here other than -1 or 200809L are explicitly specified by POSIX.1-2008. */
/* Keep this list sorted by name. */
-#define _POSIX_ADVISORY_INFO 200809L
+#define _POSIX_ADVISORY_INFO __BIONIC_POSIX_FEATURE_SINCE(23) /* posix_memadvise arrived late. */
#define _POSIX_AIO_LISTIO_MAX 2
#define _POSIX_AIO_MAX 1
#define _POSIX_ARG_MAX 4096
#define _POSIX_ASYNCHRONOUS_IO -1 /* not implemented */
-#define _POSIX_BARRIERS 200809L
+#define _POSIX_BARRIERS __BIONIC_POSIX_FEATURE_SINCE(24)
#define _POSIX_CHILD_MAX 25
#define _POSIX_CHOWN_RESTRICTED 1 /* yes, chown requires appropriate privileges */
#define _POSIX_CLOCK_SELECTION 200809L
#define _POSIX_CPUTIME 0 /* Use sysconf to detect support at runtime. */
#define _POSIX_DELAYTIMER_MAX 32
-#define _POSIX_FSYNC 200809L /* fdatasync() supported */
+#define _POSIX_FSYNC 200809L
#define _POSIX_HOST_NAME_MAX 255
#define _POSIX_IPV6 200809L
#define _POSIX_JOB_CONTROL 1 /* job control is a Linux feature */
@@ -53,8 +55,8 @@
#define _POSIX_MAPPED_FILES 200809L /* mmap-ed files supported */
#define _POSIX_MAX_CANON 255
#define _POSIX_MAX_INPUT 255
-#define _POSIX_MEMLOCK 200809L
-#define _POSIX_MEMLOCK_RANGE 200809L
+#define _POSIX_MEMLOCK __BIONIC_POSIX_FEATURE_SINCE(17) /* mlockall. */
+#define _POSIX_MEMLOCK_RANGE 200809L /* mlock. */
#define _POSIX_MEMORY_PROTECTION 200809L
#define _POSIX_MESSAGE_PASSING -1 /* not implemented */
#define _POSIX_MONOTONIC_CLOCK 0 /* the monotonic clock may be available; ask sysconf */
@@ -81,7 +83,7 @@
#define _POSIX_SHELL 1 /* system() supported */
#define _POSIX_SIGQUEUE_MAX 32
#define _POSIX_SPAWN -1 /* not implemented */
-#define _POSIX_SPIN_LOCKS 200809L
+#define _POSIX_SPIN_LOCKS __BIONIC_POSIX_FEATURE_SINCE(24)
#define _POSIX_SPORADIC_SERVER -1 /* not implemented */
#define _POSIX_SSIZE_MAX 32767
#define _POSIX_STREAM_MAX 8
@@ -103,7 +105,7 @@
#define _POSIX_THREAD_SAFE_FUNCTIONS 200809L
#define _POSIX_THREAD_SPORADIC_SERVER -1 /* not implemented */
#define _POSIX_THREAD_THREADS_MAX 64
-#define _POSIX_TIMEOUTS 200809L
+#define _POSIX_TIMEOUTS __BIONIC_POSIX_FEATURE_SINCE(21) /* pthread_mutex_timedlock arrived late. */
#define _POSIX_TIMERS 200809L /* Posix timers are supported */
#define _POSIX_TIMER_MAX 32
#define _POSIX_TRACE -1 /* not implemented */
diff --git a/libc/include/bits/pthread_types.h b/libc/include/bits/pthread_types.h
index 7fc379b..a173e3c 100644
--- a/libc/include/bits/pthread_types.h
+++ b/libc/include/bits/pthread_types.h
@@ -44,6 +44,7 @@
#endif
} pthread_attr_t;
+#if __ANDROID_API__ >= __ANDROID_API_N__
typedef struct {
#if defined(__LP64__)
int64_t __private[4];
@@ -51,8 +52,11 @@
int32_t __private[8];
#endif
} pthread_barrier_t;
+#endif
+#if __ANDROID_API__ >= __ANDROID_API_N__
typedef int pthread_barrierattr_t;
+#endif
typedef struct {
#if defined(__LP64__)
@@ -88,6 +92,7 @@
typedef long pthread_rwlockattr_t;
+#if __ANDROID_API__ >= __ANDROID_API_N__
typedef struct {
#if defined(__LP64__)
int64_t __private;
@@ -95,6 +100,7 @@
int32_t __private[2];
#endif
} pthread_spinlock_t;
+#endif
typedef long pthread_t;
diff --git a/libc/include/pthread.h b/libc/include/pthread.h
index 20fd566..ae4fdce 100644
--- a/libc/include/pthread.h
+++ b/libc/include/pthread.h
@@ -69,7 +69,9 @@
#define PTHREAD_ONCE_INIT 0
+#if __ANDROID_API__ >= __ANDROID_API_N__
#define PTHREAD_BARRIER_SERIAL_THREAD -1
+#endif
#if defined(__LP64__)
#define PTHREAD_STACK_MIN (4 * PAGE_SIZE)
@@ -178,23 +180,29 @@
int pthread_rwlock_unlock(pthread_rwlock_t* _Nonnull);
int pthread_rwlock_wrlock(pthread_rwlock_t* _Nonnull);
+#if __ANDROID_API__ >= __ANDROID_API_N__
int pthread_barrierattr_init(pthread_barrierattr_t* _Nonnull attr) __INTRODUCED_IN(24);
int pthread_barrierattr_destroy(pthread_barrierattr_t* _Nonnull attr) __INTRODUCED_IN(24);
int pthread_barrierattr_getpshared(const pthread_barrierattr_t* _Nonnull attr,
int* _Nonnull pshared) __INTRODUCED_IN(24);
int pthread_barrierattr_setpshared(pthread_barrierattr_t* _Nonnull attr, int pshared)
__INTRODUCED_IN(24);
+#endif
+#if __ANDROID_API__ >= __ANDROID_API_N__
int pthread_barrier_init(pthread_barrier_t* _Nonnull, const pthread_barrierattr_t*, unsigned)
__INTRODUCED_IN(24);
int pthread_barrier_destroy(pthread_barrier_t* _Nonnull) __INTRODUCED_IN(24);
int pthread_barrier_wait(pthread_barrier_t* _Nonnull) __INTRODUCED_IN(24);
+#endif
+#if __ANDROID_API__ >= __ANDROID_API_N__
int pthread_spin_destroy(pthread_spinlock_t* _Nonnull) __INTRODUCED_IN(24);
int pthread_spin_init(pthread_spinlock_t* _Nonnull, int) __INTRODUCED_IN(24);
int pthread_spin_lock(pthread_spinlock_t* _Nonnull) __INTRODUCED_IN(24);
int pthread_spin_trylock(pthread_spinlock_t* _Nonnull) __INTRODUCED_IN(24);
int pthread_spin_unlock(pthread_spinlock_t* _Nonnull) __INTRODUCED_IN(24);
+#endif
pthread_t pthread_self(void) __attribute_const__;
diff --git a/libc/include/stdio.h b/libc/include/stdio.h
index 7d63fa4..8b0e9df 100644
--- a/libc/include/stdio.h
+++ b/libc/include/stdio.h
@@ -176,7 +176,7 @@
int fseek(FILE*, long, int);
long ftell(FILE*);
-#if defined(__USE_FILE_OFFSET64)
+#if defined(__USE_FILE_OFFSET64) && __ANDROID_API__ >= __ANDROID_API_N__
int fgetpos(FILE*, fpos_t*) __RENAME(fgetpos64);
int fsetpos(FILE*, const fpos_t*) __RENAME(fsetpos64);
int fseeko(FILE*, off_t, int) __RENAME(fseeko64);
diff --git a/libc/include/sys/mman.h b/libc/include/sys/mman.h
index 79f1faf..a3dc95c 100644
--- a/libc/include/sys/mman.h
+++ b/libc/include/sys/mman.h
@@ -49,7 +49,7 @@
#define POSIX_MADV_WILLNEED MADV_WILLNEED
#define POSIX_MADV_DONTNEED MADV_DONTNEED
-#if defined(__USE_FILE_OFFSET64)
+#if defined(__USE_FILE_OFFSET64) && __ANDROID_API__ >= __ANDROID_API_L__
void* mmap(void*, size_t, int, int, int, off_t) __RENAME(mmap64) __INTRODUCED_IN(21);
#else
void* mmap(void*, size_t, int, int, int, off_t);
diff --git a/libc/include/sys/sendfile.h b/libc/include/sys/sendfile.h
index 3ac8fdf..dccdec5 100644
--- a/libc/include/sys/sendfile.h
+++ b/libc/include/sys/sendfile.h
@@ -34,7 +34,7 @@
__BEGIN_DECLS
-#if defined(__USE_FILE_OFFSET64)
+#if defined(__USE_FILE_OFFSET64) && __ANDROID_API__ >= __ANDROID_API_L__
ssize_t sendfile(int out_fd, int in_fd, off_t* offset, size_t count) __RENAME(sendfile64)
__INTRODUCED_IN(21);
#else
diff --git a/libc/private/bionic_systrace.h b/libc/private/bionic_systrace.h
index 0b4560f..304fb80 100644
--- a/libc/private/bionic_systrace.h
+++ b/libc/private/bionic_systrace.h
@@ -28,8 +28,13 @@
explicit ScopedTrace(const char* message);
~ScopedTrace();
+ void End();
private:
+ bool called_end_;
DISALLOW_COPY_AND_ASSIGN(ScopedTrace);
};
+void bionic_trace_begin(const char* message);
+void bionic_trace_end();
+
#endif
diff --git a/libc/seccomp/arm64_policy.cpp b/libc/seccomp/arm64_policy.cpp
index 0bf85a3..5eee365 100644
--- a/libc/seccomp/arm64_policy.cpp
+++ b/libc/seccomp/arm64_policy.cpp
@@ -5,7 +5,7 @@
#include "seccomp_bpfs.h"
const sock_filter arm64_filter[] = {
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5, 0, 25),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5, 0, 26),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 203, 13, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 101, 7, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 43, 3, 0),
diff --git a/libc/seccomp/arm_policy.cpp b/libc/seccomp/arm_policy.cpp
index fd7d48b..9f8b9fe 100644
--- a/libc/seccomp/arm_policy.cpp
+++ b/libc/seccomp/arm_policy.cpp
@@ -5,7 +5,7 @@
#include "seccomp_bpfs.h"
const sock_filter arm_filter[] = {
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 0, 0, 123),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 0, 0, 124),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 143, 61, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 74, 31, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 41, 15, 0),
@@ -23,7 +23,7 @@
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 27, 109, 108), //ptrace
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 36, 1, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 34, 107, 106), //access
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 38, 106, 105), //sync|kill
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 39, 106, 105), //sync|kill|rename
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 57, 7, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 51, 3, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 45, 1, 0),
@@ -95,7 +95,7 @@
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 249, 37, 36), //exit_group
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 270, 3, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 256, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 253, 34, 33), //epoll_create|epoll_ctl|epoll_wait
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 254, 34, 33), //epoll_create|epoll_ctl|epoll_wait|remap_file_pages
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 269, 33, 32), //set_tid_address|timer_create|timer_settime|timer_gettime|timer_getoverrun|timer_delete|clock_settime|clock_gettime|clock_getres|clock_nanosleep|statfs64|fstatfs64|tgkill
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 280, 1, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 271, 31, 30), //arm_fadvise64_64
diff --git a/libc/seccomp/include/seccomp_policy.h b/libc/seccomp/include/seccomp_policy.h
index 33b5d0e..397f8e4 100644
--- a/libc/seccomp/include/seccomp_policy.h
+++ b/libc/seccomp/include/seccomp_policy.h
@@ -17,6 +17,10 @@
#ifndef SECCOMP_POLICY_H
#define SECCOMP_POLICY_H
+#include <stddef.h>
+#include <linux/filter.h>
+
bool set_seccomp_filter();
+void get_seccomp_filter(const sock_filter*& filter, size_t& filter_size);
#endif
diff --git a/libc/seccomp/mips64_policy.cpp b/libc/seccomp/mips64_policy.cpp
index 9439922..92f175a 100644
--- a/libc/seccomp/mips64_policy.cpp
+++ b/libc/seccomp/mips64_policy.cpp
@@ -5,7 +5,7 @@
#include "seccomp_bpfs.h"
const sock_filter mips64_filter[] = {
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5000, 0, 77),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5000, 0, 78),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5168, 39, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5077, 19, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5034, 9, 0),
diff --git a/libc/seccomp/mips_policy.cpp b/libc/seccomp/mips_policy.cpp
index d2c7515..01323ce 100644
--- a/libc/seccomp/mips_policy.cpp
+++ b/libc/seccomp/mips_policy.cpp
@@ -5,99 +5,97 @@
#include "seccomp_bpfs.h"
const sock_filter mips_filter[] = {
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4001, 0, 109),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4136, 55, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4001, 0, 108),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4131, 53, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4064, 27, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4036, 13, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4023, 7, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4010, 3, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4008, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4007, 103, 102), //exit|fork|read|write|open|close
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4009, 102, 101), //creat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4007, 101, 100), //exit|fork|read|write|open|close
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4009, 100, 99), //creat
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4019, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4013, 100, 99), //unlink|execve|chdir
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4022, 99, 98), //lseek|getpid|mount
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4013, 98, 97), //unlink|execve|chdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4022, 97, 96), //lseek|getpid|mount
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4033, 3, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4026, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4025, 96, 95), //setuid|getuid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4027, 95, 94), //ptrace
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4034, 94, 93), //access
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4025, 94, 93), //setuid|getuid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4027, 93, 92), //ptrace
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4034, 92, 91), //access
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4054, 7, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4045, 3, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4041, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4038, 90, 89), //sync|kill
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4044, 89, 88), //dup|pipe|times
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4039, 88, 87), //sync|kill|rename
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4044, 87, 86), //dup|pipe|times
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4049, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4048, 87, 86), //brk|setgid|getgid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4053, 86, 85), //geteuid|getegid|acct|umount2
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4048, 85, 84), //brk|setgid|getgid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4053, 84, 83), //geteuid|getegid|acct|umount2
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4060, 3, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4057, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4056, 83, 82), //ioctl|fcntl
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4058, 82, 81), //setpgid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4062, 81, 80), //umask|chroot
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4056, 81, 80), //ioctl|fcntl
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4058, 80, 79), //setpgid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4062, 79, 78), //umask|chroot
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4094, 13, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4085, 7, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4070, 3, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4066, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4065, 76, 75), //getppid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4068, 75, 74), //setsid|sigaction
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4065, 74, 73), //getppid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4068, 73, 72), //setsid|sigaction
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4074, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4072, 73, 72), //setreuid|setregid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4082, 72, 71), //sethostname|setrlimit|getrlimit|getrusage|gettimeofday|settimeofday|getgroups|setgroups
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4072, 71, 70), //setreuid|setregid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4082, 70, 69), //sethostname|setrlimit|getrlimit|getrusage|gettimeofday|settimeofday|getgroups|setgroups
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4091, 3, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4087, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4086, 69, 68), //readlink
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4089, 68, 67), //swapon|reboot
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4093, 67, 66), //munmap|truncate
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4124, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4086, 67, 66), //readlink
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4089, 66, 65), //swapon|reboot
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4093, 65, 64), //munmap|truncate
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4118, 5, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4114, 3, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4103, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4098, 63, 62), //fchmod|fchown|getpriority|setpriority
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4106, 62, 61), //syslog|setitimer|getitimer
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4118, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4117, 60, 59), //wait4|swapoff|sysinfo
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4123, 59, 58), //fsync|sigreturn|clone|setdomainname|uname
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4131, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4128, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4126, 56, 55), //adjtimex|mprotect
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4130, 55, 54), //init_module|delete_module
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4134, 54, 53), //quotactl|getpgid|fchdir
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4246, 27, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4179, 13, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4154, 7, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4143, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4138, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4137, 48, 47), //personality
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4142, 47, 46), //setfsuid|setfsgid|_llseek|getdents
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4151, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4148, 45, 44), //flock|msync|readv|writev|cacheflush
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4153, 44, 43), //getsid|fdatasync
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4176, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4169, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4168, 41, 40), //mlock|munlock|mlockall|munlockall|sched_setparam|sched_getparam|sched_setscheduler|sched_getscheduler|sched_yield|sched_get_priority_max|sched_get_priority_min|sched_rr_get_interval|nanosleep|mremap
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4175, 40, 39), //bind|connect|getpeername|getsockname|getsockopt|listen
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4178, 39, 38), //recvfrom|recvmsg
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4210, 7, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4190, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4188, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4187, 35, 34), //sendmsg|sendto|setsockopt|shutdown|socket|socketpair|setresuid|getresuid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4189, 34, 33), //poll
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4203, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4202, 32, 31), //setresgid|getresgid|prctl|rt_sigreturn|rt_sigaction|rt_sigprocmask|rt_sigpending|rt_sigtimedwait|rt_sigqueueinfo|rt_sigsuspend|pread64|pwrite64
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4208, 31, 30), //getcwd|capget|capset|sigaltstack|sendfile
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4222, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4217, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4216, 28, 27), //mmap2|truncate64|ftruncate64|stat64|lstat64|fstat64
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4221, 27, 26), //mincore|madvise|getdents64|fcntl64
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4241, 26, 25), //gettid|readahead|setxattr|lsetxattr|fsetxattr|getxattr|lgetxattr|fgetxattr|listxattr|llistxattr|flistxattr|removexattr|lremovexattr|fremovexattr|tkill|sendfile64|futex|sched_setaffinity|sched_getaffinity
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4098, 61, 60), //fchmod|fchown|getpriority|setpriority
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4106, 60, 59), //syslog|setitimer|getitimer
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4117, 59, 58), //wait4|swapoff|sysinfo
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4128, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4124, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4123, 56, 55), //fsync|sigreturn|clone|setdomainname|uname
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4126, 55, 54), //adjtimex|mprotect
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4130, 54, 53), //init_module|delete_module
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4222, 27, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4176, 13, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4151, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4138, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4136, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4134, 48, 47), //quotactl|getpgid|fchdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4137, 47, 46), //personality
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4143, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4142, 45, 44), //setfsuid|setfsgid|_llseek|getdents
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4148, 44, 43), //flock|msync|readv|writev|cacheflush
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4169, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4154, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4153, 41, 40), //getsid|fdatasync
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4168, 40, 39), //mlock|munlock|mlockall|munlockall|sched_setparam|sched_getparam|sched_setscheduler|sched_getscheduler|sched_yield|sched_get_priority_max|sched_get_priority_min|sched_rr_get_interval|nanosleep|mremap
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4175, 39, 38), //bind|connect|getpeername|getsockname|getsockopt|listen
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4203, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4188, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4179, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4178, 35, 34), //recvfrom|recvmsg
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4187, 34, 33), //sendmsg|sendto|setsockopt|shutdown|socket|socketpair|setresuid|getresuid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4190, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4189, 32, 31), //poll
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4202, 31, 30), //setresgid|getresgid|prctl|rt_sigreturn|rt_sigaction|rt_sigprocmask|rt_sigpending|rt_sigtimedwait|rt_sigqueueinfo|rt_sigsuspend|pread64|pwrite64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4217, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4210, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4208, 28, 27), //getcwd|capget|capset|sigaltstack|sendfile
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4216, 27, 26), //mmap2|truncate64|ftruncate64|stat64|lstat64|fstat64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4221, 26, 25), //mincore|madvise|getdents64|fcntl64
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4312, 13, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4283, 7, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4252, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4248, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4247, 21, 20), //exit_group
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4251, 20, 19), //epoll_create|epoll_ctl|epoll_wait
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4248, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4246, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4241, 21, 20), //gettid|readahead|setxattr|lsetxattr|fsetxattr|getxattr|lgetxattr|fgetxattr|listxattr|llistxattr|flistxattr|removexattr|lremovexattr|fremovexattr|tkill|sendfile64|futex|sched_setaffinity|sched_getaffinity
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4247, 20, 19), //exit_group
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4278, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4267, 18, 17), //set_tid_address|restart_syscall|fadvise64|statfs64|fstatfs64|timer_create|timer_settime|timer_gettime|timer_getoverrun|timer_delete|clock_settime|clock_gettime|clock_getres|clock_nanosleep|tgkill
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4267, 18, 17), //epoll_create|epoll_ctl|epoll_wait|remap_file_pages|set_tid_address|restart_syscall|fadvise64|statfs64|fstatfs64|timer_create|timer_settime|timer_gettime|timer_getoverrun|timer_delete|clock_settime|clock_gettime|clock_getres|clock_nanosleep|tgkill
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4279, 17, 16), //waitid
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4293, 3, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4288, 1, 0),
diff --git a/libc/seccomp/seccomp_policy.cpp b/libc/seccomp/seccomp_policy.cpp
index d93ae1e..fd2179b 100644
--- a/libc/seccomp/seccomp_policy.cpp
+++ b/libc/seccomp/seccomp_policy.cpp
@@ -18,7 +18,6 @@
#include <assert.h>
#include <linux/audit.h>
-#include <linux/filter.h>
#include <linux/seccomp.h>
#include <sys/prctl.h>
@@ -154,3 +153,13 @@
return install_filter(f);
}
+
+void get_seccomp_filter(const sock_filter*& filter, size_t& filter_size) {
+#if defined __aarch64__ || defined __x86_64__ || defined __mips64__
+ filter = primary_filter;
+ filter_size = primary_filter_size;
+#else
+ filter = secondary_filter;
+ filter_size = secondary_filter_size;
+#endif
+}
diff --git a/libc/seccomp/x86_64_policy.cpp b/libc/seccomp/x86_64_policy.cpp
index e1f0aa3..69756c6 100644
--- a/libc/seccomp/x86_64_policy.cpp
+++ b/libc/seccomp/x86_64_policy.cpp
@@ -5,7 +5,7 @@
#include "seccomp_bpfs.h"
const sock_filter x86_64_filter[] = {
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 0, 0, 79),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 0, 0, 80),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 157, 39, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 72, 19, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 32, 9, 0),
diff --git a/libc/seccomp/x86_policy.cpp b/libc/seccomp/x86_policy.cpp
index 00b123b..d9ee17b 100644
--- a/libc/seccomp/x86_policy.cpp
+++ b/libc/seccomp/x86_policy.cpp
@@ -5,111 +5,109 @@
#include "seccomp_bpfs.h"
const sock_filter x86_filter[] = {
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 0, 0, 111),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 0, 0, 110),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 131, 55, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 64, 27, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 36, 13, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 24, 7, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 10, 3, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 8, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 7, 105, 104), //restart_syscall|exit|fork|read|write|open|close
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 9, 104, 103), //creat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 7, 103, 102), //restart_syscall|exit|fork|read|write|open|close
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 9, 102, 101), //creat
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 19, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 13, 102, 101), //unlink|execve|chdir
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 22, 101, 100), //lseek|getpid|mount
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 13, 100, 99), //unlink|execve|chdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 22, 99, 98), //lseek|getpid|mount
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 33, 3, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 26, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 25, 98, 97), //getuid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 27, 97, 96), //ptrace
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 34, 96, 95), //access
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 25, 96, 95), //getuid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 27, 95, 94), //ptrace
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 34, 94, 93), //access
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 54, 7, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 45, 3, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 41, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 38, 92, 91), //sync|kill
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 44, 91, 90), //dup|pipe|times
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 39, 90, 89), //sync|kill|rename
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 44, 89, 88), //dup|pipe|times
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 51, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 46, 89, 88), //brk
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 53, 88, 87), //acct|umount2
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 46, 87, 86), //brk
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 53, 86, 85), //acct|umount2
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 60, 3, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 57, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 56, 85, 84), //ioctl|fcntl
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 58, 84, 83), //setpgid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 62, 83, 82), //umask|chroot
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 56, 83, 82), //ioctl|fcntl
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 58, 82, 81), //setpgid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 62, 81, 80), //umask|chroot
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 94, 13, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 85, 7, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 74, 3, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 66, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 65, 78, 77), //getppid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 68, 77, 76), //setsid|sigaction
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 65, 76, 75), //getppid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 68, 75, 74), //setsid|sigaction
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 77, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 76, 75, 74), //sethostname|setrlimit
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 80, 74, 73), //getrusage|gettimeofday|settimeofday
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 76, 73, 72), //sethostname|setrlimit
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 80, 72, 71), //getrusage|gettimeofday|settimeofday
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 91, 3, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 87, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 86, 71, 70), //readlink
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 89, 70, 69), //swapon|reboot
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 93, 69, 68), //munmap|truncate
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 86, 69, 68), //readlink
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 89, 68, 67), //swapon|reboot
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 93, 67, 66), //munmap|truncate
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 118, 7, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 102, 3, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 96, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 95, 65, 64), //fchmod
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 98, 64, 63), //getpriority|setpriority
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 95, 63, 62), //fchmod
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 98, 62, 61), //getpriority|setpriority
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 114, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 106, 62, 61), //socketcall|syslog|setitimer|getitimer
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 117, 61, 60), //wait4|swapoff|sysinfo
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 106, 60, 59), //socketcall|syslog|setitimer|getitimer
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 117, 59, 58), //wait4|swapoff|sysinfo
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 128, 3, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 124, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 123, 58, 57), //fsync|sigreturn|clone|setdomainname|uname
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 126, 57, 56), //adjtimex|mprotect
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 130, 56, 55), //init_module|delete_module
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 123, 56, 55), //fsync|sigreturn|clone|setdomainname|uname
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 126, 55, 54), //adjtimex|mprotect
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 130, 54, 53), //init_module|delete_module
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 254, 27, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 183, 13, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 150, 7, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 138, 3, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 136, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 134, 50, 49), //quotactl|getpgid|fchdir
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 137, 49, 48), //personality
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 134, 48, 47), //quotactl|getpgid|fchdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 137, 47, 46), //personality
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 143, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 142, 47, 46), //setfsuid|setfsgid|_llseek|getdents
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 149, 46, 45), //flock|msync|readv|writev|getsid|fdatasync
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 142, 45, 44), //setfsuid|setfsgid|_llseek|getdents
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 149, 44, 43), //flock|msync|readv|writev|getsid|fdatasync
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 172, 3, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 168, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 164, 43, 42), //mlock|munlock|mlockall|munlockall|sched_setparam|sched_getparam|sched_setscheduler|sched_getscheduler|sched_yield|sched_get_priority_max|sched_get_priority_min|sched_rr_get_interval|nanosleep|mremap
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 169, 42, 41), //poll
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 182, 41, 40), //prctl|rt_sigreturn|rt_sigaction|rt_sigprocmask|rt_sigpending|rt_sigtimedwait|rt_sigqueueinfo|rt_sigsuspend|pread64|pwrite64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 164, 41, 40), //mlock|munlock|mlockall|munlockall|sched_setparam|sched_getparam|sched_setscheduler|sched_getscheduler|sched_yield|sched_get_priority_max|sched_get_priority_min|sched_rr_get_interval|nanosleep|mremap
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 169, 40, 39), //poll
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 182, 39, 38), //prctl|rt_sigreturn|rt_sigaction|rt_sigprocmask|rt_sigpending|rt_sigtimedwait|rt_sigqueueinfo|rt_sigsuspend|pread64|pwrite64
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 218, 7, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 199, 3, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 190, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 188, 37, 36), //getcwd|capget|capset|sigaltstack|sendfile
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 198, 36, 35), //vfork|ugetrlimit|mmap2|truncate64|ftruncate64|stat64|lstat64|fstat64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 188, 35, 34), //getcwd|capget|capset|sigaltstack|sendfile
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 198, 34, 33), //vfork|ugetrlimit|mmap2|truncate64|ftruncate64|stat64|lstat64|fstat64
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 213, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 212, 34, 33), //getuid32|getgid32|geteuid32|getegid32|setreuid32|setregid32|getgroups32|setgroups32|fchown32|setresuid32|getresuid32|setresgid32|getresgid32
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 215, 33, 32), //setuid32|setgid32
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 212, 32, 31), //getuid32|getgid32|geteuid32|getegid32|setreuid32|setregid32|getgroups32|setgroups32|fchown32|setresuid32|getresuid32|setresgid32|getresgid32
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 215, 31, 30), //setuid32|setgid32
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 252, 3, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 224, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 222, 30, 29), //mincore|madvise|getdents64|fcntl64
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 244, 29, 28), //gettid|readahead|setxattr|lsetxattr|fsetxattr|getxattr|lgetxattr|fgetxattr|listxattr|llistxattr|flistxattr|removexattr|lremovexattr|fremovexattr|tkill|sendfile64|futex|sched_setaffinity|sched_getaffinity|set_thread_area
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 253, 28, 27), //exit_group
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 313, 13, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 291, 7, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 272, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 258, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 257, 23, 22), //epoll_create|epoll_ctl|epoll_wait
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 271, 22, 21), //set_tid_address|timer_create|timer_settime|timer_gettime|timer_getoverrun|timer_delete|clock_settime|clock_gettime|clock_getres|clock_nanosleep|statfs64|fstatfs64|tgkill
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 284, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 222, 28, 27), //mincore|madvise|getdents64|fcntl64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 244, 27, 26), //gettid|readahead|setxattr|lsetxattr|fsetxattr|getxattr|lgetxattr|fgetxattr|listxattr|llistxattr|flistxattr|removexattr|lremovexattr|fremovexattr|tkill|sendfile64|futex|sched_setaffinity|sched_getaffinity|set_thread_area
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 253, 26, 25), //exit_group
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 318, 13, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 295, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 284, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 272, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 271, 21, 20), //epoll_create|epoll_ctl|epoll_wait|remap_file_pages|set_tid_address|timer_create|timer_settime|timer_gettime|timer_getoverrun|timer_delete|clock_settime|clock_gettime|clock_getres|clock_nanosleep|statfs64|fstatfs64|tgkill
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 273, 20, 19), //fadvise64_64
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 285, 19, 18), //waitid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 300, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 295, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 294, 16, 15), //inotify_init|inotify_add_watch|inotify_rm_watch
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 299, 15, 14), //openat|mkdirat|mknodat|fchownat
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 311, 14, 13), //fstatat64|unlinkat|renameat|linkat|symlinkat|readlinkat|fchmodat|faccessat|pselect6|ppoll|unshare
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 343, 7, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 322, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 318, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 317, 10, 9), //splice|sync_file_range|tee|vmsplice
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 321, 9, 8), //getcpu|epoll_pwait|utimensat
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 340, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 291, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 285, 18, 17), //waitid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 294, 17, 16), //inotify_init|inotify_add_watch|inotify_rm_watch
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 313, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 300, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 299, 14, 13), //openat|mkdirat|mknodat|fchownat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 311, 13, 12), //fstatat64|unlinkat|renameat|linkat|symlinkat|readlinkat|fchmodat|faccessat|pselect6|ppoll|unshare
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 317, 12, 11), //splice|sync_file_range|tee|vmsplice
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 343, 5, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 340, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 322, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 321, 8, 7), //getcpu|epoll_pwait|utimensat
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 337, 7, 6), //timerfd_create|eventfd|fallocate|timerfd_settime|timerfd_gettime|signalfd4|eventfd2|epoll_create1|dup3|pipe2|inotify_init1|preadv|pwritev|rt_tgsigqueueinfo|perf_event_open
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 341, 6, 5), //prlimit64
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 354, 3, 0),
diff --git a/libc/tools/genseccomp.py b/libc/tools/genseccomp.py
index d9e0819..a8e551e 100755
--- a/libc/tools/genseccomp.py
+++ b/libc/tools/genseccomp.py
@@ -149,13 +149,14 @@
bpf[i] = statement.format(fail=str(len(bpf) - i),
allow=str(len(bpf) - i - 1))
- # Add check that we aren't off the bottom of the syscalls
- bpf.insert(0, BPF_JGE.format(ranges[0].begin, 0, str(len(bpf))) + ',')
# Add the allow calls at the end. If the syscall is not matched, we will
# continue. This allows the user to choose to match further syscalls, and
# also to choose the action when we want to block
bpf.append(BPF_ALLOW + ",")
+
+ # Add check that we aren't off the bottom of the syscalls
+ bpf.insert(0, BPF_JGE.format(ranges[0].begin, 0, str(len(bpf))) + ',')
return bpf
diff --git a/libc/tools/test_genseccomp.py b/libc/tools/test_genseccomp.py
index 19672a1..73f768d 100755
--- a/libc/tools/test_genseccomp.py
+++ b/libc/tools/test_genseccomp.py
@@ -113,13 +113,13 @@
def test_convert_ranges_to_bpf(self):
ranges = genseccomp.convert_NRs_to_ranges([("b", 2), ("a", 1)])
bpf = genseccomp.convert_ranges_to_bpf(ranges)
- self.assertEquals(bpf, ['BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 1, 0, 1),',
+ self.assertEquals(bpf, ['BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 1, 0, 2),',
'BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 3, 1, 0), //a|b',
'BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),'])
ranges = genseccomp.convert_NRs_to_ranges([("b", 3), ("a", 1)])
bpf = genseccomp.convert_ranges_to_bpf(ranges)
- self.assertEquals(bpf, ['BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 1, 0, 3),',
+ self.assertEquals(bpf, ['BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 1, 0, 4),',
'BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 3, 1, 0),',
'BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 2, 2, 1), //a',
'BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4, 1, 0), //b',
@@ -165,7 +165,7 @@
#include "seccomp_bpfs.h"
const sock_filter arm_filter[] = {
- BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 3, 0, 3),
+ BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 3, 0, 4),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 140, 1, 0),
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4, 2, 1), //read
BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 141, 1, 0), //_llseek
diff --git a/libc/versioner-dependencies/arm/arch-arm b/libc/versioner-dependencies/arm/arch-arm
new file mode 120000
index 0000000..cc94225
--- /dev/null
+++ b/libc/versioner-dependencies/arm/arch-arm
@@ -0,0 +1 @@
+../../arch-arm/include/
\ No newline at end of file
diff --git a/libc/versioner-dependencies/arm/kernel_uapi_asm-arm b/libc/versioner-dependencies/arm/kernel_uapi_asm-arm
new file mode 120000
index 0000000..3c7584d
--- /dev/null
+++ b/libc/versioner-dependencies/arm/kernel_uapi_asm-arm
@@ -0,0 +1 @@
+../../kernel/uapi/asm-arm
\ No newline at end of file
diff --git a/libc/versioner-dependencies/arm64/arch-arm64 b/libc/versioner-dependencies/arm64/arch-arm64
new file mode 120000
index 0000000..2d9128a
--- /dev/null
+++ b/libc/versioner-dependencies/arm64/arch-arm64
@@ -0,0 +1 @@
+../../arch-arm64/include/
\ No newline at end of file
diff --git a/libc/versioner-dependencies/arm64/kernel_uapi_asm-arm64 b/libc/versioner-dependencies/arm64/kernel_uapi_asm-arm64
new file mode 120000
index 0000000..7ee6fd2
--- /dev/null
+++ b/libc/versioner-dependencies/arm64/kernel_uapi_asm-arm64
@@ -0,0 +1 @@
+../../kernel/uapi/asm-arm64
\ No newline at end of file
diff --git a/libc/versioner-dependencies/common/clang-builtins b/libc/versioner-dependencies/common/clang-builtins
new file mode 120000
index 0000000..7bd481c
--- /dev/null
+++ b/libc/versioner-dependencies/common/clang-builtins
@@ -0,0 +1 @@
+../../../../external/clang/lib/Headers/
\ No newline at end of file
diff --git a/libc/versioner-dependencies/common/kernel_android_uapi b/libc/versioner-dependencies/common/kernel_android_uapi
new file mode 120000
index 0000000..fd78315
--- /dev/null
+++ b/libc/versioner-dependencies/common/kernel_android_uapi
@@ -0,0 +1 @@
+../../kernel/android/uapi/
\ No newline at end of file
diff --git a/libc/versioner-dependencies/common/kernel_uapi b/libc/versioner-dependencies/common/kernel_uapi
new file mode 120000
index 0000000..d5cb8ee
--- /dev/null
+++ b/libc/versioner-dependencies/common/kernel_uapi
@@ -0,0 +1 @@
+../../kernel/uapi/
\ No newline at end of file
diff --git a/libc/versioner-dependencies/mips/arch-mips b/libc/versioner-dependencies/mips/arch-mips
new file mode 120000
index 0000000..56ed021
--- /dev/null
+++ b/libc/versioner-dependencies/mips/arch-mips
@@ -0,0 +1 @@
+../../arch-mips/include/
\ No newline at end of file
diff --git a/libc/versioner-dependencies/mips/kernel_uapi_asm-mips b/libc/versioner-dependencies/mips/kernel_uapi_asm-mips
new file mode 120000
index 0000000..94bb3db
--- /dev/null
+++ b/libc/versioner-dependencies/mips/kernel_uapi_asm-mips
@@ -0,0 +1 @@
+../../kernel/uapi/asm-mips
\ No newline at end of file
diff --git a/libc/versioner-dependencies/mips64/arch-mips64 b/libc/versioner-dependencies/mips64/arch-mips64
new file mode 120000
index 0000000..4893b57
--- /dev/null
+++ b/libc/versioner-dependencies/mips64/arch-mips64
@@ -0,0 +1 @@
+../../arch-mips64/include/
\ No newline at end of file
diff --git a/libc/versioner-dependencies/mips64/kernel_uapi_asm-mips b/libc/versioner-dependencies/mips64/kernel_uapi_asm-mips
new file mode 120000
index 0000000..94bb3db
--- /dev/null
+++ b/libc/versioner-dependencies/mips64/kernel_uapi_asm-mips
@@ -0,0 +1 @@
+../../kernel/uapi/asm-mips
\ No newline at end of file
diff --git a/libc/versioner-dependencies/x86/arch-x86 b/libc/versioner-dependencies/x86/arch-x86
new file mode 120000
index 0000000..6426384
--- /dev/null
+++ b/libc/versioner-dependencies/x86/arch-x86
@@ -0,0 +1 @@
+../../arch-x86/include/
\ No newline at end of file
diff --git a/libc/versioner-dependencies/x86/kernel_uapi_asm-x86 b/libc/versioner-dependencies/x86/kernel_uapi_asm-x86
new file mode 120000
index 0000000..1b7a73d
--- /dev/null
+++ b/libc/versioner-dependencies/x86/kernel_uapi_asm-x86
@@ -0,0 +1 @@
+../../kernel/uapi/asm-x86/
\ No newline at end of file
diff --git a/libc/versioner-dependencies/x86_64/arch-x86_64 b/libc/versioner-dependencies/x86_64/arch-x86_64
new file mode 120000
index 0000000..684d74e
--- /dev/null
+++ b/libc/versioner-dependencies/x86_64/arch-x86_64
@@ -0,0 +1 @@
+../../arch-x86_64/include/
\ No newline at end of file
diff --git a/libc/versioner-dependencies/x86_64/kernel_uapi_asm-x86 b/libc/versioner-dependencies/x86_64/kernel_uapi_asm-x86
new file mode 120000
index 0000000..1b7a73d
--- /dev/null
+++ b/libc/versioner-dependencies/x86_64/kernel_uapi_asm-x86
@@ -0,0 +1 @@
+../../kernel/uapi/asm-x86/
\ No newline at end of file
diff --git a/libc/zoneinfo/tzdata b/libc/zoneinfo/tzdata
index a2e8da6..c5932bc 100644
--- a/libc/zoneinfo/tzdata
+++ b/libc/zoneinfo/tzdata
Binary files differ
diff --git a/linker/Android.bp b/linker/Android.bp
index a43f8b3..23138cf 100644
--- a/linker/Android.bp
+++ b/linker/Android.bp
@@ -19,6 +19,7 @@
"linker_block_allocator.cpp",
"linker_dlwarning.cpp",
"linker_cfi.cpp",
+ "linker_config.cpp",
"linker_gdb_support.cpp",
"linker_globals.cpp",
"linker_libc_support.c",
@@ -39,35 +40,29 @@
srcs: ["arch/arm/begin.S"],
cflags: ["-D__work_around_b_24465209__"],
- ldflags: ["-Wl,-dynamic-linker,/system/bin/linker"],
},
arm64: {
srcs: ["arch/arm64/begin.S"],
- ldflags: ["-Wl,-dynamic-linker,/system/bin/linker64"],
},
x86: {
srcs: ["arch/x86/begin.c"],
cflags: ["-D__work_around_b_24465209__"],
- ldflags: ["-Wl,-dynamic-linker,/system/bin/linker"],
},
x86_64: {
srcs: ["arch/x86_64/begin.S"],
- ldflags: ["-Wl,-dynamic-linker,/system/bin/linker64"],
},
mips: {
srcs: [
"arch/mips/begin.S",
"linker_mips.cpp",
],
- ldflags: ["-Wl,-dynamic-linker,/system/bin/linker"],
},
mips64: {
srcs: [
"arch/mips64/begin.S",
"linker_mips.cpp",
],
- ldflags: ["-Wl,-dynamic-linker,/system/bin/linker64"],
},
},
diff --git a/linker/dlfcn.cpp b/linker/dlfcn.cpp
index 5ccd656..96dd477 100644
--- a/linker/dlfcn.cpp
+++ b/linker/dlfcn.cpp
@@ -48,6 +48,7 @@
char* old_value = *dlerror_slot;
*dlerror_slot = new_value;
+ LD_LOG(kLogErrors, "%s\n", new_value);
return old_value;
}
diff --git a/linker/ld.config.format.md b/linker/ld.config.format.md
new file mode 100644
index 0000000..686d6be
--- /dev/null
+++ b/linker/ld.config.format.md
@@ -0,0 +1,83 @@
+# Linker config file format
+
+This document describes format of /system/etc/ld.config.txt file. This file can be used to customize
+linker-namespace setup for dynamic executables.
+
+## Overview
+
+The configuration consists of 2 parts
+1. Mappings - maps executable locations to sections
+2. Sections - contains linker-namespace configuration
+
+## Mappings
+
+This part of the document maps location of an executable to a section. Here is an example
+
+The format is `dir.<section_name>=<directory>`
+
+The mappings should be defined between start of ld.config.txt and the first section.
+
+## Section
+
+Every section starts with `[section_name]` (which is used in mappings) and it defines namespaces
+configuration using set of properties described in example below.
+
+## Example
+
+```
+# The following line maps section to a dir. Binraies ran from this location will use namespaces
+# configuration specified in [example_section] below
+dir.example_section=/system/bin/example
+
+# Section starts
+[example_section]
+
+# When this flag is set to true linker will set target_sdk_version for this binary to
+# the version specified in <dirname>/.version file, where <dirname> = dirname(executable_path)
+#
+# default value is false
+enable.target.sdk.version = true
+
+# This property can be used to declare additional namespaces.Note that there is always the default
+# namespace. The default namespace is the namespace for the main executable. This list is
+# comma-separated.
+additional.namespaces = ns1
+
+# Each namespace property starts with "namespace.<namespace-name>" The following is configuration
+# for the default namespace
+
+# Is namespace isolated - the default value is false
+namespace.default.isolated = true
+
+# Default namespace search path. Note that ${LIB} here is substituted with "lib" for 32bit targets
+# and with "lib64" for 64bit ones.
+namespace.default.search.paths = /system/${LIB}:/system/other/${LIB}
+
+# ... same for asan
+namespace.default.asan.search.paths = /data/${LIB}:/data/other/${LIB}
+
+# Permitted path
+namespace.default.permitted.paths = /system/${LIB}
+
+# ... asan
+namespace.default.asan.permitted.paths = /data/${LIB}
+
+# This declares linked namespaces - comma separated list.
+namespace.default.links = ns1
+
+# For every link define list of shared libraries. This is list of the libraries accessilbe from
+# default namespace but loaded in the linked namespace.
+namespace.default.link.ns1.shared_libs = libexternal.so:libother.so
+
+# This part defines config for ns1
+namespace.ns1.isolated = true
+namespace.ns1.search.paths = /vendor/${LIB}
+namespace.ns1.asan.search.paths = /data/vendor/${LIB}
+namespace.ns1.permitted.paths = /vendor/${LIB}
+namespace.ns1.asan.permitted.paths = /data/vendor/${LIB}
+
+# and links it to default namespace
+namespace.ns.links = default
+namespace.ns.link.default.shared_libs = libc.so:libdl.so:libm.so:libstdc++.so
+```
+
diff --git a/linker/linker.cpp b/linker/linker.cpp
index 7b16cc3..60dff98 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -49,6 +49,7 @@
#include "linker.h"
#include "linker_block_allocator.h"
#include "linker_cfi.h"
+#include "linker_config.h"
#include "linker_gdb_support.h"
#include "linker_globals.h"
#include "linker_debug.h"
@@ -77,40 +78,22 @@
static LinkerTypeAllocator<android_namespace_t> g_namespace_allocator;
static LinkerTypeAllocator<LinkedListEntry<android_namespace_t>> g_namespace_list_allocator;
+static const char* const kLdConfigFilePath = "/system/etc/ld.config.txt";
+
#if defined(__LP64__)
-static const char* const kSystemLibDir = "/system/lib64";
-static const char* const kSystemNdkLibDir = "/system/lib64/ndk";
-static const char* const kSystemVndkLibDir = "/system/lib64/vndk";
-static const char* const kSystemVndkExtLibDir = "/system/lib64/vndk-ext";
-static const char* const kVendorSpHalLibDir = "/vendor/lib64/sameprocess";
-static const char* const kVendorLibDir = "/vendor/lib64";
-static const char* const kAsanSystemLibDir = "/data/lib64";
-static const char* const kAsanSystemNdkLibDir = "/data/lib64/ndk";
-static const char* const kAsanSystemVndkLibDir = "/data/lib64/vndk";
-static const char* const kAsanSystemVndkExtLibDir = "/data/lib64/vndk-ext";
-static const char* const kAsanVendorSpHalLibDir = "/data/vendor/lib64/sameprocess";
-static const char* const kAsanVendorLibDir = "/data/vendor/lib64";
+static const char* const kSystemLibDir = "/system/lib64";
+static const char* const kVendorLibDir = "/vendor/lib64";
+static const char* const kAsanSystemLibDir = "/data/lib64";
+static const char* const kAsanVendorLibDir = "/data/vendor/lib64";
#else
-static const char* const kSystemLibDir = "/system/lib";
-static const char* const kSystemNdkLibDir = "/system/lib/ndk";
-static const char* const kSystemVndkLibDir = "/system/lib/vndk";
-static const char* const kSystemVndkExtLibDir = "/system/lib/vndk-ext";
-static const char* const kVendorSpHalLibDir = "/vendor/lib/sameprocess";
-static const char* const kVendorLibDir = "/vendor/lib";
-static const char* const kAsanSystemLibDir = "/data/lib";
-static const char* const kAsanSystemNdkLibDir = "/data/lib/ndk";
-static const char* const kAsanSystemVndkLibDir = "/data/lib/vndk";
-static const char* const kAsanSystemVndkExtLibDir = "/data/lib/vndk-ext";
-static const char* const kAsanVendorSpHalLibDir = "/data/vendor/lib/sameprocess";
-static const char* const kAsanVendorLibDir = "/data/vendor/lib";
+static const char* const kSystemLibDir = "/system/lib";
+static const char* const kVendorLibDir = "/vendor/lib";
+static const char* const kAsanSystemLibDir = "/data/lib";
+static const char* const kAsanVendorLibDir = "/data/vendor/lib";
#endif
static const char* const kDefaultLdPaths[] = {
kSystemLibDir,
- kSystemNdkLibDir,
- kSystemVndkExtLibDir,
- kSystemVndkLibDir,
- kVendorSpHalLibDir,
kVendorLibDir,
nullptr
};
@@ -118,14 +101,6 @@
static const char* const kAsanDefaultLdPaths[] = {
kAsanSystemLibDir,
kSystemLibDir,
- kAsanSystemNdkLibDir,
- kSystemNdkLibDir,
- kAsanSystemVndkExtLibDir,
- kSystemVndkExtLibDir,
- kAsanSystemVndkLibDir,
- kSystemVndkLibDir,
- kAsanVendorSpHalLibDir,
- kVendorSpHalLibDir,
kAsanVendorLibDir,
kVendorLibDir,
nullptr
@@ -1673,6 +1648,8 @@
root = root->get_local_group_root();
}
+ ScopedTrace trace((std::string("unload ") + root->get_realpath()).c_str());
+
if (!root->can_unload()) {
TRACE("not unloading \"%s\" - the binary is flagged with NODELETE", root->get_realpath());
return;
@@ -1861,6 +1838,9 @@
void* do_dlopen(const char* name, int flags,
const android_dlextinfo* extinfo,
const void* caller_addr) {
+ std::string trace_prefix = std::string("dlopen: ") + (name == nullptr ? "(nullptr)" : name);
+ ScopedTrace trace(trace_prefix.c_str());
+ ScopedTrace loading_trace((trace_prefix + " - loading and linking").c_str());
soinfo* const caller = find_containing_library(caller_addr);
android_namespace_t* ns = get_caller_namespace(caller);
@@ -1937,6 +1917,8 @@
ProtectedDataGuard guard;
soinfo* si = find_library(ns, translated_name, flags, extinfo, caller);
+ loading_trace.End();
+
if (si != nullptr) {
void* handle = si->to_handle();
LD_LOG(kLogDlopen,
@@ -1994,6 +1976,7 @@
const char* sym_ver,
const void* caller_addr,
void** symbol) {
+ ScopedTrace trace("dlsym");
#if !defined(__LP64__)
if (handle == nullptr) {
DL_ERR("dlsym failed: library handle is null");
@@ -2069,6 +2052,7 @@
}
int do_dlclose(void* handle) {
+ ScopedTrace trace("dlclose");
ProtectedDataGuard guard;
soinfo* si = soinfo_from_handle(handle);
if (si == nullptr) {
@@ -2097,8 +2081,7 @@
"(anonymous)",
nullptr,
library_search_path,
- // TODO (dimitry): change to isolated eventually.
- ANDROID_NAMESPACE_TYPE_REGULAR,
+ ANDROID_NAMESPACE_TYPE_ISOLATED,
nullptr,
&g_default_namespace);
@@ -3358,21 +3341,9 @@
return true;
}
-void init_default_namespace() {
- g_default_namespace.set_name("(default)");
+static void init_default_namespace_no_config(bool is_asan) {
g_default_namespace.set_isolated(false);
-
- soinfo* somain = solist_get_somain();
-
- const char *interp = phdr_table_get_interpreter_name(somain->phdr, somain->phnum,
- somain->load_bias);
- const char* bname = basename(interp);
-
- bool is_asan = bname != nullptr &&
- (strcmp(bname, "linker_asan") == 0 ||
- strcmp(bname, "linker_asan64") == 0);
auto default_ld_paths = is_asan ? kAsanDefaultLdPaths : kDefaultLdPaths;
- g_is_asan = is_asan;
char real_path[PATH_MAX];
std::vector<std::string> ld_default_paths;
@@ -3385,4 +3356,91 @@
}
g_default_namespace.set_default_library_paths(std::move(ld_default_paths));
-};
+}
+
+void init_default_namespace(const char* executable_path) {
+ g_default_namespace.set_name("(default)");
+
+ soinfo* somain = solist_get_somain();
+
+ const char *interp = phdr_table_get_interpreter_name(somain->phdr, somain->phnum,
+ somain->load_bias);
+ const char* bname = basename(interp);
+
+ g_is_asan = bname != nullptr &&
+ (strcmp(bname, "linker_asan") == 0 ||
+ strcmp(bname, "linker_asan64") == 0);
+
+ const Config* config = nullptr;
+
+ std::string error_msg;
+
+ if (!Config::read_binary_config(kLdConfigFilePath,
+ executable_path,
+ g_is_asan,
+ &config,
+ &error_msg)) {
+ if (!error_msg.empty()) {
+ DL_WARN("error reading config file \"%s\" for \"%s\" (will use default configuration): %s",
+ kLdConfigFilePath,
+ executable_path,
+ error_msg.c_str());
+ }
+ config = nullptr;
+ }
+
+ if (config == nullptr) {
+ init_default_namespace_no_config(g_is_asan);
+ return;
+ }
+
+ const auto& namespace_configs = config->namespace_configs();
+ std::unordered_map<std::string, android_namespace_t*> namespaces;
+
+ // 1. Initialize default namespace
+ const NamespaceConfig* default_ns_config = config->default_namespace_config();
+
+ g_default_namespace.set_isolated(default_ns_config->isolated());
+ g_default_namespace.set_default_library_paths(default_ns_config->search_paths());
+ g_default_namespace.set_permitted_paths(default_ns_config->permitted_paths());
+
+ namespaces[default_ns_config->name()] = &g_default_namespace;
+
+ // 2. Initialize other namespaces
+
+ for (auto& ns_config : namespace_configs) {
+ if (namespaces.find(ns_config->name()) != namespaces.end()) {
+ continue;
+ }
+
+ android_namespace_t* ns = new (g_namespace_allocator.alloc()) android_namespace_t();
+ ns->set_name(ns_config->name());
+ ns->set_isolated(ns_config->isolated());
+ ns->set_default_library_paths(ns_config->search_paths());
+ ns->set_permitted_paths(ns_config->permitted_paths());
+
+ namespaces[ns_config->name()] = ns;
+ }
+
+ // 3. Establish links between namespaces
+ for (auto& ns_config : namespace_configs) {
+ auto it_from = namespaces.find(ns_config->name());
+ CHECK(it_from != namespaces.end());
+ android_namespace_t* namespace_from = it_from->second;
+ for (const NamespaceLinkConfig& ns_link : ns_config->links()) {
+ auto it_to = namespaces.find(ns_link.ns_name());
+ CHECK(it_to != namespaces.end());
+ android_namespace_t* namespace_to = it_to->second;
+ link_namespaces(namespace_from, namespace_to, ns_link.shared_libs().c_str());
+ }
+ }
+ // we can no longer rely on the fact that libdl.so is part of default namespace
+ // this is why we want to add ld-android.so to all namespaces from ld.config.txt
+ soinfo* ld_android_so = solist_get_head();
+ for (auto it : namespaces) {
+ it.second->add_soinfo(ld_android_so);
+ // TODO (dimitry): somain and ld_preloads should probably be added to all of these namespaces too?
+ }
+
+ set_application_target_sdk_version(config->target_sdk_version());
+}
diff --git a/linker/linker_config.cpp b/linker/linker_config.cpp
new file mode 100644
index 0000000..33616f7
--- /dev/null
+++ b/linker/linker_config.cpp
@@ -0,0 +1,487 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "linker_config.h"
+
+#include "linker_globals.h"
+#include "linker_debug.h"
+#include "linker_utils.h"
+
+#include <android-base/file.h>
+#include <android-base/strings.h>
+
+#include <private/ScopeGuard.h>
+
+#include <stdlib.h>
+
+#include <string>
+#include <unordered_map>
+
+class ConfigParser {
+ public:
+ enum {
+ kProperty,
+ kSection,
+ kEndOfFile,
+ kError,
+ };
+
+ explicit ConfigParser(std::string&& content)
+ : content_(content), p_(0), lineno_(0), was_end_of_file_(false) {}
+
+ /*
+ * Possible return values
+ * kProperty: name is set to property name and value is set to property value
+ * kSection: name is set to section name.
+ * kEndOfFile: reached end of file.
+ * kError: error_msg is set.
+ */
+ int next_token(std::string* name, std::string* value, std::string* error_msg) {
+ std::string line;
+ while(NextLine(&line)) {
+ size_t found = line.find('#');
+ line = android::base::Trim(line.substr(0, found));
+
+ if (line.empty()) {
+ continue;
+ }
+
+ if (line[0] == '[' && line[line.size() - 1] == ']') {
+ *name = line.substr(1, line.size() - 2);
+ return kSection;
+ }
+
+ found = line.find('=');
+ if (found == std::string::npos) {
+ *error_msg = std::string("invalid format: ") +
+ line +
+ ", expected \"name = property\" or \"[section]\"";
+ return kError;
+ }
+
+ *name = android::base::Trim(line.substr(0, found));
+ *value = android::base::Trim(line.substr(found + 1));
+ return kProperty;
+ }
+
+ // to avoid infinite cycles when programmer makes a mistake
+ CHECK(!was_end_of_file_);
+ was_end_of_file_ = true;
+ return kEndOfFile;
+ }
+
+ size_t lineno() const {
+ return lineno_;
+ }
+
+ private:
+ bool NextLine(std::string* line) {
+ if (p_ == std::string::npos) {
+ return false;
+ }
+
+ size_t found = content_.find('\n', p_);
+ if (found != std::string::npos) {
+ *line = content_.substr(p_, found - p_);
+ p_ = found + 1;
+ } else {
+ *line = content_.substr(p_);
+ p_ = std::string::npos;
+ }
+
+ lineno_++;
+ return true;
+ }
+
+ std::string content_;
+ size_t p_;
+ size_t lineno_;
+ bool was_end_of_file_;
+
+ DISALLOW_IMPLICIT_CONSTRUCTORS(ConfigParser);
+};
+
+class PropertyValue {
+ public:
+ PropertyValue() = default;
+
+ PropertyValue(std::string&& value, size_t lineno)
+ : value_(value), lineno_(lineno) {}
+
+ const std::string& value() const {
+ return value_;
+ }
+
+ size_t lineno() const {
+ return lineno_;
+ }
+
+ private:
+ std::string value_;
+ size_t lineno_;
+};
+
+static std::string create_error_msg(const char* file,
+ size_t lineno,
+ const std::string& msg) {
+ char buf[1024];
+ __libc_format_buffer(buf, sizeof(buf), "%s:%zu: error: %s", file, lineno, msg.c_str());
+
+ return std::string(buf);
+}
+
+static bool parse_config_file(const char* ld_config_file_path,
+ const char* binary_realpath,
+ std::unordered_map<std::string, PropertyValue>* properties,
+ std::string* error_msg) {
+ std::string content;
+ if (!android::base::ReadFileToString(ld_config_file_path, &content)) {
+ if (errno != ENOENT) {
+ *error_msg = std::string("error reading file \"") +
+ ld_config_file_path + "\": " + strerror(errno);
+ }
+ return false;
+ }
+
+ ConfigParser cp(std::move(content));
+
+ std::string section_name;
+
+ while(true) {
+ std::string name;
+ std::string value;
+ std::string error;
+
+ int result = cp.next_token(&name, &value, &error);
+ if (result == ConfigParser::kError) {
+ DL_WARN("error parsing %s:%zd: %s (ignoring this line)",
+ ld_config_file_path,
+ cp.lineno(),
+ error.c_str());
+ continue;
+ }
+
+ if (result == ConfigParser::kSection || result == ConfigParser::kEndOfFile) {
+ return false;
+ }
+
+ if (result == ConfigParser::kProperty) {
+ if (!android::base::StartsWith(name, "dir.")) {
+ DL_WARN("error parsing %s:%zd: unexpected property name \"%s\", "
+ "expected format dir.<section_name> (ignoring this line)",
+ ld_config_file_path,
+ cp.lineno(),
+ name.c_str());
+ continue;
+ }
+
+ // remove trailing '/'
+ while (value[value.size() - 1] == '/') {
+ value = value.substr(0, value.size() - 1);
+ }
+
+ if (value.empty()) {
+ DL_WARN("error parsing %s:%zd: property value is empty (ignoring this line)",
+ ld_config_file_path,
+ cp.lineno());
+ continue;
+ }
+
+ if (file_is_under_dir(binary_realpath, value)) {
+ section_name = name.substr(4);
+ break;
+ }
+ }
+ }
+
+ // skip everything until we meet a correct section
+ while (true) {
+ std::string name;
+ std::string value;
+ std::string error;
+
+ int result = cp.next_token(&name, &value, &error);
+
+ if (result == ConfigParser::kSection && name == section_name) {
+ break;
+ }
+
+ if (result == ConfigParser::kEndOfFile) {
+ *error_msg = create_error_msg(ld_config_file_path,
+ cp.lineno(),
+ std::string("section \"") + section_name + "\" not found");
+ return false;
+ }
+ }
+
+ // found the section - parse it
+ while (true) {
+ std::string name;
+ std::string value;
+ std::string error;
+
+ int result = cp.next_token(&name, &value, &error);
+
+ if (result == ConfigParser::kEndOfFile || result == ConfigParser::kSection) {
+ break;
+ }
+
+ if (result == ConfigParser::kProperty) {
+ if (properties->find(name) != properties->end()) {
+ DL_WARN("%s:%zd: warning: property \"%s\" redefinition",
+ ld_config_file_path,
+ cp.lineno(),
+ name.c_str());
+ }
+
+ (*properties)[name] = PropertyValue(std::move(value), cp.lineno());
+ }
+
+ if (result == ConfigParser::kError) {
+ DL_WARN("error parsing %s:%zd: %s (ignoring this line)",
+ ld_config_file_path,
+ cp.lineno(),
+ error.c_str());
+ continue;
+ }
+ }
+
+ return true;
+}
+
+static Config g_config;
+
+static constexpr const char* kDefaultConfigName = "default";
+static constexpr const char* kPropertyAdditionalNamespaces = "additional.namespaces";
+#if defined(__LP64__)
+static constexpr const char* kLibParamValue = "lib64";
+#else
+static constexpr const char* kLibParamValue = "lib";
+#endif
+
+class Properties {
+ public:
+ explicit Properties(std::unordered_map<std::string, PropertyValue>&& properties)
+ : properties_(properties), target_sdk_version_(__ANDROID_API__) {}
+
+ std::vector<std::string> get_strings(const std::string& name, size_t* lineno = nullptr) const {
+ auto it = find_property(name, lineno);
+ if (it == properties_.end()) {
+ // return empty vector
+ return std::vector<std::string>();
+ }
+
+ std::vector<std::string> strings = android::base::Split(it->second.value(), ",");
+
+ for (size_t i = 0; i < strings.size(); ++i) {
+ strings[i] = android::base::Trim(strings[i]);
+ }
+
+ return strings;
+ }
+
+ bool get_bool(const std::string& name, size_t* lineno = nullptr) const {
+ auto it = find_property(name, lineno);
+ if (it == properties_.end()) {
+ return false;
+ }
+
+ return it->second.value() == "true";
+ }
+
+ std::string get_string(const std::string& name, size_t* lineno = nullptr) const {
+ auto it = find_property(name, lineno);
+ return (it == properties_.end()) ? "" : it->second.value();
+ }
+
+ std::vector<std::string> get_paths(const std::string& name, size_t* lineno = nullptr) {
+ std::string paths_str = get_string(name, lineno);
+
+ std::vector<std::string> paths;
+ split_path(paths_str.c_str(), ":", &paths);
+
+ std::vector<std::pair<std::string, std::string>> params;
+ params.push_back({ "LIB", kLibParamValue });
+ if (target_sdk_version_ != 0) {
+ char buf[16];
+ __libc_format_buffer(buf, sizeof(buf), "%d", target_sdk_version_);
+ params.push_back({ "SDK_VER", buf });
+ }
+
+ for (auto&& path : paths) {
+ format_string(&path, params);
+ }
+
+ std::vector<std::string> resolved_paths;
+
+ // do not remove paths that do not exist
+ resolve_paths(paths, &resolved_paths);
+
+ return resolved_paths;
+ }
+
+ void set_target_sdk_version(int target_sdk_version) {
+ target_sdk_version_ = target_sdk_version;
+ }
+
+ private:
+ std::unordered_map<std::string, PropertyValue>::const_iterator
+ find_property(const std::string& name, size_t* lineno) const {
+ auto it = properties_.find(name);
+ if (it != properties_.end() && lineno != nullptr) {
+ *lineno = it->second.lineno();
+ }
+
+ return it;
+ }
+ std::unordered_map<std::string, PropertyValue> properties_;
+ int target_sdk_version_;
+
+ DISALLOW_IMPLICIT_CONSTRUCTORS(Properties);
+};
+
+bool Config::read_binary_config(const char* ld_config_file_path,
+ const char* binary_realpath,
+ bool is_asan,
+ const Config** config,
+ std::string* error_msg) {
+ g_config.clear();
+
+ std::unordered_map<std::string, PropertyValue> property_map;
+ if (!parse_config_file(ld_config_file_path, binary_realpath, &property_map, error_msg)) {
+ return false;
+ }
+
+ Properties properties(std::move(property_map));
+
+ auto failure_guard = make_scope_guard([] {
+ g_config.clear();
+ });
+
+ std::unordered_map<std::string, NamespaceConfig*> namespace_configs;
+
+ namespace_configs[kDefaultConfigName] = g_config.create_namespace_config(kDefaultConfigName);
+
+ std::vector<std::string> additional_namespaces = properties.get_strings(kPropertyAdditionalNamespaces);
+ for (const auto& name : additional_namespaces) {
+ namespace_configs[name] = g_config.create_namespace_config(name);
+ }
+
+ bool versioning_enabled = properties.get_bool("enable.target.sdk.version");
+ int target_sdk_version = __ANDROID_API__;
+ if (versioning_enabled) {
+ std::string version_file = dirname(binary_realpath) + "/.version";
+ std::string content;
+ if (!android::base::ReadFileToString(version_file, &content)) {
+ if (errno != ENOENT) {
+ *error_msg = std::string("error reading version file \"") +
+ version_file + "\": " + strerror(errno);
+ return false;
+ }
+ } else {
+ content = android::base::Trim(content);
+ errno = 0;
+ char* end = nullptr;
+ const char* content_str = content.c_str();
+ int result = strtol(content_str, &end, 10);
+ if (errno == 0 && *end == '\0' && result > 0) {
+ target_sdk_version = result;
+ properties.set_target_sdk_version(target_sdk_version);
+ } else {
+ *error_msg = std::string("invalid version \"") + version_file + "\": \"" + content +"\"";
+ return false;
+ }
+ }
+ }
+
+ g_config.set_target_sdk_version(target_sdk_version);
+
+ for (auto ns_config_it : namespace_configs) {
+ auto& name = ns_config_it.first;
+ NamespaceConfig* ns_config = ns_config_it.second;
+
+ std::string property_name_prefix = std::string("namespace.") + name;
+
+ size_t lineno = 0;
+ std::vector<std::string> linked_namespaces =
+ properties.get_strings(property_name_prefix + ".links", &lineno);
+
+ for (const auto& linked_ns_name : linked_namespaces) {
+ if (namespace_configs.find(linked_ns_name) == namespace_configs.end()) {
+ *error_msg = create_error_msg(ld_config_file_path,
+ lineno,
+ std::string("undefined namespace: ") + linked_ns_name);
+ return false;
+ }
+
+ std::string shared_libs = properties.get_string(property_name_prefix +
+ ".link." +
+ linked_ns_name +
+ ".shared_libs", &lineno);
+
+ if (shared_libs.empty()) {
+ *error_msg = create_error_msg(ld_config_file_path,
+ lineno,
+ std::string("list of shared_libs for ") +
+ name +
+ "->" +
+ linked_ns_name +
+ " link is not specified or is empty.");
+ return false;
+ }
+
+ ns_config->add_namespace_link(linked_ns_name, shared_libs);
+ }
+
+ ns_config->set_isolated(properties.get_bool(property_name_prefix + ".isolated"));
+
+ // these are affected by is_asan flag
+ if (is_asan) {
+ property_name_prefix += ".asan";
+ }
+
+ ns_config->set_search_paths(properties.get_paths(property_name_prefix + ".search.paths"));
+ ns_config->set_permitted_paths(properties.get_paths(property_name_prefix + ".permitted.paths"));
+ }
+
+ failure_guard.disable();
+ *config = &g_config;
+ return true;
+}
+
+NamespaceConfig* Config::create_namespace_config(const std::string& name) {
+ namespace_configs_.push_back(std::unique_ptr<NamespaceConfig>(new NamespaceConfig(name)));
+ NamespaceConfig* ns_config_ptr = namespace_configs_.back().get();
+ namespace_configs_map_[name] = ns_config_ptr;
+ return ns_config_ptr;
+}
+
+void Config::clear() {
+ namespace_configs_.clear();
+ namespace_configs_map_.clear();
+}
diff --git a/linker/linker_config.h b/linker/linker_config.h
new file mode 100644
index 0000000..4ec8b26
--- /dev/null
+++ b/linker/linker_config.h
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _LINKER_CONFIG_H_
+#define _LINKER_CONFIG_H_
+
+#include <android/api-level.h>
+
+#include <stdlib.h>
+#include <limits.h>
+#include "private/bionic_macros.h"
+
+#include <memory>
+#include <string>
+#include <vector>
+#include <unordered_map>
+
+class NamespaceLinkConfig {
+ public:
+ NamespaceLinkConfig() = default;
+ NamespaceLinkConfig(const std::string& ns_name, const std::string& shared_libs)
+ : ns_name_(ns_name), shared_libs_(shared_libs) {}
+
+ const std::string& ns_name() const {
+ return ns_name_;
+ }
+
+ const std::string& shared_libs() const {
+ return shared_libs_;
+ }
+
+ private:
+ std::string ns_name_;
+ std::string shared_libs_;
+};
+
+class NamespaceConfig {
+ public:
+ explicit NamespaceConfig(const std::string& name)
+ : name_(name), isolated_(false)
+ {}
+
+ const char* name() const {
+ return name_.c_str();
+ }
+
+ bool isolated() const {
+ return isolated_;
+ }
+
+ const std::vector<std::string>& search_paths() const {
+ return search_paths_;
+ }
+
+ const std::vector<std::string>& permitted_paths() const {
+ return permitted_paths_;
+ }
+
+ const std::vector<NamespaceLinkConfig>& links() const {
+ return namespace_links_;
+ }
+
+ void add_namespace_link(const std::string& ns_name, const std::string& shared_libs) {
+ namespace_links_.push_back(NamespaceLinkConfig(ns_name, shared_libs));
+ }
+
+ void set_isolated(bool isolated) {
+ isolated_ = isolated;
+ }
+
+ void set_search_paths(std::vector<std::string>&& search_paths) {
+ search_paths_ = search_paths;
+ }
+
+ void set_permitted_paths(std::vector<std::string>&& permitted_paths) {
+ permitted_paths_ = permitted_paths;
+ }
+ private:
+ const std::string name_;
+ bool isolated_;
+ std::vector<std::string> search_paths_;
+ std::vector<std::string> permitted_paths_;
+ std::vector<NamespaceLinkConfig> namespace_links_;
+
+ DISALLOW_IMPLICIT_CONSTRUCTORS(NamespaceConfig);
+};
+
+class Config {
+ public:
+ Config() : target_sdk_version_(__ANDROID_API__) {}
+
+ const std::vector<std::unique_ptr<NamespaceConfig>>& namespace_configs() const {
+ return namespace_configs_;
+ }
+
+ const NamespaceConfig* default_namespace_config() const {
+ auto it = namespace_configs_map_.find("default");
+ return it == namespace_configs_map_.end() ? nullptr : it->second;
+ }
+
+ uint32_t target_sdk_version() const {
+ return target_sdk_version_;
+ }
+
+ // note that this is one time event and therefore there is no need to
+ // read every section of the config. Every linker instance needs at
+ // most one configuration.
+ // Returns false in case of an error. If binary config was not found
+ // sets *config = nullptr.
+ static bool read_binary_config(const char* ld_config_file_path,
+ const char* binary_realpath,
+ bool is_asan,
+ const Config** config,
+ std::string* error_msg);
+ private:
+ void clear();
+
+ void set_target_sdk_version(uint32_t target_sdk_version) {
+ target_sdk_version_ = target_sdk_version;
+ }
+
+ NamespaceConfig* create_namespace_config(const std::string& name);
+
+ std::vector<std::unique_ptr<NamespaceConfig>> namespace_configs_;
+ std::unordered_map<std::string, NamespaceConfig*> namespace_configs_map_;
+ uint32_t target_sdk_version_;
+
+ DISALLOW_COPY_AND_ASSIGN(Config);
+};
+
+#endif /* _LINKER_CONFIG_H_ */
diff --git a/linker/linker_globals.h b/linker/linker_globals.h
index b6f8a04..e4e3d97 100644
--- a/linker/linker_globals.h
+++ b/linker/linker_globals.h
@@ -38,7 +38,6 @@
do { \
__libc_format_buffer(linker_get_error_buffer(), linker_get_error_buffer_size(), fmt, ##x); \
/* If LD_DEBUG is set high enough, log every dlerror(3) message. */ \
- LD_LOG(kLogErrors, "%s\n", linker_get_error_buffer()); \
} while (false)
#define DL_WARN(fmt, x...) \
diff --git a/linker/linker_logger.h b/linker/linker_logger.h
index 502f872..f37b974 100644
--- a/linker/linker_logger.h
+++ b/linker/linker_logger.h
@@ -32,6 +32,7 @@
#include <stdlib.h>
#include <limits.h>
#include "private/bionic_macros.h"
+#include "private/bionic_systrace.h"
#define LD_LOG(type, x...) \
{ \
diff --git a/linker/linker_main.cpp b/linker/linker_main.cpp
index d037a18..40f82a1 100644
--- a/linker/linker_main.cpp
+++ b/linker/linker_main.cpp
@@ -209,6 +209,8 @@
* and other non-local data at this point.
*/
static ElfW(Addr) __linker_init_post_relocation(KernelArgumentBlock& args, ElfW(Addr) linker_base) {
+ ProtectedDataGuard guard;
+
#if TIMING
struct timeval t0, t1;
gettimeofday(&t0, 0);
@@ -330,7 +332,7 @@
somain = si;
- init_default_namespace();
+ init_default_namespace(executable_path);
if (!si->prelink_image()) {
__libc_fatal("CANNOT LINK EXECUTABLE \"%s\": %s", g_argv[0], linker_get_error_buffer());
@@ -381,19 +383,15 @@
__libc_fatal("CANNOT LINK EXECUTABLE \"%s\": %s", g_argv[0], linker_get_error_buffer());
}
- {
- ProtectedDataGuard guard;
+ si->call_pre_init_constructors();
- si->call_pre_init_constructors();
-
- /* After the prelink_image, the si->load_bias is initialized.
- * For so lib, the map->l_addr will be updated in notify_gdb_of_load.
- * We need to update this value for so exe here. So Unwind_Backtrace
- * for some arch like x86 could work correctly within so exe.
- */
- map->l_addr = si->load_bias;
- si->call_constructors();
- }
+ /* After the prelink_image, the si->load_bias is initialized.
+ * For so lib, the map->l_addr will be updated in notify_gdb_of_load.
+ * We need to update this value for so exe here. So Unwind_Backtrace
+ * for some arch like x86 could work correctly within so exe.
+ */
+ map->l_addr = si->load_bias;
+ si->call_constructors();
#if TIMING
gettimeofday(&t1, nullptr);
@@ -481,26 +479,20 @@
extern "C" ElfW(Addr) __linker_init(void* raw_args) {
KernelArgumentBlock args(raw_args);
- ElfW(Addr) linker_addr = args.getauxval(AT_BASE);
+ // AT_BASE is set to 0 in the case when linker is run by iself
+ // so in order to link the linker it needs to calcuate AT_BASE
+ // using information at hand. The trick below takes advantage
+ // of the fact that the value of linktime_addr before relocations
+ // are run is an offset and this can be used to calculate AT_BASE.
+ static uintptr_t linktime_addr = reinterpret_cast<uintptr_t>(&linktime_addr);
+ ElfW(Addr) linker_addr = reinterpret_cast<uintptr_t>(&linktime_addr) - linktime_addr;
+
ElfW(Addr) entry_point = args.getauxval(AT_ENTRY);
ElfW(Ehdr)* elf_hdr = reinterpret_cast<ElfW(Ehdr)*>(linker_addr);
ElfW(Phdr)* phdr = reinterpret_cast<ElfW(Phdr)*>(linker_addr + elf_hdr->e_phoff);
soinfo linker_so(nullptr, nullptr, nullptr, 0, 0);
- // If the linker is not acting as PT_INTERP entry_point is equal to
- // _start. Which means that the linker is running as an executable and
- // already linked by PT_INTERP.
- //
- // This happens when user tries to run 'adb shell /system/bin/linker'
- // see also https://code.google.com/p/android/issues/detail?id=63174
- if (reinterpret_cast<ElfW(Addr)>(&_start) == entry_point) {
- __libc_format_fd(STDOUT_FILENO,
- "This is %s, the helper program for dynamic executables.\n",
- args.argv[0]);
- exit(0);
- }
-
linker_so.base = linker_addr;
linker_so.size = phdr_table_get_load_size(phdr, elf_hdr->e_phnum);
linker_so.load_bias = get_elf_exec_load_bias(elf_hdr);
@@ -547,6 +539,19 @@
// Initialize the linker's own global variables
linker_so.call_constructors();
+ // If the linker is not acting as PT_INTERP entry_point is equal to
+ // _start. Which means that the linker is running as an executable and
+ // already linked by PT_INTERP.
+ //
+ // This happens when user tries to run 'adb shell /system/bin/linker'
+ // see also https://code.google.com/p/android/issues/detail?id=63174
+ if (reinterpret_cast<ElfW(Addr)>(&_start) == entry_point) {
+ __libc_format_fd(STDOUT_FILENO,
+ "This is %s, the helper program for dynamic executables.\n",
+ args.argv[0]);
+ exit(0);
+ }
+
// Initialize static variables. Note that in order to
// get correct libdl_info we need to call constructors
// before get_libdl_info().
diff --git a/linker/linker_main.h b/linker/linker_main.h
index b68035b..8f3f07c 100644
--- a/linker/linker_main.h
+++ b/linker/linker_main.h
@@ -44,7 +44,7 @@
static size_t ref_count_;
};
-void init_default_namespace();
+void init_default_namespace(const char* executable_path);
soinfo* soinfo_alloc(android_namespace_t* ns, const char* name,
struct stat* file_stat, off64_t file_offset,
uint32_t rtld_flags);
diff --git a/linker/linker_namespaces.h b/linker/linker_namespaces.h
index 868b4a6..e7d9b2e 100644
--- a/linker/linker_namespaces.h
+++ b/linker/linker_namespaces.h
@@ -80,6 +80,9 @@
void set_default_library_paths(std::vector<std::string>&& library_paths) {
default_library_paths_ = library_paths;
}
+ void set_default_library_paths(const std::vector<std::string>& library_paths) {
+ default_library_paths_ = library_paths;
+ }
const std::vector<std::string>& get_permitted_paths() const {
return permitted_paths_;
@@ -87,6 +90,9 @@
void set_permitted_paths(std::vector<std::string>&& permitted_paths) {
permitted_paths_ = permitted_paths;
}
+ void set_permitted_paths(const std::vector<std::string>& permitted_paths) {
+ permitted_paths_ = permitted_paths;
+ }
const std::vector<android_namespace_link_t>& linked_namespaces() const {
return linked_namespaces_;
diff --git a/linker/linker_soinfo.cpp b/linker/linker_soinfo.cpp
index fe3a6fb..1d59dbb 100644
--- a/linker/linker_soinfo.cpp
+++ b/linker/linker_soinfo.cpp
@@ -409,18 +409,25 @@
si->call_constructors();
});
- TRACE("\"%s\": calling constructors", get_realpath());
+ if (!is_linker()) {
+ bionic_trace_begin((std::string("calling constructors: ") + get_realpath()).c_str());
+ }
// DT_INIT should be called before DT_INIT_ARRAY if both are present.
call_function("DT_INIT", init_func_, get_realpath());
call_array("DT_INIT_ARRAY", init_array_, init_array_count_, false, get_realpath());
+
+ if (!is_linker()) {
+ bionic_trace_end();
+ }
}
void soinfo::call_destructors() {
if (!constructors_called) {
return;
}
- TRACE("\"%s\": calling destructors", get_realpath());
+
+ ScopedTrace trace((std::string("calling destructors: ") + get_realpath()).c_str());
// DT_FINI_ARRAY must be parsed in reverse order.
call_array("DT_FINI_ARRAY", fini_array_, fini_array_count_, true, get_realpath());
diff --git a/linker/linker_utils.h b/linker/linker_utils.h
index 740d04b..e104a25 100644
--- a/linker/linker_utils.h
+++ b/linker/linker_utils.h
@@ -46,7 +46,9 @@
// 1. For regular path it converts it to realpath()
// 2. For path in a zip file it uses realpath on the zipfile
// normalizes entry name by calling normalize_path function.
-void resolve_paths(std::vector<std::string>& paths, std::vector<std::string>* resolved_paths);
+void resolve_paths(std::vector<std::string>& paths,
+ std::vector<std::string>* resolved_paths);
+
void split_path(const char* path, const char* delimiters, std::vector<std::string>* paths);
std::string dirname(const char* path);
diff --git a/linker/tests/Android.mk b/linker/tests/Android.mk
index f3810c1..61c43c9 100644
--- a/linker/tests/Android.mk
+++ b/linker/tests/Android.mk
@@ -40,6 +40,7 @@
LOCAL_SRC_FILES := \
linker_block_allocator_test.cpp \
+ linker_config_test.cpp \
linker_globals.cpp \
linked_list_test.cpp \
linker_memory_allocator_test.cpp \
@@ -47,7 +48,8 @@
linker_utils_test.cpp \
../linker_allocator.cpp \
../linker_block_allocator.cpp \
- ../linker_utils.cpp
+ ../linker_config.cpp \
+ ../linker_utils.cpp \
# for __libc_fatal
LOCAL_SRC_FILES += ../../libc/bionic/libc_logging.cpp
diff --git a/linker/tests/linker_config_test.cpp b/linker/tests/linker_config_test.cpp
new file mode 100644
index 0000000..64ab00f
--- /dev/null
+++ b/linker/tests/linker_config_test.cpp
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
+
+#include <gtest/gtest.h>
+
+#include "../linker_config.h"
+
+#include <unistd.h>
+
+#include <android-base/stringprintf.h>
+#include <android-base/file.h>
+#include <android-base/test_utils.h>
+
+#include "private/ScopeGuard.h"
+
+
+static const char* config_str =
+ "# comment \n"
+ "dir.test = /data/local/tmp\n"
+ "\n"
+ "[test]\n"
+ "\n"
+ "enable.target.sdk.version = true\n"
+ "additional.namespaces=system\n"
+ "namespace.default.isolated = true\n"
+ "namespace.default.search.paths = /vendor/${LIB}\n"
+ "namespace.default.permitted.paths = /vendor/${LIB}\n"
+ "namespace.default.asan.search.paths = /data:/vendor/${LIB}\n"
+ "namespace.default.asan.permitted.paths = /data:/vendor\n"
+ "namespace.default.links = system\n"
+ "namespace.default.link.system.shared_libs = libc.so:libm.so:libdl.so:libstdc++.so\n"
+ "namespace.system.isolated = true\n"
+ "namespace.system.search.paths = /system/${LIB}\n"
+ "namespace.system.permitted.paths = /system/${LIB}\n"
+ "namespace.system.asan.search.paths = /data:/system/${LIB}\n"
+ "namespace.system.asan.permitted.paths = /data:/system\n"
+ "\n";
+
+static bool write_version(const std::string& path, uint32_t version) {
+ std::string content = android::base::StringPrintf("%d", version);
+ return android::base::WriteStringToFile(content, path);
+}
+
+static void run_linker_config_smoke_test(bool is_asan) {
+#if defined(__LP64__)
+ const std::vector<std::string> kExpectedDefaultSearchPath = is_asan ?
+ std::vector<std::string>({ "/data", "/vendor/lib64"}) :
+ std::vector<std::string>({ "/vendor/lib64" });
+
+ const std::vector<std::string> kExpectedDefaultPermittedPath = is_asan ?
+ std::vector<std::string>({ "/data", "/vendor" }) :
+ std::vector<std::string>({ "/vendor/lib64" });
+
+ const std::vector<std::string> kExpectedSystemSearchPath = is_asan ?
+ std::vector<std::string>({ "/data", "/system/lib64" }) :
+ std::vector<std::string>({ "/system/lib64" });
+
+ const std::vector<std::string> kExpectedSystemPermittedPath = is_asan ?
+ std::vector<std::string>({ "/data", "/system" }) :
+ std::vector<std::string>({ "/system/lib64" });
+#else
+ const std::vector<std::string> kExpectedDefaultSearchPath = is_asan ?
+ std::vector<std::string>({ "/data", "/vendor/lib"}) :
+ std::vector<std::string>({ "/vendor/lib" });
+
+ const std::vector<std::string> kExpectedDefaultPermittedPath = is_asan ?
+ std::vector<std::string>({ "/data", "/vendor" }) :
+ std::vector<std::string>({ "/vendor/lib" });
+
+ const std::vector<std::string> kExpectedSystemSearchPath = is_asan ?
+ std::vector<std::string>({ "/data", "/system/lib" }) :
+ std::vector<std::string>({ "/system/lib" });
+
+ const std::vector<std::string> kExpectedSystemPermittedPath = is_asan ?
+ std::vector<std::string>({ "/data", "/system" }) :
+ std::vector<std::string>({ "/system/lib" });
+#endif
+
+ TemporaryFile tmp_file;
+ close(tmp_file.fd);
+ tmp_file.fd = -1;
+
+ android::base::WriteStringToFile(config_str, tmp_file.path);
+
+ TemporaryDir tmp_dir;
+
+ std::string executable_path = std::string(tmp_dir.path) + "/some-binary";
+ std::string version_file = std::string(tmp_dir.path) + "/.version";
+
+ auto file_guard = make_scope_guard([&version_file] {
+ unlink(version_file.c_str());
+ });
+
+ ASSERT_TRUE(write_version(version_file, 113U)) << strerror(errno);
+
+ // read config
+ const Config* config = nullptr;
+ std::string error_msg;
+ ASSERT_TRUE(Config::read_binary_config(tmp_file.path,
+ executable_path.c_str(),
+ is_asan,
+ &config,
+ &error_msg)) << error_msg;
+ ASSERT_TRUE(config != nullptr);
+ ASSERT_TRUE(error_msg.empty());
+
+ ASSERT_EQ(113U, config->target_sdk_version());
+
+ const NamespaceConfig* default_ns_config = config->default_namespace_config();
+ ASSERT_TRUE(default_ns_config != nullptr);
+
+ ASSERT_TRUE(default_ns_config->isolated());
+ ASSERT_EQ(kExpectedDefaultSearchPath, default_ns_config->search_paths());
+ ASSERT_EQ(kExpectedDefaultPermittedPath, default_ns_config->permitted_paths());
+
+ const auto& default_ns_links = default_ns_config->links();
+ ASSERT_EQ(1U, default_ns_links.size());
+ ASSERT_EQ("system", default_ns_links[0].ns_name());
+ ASSERT_EQ("libc.so:libm.so:libdl.so:libstdc++.so", default_ns_links[0].shared_libs());
+
+ auto& ns_configs = config->namespace_configs();
+ ASSERT_EQ(2U, ns_configs.size());
+
+ // find second namespace
+ const NamespaceConfig* ns_system = nullptr;
+ for (auto& ns : ns_configs) {
+ std::string ns_name = ns->name();
+ ASSERT_TRUE(ns_name == "system" || ns_name == "default")
+ << "unexpected ns name: " << ns->name();
+
+ if (ns_name == "system") {
+ ns_system = ns.get();
+ }
+ }
+
+ ASSERT_TRUE(ns_system != nullptr) << "system namespace was not found";
+
+ ASSERT_TRUE(ns_system->isolated());
+ ASSERT_EQ(kExpectedSystemSearchPath, ns_system->search_paths());
+ ASSERT_EQ(kExpectedSystemPermittedPath, ns_system->permitted_paths());
+}
+
+TEST(linker_config, smoke) {
+ run_linker_config_smoke_test(false);
+}
+
+TEST(linker_config, asan_smoke) {
+ run_linker_config_smoke_test(true);
+}
diff --git a/tests/dlfcn_test.cpp b/tests/dlfcn_test.cpp
index 0f24170..ad8444e 100644
--- a/tests/dlfcn_test.cpp
+++ b/tests/dlfcn_test.cpp
@@ -1256,7 +1256,7 @@
// Bionic specific tests
#if defined(__BIONIC__)
-#if defined(__arm__) || defined(__i386__)
+#if defined(__arm__)
const llvm::ELF::Elf32_Dyn* to_dynamic_table(const char* p) {
return reinterpret_cast<const llvm::ELF::Elf32_Dyn*>(p);
}
@@ -1320,7 +1320,7 @@
validate_compatibility_of_native_library(path, elf);
}
-// This is a test for app compatibility workaround for arm and x86 apps
+// This is a test for app compatibility workaround for arm apps
// affected by http://b/24465209
TEST(dlext, compat_elf_hash_and_relocation_tables) {
validate_compatibility_of_native_library("libc.so");
@@ -1332,7 +1332,7 @@
validate_compatibility_of_native_library("libjnigraphics.so");
}
-#endif // defined(__arm__) || defined(__i386__)
+#endif // defined(__arm__)
TEST(dlfcn, dt_runpath_absolute_path) {
std::string libpath = get_testlib_root() + "/libtest_dt_runpath_d.so";
diff --git a/tests/stack_unwinding_test.cpp b/tests/stack_unwinding_test.cpp
index afd9e7f..bb58ae4 100644
--- a/tests/stack_unwinding_test.cpp
+++ b/tests/stack_unwinding_test.cpp
@@ -90,15 +90,20 @@
}
static void verify_unwind_data(const UnwindData& unwind_data) {
- EXPECT_GT(unwind_data.handler_frame_count, unwind_data.expected_frame_count);
+ // In order to avoid a false positive, the caller must have at least 2 frames
+ // outside of the signal handler. This avoids a case where the only frame
+ // right after the signal handler winds up being garbage.
+ EXPECT_GT(unwind_data.handler_frame_count, unwind_data.expected_frame_count + 1);
+
EXPECT_EQ(unwind_data.handler_frame_count + 1, unwind_data.handler_one_deeper_frame_count);
}
-TEST(stack_unwinding, unwind_through_signal_frame) {
+static void noinline UnwindTest() {
g_unwind_data = {};
- ScopedSignalHandler ssh(SIGUSR1, UnwindSignalHandler);
_Unwind_Backtrace(FrameCounter, &g_unwind_data.expected_frame_count);
+ ASSERT_LE(2, g_unwind_data.expected_frame_count)
+ << "The current call must contain at least 2 frames for the test to be valid.";
ASSERT_EQ(0, kill(getpid(), SIGUSR1));
while (!g_unwind_data.signal_handler_complete) {}
@@ -106,14 +111,15 @@
verify_unwind_data(g_unwind_data);
}
+TEST(stack_unwinding, unwind_through_signal_frame) {
+ ScopedSignalHandler ssh(SIGUSR1, UnwindSignalHandler);
+
+ UnwindTest();
+}
+
// On LP32, the SA_SIGINFO flag gets you __restore_rt instead of __restore.
TEST(stack_unwinding, unwind_through_signal_frame_SA_SIGINFO) {
- g_unwind_data = {};
ScopedSignalHandler ssh(SIGUSR1, UnwindSignalHandler, SA_SIGINFO);
- _Unwind_Backtrace(FrameCounter, &g_unwind_data.expected_frame_count);
- ASSERT_EQ(0, kill(getpid(), SIGUSR1));
- while (!g_unwind_data.signal_handler_complete) {}
-
- verify_unwind_data(g_unwind_data);
+ UnwindTest();
}
diff --git a/tools/update_headers.sh b/tools/update_headers.sh
deleted file mode 100755
index 0095d50..0000000
--- a/tools/update_headers.sh
+++ /dev/null
@@ -1,53 +0,0 @@
-#!/bin/bash
-DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
-cd $DIR
-
-which versioner >/dev/null 2>&1
-if [ $? -ne 0 ]; then
- >&2 echo "versioner not in path; run mma in $DIR/versioner"
- exit 1
-fi
-
-VERSION=$(git rev-parse --short HEAD)
-git diff-index --quiet HEAD
-DIRTY=$?
-git branch -r --contains HEAD | grep -q aosp/master
-SUBMITTED=$?
-
-if [ $DIRTY -ne 0 ]; then
- >&2 echo "Warning: bionic has uncommitted changes"
- VERSION="${VERSION}-dirty"
-elif [ $SUBMITTED -ne 0 ]; then
- >&2 echo "Warning: current HEAD does not exist in aosp/master"
- VERSION="${VERSION}-unsubmitted"
-fi
-
-PREBUILTS_DIR=$ANDROID_BUILD_TOP/prebuilts/ndk
-BRANCH_NAME=$(git -C $PREBUILTS_DIR symbolic-ref --short -q HEAD)
-if [ $? -ne 0 ]; then
- BRANCH_NAME=update-bionic-headers-$VERSION
- echo "prebuilts/ndk has detached head; creating branch $BRANCH_NAME"
- repo start $BRANCH_NAME $PREBUILTS_DIR
-else
- echo "prebuilts/ndk already on branch $BRANCH_NAME"
-fi
-
-HEADERS_INSTALL=$PREBUILTS_DIR/headers
-if [ -d "$HEADERS_INSTALL" ]; then
- git -C $PREBUILTS_DIR rm -r --ignore-unmatch $HEADERS_INSTALL
- if [ -d $HEADERS_INSTALL ]; then
- rm -r $HEADERS_INSTALL
- fi
-fi
-
-versioner -p versioner/platforms versioner/current versioner/dependencies \
- -o $HEADERS_INSTALL
-if [ $? -ne 0 ]; then
- >&2 echo "Header preprocessing failed"
- exit 1
-fi
-
-cp ../libc/NOTICE $PREBUILTS_DIR
-
-git -C $PREBUILTS_DIR add $HEADERS_INSTALL $PREBUILTS_DIR/NOTICE
-git -C $PREBUILTS_DIR commit -m "Update bionic headers to $VERSION."
diff --git a/tools/versioner/dependencies/arm/arch-arm b/tools/versioner/dependencies/arm/arch-arm
deleted file mode 120000
index ed69f41..0000000
--- a/tools/versioner/dependencies/arm/arch-arm
+++ /dev/null
@@ -1 +0,0 @@
-../../../../libc/arch-arm/include
\ No newline at end of file
diff --git a/tools/versioner/dependencies/arm/kernel_uapi_asm-arm b/tools/versioner/dependencies/arm/kernel_uapi_asm-arm
deleted file mode 120000
index fabed85..0000000
--- a/tools/versioner/dependencies/arm/kernel_uapi_asm-arm
+++ /dev/null
@@ -1 +0,0 @@
-../../../../libc/kernel/uapi/asm-arm
\ No newline at end of file
diff --git a/tools/versioner/dependencies/arm64/arch-arm64 b/tools/versioner/dependencies/arm64/arch-arm64
deleted file mode 120000
index 21a21d4..0000000
--- a/tools/versioner/dependencies/arm64/arch-arm64
+++ /dev/null
@@ -1 +0,0 @@
-../../../../libc/arch-arm64/include
\ No newline at end of file
diff --git a/tools/versioner/dependencies/arm64/kernel_uapi_asm-arm64 b/tools/versioner/dependencies/arm64/kernel_uapi_asm-arm64
deleted file mode 120000
index 16e74a3..0000000
--- a/tools/versioner/dependencies/arm64/kernel_uapi_asm-arm64
+++ /dev/null
@@ -1 +0,0 @@
-../../../../libc/kernel/uapi/asm-arm64
\ No newline at end of file
diff --git a/tools/versioner/dependencies/common/clang-builtins b/tools/versioner/dependencies/common/clang-builtins
deleted file mode 120000
index fc27e65..0000000
--- a/tools/versioner/dependencies/common/clang-builtins
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../external/clang/lib/Headers
\ No newline at end of file
diff --git a/tools/versioner/dependencies/common/kernel_android_uapi b/tools/versioner/dependencies/common/kernel_android_uapi
deleted file mode 120000
index bcf6daa..0000000
--- a/tools/versioner/dependencies/common/kernel_android_uapi
+++ /dev/null
@@ -1 +0,0 @@
-../../../../libc/kernel/android/uapi
\ No newline at end of file
diff --git a/tools/versioner/dependencies/common/kernel_uapi b/tools/versioner/dependencies/common/kernel_uapi
deleted file mode 120000
index 2a915ef..0000000
--- a/tools/versioner/dependencies/common/kernel_uapi
+++ /dev/null
@@ -1 +0,0 @@
-../../../../libc/kernel/uapi
\ No newline at end of file
diff --git a/tools/versioner/dependencies/mips/arch-mips b/tools/versioner/dependencies/mips/arch-mips
deleted file mode 120000
index 7f2f104..0000000
--- a/tools/versioner/dependencies/mips/arch-mips
+++ /dev/null
@@ -1 +0,0 @@
-../../../../libc/arch-mips/include
\ No newline at end of file
diff --git a/tools/versioner/dependencies/mips/kernel_uapi_asm-mips b/tools/versioner/dependencies/mips/kernel_uapi_asm-mips
deleted file mode 120000
index dcd1955..0000000
--- a/tools/versioner/dependencies/mips/kernel_uapi_asm-mips
+++ /dev/null
@@ -1 +0,0 @@
-../../../../libc/kernel/uapi/asm-mips
\ No newline at end of file
diff --git a/tools/versioner/dependencies/mips64/arch-mips64 b/tools/versioner/dependencies/mips64/arch-mips64
deleted file mode 120000
index 48cea72..0000000
--- a/tools/versioner/dependencies/mips64/arch-mips64
+++ /dev/null
@@ -1 +0,0 @@
-../../../../libc/arch-mips64/include
\ No newline at end of file
diff --git a/tools/versioner/dependencies/mips64/kernel_uapi_asm-mips b/tools/versioner/dependencies/mips64/kernel_uapi_asm-mips
deleted file mode 120000
index dcd1955..0000000
--- a/tools/versioner/dependencies/mips64/kernel_uapi_asm-mips
+++ /dev/null
@@ -1 +0,0 @@
-../../../../libc/kernel/uapi/asm-mips
\ No newline at end of file
diff --git a/tools/versioner/dependencies/x86/arch-x86 b/tools/versioner/dependencies/x86/arch-x86
deleted file mode 120000
index d0f016a..0000000
--- a/tools/versioner/dependencies/x86/arch-x86
+++ /dev/null
@@ -1 +0,0 @@
-../../../../libc/arch-x86/include
\ No newline at end of file
diff --git a/tools/versioner/dependencies/x86/kernel_uapi_asm-x86 b/tools/versioner/dependencies/x86/kernel_uapi_asm-x86
deleted file mode 120000
index 0efae62..0000000
--- a/tools/versioner/dependencies/x86/kernel_uapi_asm-x86
+++ /dev/null
@@ -1 +0,0 @@
-../../../../libc/kernel/uapi/asm-x86
\ No newline at end of file
diff --git a/tools/versioner/dependencies/x86_64/arch-x86_64 b/tools/versioner/dependencies/x86_64/arch-x86_64
deleted file mode 120000
index deb647d..0000000
--- a/tools/versioner/dependencies/x86_64/arch-x86_64
+++ /dev/null
@@ -1 +0,0 @@
-../../../../libc/arch-x86_64/include
\ No newline at end of file
diff --git a/tools/versioner/dependencies/x86_64/kernel_uapi_asm-x86 b/tools/versioner/dependencies/x86_64/kernel_uapi_asm-x86
deleted file mode 120000
index 0efae62..0000000
--- a/tools/versioner/dependencies/x86_64/kernel_uapi_asm-x86
+++ /dev/null
@@ -1 +0,0 @@
-../../../../libc/kernel/uapi/asm-x86
\ No newline at end of file
diff --git a/tools/versioner/preupload.sh b/tools/versioner/preupload.sh
deleted file mode 100755
index 45d6cca..0000000
--- a/tools/versioner/preupload.sh
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/bin/bash
-
-if ! which versioner > /dev/null; then
- echo "versioner not found (lunch and mma in bionic)"
- exit 1
-fi
-
-versioner -r arm -r arm64
-exit $?
diff --git a/tools/versioner/src/Android.bp b/tools/versioner/src/Android.bp
index d1362d0..c5afa56 100644
--- a/tools/versioner/src/Android.bp
+++ b/tools/versioner/src/Android.bp
@@ -41,18 +41,8 @@
"-fno-rtti",
],
},
- darwin: {
- enabled: false,
- },
windows: {
enabled: false,
},
},
-
- product_variables: {
- unbundled_build: {
- // Only do this when Clang is available.
- enabled: false,
- },
- },
}