Merge "Blacklist setregid(32) for apps."
diff --git a/libc/Android.bp b/libc/Android.bp
index e0d0fee..6f2e347 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -1612,6 +1612,8 @@
symbol_file: "libc.map.txt",
versions: ["10000"],
},
+
+ symbol_ordering_file: "symbol_ordering",
}
genrule {
@@ -1646,6 +1648,59 @@
cmd: "$(location :bionic-generate-version-script) x86_64 $(in) $(out)",
}
+// libc_headers for libasync_safe and libpropertyinfoparser
+cc_library_headers {
+ name: "libc_headers",
+
+ host_supported: true,
+ vendor_available: true,
+ recovery_available: true,
+
+ no_libcrt: true,
+ no_libgcc: true,
+ stl: "none",
+ system_shared_libs: [],
+
+ export_include_dirs: [
+ "include",
+ "kernel/uapi",
+ "kernel/android/uapi",
+ ],
+
+ arch: {
+ arm: {
+ export_include_dirs: [
+ "kernel/uapi/asm-arm",
+ ],
+ },
+ arm64: {
+ export_include_dirs: [
+ "kernel/uapi/asm-arm64",
+ ],
+ },
+ mips: {
+ export_include_dirs: [
+ "kernel/uapi/asm-mips",
+ ],
+ },
+ mips64: {
+ export_include_dirs: [
+ "kernel/uapi/asm-mips",
+ ],
+ },
+ x86: {
+ export_include_dirs: [
+ "kernel/uapi/asm-x86",
+ ],
+ },
+ x86_64: {
+ export_include_dirs: [
+ "kernel/uapi/asm-x86",
+ ],
+ },
+ },
+}
+
// ========================================================
// libstdc++.so and libstdc++.a.
// ========================================================
@@ -1999,47 +2054,39 @@
symbol_file: "libc.map.txt",
export_headers_as_system: true,
export_preprocessed_headers: ["include"],
+ export_include_dirs: [
+ "kernel/android/uapi",
+ "kernel/uapi",
+ ],
arch: {
arm: {
export_include_dirs: [
- "kernel/uapi",
"kernel/uapi/asm-arm",
- "kernel/android/uapi",
],
},
arm64: {
export_include_dirs: [
- "kernel/uapi",
"kernel/uapi/asm-arm64",
- "kernel/android/uapi",
],
},
mips: {
export_include_dirs: [
- "kernel/uapi",
"kernel/uapi/asm-mips",
- "kernel/android/uapi",
],
},
mips64: {
export_include_dirs: [
- "kernel/uapi",
"kernel/uapi/asm-mips",
- "kernel/android/uapi",
],
},
x86: {
export_include_dirs: [
- "kernel/uapi",
"kernel/uapi/asm-x86",
- "kernel/android/uapi",
],
},
x86_64: {
export_include_dirs: [
- "kernel/uapi",
"kernel/uapi/asm-x86",
- "kernel/android/uapi",
],
},
},
@@ -2165,6 +2212,91 @@
},
}
+python_binary_host {
+ name: "genfunctosyscallnrs",
+ main: "tools/genfunctosyscallnrs.py",
+
+ srcs: [
+ "tools/genseccomp.py",
+ "tools/genfunctosyscallnrs.py",
+ "tools/gensyscalls.py",
+ ],
+
+ data: [
+ "kernel/uapi/**/*.h",
+ ],
+
+ version: {
+ py2: {
+ enabled: true,
+ },
+ py3: {
+ enabled: false,
+ },
+ },
+}
+
+cc_genrule {
+ name: "func_to_syscall_nrs",
+ recovery_available: true,
+ cmd: "$(location genfunctosyscallnrs) --out-dir=$(genDir) $(in)",
+
+ tools: [ "genfunctosyscallnrs" ],
+
+ srcs: [
+ "SYSCALLS.TXT",
+ ":libseccomp_gen_syscall_nrs_arm",
+ ":libseccomp_gen_syscall_nrs_arm64",
+ ":libseccomp_gen_syscall_nrs_mips",
+ ":libseccomp_gen_syscall_nrs_mips64",
+ ":libseccomp_gen_syscall_nrs_x86",
+ ":libseccomp_gen_syscall_nrs_x86_64",
+ ],
+
+ out: [
+ "func_to_syscall_nrs.h",
+ ],
+}
+
+// SECCOMP_BLACKLIST_APP_ZYGOTE.TXT = SECCOMP_BLACKLIST_APP.txt - setresgid*
+genrule {
+ name: "generate_app_zygote_blacklist",
+ out: ["SECCOMP_BLACKLIST_APP_ZYGOTE.TXT"],
+ srcs: ["SECCOMP_BLACKLIST_APP.TXT"],
+ cmd: "grep -v '^int[ \t]*setresgid' $(in) > $(out)",
+}
+
+cc_genrule {
+ name: "libseccomp_policy_app_zygote_sources",
+ recovery_available: true,
+ cmd: "$(location genseccomp) --out-dir=$(genDir) --name-modifier=app_zygote $(in)",
+
+ tools: [ "genseccomp" ],
+
+ srcs: [
+ "SYSCALLS.TXT",
+ "SECCOMP_WHITELIST_COMMON.TXT",
+ "SECCOMP_WHITELIST_APP.TXT",
+ "SECCOMP_BLACKLIST_COMMON.TXT",
+ ":generate_app_zygote_blacklist",
+ ":libseccomp_gen_syscall_nrs_arm",
+ ":libseccomp_gen_syscall_nrs_arm64",
+ ":libseccomp_gen_syscall_nrs_mips",
+ ":libseccomp_gen_syscall_nrs_mips64",
+ ":libseccomp_gen_syscall_nrs_x86",
+ ":libseccomp_gen_syscall_nrs_x86_64",
+ ],
+
+ out: [
+ "arm64_app_zygote_policy.cpp",
+ "arm_app_zygote_policy.cpp",
+ "mips64_app_zygote_policy.cpp",
+ "mips_app_zygote_policy.cpp",
+ "x86_64_app_zygote_policy.cpp",
+ "x86_app_zygote_policy.cpp",
+ ],
+}
+
cc_genrule {
name: "libseccomp_policy_app_sources",
recovery_available: true,
@@ -2261,8 +2393,10 @@
cc_library {
name: "libseccomp_policy",
recovery_available: true,
+ generated_headers: ["func_to_syscall_nrs"],
generated_sources: [
"libseccomp_policy_app_sources",
+ "libseccomp_policy_app_zygote_sources",
"libseccomp_policy_global_sources",
"libseccomp_policy_system_sources",
],
diff --git a/libc/arch-arm/bionic/vfork.S b/libc/arch-arm/bionic/vfork.S
index 8329111..0b17d64 100644
--- a/libc/arch-arm/bionic/vfork.S
+++ b/libc/arch-arm/bionic/vfork.S
@@ -27,12 +27,13 @@
*/
#include <private/bionic_asm.h>
+#include <private/bionic_asm_tls.h>
ENTRY(vfork)
__BIONIC_WEAK_ASM_FOR_NATIVE_BRIDGE(vfork)
// __get_tls()[TLS_SLOT_THREAD_ID]->cached_pid_ = 0
mrc p15, 0, r3, c13, c0, 3
- ldr r3, [r3, #4]
+ ldr r3, [r3, #(TLS_SLOT_THREAD_ID * 4)]
mov r0, #0
str r0, [r3, #12]
diff --git a/libc/arch-arm64/bionic/vfork.S b/libc/arch-arm64/bionic/vfork.S
index 0a83cc7..6acd64b 100644
--- a/libc/arch-arm64/bionic/vfork.S
+++ b/libc/arch-arm64/bionic/vfork.S
@@ -27,6 +27,7 @@
*/
#include <private/bionic_asm.h>
+#include <private/bionic_asm_tls.h>
#include <asm/signal.h>
#include <linux/sched.h>
@@ -34,7 +35,7 @@
__BIONIC_WEAK_ASM_FOR_NATIVE_BRIDGE(vfork)
// __get_tls()[TLS_SLOT_THREAD_ID]->cached_pid_ = 0
mrs x0, tpidr_el0
- ldr x0, [x0, #8]
+ ldr x0, [x0, #(TLS_SLOT_THREAD_ID * 8)]
str wzr, [x0, #20]
mov x0, #(CLONE_VM | CLONE_VFORK | SIGCHLD)
diff --git a/libc/arch-x86/bionic/vfork.S b/libc/arch-x86/bionic/vfork.S
index 79d7899..24ede3d 100644
--- a/libc/arch-x86/bionic/vfork.S
+++ b/libc/arch-x86/bionic/vfork.S
@@ -27,6 +27,7 @@
*/
#include <private/bionic_asm.h>
+#include <private/bionic_asm_tls.h>
// This custom code preserves the return address across the system call.
@@ -38,7 +39,7 @@
// __get_tls()[TLS_SLOT_THREAD_ID]->cached_pid_ = 0
movl %gs:0, %eax
- movl 4(%eax), %eax
+ movl (TLS_SLOT_THREAD_ID * 4)(%eax), %eax
movl $0, 12(%eax)
movl $__NR_vfork, %eax
diff --git a/libc/arch-x86_64/bionic/vfork.S b/libc/arch-x86_64/bionic/vfork.S
index ce96a8c..e32b517 100644
--- a/libc/arch-x86_64/bionic/vfork.S
+++ b/libc/arch-x86_64/bionic/vfork.S
@@ -27,6 +27,7 @@
*/
#include <private/bionic_asm.h>
+#include <private/bionic_asm_tls.h>
// This custom code preserves the return address across the system call.
@@ -36,7 +37,7 @@
// __get_tls()[TLS_SLOT_THREAD_ID]->cached_pid_ = 0
mov %fs:0, %rax
- mov 8(%rax), %rax
+ mov (TLS_SLOT_THREAD_ID * 8)(%rax), %rax
movl $0, 20(%rax)
movl $__NR_vfork, %eax
diff --git a/libc/async_safe/Android.bp b/libc/async_safe/Android.bp
index 29f90d1..a54d3b0 100644
--- a/libc/async_safe/Android.bp
+++ b/libc/async_safe/Android.bp
@@ -12,6 +12,7 @@
recovery_available: true,
include_dirs: ["bionic/libc"],
+ header_libs: ["libc_headers"],
export_include_dirs: ["include"],
}
diff --git a/libc/bionic/__libc_init_main_thread.cpp b/libc/bionic/__libc_init_main_thread.cpp
index 2b90c90..6279e65 100644
--- a/libc/bionic/__libc_init_main_thread.cpp
+++ b/libc/bionic/__libc_init_main_thread.cpp
@@ -126,6 +126,7 @@
auto new_tcb = reinterpret_cast<bionic_tcb*>(mapping.static_tls + layout.offset_bionic_tcb());
auto new_tls = reinterpret_cast<bionic_tls*>(mapping.static_tls + layout.offset_bionic_tls());
+ __init_static_tls(mapping.static_tls);
new_tcb->copy_from_bootstrap(temp_tcb);
new_tls->copy_from_bootstrap(temp_tls);
__init_tcb(new_tcb, &main_thread);
diff --git a/libc/bionic/bionic_elf_tls.cpp b/libc/bionic/bionic_elf_tls.cpp
index 55c2c31..4253b97 100644
--- a/libc/bionic/bionic_elf_tls.cpp
+++ b/libc/bionic/bionic_elf_tls.cpp
@@ -28,13 +28,104 @@
#include "private/bionic_elf_tls.h"
+#include <async_safe/log.h>
+#include <string.h>
#include <sys/param.h>
+#include <unistd.h>
+#include "private/ScopedRWLock.h"
+#include "private/bionic_globals.h"
#include "private/bionic_macros.h"
#include "private/bionic_tls.h"
-void StaticTlsLayout::reserve_tcb() {
- offset_bionic_tcb_ = reserve_type<bionic_tcb>();
+// Search for a TLS segment in the given phdr table. Returns true if it has a
+// TLS segment and false otherwise.
+bool __bionic_get_tls_segment(const ElfW(Phdr)* phdr_table, size_t phdr_count,
+ ElfW(Addr) load_bias, TlsSegment* out) {
+ for (size_t i = 0; i < phdr_count; ++i) {
+ const ElfW(Phdr)& phdr = phdr_table[i];
+ if (phdr.p_type == PT_TLS) {
+ *out = TlsSegment {
+ phdr.p_memsz,
+ phdr.p_align,
+ reinterpret_cast<void*>(load_bias + phdr.p_vaddr),
+ phdr.p_filesz,
+ };
+ return true;
+ }
+ }
+ return false;
+}
+
+// Return true if the alignment of a TLS segment is a valid power-of-two. Also
+// cap the alignment if it's too high.
+bool __bionic_check_tls_alignment(size_t* alignment) {
+ // N.B. The size does not need to be a multiple of the alignment. With
+ // ld.bfd (or after using binutils' strip), the TLS segment's size isn't
+ // rounded up.
+ if (*alignment == 0 || !powerof2(*alignment)) {
+ return false;
+ }
+ // Bionic only respects TLS alignment up to one page.
+ *alignment = MIN(*alignment, PAGE_SIZE);
+ return true;
+}
+
+size_t StaticTlsLayout::offset_thread_pointer() const {
+ return offset_bionic_tcb_ + (-MIN_TLS_SLOT * sizeof(void*));
+}
+
+// Reserves space for the Bionic TCB and the executable's TLS segment. Returns
+// the offset of the executable's TLS segment.
+size_t StaticTlsLayout::reserve_exe_segment_and_tcb(const TlsSegment* exe_segment,
+ const char* progname __attribute__((unused))) {
+ // Special case: if the executable has no TLS segment, then just allocate a
+ // TCB and skip the minimum alignment check on ARM.
+ if (exe_segment == nullptr) {
+ offset_bionic_tcb_ = reserve_type<bionic_tcb>();
+ return 0;
+ }
+
+#if defined(__arm__) || defined(__aarch64__)
+
+ // First reserve enough space for the TCB before the executable segment.
+ reserve(sizeof(bionic_tcb), 1);
+
+ // Then reserve the segment itself.
+ const size_t result = reserve(exe_segment->size, exe_segment->alignment);
+
+ // The variant 1 ABI that ARM linkers follow specifies a 2-word TCB between
+ // the thread pointer and the start of the executable's TLS segment, but both
+ // the thread pointer and the TLS segment are aligned appropriately for the
+ // TLS segment. Calculate the distance between the thread pointer and the
+ // EXE's segment.
+ const size_t exe_tpoff = __BIONIC_ALIGN(sizeof(void*) * 2, exe_segment->alignment);
+
+ const size_t min_bionic_alignment = BIONIC_ROUND_UP_POWER_OF_2(MAX_TLS_SLOT) * sizeof(void*);
+ if (exe_tpoff < min_bionic_alignment) {
+ async_safe_fatal("error: \"%s\": executable's TLS segment is underaligned: "
+ "alignment is %zu, needs to be at least %zu for %s Bionic",
+ progname, exe_segment->alignment, min_bionic_alignment,
+ (sizeof(void*) == 4 ? "ARM" : "ARM64"));
+ }
+
+ offset_bionic_tcb_ = result - exe_tpoff - (-MIN_TLS_SLOT * sizeof(void*));
+ return result;
+
+#elif defined(__i386__) || defined(__x86_64__)
+
+ // x86 uses variant 2 TLS layout. The executable's segment is located just
+ // before the TCB.
+ static_assert(MIN_TLS_SLOT == 0, "First slot of bionic_tcb must be slot #0 on x86");
+ const size_t exe_size = round_up_with_overflow_check(exe_segment->size, exe_segment->alignment);
+ reserve(exe_size, 1);
+ const size_t max_align = MAX(alignof(bionic_tcb), exe_segment->alignment);
+ offset_bionic_tcb_ = reserve(sizeof(bionic_tcb), max_align);
+ return offset_bionic_tcb_ - exe_size;
+
+#else
+#error "Unrecognized architecture"
+#endif
}
void StaticTlsLayout::reserve_bionic_tls() {
@@ -44,6 +135,10 @@
void StaticTlsLayout::finish_layout() {
// Round the offset up to the alignment.
offset_ = round_up_with_overflow_check(offset_, alignment_);
+
+ if (overflowed_) {
+ async_safe_fatal("error: TLS segments in static TLS overflowed");
+ }
}
// The size is not required to be a multiple of the alignment. The alignment
@@ -62,3 +157,33 @@
if (value < old_value) overflowed_ = true;
return value;
}
+
+// Copy each TLS module's initialization image into a newly-allocated block of
+// static TLS memory. To reduce dirty pages, this function only writes to pages
+// within the static TLS that need initialization. The memory should already be
+// zero-initialized on entry.
+void __init_static_tls(void* static_tls) {
+ // The part of the table we care about (i.e. static TLS modules) never changes
+ // after startup, but we still need the mutex because the table could grow,
+ // moving the initial part. If this locking is too slow, we can duplicate the
+ // static part of the table.
+ TlsModules& modules = __libc_shared_globals()->tls_modules;
+ ScopedReadLock locker(&modules.rwlock);
+
+ for (size_t i = 0; i < modules.module_count; ++i) {
+ TlsModule& module = modules.module_table[i];
+ if (module.static_offset == SIZE_MAX) {
+ // All of the static modules come before all of the dynamic modules, so
+ // once we see the first dynamic module, we're done.
+ break;
+ }
+ if (module.segment.init_size == 0) {
+ // Skip the memcpy call for TLS segments with no initializer, which is
+ // common.
+ continue;
+ }
+ memcpy(static_cast<char*>(static_tls) + module.static_offset,
+ module.segment.init_ptr,
+ module.segment.init_size);
+ }
+}
diff --git a/libc/bionic/libc_init_static.cpp b/libc/bionic/libc_init_static.cpp
index 68650ed..8fbc20e 100644
--- a/libc/bionic/libc_init_static.cpp
+++ b/libc/bionic/libc_init_static.cpp
@@ -83,10 +83,29 @@
}
}
-static void layout_static_tls() {
+static void layout_static_tls(KernelArgumentBlock& args) {
StaticTlsLayout& layout = __libc_shared_globals()->static_tls_layout;
layout.reserve_bionic_tls();
- layout.reserve_tcb();
+
+ const char* progname = args.argv[0];
+ ElfW(Phdr)* phdr_start = reinterpret_cast<ElfW(Phdr)*>(getauxval(AT_PHDR));
+ size_t phdr_ct = getauxval(AT_PHNUM);
+
+ static TlsModule mod;
+ if (__bionic_get_tls_segment(phdr_start, phdr_ct, 0, &mod.segment)) {
+ if (!__bionic_check_tls_alignment(&mod.segment.alignment)) {
+ async_safe_fatal("error: TLS segment alignment in \"%s\" is not a power of 2: %zu\n",
+ progname, mod.segment.alignment);
+ }
+ mod.static_offset = layout.reserve_exe_segment_and_tcb(&mod.segment, progname);
+ mod.first_generation = 1;
+ __libc_shared_globals()->tls_modules.generation = 1;
+ __libc_shared_globals()->tls_modules.module_count = 1;
+ __libc_shared_globals()->tls_modules.module_table = &mod;
+ } else {
+ layout.reserve_exe_segment_and_tcb(nullptr, progname);
+ }
+
layout.finish_layout();
}
@@ -111,7 +130,7 @@
__libc_init_globals();
__libc_shared_globals()->init_progname = args.argv[0];
__libc_init_AT_SECURE(args.envp);
- layout_static_tls();
+ layout_static_tls(args);
__libc_init_main_thread_final();
__libc_init_common();
diff --git a/libc/bionic/malloc_common.cpp b/libc/bionic/malloc_common.cpp
index d530fa4..4cc5df9 100644
--- a/libc/bionic/malloc_common.cpp
+++ b/libc/bionic/malloc_common.cpp
@@ -641,42 +641,6 @@
}
}
-extern "C" void InstallInitHeapprofdHook(int);
-
-// Initializes memory allocation framework once per process.
-static void malloc_init_impl(libc_globals* globals) {
- struct sigaction action = {};
- action.sa_handler = InstallInitHeapprofdHook;
- sigaction(HEAPPROFD_SIGNAL, &action, nullptr);
-
- const char* prefix;
- const char* shared_lib;
- char prop[PROP_VALUE_MAX];
- char* options = prop;
- // Prefer malloc debug since it existed first and is a more complete
- // malloc interceptor than the hooks.
- if (CheckLoadMallocDebug(&options)) {
- prefix = "debug";
- shared_lib = DEBUG_SHARED_LIB;
- } else if (CheckLoadMallocHooks(&options)) {
- prefix = "hooks";
- shared_lib = HOOKS_SHARED_LIB;
- } else if (CheckLoadHeapprofd()) {
- prefix = "heapprofd";
- shared_lib = HEAPPROFD_SHARED_LIB;
- } else {
- return;
- }
- install_hooks(globals, options, prefix, shared_lib);
-}
-
-// Initializes memory allocation framework.
-// This routine is called from __libc_init routines in libc_init_dynamic.cpp.
-__BIONIC_WEAK_FOR_NATIVE_BRIDGE
-__LIBC_HIDDEN__ void __libc_init_malloc(libc_globals* globals) {
- malloc_init_impl(globals);
-}
-
// The logic for triggering heapprofd below is as following.
// 1. HEAPPROFD_SIGNAL is received by the process.
// 2. If neither InitHeapprofd nor InitHeapprofdHook are currently installed
@@ -704,6 +668,45 @@
static _Atomic bool g_heapprofd_init_in_progress = false;
static _Atomic bool g_heapprofd_init_hook_installed = false;
+extern "C" void InstallInitHeapprofdHook(int);
+
+// Initializes memory allocation framework once per process.
+static void malloc_init_impl(libc_globals* globals) {
+ struct sigaction action = {};
+ action.sa_handler = InstallInitHeapprofdHook;
+ sigaction(HEAPPROFD_SIGNAL, &action, nullptr);
+
+ const char* prefix;
+ const char* shared_lib;
+ char prop[PROP_VALUE_MAX];
+ char* options = prop;
+ // Prefer malloc debug since it existed first and is a more complete
+ // malloc interceptor than the hooks.
+ if (CheckLoadMallocDebug(&options)) {
+ prefix = "debug";
+ shared_lib = DEBUG_SHARED_LIB;
+ } else if (CheckLoadMallocHooks(&options)) {
+ prefix = "hooks";
+ shared_lib = HOOKS_SHARED_LIB;
+ } else if (CheckLoadHeapprofd()) {
+ prefix = "heapprofd";
+ shared_lib = HEAPPROFD_SHARED_LIB;
+ } else {
+ return;
+ }
+ if (!atomic_exchange(&g_heapprofd_init_in_progress, true)) {
+ install_hooks(globals, options, prefix, shared_lib);
+ atomic_store(&g_heapprofd_init_in_progress, false);
+ }
+}
+
+// Initializes memory allocation framework.
+// This routine is called from __libc_init routines in libc_init_dynamic.cpp.
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
+__LIBC_HIDDEN__ void __libc_init_malloc(libc_globals* globals) {
+ malloc_init_impl(globals);
+}
+
static void* InitHeapprofd(void*) {
__libc_globals.mutate([](libc_globals* globals) {
install_hooks(globals, nullptr, HEAPPROFD_PREFIX, HEAPPROFD_SHARED_LIB);
diff --git a/libc/bionic/pthread_create.cpp b/libc/bionic/pthread_create.cpp
index 8676a45..31e0378 100644
--- a/libc/bionic/pthread_create.cpp
+++ b/libc/bionic/pthread_create.cpp
@@ -288,7 +288,8 @@
auto tcb = reinterpret_cast<bionic_tcb*>(mapping.static_tls + layout.offset_bionic_tcb());
auto tls = reinterpret_cast<bionic_tls*>(mapping.static_tls + layout.offset_bionic_tls());
- // (Re)initialize TLS pointers.
+ // Initialize TLS memory.
+ __init_static_tls(mapping.static_tls);
__init_tcb(tcb, thread);
__init_tcb_stack_guard(tcb);
__init_bionic_tls_ptrs(tcb, tls);
diff --git a/libc/bionic/pthread_internal.cpp b/libc/bionic/pthread_internal.cpp
index 870a526..46fa630 100644
--- a/libc/bionic/pthread_internal.cpp
+++ b/libc/bionic/pthread_internal.cpp
@@ -35,30 +35,13 @@
#include <async_safe/log.h>
+#include "private/ScopedRWLock.h"
#include "private/bionic_futex.h"
#include "private/bionic_tls.h"
static pthread_internal_t* g_thread_list = nullptr;
static pthread_rwlock_t g_thread_list_lock = PTHREAD_RWLOCK_INITIALIZER;
-template <bool write> class ScopedRWLock {
- public:
- explicit ScopedRWLock(pthread_rwlock_t* rwlock) : rwlock_(rwlock) {
- (write ? pthread_rwlock_wrlock : pthread_rwlock_rdlock)(rwlock_);
- }
-
- ~ScopedRWLock() {
- pthread_rwlock_unlock(rwlock_);
- }
-
- private:
- pthread_rwlock_t* rwlock_;
- BIONIC_DISALLOW_IMPLICIT_CONSTRUCTORS(ScopedRWLock);
-};
-
-typedef ScopedRWLock<true> ScopedWriteLock;
-typedef ScopedRWLock<false> ScopedReadLock;
-
pthread_t __pthread_internal_add(pthread_internal_t* thread) {
ScopedWriteLock locker(&g_thread_list_lock);
diff --git a/libc/include/sys/cdefs.h b/libc/include/sys/cdefs.h
index e9d0e4b..a919a79 100644
--- a/libc/include/sys/cdefs.h
+++ b/libc/include/sys/cdefs.h
@@ -280,7 +280,7 @@
*/
# define __BIONIC_FORTIFY_VARIADIC static __inline__
/* Error functions don't have bodies, so they can just be static. */
-# define __BIONIC_ERROR_FUNCTION_VISIBILITY static
+# define __BIONIC_ERROR_FUNCTION_VISIBILITY static __attribute__((unused))
#else
/* Further increase sharing for some inline functions */
# define __pass_object_size_n(n)
diff --git a/libc/kernel/uapi/asm-arm64/asm/hwcap.h b/libc/kernel/uapi/asm-arm64/asm/hwcap.h
index a7cd560..8f50b1d 100644
--- a/libc/kernel/uapi/asm-arm64/asm/hwcap.h
+++ b/libc/kernel/uapi/asm-arm64/asm/hwcap.h
@@ -46,4 +46,5 @@
#define HWCAP_USCAT (1 << 25)
#define HWCAP_ILRCPC (1 << 26)
#define HWCAP_FLAGM (1 << 27)
+#define HWCAP_SSBS (1 << 28)
#endif
diff --git a/libc/kernel/uapi/asm-arm64/asm/ptrace.h b/libc/kernel/uapi/asm-arm64/asm/ptrace.h
index 4e6c755..e1cfb48 100644
--- a/libc/kernel/uapi/asm-arm64/asm/ptrace.h
+++ b/libc/kernel/uapi/asm-arm64/asm/ptrace.h
@@ -34,6 +34,7 @@
#define PSR_I_BIT 0x00000080
#define PSR_A_BIT 0x00000100
#define PSR_D_BIT 0x00000200
+#define PSR_SSBS_BIT 0x00001000
#define PSR_PAN_BIT 0x00400000
#define PSR_UAO_BIT 0x00800000
#define PSR_V_BIT 0x10000000
diff --git a/libc/kernel/uapi/asm-arm64/asm/siginfo.h b/libc/kernel/uapi/asm-arm64/asm/siginfo.h
index 111a215..a31ebb2 100644
--- a/libc/kernel/uapi/asm-arm64/asm/siginfo.h
+++ b/libc/kernel/uapi/asm-arm64/asm/siginfo.h
@@ -16,8 +16,4 @@
***
****************************************************************************
****************************************************************************/
-#ifndef __ASM_SIGINFO_H
-#define __ASM_SIGINFO_H
-#define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int))
#include <asm-generic/siginfo.h>
-#endif
diff --git a/libc/kernel/uapi/asm-arm64/asm/unistd.h b/libc/kernel/uapi/asm-arm64/asm/unistd.h
index cc151fd..0648b02 100644
--- a/libc/kernel/uapi/asm-arm64/asm/unistd.h
+++ b/libc/kernel/uapi/asm-arm64/asm/unistd.h
@@ -17,4 +17,5 @@
****************************************************************************
****************************************************************************/
#define __ARCH_WANT_RENAMEAT
+#define __ARCH_WANT_NEW_STAT
#include <asm-generic/unistd.h>
diff --git a/libc/kernel/uapi/asm-generic/ioctls.h b/libc/kernel/uapi/asm-generic/ioctls.h
index 41dbce2..f8a4357 100644
--- a/libc/kernel/uapi/asm-generic/ioctls.h
+++ b/libc/kernel/uapi/asm-generic/ioctls.h
@@ -81,6 +81,8 @@
#define TIOCGPTLCK _IOR('T', 0x39, int)
#define TIOCGEXCL _IOR('T', 0x40, int)
#define TIOCGPTPEER _IO('T', 0x41)
+#define TIOCGISO7816 _IOR('T', 0x42, struct serial_iso7816)
+#define TIOCSISO7816 _IOWR('T', 0x43, struct serial_iso7816)
#define FIONCLEX 0x5450
#define FIOCLEX 0x5451
#define FIOASYNC 0x5452
diff --git a/libc/kernel/uapi/asm-generic/siginfo.h b/libc/kernel/uapi/asm-generic/siginfo.h
index 166193b..829ffad 100644
--- a/libc/kernel/uapi/asm-generic/siginfo.h
+++ b/libc/kernel/uapi/asm-generic/siginfo.h
@@ -24,13 +24,7 @@
int sival_int;
void __user * sival_ptr;
} sigval_t;
-#ifndef __ARCH_SI_PREAMBLE_SIZE
-#define __ARCH_SI_PREAMBLE_SIZE (3 * sizeof(int))
-#endif
#define SI_MAX_SIZE 128
-#ifndef SI_PAD_SIZE
-#define SI_PAD_SIZE ((SI_MAX_SIZE - __ARCH_SI_PREAMBLE_SIZE) / sizeof(int))
-#endif
#ifndef __ARCH_SI_BAND_T
#define __ARCH_SI_BAND_T long
#endif
@@ -40,73 +34,75 @@
#ifndef __ARCH_SI_ATTRIBUTES
#define __ARCH_SI_ATTRIBUTES
#endif
-typedef struct siginfo {
- int si_signo;
-#ifndef __ARCH_HAS_SWAPPED_SIGINFO
- int si_errno;
- int si_code;
-#else
- int si_code;
- int si_errno;
-#endif
- union {
- int _pad[SI_PAD_SIZE];
- struct {
- __kernel_pid_t _pid;
- __kernel_uid32_t _uid;
- } _kill;
- struct {
- __kernel_timer_t _tid;
- int _overrun;
- sigval_t _sigval;
- int _sys_private;
- } _timer;
- struct {
- __kernel_pid_t _pid;
- __kernel_uid32_t _uid;
- sigval_t _sigval;
- } _rt;
- struct {
- __kernel_pid_t _pid;
- __kernel_uid32_t _uid;
- int _status;
- __ARCH_SI_CLOCK_T _utime;
- __ARCH_SI_CLOCK_T _stime;
- } _sigchld;
- struct {
- void __user * _addr;
+union __sifields {
+ struct {
+ __kernel_pid_t _pid;
+ __kernel_uid32_t _uid;
+ } _kill;
+ struct {
+ __kernel_timer_t _tid;
+ int _overrun;
+ sigval_t _sigval;
+ int _sys_private;
+ } _timer;
+ struct {
+ __kernel_pid_t _pid;
+ __kernel_uid32_t _uid;
+ sigval_t _sigval;
+ } _rt;
+ struct {
+ __kernel_pid_t _pid;
+ __kernel_uid32_t _uid;
+ int _status;
+ __ARCH_SI_CLOCK_T _utime;
+ __ARCH_SI_CLOCK_T _stime;
+ } _sigchld;
+ struct {
+ void __user * _addr;
#ifdef __ARCH_SI_TRAPNO
- int _trapno;
+ int _trapno;
#endif
#ifdef __ia64__
- int _imm;
- unsigned int _flags;
- unsigned long _isr;
+ int _imm;
+ unsigned int _flags;
+ unsigned long _isr;
#endif
#define __ADDR_BND_PKEY_PAD (__alignof__(void *) < sizeof(short) ? sizeof(short) : __alignof__(void *))
- union {
- short _addr_lsb;
- struct {
- char _dummy_bnd[__ADDR_BND_PKEY_PAD];
- void __user * _lower;
- void __user * _upper;
- } _addr_bnd;
- struct {
- char _dummy_pkey[__ADDR_BND_PKEY_PAD];
- __u32 _pkey;
- } _addr_pkey;
- };
- } _sigfault;
- struct {
- __ARCH_SI_BAND_T _band;
- int _fd;
- } _sigpoll;
- struct {
- void __user * _call_addr;
- int _syscall;
- unsigned int _arch;
- } _sigsys;
- } _sifields;
+ union {
+ short _addr_lsb;
+ struct {
+ char _dummy_bnd[__ADDR_BND_PKEY_PAD];
+ void __user * _lower;
+ void __user * _upper;
+ } _addr_bnd;
+ struct {
+ char _dummy_pkey[__ADDR_BND_PKEY_PAD];
+ __u32 _pkey;
+ } _addr_pkey;
+ };
+ } _sigfault;
+ struct {
+ __ARCH_SI_BAND_T _band;
+ int _fd;
+ } _sigpoll;
+ struct {
+ void __user * _call_addr;
+ int _syscall;
+ unsigned int _arch;
+ } _sigsys;
+};
+#ifndef __ARCH_HAS_SWAPPED_SIGINFO
+#define __SIGINFO struct { int si_signo; int si_errno; int si_code; union __sifields _sifields; \
+}
+#else
+#define __SIGINFO struct { int si_signo; int si_code; int si_errno; union __sifields _sifields; \
+}
+#endif
+typedef struct siginfo {
+ union {
+ __SIGINFO;
+ int _si_pad[SI_MAX_SIZE / sizeof(int)];
+ };
} __ARCH_SI_ATTRIBUTES siginfo_t;
#define si_pid _sifields._kill._pid
#define si_uid _sifields._kill._uid
@@ -212,6 +208,8 @@
#define NSIGPOLL 6
#define SYS_SECCOMP 1
#define NSIGSYS 1
+#define EMT_TAGOVF 1
+#define NSIGEMT 1
#define SIGEV_SIGNAL 0
#define SIGEV_NONE 1
#define SIGEV_THREAD 2
diff --git a/libc/kernel/uapi/asm-generic/unistd.h b/libc/kernel/uapi/asm-generic/unistd.h
index 52f0b57..fddf1d0 100644
--- a/libc/kernel/uapi/asm-generic/unistd.h
+++ b/libc/kernel/uapi/asm-generic/unistd.h
@@ -113,8 +113,10 @@
#define __NR_splice 76
#define __NR_tee 77
#define __NR_readlinkat 78
+#if defined(__ARCH_WANT_NEW_STAT) || defined(__ARCH_WANT_STAT64)
#define __NR3264_fstatat 79
#define __NR3264_fstat 80
+#endif
#define __NR_sync 81
#define __NR_fsync 82
#define __NR_fdatasync 83
@@ -329,8 +331,10 @@
#define __NR_ftruncate __NR3264_ftruncate
#define __NR_lseek __NR3264_lseek
#define __NR_sendfile __NR3264_sendfile
+#if defined(__ARCH_WANT_NEW_STAT) || defined(__ARCH_WANT_STAT64)
#define __NR_newfstatat __NR3264_fstatat
#define __NR_fstat __NR3264_fstat
+#endif
#define __NR_mmap __NR3264_mmap
#define __NR_fadvise64 __NR3264_fadvise64
#ifdef __NR3264_stat
@@ -345,8 +349,10 @@
#define __NR_ftruncate64 __NR3264_ftruncate
#define __NR_llseek __NR3264_lseek
#define __NR_sendfile64 __NR3264_sendfile
+#if defined(__ARCH_WANT_NEW_STAT) || defined(__ARCH_WANT_STAT64)
#define __NR_fstatat64 __NR3264_fstatat
#define __NR_fstat64 __NR3264_fstat
+#endif
#define __NR_mmap2 __NR3264_mmap
#define __NR_fadvise64_64 __NR3264_fadvise64
#ifdef __NR3264_stat
diff --git a/libc/kernel/uapi/asm-mips/asm/ioctls.h b/libc/kernel/uapi/asm-mips/asm/ioctls.h
index a4a40b0..694546f 100644
--- a/libc/kernel/uapi/asm-mips/asm/ioctls.h
+++ b/libc/kernel/uapi/asm-mips/asm/ioctls.h
@@ -85,6 +85,8 @@
#define TIOCGPTLCK _IOR('T', 0x39, int)
#define TIOCGEXCL _IOR('T', 0x40, int)
#define TIOCGPTPEER _IO('T', 0x41)
+#define TIOCGISO7816 _IOR('T', 0x42, struct serial_iso7816)
+#define TIOCSISO7816 _IOWR('T', 0x43, struct serial_iso7816)
#define TIOCSCTTY 0x5480
#define TIOCGSOFTCAR 0x5481
#define TIOCSSOFTCAR 0x5482
diff --git a/libc/kernel/uapi/asm-mips/asm/siginfo.h b/libc/kernel/uapi/asm-mips/asm/siginfo.h
index c37107b..c9efb21 100644
--- a/libc/kernel/uapi/asm-mips/asm/siginfo.h
+++ b/libc/kernel/uapi/asm-mips/asm/siginfo.h
@@ -20,13 +20,6 @@
#define _UAPI_ASM_SIGINFO_H
#define __ARCH_SIGEV_PREAMBLE_SIZE (sizeof(long) + 2 * sizeof(int))
#undef __ARCH_SI_TRAPNO
-#if _MIPS_SZLONG == 32
-#define __ARCH_SI_PREAMBLE_SIZE (3 * sizeof(int))
-#elif _MIPS_SZLONG==64
-#define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int))
-#else
-#error _MIPS_SZLONG neither 32 nor 64
-#endif
#define __ARCH_HAS_SWAPPED_SIGINFO
#include <asm-generic/siginfo.h>
#undef SI_ASYNCIO
diff --git a/libc/kernel/uapi/asm-x86/asm/bootparam.h b/libc/kernel/uapi/asm-x86/asm/bootparam.h
index b010277..dc90f57 100644
--- a/libc/kernel/uapi/asm-x86/asm/bootparam.h
+++ b/libc/kernel/uapi/asm-x86/asm/bootparam.h
@@ -135,7 +135,8 @@
__u8 _pad2[4];
__u64 tboot_addr;
struct ist_info ist_info;
- __u8 _pad3[16];
+ __u64 acpi_rsdp_addr;
+ __u8 _pad3[8];
__u8 hd0_info[16];
__u8 hd1_info[16];
struct sys_desc_table sys_desc_table;
diff --git a/libc/kernel/uapi/asm-x86/asm/kvm.h b/libc/kernel/uapi/asm-x86/asm/kvm.h
index 1d7f767..4386f76 100644
--- a/libc/kernel/uapi/asm-x86/asm/kvm.h
+++ b/libc/kernel/uapi/asm-x86/asm/kvm.h
@@ -248,6 +248,7 @@
#define KVM_VCPUEVENT_VALID_SIPI_VECTOR 0x00000002
#define KVM_VCPUEVENT_VALID_SHADOW 0x00000004
#define KVM_VCPUEVENT_VALID_SMM 0x00000008
+#define KVM_VCPUEVENT_VALID_PAYLOAD 0x00000010
#define KVM_X86_SHADOW_INT_MOV_SS 0x01
#define KVM_X86_SHADOW_INT_STI 0x02
struct kvm_vcpu_events {
@@ -255,7 +256,7 @@
__u8 injected;
__u8 nr;
__u8 has_error_code;
- __u8 pad;
+ __u8 pending;
__u32 error_code;
} exception;
struct {
@@ -278,7 +279,9 @@
__u8 smm_inside_nmi;
__u8 latched_init;
} smi;
- __u32 reserved[9];
+ __u8 reserved[27];
+ __u8 exception_has_payload;
+ __u64 exception_payload;
};
struct kvm_debugregs {
__u64 db[4];
@@ -316,6 +319,7 @@
#define KVM_X86_QUIRK_LAPIC_MMIO_HOLE (1 << 2)
#define KVM_STATE_NESTED_GUEST_MODE 0x00000001
#define KVM_STATE_NESTED_RUN_PENDING 0x00000002
+#define KVM_STATE_NESTED_EVMCS 0x00000004
#define KVM_STATE_NESTED_SMM_GUEST_MODE 0x00000001
#define KVM_STATE_NESTED_SMM_VMXON 0x00000002
struct kvm_vmx_nested_state {
diff --git a/libc/kernel/uapi/asm-x86/asm/siginfo.h b/libc/kernel/uapi/asm-x86/asm/siginfo.h
index 1da8066..0de5283 100644
--- a/libc/kernel/uapi/asm-x86/asm/siginfo.h
+++ b/libc/kernel/uapi/asm-x86/asm/siginfo.h
@@ -23,8 +23,6 @@
typedef long long __kernel_si_clock_t __attribute__((aligned(4)));
#define __ARCH_SI_CLOCK_T __kernel_si_clock_t
#define __ARCH_SI_ATTRIBUTES __attribute__((aligned(8)))
-#else
-#define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int))
#endif
#endif
#include <asm-generic/siginfo.h>
diff --git a/libc/kernel/uapi/drm/amdgpu_drm.h b/libc/kernel/uapi/drm/amdgpu_drm.h
index 2013fa7..8d65fd4 100644
--- a/libc/kernel/uapi/drm/amdgpu_drm.h
+++ b/libc/kernel/uapi/drm/amdgpu_drm.h
@@ -406,6 +406,7 @@
#define AMDGPU_INFO_FW_GFX_RLC_RESTORE_LIST_CNTL 0x0f
#define AMDGPU_INFO_FW_GFX_RLC_RESTORE_LIST_GPM_MEM 0x10
#define AMDGPU_INFO_FW_GFX_RLC_RESTORE_LIST_SRM_MEM 0x11
+#define AMDGPU_INFO_FW_DMCU 0x12
#define AMDGPU_INFO_NUM_BYTES_MOVED 0x0f
#define AMDGPU_INFO_VRAM_USAGE 0x10
#define AMDGPU_INFO_GTT_USAGE 0x11
diff --git a/libc/kernel/uapi/drm/drm_fourcc.h b/libc/kernel/uapi/drm/drm_fourcc.h
index 4589cfe..df89cd1 100644
--- a/libc/kernel/uapi/drm/drm_fourcc.h
+++ b/libc/kernel/uapi/drm/drm_fourcc.h
@@ -24,6 +24,7 @@
#endif
#define fourcc_code(a,b,c,d) ((__u32) (a) | ((__u32) (b) << 8) | ((__u32) (c) << 16) | ((__u32) (d) << 24))
#define DRM_FORMAT_BIG_ENDIAN (1 << 31)
+#define DRM_FORMAT_INVALID 0
#define DRM_FORMAT_C8 fourcc_code('C', '8', ' ', ' ')
#define DRM_FORMAT_R8 fourcc_code('R', '8', ' ', ' ')
#define DRM_FORMAT_R16 fourcc_code('R', '1', '6', ' ')
@@ -118,6 +119,7 @@
#define I915_FORMAT_MOD_Y_TILED_CCS fourcc_mod_code(INTEL, 4)
#define I915_FORMAT_MOD_Yf_TILED_CCS fourcc_mod_code(INTEL, 5)
#define DRM_FORMAT_MOD_SAMSUNG_64_32_TILE fourcc_mod_code(SAMSUNG, 1)
+#define DRM_FORMAT_MOD_SAMSUNG_16_16_TILE fourcc_mod_code(SAMSUNG, 2)
#define DRM_FORMAT_MOD_QCOM_COMPRESSED fourcc_mod_code(QCOM, 1)
#define DRM_FORMAT_MOD_VIVANTE_TILED fourcc_mod_code(VIVANTE, 1)
#define DRM_FORMAT_MOD_VIVANTE_SUPER_TILED fourcc_mod_code(VIVANTE, 2)
diff --git a/libc/kernel/uapi/drm/i915_drm.h b/libc/kernel/uapi/drm/i915_drm.h
index 53d1548..89fa529 100644
--- a/libc/kernel/uapi/drm/i915_drm.h
+++ b/libc/kernel/uapi/drm/i915_drm.h
@@ -335,6 +335,7 @@
#define I915_PARAM_HAS_EXEC_FENCE_ARRAY 49
#define I915_PARAM_HAS_CONTEXT_ISOLATION 50
#define I915_PARAM_CS_TIMESTAMP_FREQUENCY 51
+#define I915_PARAM_MMAP_GTT_COHERENT 52
typedef struct drm_i915_getparam {
__s32 param;
int __user * value;
diff --git a/libc/kernel/uapi/linux/android/binder.h b/libc/kernel/uapi/linux/android/binder.h
index 538a441..2d00a79 100644
--- a/libc/kernel/uapi/linux/android/binder.h
+++ b/libc/kernel/uapi/linux/android/binder.h
@@ -103,6 +103,14 @@
__u32 has_strong_ref;
__u32 has_weak_ref;
};
+struct binder_node_info_for_ref {
+ __u32 handle;
+ __u32 strong_count;
+ __u32 weak_count;
+ __u32 reserved1;
+ __u32 reserved2;
+ __u32 reserved3;
+};
#define BINDER_WRITE_READ _IOWR('b', 1, struct binder_write_read)
#define BINDER_SET_IDLE_TIMEOUT _IOW('b', 3, __s64)
#define BINDER_SET_MAX_THREADS _IOW('b', 5, __u32)
@@ -111,6 +119,7 @@
#define BINDER_THREAD_EXIT _IOW('b', 8, __s32)
#define BINDER_VERSION _IOWR('b', 9, struct binder_version)
#define BINDER_GET_NODE_DEBUG_INFO _IOWR('b', 11, struct binder_node_debug_info)
+#define BINDER_GET_NODE_INFO_FOR_REF _IOWR('b', 12, struct binder_node_info_for_ref)
enum transaction_flags {
TF_ONE_WAY = 0x01,
TF_ROOT_OBJECT = 0x04,
diff --git a/libc/kernel/uapi/linux/blkzoned.h b/libc/kernel/uapi/linux/blkzoned.h
index eaff1d8..62f826f 100644
--- a/libc/kernel/uapi/linux/blkzoned.h
+++ b/libc/kernel/uapi/linux/blkzoned.h
@@ -57,4 +57,6 @@
};
#define BLKREPORTZONE _IOWR(0x12, 130, struct blk_zone_report)
#define BLKRESETZONE _IOW(0x12, 131, struct blk_zone_range)
+#define BLKGETZONESZ _IOR(0x12, 132, __u32)
+#define BLKGETNRZONES _IOR(0x12, 133, __u32)
#endif
diff --git a/libc/kernel/uapi/linux/bpf.h b/libc/kernel/uapi/linux/bpf.h
index a187913..d70a409 100644
--- a/libc/kernel/uapi/linux/bpf.h
+++ b/libc/kernel/uapi/linux/bpf.h
@@ -91,6 +91,7 @@
BPF_BTF_LOAD,
BPF_BTF_GET_FD_BY_ID,
BPF_TASK_FD_QUERY,
+ BPF_MAP_LOOKUP_AND_DELETE_ELEM,
};
enum bpf_map_type {
BPF_MAP_TYPE_UNSPEC,
@@ -114,6 +115,9 @@
BPF_MAP_TYPE_SOCKHASH,
BPF_MAP_TYPE_CGROUP_STORAGE,
BPF_MAP_TYPE_REUSEPORT_SOCKARRAY,
+ BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE,
+ BPF_MAP_TYPE_QUEUE,
+ BPF_MAP_TYPE_STACK,
};
enum bpf_prog_type {
BPF_PROG_TYPE_UNSPEC,
@@ -138,6 +142,7 @@
BPF_PROG_TYPE_LWT_SEG6LOCAL,
BPF_PROG_TYPE_LIRC_MODE2,
BPF_PROG_TYPE_SK_REUSEPORT,
+ BPF_PROG_TYPE_FLOW_DISSECTOR,
};
enum bpf_attach_type {
BPF_CGROUP_INET_INGRESS,
@@ -157,6 +162,7 @@
BPF_CGROUP_UDP4_SENDMSG,
BPF_CGROUP_UDP6_SENDMSG,
BPF_LIRC_MODE2,
+ BPF_FLOW_DISSECTOR,
__MAX_BPF_ATTACH_TYPE
};
#define MAX_BPF_ATTACH_TYPE __MAX_BPF_ATTACH_TYPE
@@ -295,7 +301,7 @@
__u64 probe_addr;
} task_fd_query;
} __attribute__((aligned(8)));
-#define __BPF_FUNC_MAPPER(FN) FN(unspec), FN(map_lookup_elem), FN(map_update_elem), FN(map_delete_elem), FN(probe_read), FN(ktime_get_ns), FN(trace_printk), FN(get_prandom_u32), FN(get_smp_processor_id), FN(skb_store_bytes), FN(l3_csum_replace), FN(l4_csum_replace), FN(tail_call), FN(clone_redirect), FN(get_current_pid_tgid), FN(get_current_uid_gid), FN(get_current_comm), FN(get_cgroup_classid), FN(skb_vlan_push), FN(skb_vlan_pop), FN(skb_get_tunnel_key), FN(skb_set_tunnel_key), FN(perf_event_read), FN(redirect), FN(get_route_realm), FN(perf_event_output), FN(skb_load_bytes), FN(get_stackid), FN(csum_diff), FN(skb_get_tunnel_opt), FN(skb_set_tunnel_opt), FN(skb_change_proto), FN(skb_change_type), FN(skb_under_cgroup), FN(get_hash_recalc), FN(get_current_task), FN(probe_write_user), FN(current_task_under_cgroup), FN(skb_change_tail), FN(skb_pull_data), FN(csum_update), FN(set_hash_invalid), FN(get_numa_node_id), FN(skb_change_head), FN(xdp_adjust_head), FN(probe_read_str), FN(get_socket_cookie), FN(get_socket_uid), FN(set_hash), FN(setsockopt), FN(skb_adjust_room), FN(redirect_map), FN(sk_redirect_map), FN(sock_map_update), FN(xdp_adjust_meta), FN(perf_event_read_value), FN(perf_prog_read_value), FN(getsockopt), FN(override_return), FN(sock_ops_cb_flags_set), FN(msg_redirect_map), FN(msg_apply_bytes), FN(msg_cork_bytes), FN(msg_pull_data), FN(bind), FN(xdp_adjust_tail), FN(skb_get_xfrm_state), FN(get_stack), FN(skb_load_bytes_relative), FN(fib_lookup), FN(sock_hash_update), FN(msg_redirect_hash), FN(sk_redirect_hash), FN(lwt_push_encap), FN(lwt_seg6_store_bytes), FN(lwt_seg6_adjust_srh), FN(lwt_seg6_action), FN(rc_repeat), FN(rc_keydown), FN(skb_cgroup_id), FN(get_current_cgroup_id), FN(get_local_storage), FN(sk_select_reuseport), FN(skb_ancestor_cgroup_id),
+#define __BPF_FUNC_MAPPER(FN) FN(unspec), FN(map_lookup_elem), FN(map_update_elem), FN(map_delete_elem), FN(probe_read), FN(ktime_get_ns), FN(trace_printk), FN(get_prandom_u32), FN(get_smp_processor_id), FN(skb_store_bytes), FN(l3_csum_replace), FN(l4_csum_replace), FN(tail_call), FN(clone_redirect), FN(get_current_pid_tgid), FN(get_current_uid_gid), FN(get_current_comm), FN(get_cgroup_classid), FN(skb_vlan_push), FN(skb_vlan_pop), FN(skb_get_tunnel_key), FN(skb_set_tunnel_key), FN(perf_event_read), FN(redirect), FN(get_route_realm), FN(perf_event_output), FN(skb_load_bytes), FN(get_stackid), FN(csum_diff), FN(skb_get_tunnel_opt), FN(skb_set_tunnel_opt), FN(skb_change_proto), FN(skb_change_type), FN(skb_under_cgroup), FN(get_hash_recalc), FN(get_current_task), FN(probe_write_user), FN(current_task_under_cgroup), FN(skb_change_tail), FN(skb_pull_data), FN(csum_update), FN(set_hash_invalid), FN(get_numa_node_id), FN(skb_change_head), FN(xdp_adjust_head), FN(probe_read_str), FN(get_socket_cookie), FN(get_socket_uid), FN(set_hash), FN(setsockopt), FN(skb_adjust_room), FN(redirect_map), FN(sk_redirect_map), FN(sock_map_update), FN(xdp_adjust_meta), FN(perf_event_read_value), FN(perf_prog_read_value), FN(getsockopt), FN(override_return), FN(sock_ops_cb_flags_set), FN(msg_redirect_map), FN(msg_apply_bytes), FN(msg_cork_bytes), FN(msg_pull_data), FN(bind), FN(xdp_adjust_tail), FN(skb_get_xfrm_state), FN(get_stack), FN(skb_load_bytes_relative), FN(fib_lookup), FN(sock_hash_update), FN(msg_redirect_hash), FN(sk_redirect_hash), FN(lwt_push_encap), FN(lwt_seg6_store_bytes), FN(lwt_seg6_adjust_srh), FN(lwt_seg6_action), FN(rc_repeat), FN(rc_keydown), FN(skb_cgroup_id), FN(get_current_cgroup_id), FN(get_local_storage), FN(sk_select_reuseport), FN(skb_ancestor_cgroup_id), FN(sk_lookup_tcp), FN(sk_lookup_udp), FN(sk_release), FN(map_push_elem), FN(map_pop_elem), FN(map_peek_elem), FN(msg_push_data),
#define __BPF_ENUM_FN(x) BPF_FUNC_ ##x
enum bpf_func_id {
__BPF_FUNC_MAPPER(__BPF_ENUM_FN) __BPF_FUNC_MAX_ID,
@@ -320,6 +326,7 @@
#define BPF_F_INDEX_MASK 0xffffffffULL
#define BPF_F_CURRENT_CPU BPF_F_INDEX_MASK
#define BPF_F_CTXLEN_MASK (0xfffffULL << 32)
+#define BPF_F_CURRENT_NETNS (- 1L)
enum bpf_adj_room_mode {
BPF_ADJ_ROOM_NET,
};
@@ -331,6 +338,8 @@
BPF_LWT_ENCAP_SEG6,
BPF_LWT_ENCAP_SEG6_INLINE
};
+#define __bpf_md_ptr(type,name) union { type name; __u64 : 64; \
+} __attribute__((aligned(8)))
struct __sk_buff {
__u32 len;
__u32 pkt_type;
@@ -358,6 +367,7 @@
__u32 remote_port;
__u32 local_port;
__u32 data_meta;
+ __bpf_md_ptr(struct bpf_flow_keys *, flow_keys);
};
struct bpf_tunnel_key {
__u32 tunnel_id;
@@ -396,6 +406,22 @@
__u32 src_ip6[4];
__u32 src_port;
};
+struct bpf_sock_tuple {
+ union {
+ struct {
+ __be32 saddr;
+ __be32 daddr;
+ __be16 sport;
+ __be16 dport;
+ } ipv4;
+ struct {
+ __be32 saddr[4];
+ __be32 daddr[4];
+ __be16 sport;
+ __be16 dport;
+ } ipv6;
+ };
+};
#define XDP_PACKET_HEADROOM 256
enum xdp_action {
XDP_ABORTED = 0,
@@ -416,8 +442,8 @@
SK_PASS,
};
struct sk_msg_md {
- void * data;
- void * data_end;
+ __bpf_md_ptr(void *, data);
+ __bpf_md_ptr(void *, data_end);
__u32 family;
__u32 remote_ip4;
__u32 local_ip4;
@@ -427,8 +453,8 @@
__u32 local_port;
};
struct sk_reuseport_md {
- void * data;
- void * data_end;
+ __bpf_md_ptr(void *, data);
+ __bpf_md_ptr(void *, data_end);
__u32 len;
__u32 eth_protocol;
__u32 ip_protocol;
@@ -630,4 +656,26 @@
BPF_FD_TYPE_UPROBE,
BPF_FD_TYPE_URETPROBE,
};
+struct bpf_flow_keys {
+ __u16 nhoff;
+ __u16 thoff;
+ __u16 addr_proto;
+ __u8 is_frag;
+ __u8 is_first_frag;
+ __u8 is_encap;
+ __u8 ip_proto;
+ __be16 n_proto;
+ __be16 sport;
+ __be16 dport;
+ union {
+ struct {
+ __be32 ipv4_src;
+ __be32 ipv4_dst;
+ };
+ struct {
+ __u32 ipv6_src[4];
+ __u32 ipv6_dst[4];
+ };
+ };
+};
#endif
diff --git a/libc/kernel/uapi/linux/cec.h b/libc/kernel/uapi/linux/cec.h
index fd0f824..05af529 100644
--- a/libc/kernel/uapi/linux/cec.h
+++ b/libc/kernel/uapi/linux/cec.h
@@ -44,9 +44,12 @@
#define CEC_TX_STATUS_LOW_DRIVE (1 << 3)
#define CEC_TX_STATUS_ERROR (1 << 4)
#define CEC_TX_STATUS_MAX_RETRIES (1 << 5)
+#define CEC_TX_STATUS_ABORTED (1 << 6)
+#define CEC_TX_STATUS_TIMEOUT (1 << 7)
#define CEC_RX_STATUS_OK (1 << 0)
#define CEC_RX_STATUS_TIMEOUT (1 << 1)
#define CEC_RX_STATUS_FEATURE_ABORT (1 << 2)
+#define CEC_RX_STATUS_ABORTED (1 << 3)
#define CEC_LOG_ADDR_INVALID 0xff
#define CEC_PHYS_ADDR_INVALID 0xffff
#define CEC_MAX_LOG_ADDRS 4
diff --git a/libc/kernel/uapi/linux/cryptouser.h b/libc/kernel/uapi/linux/cryptouser.h
index 15c46d8..816fb05 100644
--- a/libc/kernel/uapi/linux/cryptouser.h
+++ b/libc/kernel/uapi/linux/cryptouser.h
@@ -24,6 +24,7 @@
CRYPTO_MSG_UPDATEALG,
CRYPTO_MSG_GETALG,
CRYPTO_MSG_DELRNG,
+ CRYPTO_MSG_GETSTAT,
__CRYPTO_MSG_MAX
};
#define CRYPTO_MSG_MAX (__CRYPTO_MSG_MAX - 1)
@@ -42,6 +43,16 @@
CRYPTOCFGA_REPORT_AKCIPHER,
CRYPTOCFGA_REPORT_KPP,
CRYPTOCFGA_REPORT_ACOMP,
+ CRYPTOCFGA_STAT_LARVAL,
+ CRYPTOCFGA_STAT_HASH,
+ CRYPTOCFGA_STAT_BLKCIPHER,
+ CRYPTOCFGA_STAT_AEAD,
+ CRYPTOCFGA_STAT_COMPRESS,
+ CRYPTOCFGA_STAT_RNG,
+ CRYPTOCFGA_STAT_CIPHER,
+ CRYPTOCFGA_STAT_AKCIPHER,
+ CRYPTOCFGA_STAT_KPP,
+ CRYPTOCFGA_STAT_ACOMP,
__CRYPTOCFGA_MAX
#define CRYPTOCFGA_MAX (__CRYPTOCFGA_MAX - 1)
};
@@ -54,6 +65,46 @@
__u32 cru_refcnt;
__u32 cru_flags;
};
+struct crypto_stat {
+ char type[CRYPTO_MAX_NAME];
+ union {
+ __u32 stat_encrypt_cnt;
+ __u32 stat_compress_cnt;
+ __u32 stat_generate_cnt;
+ __u32 stat_hash_cnt;
+ __u32 stat_setsecret_cnt;
+ };
+ union {
+ __u64 stat_encrypt_tlen;
+ __u64 stat_compress_tlen;
+ __u64 stat_generate_tlen;
+ __u64 stat_hash_tlen;
+ };
+ union {
+ __u32 stat_akcipher_err_cnt;
+ __u32 stat_cipher_err_cnt;
+ __u32 stat_compress_err_cnt;
+ __u32 stat_aead_err_cnt;
+ __u32 stat_hash_err_cnt;
+ __u32 stat_rng_err_cnt;
+ __u32 stat_kpp_err_cnt;
+ };
+ union {
+ __u32 stat_decrypt_cnt;
+ __u32 stat_decompress_cnt;
+ __u32 stat_seed_cnt;
+ __u32 stat_generate_public_key_cnt;
+ };
+ union {
+ __u64 stat_decrypt_tlen;
+ __u64 stat_decompress_tlen;
+ };
+ union {
+ __u32 stat_verify_cnt;
+ __u32 stat_compute_shared_secret_cnt;
+ };
+ __u32 stat_sign_cnt;
+};
struct crypto_report_larval {
char type[CRYPTO_MAX_NAME];
};
diff --git a/libc/kernel/uapi/linux/dns_resolver.h b/libc/kernel/uapi/linux/dns_resolver.h
new file mode 100644
index 0000000..21cb5c0
--- /dev/null
+++ b/libc/kernel/uapi/linux/dns_resolver.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ *** To edit the content of this header, modify the corresponding
+ *** source file (e.g. under external/kernel-headers/original/) then
+ *** run bionic/libc/kernel/tools/update_all.py
+ ***
+ *** Any manual change here will be lost the next time this script will
+ *** be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _UAPI_LINUX_DNS_RESOLVER_H
+#define _UAPI_LINUX_DNS_RESOLVER_H
+#include <linux/types.h>
+enum dns_payload_content_type {
+ DNS_PAYLOAD_IS_SERVER_LIST = 0,
+};
+enum dns_payload_address_type {
+ DNS_ADDRESS_IS_IPV4 = 0,
+ DNS_ADDRESS_IS_IPV6 = 1,
+};
+enum dns_payload_protocol_type {
+ DNS_SERVER_PROTOCOL_UNSPECIFIED = 0,
+ DNS_SERVER_PROTOCOL_UDP = 1,
+ DNS_SERVER_PROTOCOL_TCP = 2,
+};
+enum dns_record_source {
+ DNS_RECORD_UNAVAILABLE = 0,
+ DNS_RECORD_FROM_CONFIG = 1,
+ DNS_RECORD_FROM_DNS_A = 2,
+ DNS_RECORD_FROM_DNS_AFSDB = 3,
+ DNS_RECORD_FROM_DNS_SRV = 4,
+ DNS_RECORD_FROM_NSS = 5,
+ NR__dns_record_source
+};
+enum dns_lookup_status {
+ DNS_LOOKUP_NOT_DONE = 0,
+ DNS_LOOKUP_GOOD = 1,
+ DNS_LOOKUP_GOOD_WITH_BAD = 2,
+ DNS_LOOKUP_BAD = 3,
+ DNS_LOOKUP_GOT_NOT_FOUND = 4,
+ DNS_LOOKUP_GOT_LOCAL_FAILURE = 5,
+ DNS_LOOKUP_GOT_TEMP_FAILURE = 6,
+ DNS_LOOKUP_GOT_NS_FAILURE = 7,
+ NR__dns_lookup_status
+};
+struct dns_payload_header {
+ __u8 zero;
+ __u8 content;
+ __u8 version;
+} __packed;
+struct dns_server_list_v1_header {
+ struct dns_payload_header hdr;
+ __u8 source;
+ __u8 status;
+ __u8 nr_servers;
+} __packed;
+struct dns_server_list_v1_server {
+ __u16 name_len;
+ __u16 priority;
+ __u16 weight;
+ __u16 port;
+ __u8 source;
+ __u8 status;
+ __u8 protocol;
+ __u8 nr_addrs;
+} __packed;
+struct dns_server_list_v1_address {
+ __u8 address_type;
+} __packed;
+#endif
diff --git a/libc/kernel/uapi/linux/elf-em.h b/libc/kernel/uapi/linux/elf-em.h
index b7c89da..5b54e18 100644
--- a/libc/kernel/uapi/linux/elf-em.h
+++ b/libc/kernel/uapi/linux/elf-em.h
@@ -52,6 +52,7 @@
#define EM_TILEPRO 188
#define EM_MICROBLAZE 189
#define EM_TILEGX 191
+#define EM_RISCV 243
#define EM_BPF 247
#define EM_FRV 0x5441
#define EM_ALPHA 0x9026
diff --git a/libc/kernel/uapi/linux/fanotify.h b/libc/kernel/uapi/linux/fanotify.h
index 73d92ca..00a1871 100644
--- a/libc/kernel/uapi/linux/fanotify.h
+++ b/libc/kernel/uapi/linux/fanotify.h
@@ -39,15 +39,18 @@
#define FAN_UNLIMITED_QUEUE 0x00000010
#define FAN_UNLIMITED_MARKS 0x00000020
#define FAN_ENABLE_AUDIT 0x00000040
+#define FAN_REPORT_TID 0x00000100
#define FAN_ALL_INIT_FLAGS (FAN_CLOEXEC | FAN_NONBLOCK | FAN_ALL_CLASS_BITS | FAN_UNLIMITED_QUEUE | FAN_UNLIMITED_MARKS)
#define FAN_MARK_ADD 0x00000001
#define FAN_MARK_REMOVE 0x00000002
#define FAN_MARK_DONT_FOLLOW 0x00000004
#define FAN_MARK_ONLYDIR 0x00000008
-#define FAN_MARK_MOUNT 0x00000010
#define FAN_MARK_IGNORED_MASK 0x00000020
#define FAN_MARK_IGNORED_SURV_MODIFY 0x00000040
#define FAN_MARK_FLUSH 0x00000080
+#define FAN_MARK_INODE 0x00000000
+#define FAN_MARK_MOUNT 0x00000010
+#define FAN_MARK_FILESYSTEM 0x00000100
#define FAN_ALL_MARK_FLAGS (FAN_MARK_ADD | FAN_MARK_REMOVE | FAN_MARK_DONT_FOLLOW | FAN_MARK_ONLYDIR | FAN_MARK_MOUNT | FAN_MARK_IGNORED_MASK | FAN_MARK_IGNORED_SURV_MODIFY | FAN_MARK_FLUSH)
#define FAN_ALL_EVENTS (FAN_ACCESS | FAN_MODIFY | FAN_CLOSE | FAN_OPEN)
#define FAN_ALL_PERM_EVENTS (FAN_OPEN_PERM | FAN_ACCESS_PERM)
diff --git a/libc/kernel/uapi/linux/fuse.h b/libc/kernel/uapi/linux/fuse.h
index a727580..3c3a124 100644
--- a/libc/kernel/uapi/linux/fuse.h
+++ b/libc/kernel/uapi/linux/fuse.h
@@ -20,7 +20,7 @@
#define _LINUX_FUSE_H
#include <stdint.h>
#define FUSE_KERNEL_VERSION 7
-#define FUSE_KERNEL_MINOR_VERSION 27
+#define FUSE_KERNEL_MINOR_VERSION 28
#define FUSE_ROOT_ID 1
struct fuse_attr {
uint64_t ino;
@@ -72,6 +72,7 @@
#define FOPEN_DIRECT_IO (1 << 0)
#define FOPEN_KEEP_CACHE (1 << 1)
#define FOPEN_NONSEEKABLE (1 << 2)
+#define FOPEN_CACHE_DIR (1 << 3)
#define FUSE_ASYNC_READ (1 << 0)
#define FUSE_POSIX_LOCKS (1 << 1)
#define FUSE_FILE_OPS (1 << 2)
@@ -94,6 +95,8 @@
#define FUSE_HANDLE_KILLPRIV (1 << 19)
#define FUSE_POSIX_ACL (1 << 20)
#define FUSE_ABORT_ERROR (1 << 21)
+#define FUSE_MAX_PAGES (1 << 22)
+#define FUSE_CACHE_SYMLINKS (1 << 23)
#define CUSE_UNRESTRICTED_IOCTL (1 << 0)
#define FUSE_RELEASE_FLUSH (1 << 0)
#define FUSE_RELEASE_FLOCK_UNLOCK (1 << 1)
@@ -154,6 +157,7 @@
FUSE_READDIRPLUS = 44,
FUSE_RENAME2 = 45,
FUSE_LSEEK = 46,
+ FUSE_COPY_FILE_RANGE = 47,
CUSE_INIT = 4096,
};
enum fuse_notify_code {
@@ -341,7 +345,9 @@
uint16_t congestion_threshold;
uint32_t max_write;
uint32_t time_gran;
- uint32_t unused[9];
+ uint16_t max_pages;
+ uint16_t padding;
+ uint32_t unused[8];
};
#define CUSE_INIT_INFO_MAX 4096
struct cuse_init_in {
@@ -488,4 +494,13 @@
struct fuse_lseek_out {
uint64_t offset;
};
+struct fuse_copy_file_range_in {
+ uint64_t fh_in;
+ uint64_t off_in;
+ uint64_t nodeid_out;
+ uint64_t fh_out;
+ uint64_t off_out;
+ uint64_t len;
+ uint64_t flags;
+};
#endif
diff --git a/libc/kernel/uapi/linux/gen_stats.h b/libc/kernel/uapi/linux/gen_stats.h
index 127ae88..0b6c228 100644
--- a/libc/kernel/uapi/linux/gen_stats.h
+++ b/libc/kernel/uapi/linux/gen_stats.h
@@ -27,6 +27,7 @@
TCA_STATS_APP,
TCA_STATS_RATE_EST64,
TCA_STATS_PAD,
+ TCA_STATS_BASIC_HW,
__TCA_STATS_MAX,
};
#define TCA_STATS_MAX (__TCA_STATS_MAX - 1)
diff --git a/libc/kernel/uapi/linux/if_addr.h b/libc/kernel/uapi/linux/if_addr.h
index 0a4b0ae..6a6b640 100644
--- a/libc/kernel/uapi/linux/if_addr.h
+++ b/libc/kernel/uapi/linux/if_addr.h
@@ -38,6 +38,7 @@
IFA_MULTICAST,
IFA_FLAGS,
IFA_RT_PRIORITY,
+ IFA_TARGET_NETNSID,
__IFA_MAX,
};
#define IFA_MAX (__IFA_MAX - 1)
diff --git a/libc/kernel/uapi/linux/if_arp.h b/libc/kernel/uapi/linux/if_arp.h
index 0b1959d..eda888f 100644
--- a/libc/kernel/uapi/linux/if_arp.h
+++ b/libc/kernel/uapi/linux/if_arp.h
@@ -98,7 +98,7 @@
struct sockaddr arp_ha;
int arp_flags;
struct sockaddr arp_netmask;
- char arp_dev[16];
+ char arp_dev[IFNAMSIZ];
};
struct arpreq_old {
struct sockaddr arp_pa;
diff --git a/libc/kernel/uapi/linux/if_fddi.h b/libc/kernel/uapi/linux/if_fddi.h
index 4efd7f8..4b5074b 100644
--- a/libc/kernel/uapi/linux/if_fddi.h
+++ b/libc/kernel/uapi/linux/if_fddi.h
@@ -29,6 +29,18 @@
#define FDDI_K_LLC_ZLEN 13
#define FDDI_K_LLC_LEN 4491
#define FDDI_K_OUI_LEN 3
+#define FDDI_FC_K_CLASS_MASK 0x80
+#define FDDI_FC_K_CLASS_SYNC 0x80
+#define FDDI_FC_K_CLASS_ASYNC 0x00
+#define FDDI_FC_K_ALEN_MASK 0x40
+#define FDDI_FC_K_ALEN_48 0x40
+#define FDDI_FC_K_ALEN_16 0x00
+#define FDDI_FC_K_FORMAT_MASK 0x30
+#define FDDI_FC_K_FORMAT_FUTURE 0x30
+#define FDDI_FC_K_FORMAT_IMPLEMENTOR 0x20
+#define FDDI_FC_K_FORMAT_LLC 0x10
+#define FDDI_FC_K_FORMAT_MANAGEMENT 0x00
+#define FDDI_FC_K_CONTROL_MASK 0x0f
#define FDDI_FC_K_VOID 0x00
#define FDDI_FC_K_NON_RESTRICTED_TOKEN 0x80
#define FDDI_FC_K_RESTRICTED_TOKEN 0xC0
diff --git a/libc/kernel/uapi/linux/if_link.h b/libc/kernel/uapi/linux/if_link.h
index 4bbf21d..2c80d3d 100644
--- a/libc/kernel/uapi/linux/if_link.h
+++ b/libc/kernel/uapi/linux/if_link.h
@@ -138,6 +138,7 @@
IFLA_EVENT,
IFLA_NEW_NETNSID,
IFLA_IF_NETNSID,
+ IFLA_TARGET_NETNSID = IFLA_IF_NETNSID,
IFLA_CARRIER_UP_COUNT,
IFLA_CARRIER_DOWN_COUNT,
IFLA_NEW_IFINDEX,
@@ -219,6 +220,7 @@
IFLA_BR_MCAST_STATS_ENABLED,
IFLA_BR_MCAST_IGMP_VERSION,
IFLA_BR_MCAST_MLD_VERSION,
+ IFLA_BR_VLAN_STATS_PER_PORT,
__IFLA_BR_MAX,
};
#define IFLA_BR_MAX (__IFLA_BR_MAX - 1)
@@ -444,6 +446,7 @@
IFLA_GENEVE_UDP_ZERO_CSUM6_TX,
IFLA_GENEVE_UDP_ZERO_CSUM6_RX,
IFLA_GENEVE_LABEL,
+ IFLA_GENEVE_TTL_INHERIT,
__IFLA_GENEVE_MAX
};
#define IFLA_GENEVE_MAX (__IFLA_GENEVE_MAX - 1)
diff --git a/libc/kernel/uapi/linux/if_packet.h b/libc/kernel/uapi/linux/if_packet.h
index 61d0a3a..300aa7b 100644
--- a/libc/kernel/uapi/linux/if_packet.h
+++ b/libc/kernel/uapi/linux/if_packet.h
@@ -63,6 +63,7 @@
#define PACKET_QDISC_BYPASS 20
#define PACKET_ROLLOVER_STATS 21
#define PACKET_FANOUT_DATA 22
+#define PACKET_IGNORE_OUTGOING 23
#define PACKET_FANOUT_HASH 0
#define PACKET_FANOUT_LB 1
#define PACKET_FANOUT_CPU 2
diff --git a/libc/kernel/uapi/linux/if_tunnel.h b/libc/kernel/uapi/linux/if_tunnel.h
index d41dc49..8e1847f 100644
--- a/libc/kernel/uapi/linux/if_tunnel.h
+++ b/libc/kernel/uapi/linux/if_tunnel.h
@@ -154,4 +154,20 @@
__IFLA_VTI_MAX,
};
#define IFLA_VTI_MAX (__IFLA_VTI_MAX - 1)
+#define TUNNEL_CSUM __cpu_to_be16(0x01)
+#define TUNNEL_ROUTING __cpu_to_be16(0x02)
+#define TUNNEL_KEY __cpu_to_be16(0x04)
+#define TUNNEL_SEQ __cpu_to_be16(0x08)
+#define TUNNEL_STRICT __cpu_to_be16(0x10)
+#define TUNNEL_REC __cpu_to_be16(0x20)
+#define TUNNEL_VERSION __cpu_to_be16(0x40)
+#define TUNNEL_NO_KEY __cpu_to_be16(0x80)
+#define TUNNEL_DONT_FRAGMENT __cpu_to_be16(0x0100)
+#define TUNNEL_OAM __cpu_to_be16(0x0200)
+#define TUNNEL_CRIT_OPT __cpu_to_be16(0x0400)
+#define TUNNEL_GENEVE_OPT __cpu_to_be16(0x0800)
+#define TUNNEL_VXLAN_OPT __cpu_to_be16(0x1000)
+#define TUNNEL_NOCACHE __cpu_to_be16(0x2000)
+#define TUNNEL_ERSPAN_OPT __cpu_to_be16(0x4000)
+#define TUNNEL_OPTIONS_PRESENT (TUNNEL_GENEVE_OPT | TUNNEL_VXLAN_OPT | TUNNEL_ERSPAN_OPT)
#endif
diff --git a/libc/kernel/uapi/linux/in.h b/libc/kernel/uapi/linux/in.h
index 788a6d9..78bd72a 100644
--- a/libc/kernel/uapi/linux/in.h
+++ b/libc/kernel/uapi/linux/in.h
@@ -200,9 +200,12 @@
#define IN_CLASSC_HOST (0xffffffff & ~IN_CLASSC_NET)
#define IN_CLASSD(a) ((((long int) (a)) & 0xf0000000) == 0xe0000000)
#define IN_MULTICAST(a) IN_CLASSD(a)
-#define IN_MULTICAST_NET 0xF0000000
-#define IN_EXPERIMENTAL(a) ((((long int) (a)) & 0xf0000000) == 0xf0000000)
-#define IN_BADCLASS(a) IN_EXPERIMENTAL((a))
+#define IN_MULTICAST_NET 0xe0000000
+#define IN_BADCLASS(a) (((long int) (a)) == (long int)0xffffffff)
+#define IN_EXPERIMENTAL(a) IN_BADCLASS((a))
+#define IN_CLASSE(a) ((((long int) (a)) & 0xf0000000) == 0xf0000000)
+#define IN_CLASSE_NET 0xffffffff
+#define IN_CLASSE_NSHIFT 0
#define INADDR_ANY ((unsigned long int) 0x00000000)
#define INADDR_BROADCAST ((unsigned long int) 0xffffffff)
#define INADDR_NONE ((unsigned long int) 0xffffffff)
diff --git a/libc/kernel/uapi/linux/in6.h b/libc/kernel/uapi/linux/in6.h
index 9da111c..3627f52 100644
--- a/libc/kernel/uapi/linux/in6.h
+++ b/libc/kernel/uapi/linux/in6.h
@@ -132,6 +132,7 @@
#define IPV6_V6ONLY 26
#define IPV6_JOIN_ANYCAST 27
#define IPV6_LEAVE_ANYCAST 28
+#define IPV6_MULTICAST_ALL 29
#define IPV6_PMTUDISC_DONT 0
#define IPV6_PMTUDISC_WANT 1
#define IPV6_PMTUDISC_DO 2
diff --git a/libc/kernel/uapi/linux/input-event-codes.h b/libc/kernel/uapi/linux/input-event-codes.h
index d8ae4c8..11e6d5b 100644
--- a/libc/kernel/uapi/linux/input-event-codes.h
+++ b/libc/kernel/uapi/linux/input-event-codes.h
@@ -622,6 +622,7 @@
#define REL_DIAL 0x07
#define REL_WHEEL 0x08
#define REL_MISC 0x09
+#define REL_RESERVED 0x0a
#define REL_MAX 0x0f
#define REL_CNT (REL_MAX + 1)
#define ABS_X 0x00
@@ -650,6 +651,7 @@
#define ABS_TOOL_WIDTH 0x1c
#define ABS_VOLUME 0x20
#define ABS_MISC 0x28
+#define ABS_RESERVED 0x2e
#define ABS_MT_SLOT 0x2f
#define ABS_MT_TOUCH_MAJOR 0x30
#define ABS_MT_TOUCH_MINOR 0x31
diff --git a/libc/kernel/uapi/linux/keyctl.h b/libc/kernel/uapi/linux/keyctl.h
index 0cc7f55..53f0468 100644
--- a/libc/kernel/uapi/linux/keyctl.h
+++ b/libc/kernel/uapi/linux/keyctl.h
@@ -60,9 +60,19 @@
#define KEYCTL_INVALIDATE 21
#define KEYCTL_GET_PERSISTENT 22
#define KEYCTL_DH_COMPUTE 23
+#define KEYCTL_PKEY_QUERY 24
+#define KEYCTL_PKEY_ENCRYPT 25
+#define KEYCTL_PKEY_DECRYPT 26
+#define KEYCTL_PKEY_SIGN 27
+#define KEYCTL_PKEY_VERIFY 28
#define KEYCTL_RESTRICT_KEYRING 29
struct keyctl_dh_params {
- __s32 __linux_private;
+ union {
+#ifndef __cplusplus
+ __s32 __linux_private;
+#endif
+ __s32 priv;
+ };
__s32 prime;
__s32 base;
};
@@ -72,4 +82,26 @@
__u32 otherinfolen;
__u32 __spare[8];
};
+#define KEYCTL_SUPPORTS_ENCRYPT 0x01
+#define KEYCTL_SUPPORTS_DECRYPT 0x02
+#define KEYCTL_SUPPORTS_SIGN 0x04
+#define KEYCTL_SUPPORTS_VERIFY 0x08
+struct keyctl_pkey_query {
+ __u32 supported_ops;
+ __u32 key_size;
+ __u16 max_data_size;
+ __u16 max_sig_size;
+ __u16 max_enc_size;
+ __u16 max_dec_size;
+ __u32 __spare[10];
+};
+struct keyctl_pkey_params {
+ __s32 key_id;
+ __u32 in_len;
+ union {
+ __u32 out_len;
+ __u32 in2_len;
+ };
+ __u32 __spare[7];
+};
#endif
diff --git a/libc/kernel/uapi/linux/kfd_ioctl.h b/libc/kernel/uapi/linux/kfd_ioctl.h
index 55aff04..525f672 100644
--- a/libc/kernel/uapi/linux/kfd_ioctl.h
+++ b/libc/kernel/uapi/linux/kfd_ioctl.h
@@ -64,6 +64,13 @@
__u32 num_cu_mask;
__u64 cu_mask_ptr;
};
+struct kfd_ioctl_get_queue_wave_state_args {
+ __u64 ctl_stack_address;
+ __u32 ctl_stack_used_size;
+ __u32 save_area_used_size;
+ __u32 queue_id;
+ __u32 pad;
+};
#define KFD_IOC_CACHE_POLICY_COHERENT 0
#define KFD_IOC_CACHE_POLICY_NONCOHERENT 1
struct kfd_ioctl_set_memory_policy_args {
@@ -175,10 +182,10 @@
__u32 pad;
};
struct kfd_hsa_hw_exception_data {
- uint32_t reset_type;
- uint32_t reset_cause;
- uint32_t memory_lost;
- uint32_t gpu_id;
+ __u32 reset_type;
+ __u32 reset_cause;
+ __u32 memory_lost;
+ __u32 gpu_id;
};
struct kfd_event_data {
union {
@@ -285,6 +292,7 @@
#define AMDKFD_IOC_MAP_MEMORY_TO_GPU AMDKFD_IOWR(0x18, struct kfd_ioctl_map_memory_to_gpu_args)
#define AMDKFD_IOC_UNMAP_MEMORY_FROM_GPU AMDKFD_IOWR(0x19, struct kfd_ioctl_unmap_memory_from_gpu_args)
#define AMDKFD_IOC_SET_CU_MASK AMDKFD_IOW(0x1A, struct kfd_ioctl_set_cu_mask_args)
+#define AMDKFD_IOC_GET_QUEUE_WAVE_STATE AMDKFD_IOWR(0x1B, struct kfd_ioctl_get_queue_wave_state_args)
#define AMDKFD_COMMAND_START 0x01
-#define AMDKFD_COMMAND_END 0x1B
+#define AMDKFD_COMMAND_END 0x1C
#endif
diff --git a/libc/kernel/uapi/linux/kvm.h b/libc/kernel/uapi/linux/kvm.h
index 14e882b..b70bcd9 100644
--- a/libc/kernel/uapi/linux/kvm.h
+++ b/libc/kernel/uapi/linux/kvm.h
@@ -316,12 +316,18 @@
struct kvm_coalesced_mmio_zone {
__u64 addr;
__u32 size;
- __u32 pad;
+ union {
+ __u32 pad;
+ __u32 pio;
+ };
};
struct kvm_coalesced_mmio {
__u64 phys_addr;
__u32 len;
- __u32 pad;
+ union {
+ __u32 pad;
+ __u32 pio;
+ };
__u8 data[8];
};
struct kvm_coalesced_mmio_ring {
@@ -539,6 +545,7 @@
};
#define KVM_PPC_PAGE_SIZES_REAL 0x00000001
#define KVM_PPC_1T_SEGMENTS 0x00000002
+#define KVM_PPC_NO_HASH 0x00000004
struct kvm_ppc_smmu_info {
__u64 flags;
__u32 slb_size;
@@ -558,6 +565,8 @@
#define KVM_VM_MIPS_TE 0
#define KVM_VM_MIPS_VZ 1
#define KVM_S390_SIE_PAGE_OFFSET 1
+#define KVM_VM_TYPE_ARM_IPA_SIZE_MASK 0xffULL
+#define KVM_VM_TYPE_ARM_IPA_SIZE(x) ((x) & KVM_VM_TYPE_ARM_IPA_SIZE_MASK)
#define KVM_GET_API_VERSION _IO(KVMIO, 0x00)
#define KVM_CREATE_VM _IO(KVMIO, 0x01)
#define KVM_GET_MSR_INDEX_LIST _IOWR(KVMIO, 0x02, struct kvm_msr_list)
@@ -744,6 +753,12 @@
#define KVM_CAP_NESTED_STATE 157
#define KVM_CAP_ARM_INJECT_SERROR_ESR 158
#define KVM_CAP_MSR_PLATFORM_INFO 159
+#define KVM_CAP_PPC_NESTED_HV 160
+#define KVM_CAP_HYPERV_SEND_IPI 161
+#define KVM_CAP_COALESCED_PIO 162
+#define KVM_CAP_HYPERV_ENLIGHTENED_VMCS 163
+#define KVM_CAP_EXCEPTION_PAYLOAD 164
+#define KVM_CAP_ARM_VM_IPA_SIZE 165
#ifdef KVM_CAP_IRQ_ROUTING
struct kvm_irq_routing_irqchip {
__u32 irqchip;
diff --git a/libc/kernel/uapi/linux/magic.h b/libc/kernel/uapi/linux/magic.h
index 68b4c65..bf57a58 100644
--- a/libc/kernel/uapi/linux/magic.h
+++ b/libc/kernel/uapi/linux/magic.h
@@ -45,6 +45,7 @@
#define HPFS_SUPER_MAGIC 0xf995e849
#define ISOFS_SUPER_MAGIC 0x9660
#define JFFS2_SUPER_MAGIC 0x72b6
+#define XFS_SUPER_MAGIC 0x58465342
#define PSTOREFS_MAGIC 0x6165676C
#define EFIVARFS_MAGIC 0xde5e81e4
#define HOSTFS_SUPER_MAGIC 0x00c0ffee
diff --git a/libc/kernel/uapi/linux/media.h b/libc/kernel/uapi/linux/media.h
index eefc07a..4ba0ef6 100644
--- a/libc/kernel/uapi/linux/media.h
+++ b/libc/kernel/uapi/linux/media.h
@@ -198,6 +198,9 @@
#define MEDIA_IOC_ENUM_LINKS _IOWR('|', 0x02, struct media_links_enum)
#define MEDIA_IOC_SETUP_LINK _IOWR('|', 0x03, struct media_link_desc)
#define MEDIA_IOC_G_TOPOLOGY _IOWR('|', 0x04, struct media_v2_topology)
+#define MEDIA_IOC_REQUEST_ALLOC _IOR('|', 0x05, int)
+#define MEDIA_REQUEST_IOC_QUEUE _IO('|', 0x80)
+#define MEDIA_REQUEST_IOC_REINIT _IO('|', 0x81)
#define MEDIA_ENT_TYPE_SHIFT 16
#define MEDIA_ENT_TYPE_MASK 0x00ff0000
#define MEDIA_ENT_SUBTYPE_MASK 0x0000ffff
diff --git a/libc/kernel/uapi/linux/ncsi.h b/libc/kernel/uapi/linux/ncsi.h
index 6b128e4..23cdf1b 100644
--- a/libc/kernel/uapi/linux/ncsi.h
+++ b/libc/kernel/uapi/linux/ncsi.h
@@ -23,6 +23,7 @@
NCSI_CMD_PKG_INFO,
NCSI_CMD_SET_INTERFACE,
NCSI_CMD_CLEAR_INTERFACE,
+ NCSI_CMD_SEND_CMD,
__NCSI_CMD_AFTER_LAST,
NCSI_CMD_MAX = __NCSI_CMD_AFTER_LAST - 1
};
@@ -32,6 +33,7 @@
NCSI_ATTR_PACKAGE_LIST,
NCSI_ATTR_PACKAGE_ID,
NCSI_ATTR_CHANNEL_ID,
+ NCSI_ATTR_DATA,
__NCSI_ATTR_AFTER_LAST,
NCSI_ATTR_MAX = __NCSI_ATTR_AFTER_LAST - 1
};
diff --git a/libc/kernel/uapi/linux/ndctl.h b/libc/kernel/uapi/linux/ndctl.h
index bee0b1c..742fbad 100644
--- a/libc/kernel/uapi/linux/ndctl.h
+++ b/libc/kernel/uapi/linux/ndctl.h
@@ -140,9 +140,6 @@
ND_DRIVER_NAMESPACE_BLK = 1 << ND_DEVICE_NAMESPACE_BLK,
ND_DRIVER_DAX_PMEM = 1 << ND_DEVICE_DAX_PMEM,
};
-enum {
- ND_MIN_NAMESPACE_SIZE = PAGE_SIZE,
-};
enum ars_masks {
ARS_STATUS_MASK = 0x0000FFFF,
ARS_EXT_STATUS_SHIFT = 16,
diff --git a/libc/kernel/uapi/linux/neighbour.h b/libc/kernel/uapi/linux/neighbour.h
index cf32a12..6329211 100644
--- a/libc/kernel/uapi/linux/neighbour.h
+++ b/libc/kernel/uapi/linux/neighbour.h
@@ -51,6 +51,7 @@
#define NTF_PROXY 0x08
#define NTF_EXT_LEARNED 0x10
#define NTF_OFFLOADED 0x20
+#define NTF_STICKY 0x40
#define NTF_ROUTER 0x80
#define NUD_INCOMPLETE 0x01
#define NUD_REACHABLE 0x02
diff --git a/libc/kernel/uapi/linux/net_tstamp.h b/libc/kernel/uapi/linux/net_tstamp.h
index 2f022ea..375906a 100644
--- a/libc/kernel/uapi/linux/net_tstamp.h
+++ b/libc/kernel/uapi/linux/net_tstamp.h
@@ -80,7 +80,7 @@
SOF_TXTIME_FLAGS_MASK = (SOF_TXTIME_FLAGS_LAST - 1) | SOF_TXTIME_FLAGS_LAST
};
struct sock_txtime {
- clockid_t clockid;
+ __kernel_clockid_t clockid;
__u32 flags;
};
#endif
diff --git a/libc/kernel/uapi/linux/netfilter/nf_tables.h b/libc/kernel/uapi/linux/netfilter/nf_tables.h
index 63394e0..2bb7c86 100644
--- a/libc/kernel/uapi/linux/netfilter/nf_tables.h
+++ b/libc/kernel/uapi/linux/netfilter/nf_tables.h
@@ -419,6 +419,7 @@
NFT_RT_NEXTHOP4,
NFT_RT_NEXTHOP6,
NFT_RT_TCPMSS,
+ NFT_RT_XFRM,
__NFT_RT_MAX
};
#define NFT_RT_MAX (__NFT_RT_MAX - 1)
@@ -596,6 +597,13 @@
__NFTA_QUOTA_MAX
};
#define NFTA_QUOTA_MAX (__NFTA_QUOTA_MAX - 1)
+enum nft_secmark_attributes {
+ NFTA_SECMARK_UNSPEC,
+ NFTA_SECMARK_CTX,
+ __NFTA_SECMARK_MAX,
+};
+#define NFTA_SECMARK_MAX (__NFTA_SECMARK_MAX - 1)
+#define NFT_SECMARK_CTX_MAXLEN 256
enum nft_reject_types {
NFT_REJECT_ICMP_UNREACH,
NFT_REJECT_TCP_RST,
@@ -737,7 +745,8 @@
#define NFT_OBJECT_CONNLIMIT 5
#define NFT_OBJECT_TUNNEL 6
#define NFT_OBJECT_CT_TIMEOUT 7
-#define __NFT_OBJECT_MAX 8
+#define NFT_OBJECT_SECMARK 8
+#define __NFT_OBJECT_MAX 9
#define NFT_OBJECT_MAX (__NFT_OBJECT_MAX - 1)
enum nft_object_attributes {
NFTA_OBJ_UNSPEC,
@@ -773,6 +782,7 @@
enum nft_osf_attributes {
NFTA_OSF_UNSPEC,
NFTA_OSF_DREG,
+ NFTA_OSF_TTL,
__NFTA_OSF_MAX,
};
#define NFTA_OSF_MAX (__NFTA_OSF_MAX - 1)
@@ -782,6 +792,26 @@
__NFTA_DEVICE_MAX
};
#define NFTA_DEVICE_MAX (__NFTA_DEVICE_MAX - 1)
+enum nft_xfrm_attributes {
+ NFTA_XFRM_UNSPEC,
+ NFTA_XFRM_DREG,
+ NFTA_XFRM_KEY,
+ NFTA_XFRM_DIR,
+ NFTA_XFRM_SPNUM,
+ __NFTA_XFRM_MAX
+};
+#define NFTA_XFRM_MAX (__NFTA_XFRM_MAX - 1)
+enum nft_xfrm_keys {
+ NFT_XFRM_KEY_UNSPEC,
+ NFT_XFRM_KEY_DADDR_IP4,
+ NFT_XFRM_KEY_DADDR_IP6,
+ NFT_XFRM_KEY_SADDR_IP4,
+ NFT_XFRM_KEY_SADDR_IP6,
+ NFT_XFRM_KEY_REQID,
+ NFT_XFRM_KEY_SPI,
+ __NFT_XFRM_KEY_MAX,
+};
+#define NFT_XFRM_KEY_MAX (__NFT_XFRM_KEY_MAX - 1)
enum nft_trace_attributes {
NFTA_TRACE_UNSPEC,
NFTA_TRACE_TABLE,
diff --git a/libc/kernel/uapi/linux/netfilter/xt_cgroup.h b/libc/kernel/uapi/linux/netfilter/xt_cgroup.h
index ccc0349..6d939ea 100644
--- a/libc/kernel/uapi/linux/netfilter/xt_cgroup.h
+++ b/libc/kernel/uapi/linux/netfilter/xt_cgroup.h
@@ -33,4 +33,16 @@
__u32 classid;
void * priv __attribute__((aligned(8)));
};
+#define XT_CGROUP_PATH_MAX 512
+struct xt_cgroup_info_v2 {
+ __u8 has_path;
+ __u8 has_classid;
+ __u8 invert_path;
+ __u8 invert_classid;
+ union {
+ char path[XT_CGROUP_PATH_MAX];
+ __u32 classid;
+ };
+ void * priv __attribute__((aligned(8)));
+};
#endif
diff --git a/libc/kernel/uapi/linux/netfilter_bridge.h b/libc/kernel/uapi/linux/netfilter_bridge.h
index 6da98f5..e1434f4 100644
--- a/libc/kernel/uapi/linux/netfilter_bridge.h
+++ b/libc/kernel/uapi/linux/netfilter_bridge.h
@@ -23,6 +23,7 @@
#include <linux/if_ether.h>
#include <linux/if_vlan.h>
#include <linux/if_pppox.h>
+#include <limits.h>
#define NF_BR_PRE_ROUTING 0
#define NF_BR_LOCAL_IN 1
#define NF_BR_FORWARD 2
diff --git a/libc/kernel/uapi/linux/netlink.h b/libc/kernel/uapi/linux/netlink.h
index 4f35c02..4c0fd1f 100644
--- a/libc/kernel/uapi/linux/netlink.h
+++ b/libc/kernel/uapi/linux/netlink.h
@@ -112,6 +112,7 @@
#define NETLINK_LIST_MEMBERSHIPS 9
#define NETLINK_CAP_ACK 10
#define NETLINK_EXT_ACK 11
+#define NETLINK_GET_STRICT_CHK 12
struct nl_pktinfo {
__u32 group;
};
diff --git a/libc/kernel/uapi/linux/nl80211.h b/libc/kernel/uapi/linux/nl80211.h
index 1f2f77d..471e65f 100644
--- a/libc/kernel/uapi/linux/nl80211.h
+++ b/libc/kernel/uapi/linux/nl80211.h
@@ -163,6 +163,7 @@
NL80211_CMD_EXTERNAL_AUTH,
NL80211_CMD_STA_OPMODE_CHANGED,
NL80211_CMD_CONTROL_PORT_FRAME,
+ NL80211_CMD_GET_FTM_RESPONDER_STATS,
__NL80211_CMD_AFTER_LAST,
NL80211_CMD_MAX = __NL80211_CMD_AFTER_LAST - 1
};
@@ -449,6 +450,8 @@
NL80211_ATTR_TXQ_MEMORY_LIMIT,
NL80211_ATTR_TXQ_QUANTUM,
NL80211_ATTR_HE_CAPABILITY,
+ NL80211_ATTR_FTM_RESPONDER,
+ NL80211_ATTR_FTM_RESPONDER_STATS,
__NL80211_ATTR_AFTER_LAST,
NUM_NL80211_ATTR = __NL80211_ATTR_AFTER_LAST,
NL80211_ATTR_MAX = __NL80211_ATTR_AFTER_LAST - 1
@@ -615,10 +618,13 @@
NL80211_STA_INFO_RX_DURATION,
NL80211_STA_INFO_PAD,
NL80211_STA_INFO_ACK_SIGNAL,
- NL80211_STA_INFO_DATA_ACK_SIGNAL_AVG,
+ NL80211_STA_INFO_ACK_SIGNAL_AVG,
+ NL80211_STA_INFO_RX_MPDUS,
+ NL80211_STA_INFO_FCS_ERROR_COUNT,
__NL80211_STA_INFO_AFTER_LAST,
NL80211_STA_INFO_MAX = __NL80211_STA_INFO_AFTER_LAST - 1
};
+#define NL80211_STA_INFO_DATA_ACK_SIGNAL_AVG NL80211_STA_INFO_ACK_SIGNAL_AVG
enum nl80211_tid_stats {
__NL80211_TID_STATS_INVALID,
NL80211_TID_STATS_RX_MSDU,
@@ -1283,10 +1289,13 @@
NL80211_EXT_FEATURE_HIGH_ACCURACY_SCAN,
NL80211_EXT_FEATURE_DFS_OFFLOAD,
NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211,
- NL80211_EXT_FEATURE_DATA_ACK_SIGNAL_SUPPORT,
+ NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT,
+ NL80211_EXT_FEATURE_DATA_ACK_SIGNAL_SUPPORT = NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT,
NL80211_EXT_FEATURE_TXQS,
NL80211_EXT_FEATURE_SCAN_RANDOM_SN,
NL80211_EXT_FEATURE_SCAN_MIN_PREQ_CONTENT,
+ NL80211_EXT_FEATURE_CAN_REPLACE_PTK0,
+ NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER,
NUM_NL80211_EXT_FEATURES,
MAX_NL80211_EXT_FEATURES = NUM_NL80211_EXT_FEATURES - 1
};
@@ -1448,4 +1457,27 @@
NL80211_EXTERNAL_AUTH_START,
NL80211_EXTERNAL_AUTH_ABORT,
};
+enum nl80211_ftm_responder_attributes {
+ __NL80211_FTM_RESP_ATTR_INVALID,
+ NL80211_FTM_RESP_ATTR_ENABLED,
+ NL80211_FTM_RESP_ATTR_LCI,
+ NL80211_FTM_RESP_ATTR_CIVICLOC,
+ __NL80211_FTM_RESP_ATTR_LAST,
+ NL80211_FTM_RESP_ATTR_MAX = __NL80211_FTM_RESP_ATTR_LAST - 1,
+};
+enum nl80211_ftm_responder_stats {
+ __NL80211_FTM_STATS_INVALID,
+ NL80211_FTM_STATS_SUCCESS_NUM,
+ NL80211_FTM_STATS_PARTIAL_NUM,
+ NL80211_FTM_STATS_FAILED_NUM,
+ NL80211_FTM_STATS_ASAP_NUM,
+ NL80211_FTM_STATS_NON_ASAP_NUM,
+ NL80211_FTM_STATS_TOTAL_DURATION_MSEC,
+ NL80211_FTM_STATS_UNKNOWN_TRIGGERS_NUM,
+ NL80211_FTM_STATS_RESCHEDULE_REQUESTS_NUM,
+ NL80211_FTM_STATS_OUT_OF_WINDOW_TRIGGERS_NUM,
+ NL80211_FTM_STATS_PAD,
+ __NL80211_FTM_STATS_AFTER_LAST,
+ NL80211_FTM_STATS_MAX = __NL80211_FTM_STATS_AFTER_LAST - 1
+};
#endif
diff --git a/libc/kernel/uapi/linux/pci_regs.h b/libc/kernel/uapi/linux/pci_regs.h
index 7b234f5..8122fbb 100644
--- a/libc/kernel/uapi/linux/pci_regs.h
+++ b/libc/kernel/uapi/linux/pci_regs.h
@@ -36,6 +36,7 @@
#define PCI_COMMAND_FAST_BACK 0x200
#define PCI_COMMAND_INTX_DISABLE 0x400
#define PCI_STATUS 0x06
+#define PCI_STATUS_IMM_READY 0x01
#define PCI_STATUS_INTERRUPT 0x08
#define PCI_STATUS_CAP_LIST 0x10
#define PCI_STATUS_66MHZ 0x20
diff --git a/libc/kernel/uapi/linux/perf_event.h b/libc/kernel/uapi/linux/perf_event.h
index c106b5b..bf51785 100644
--- a/libc/kernel/uapi/linux/perf_event.h
+++ b/libc/kernel/uapi/linux/perf_event.h
@@ -286,6 +286,7 @@
#define PERF_RECORD_MISC_PROC_MAP_PARSE_TIMEOUT (1 << 12)
#define PERF_RECORD_MISC_MMAP_DATA (1 << 13)
#define PERF_RECORD_MISC_COMM_EXEC (1 << 13)
+#define PERF_RECORD_MISC_FORK_EXEC (1 << 13)
#define PERF_RECORD_MISC_SWITCH_OUT (1 << 13)
#define PERF_RECORD_MISC_EXACT_IP (1 << 14)
#define PERF_RECORD_MISC_SWITCH_OUT_PREEMPT (1 << 14)
diff --git a/libc/kernel/uapi/linux/pkt_cls.h b/libc/kernel/uapi/linux/pkt_cls.h
index 1ede892..ac80a0a 100644
--- a/libc/kernel/uapi/linux/pkt_cls.h
+++ b/libc/kernel/uapi/linux/pkt_cls.h
@@ -388,6 +388,7 @@
TCA_FLOWER_KEY_ENC_IP_TTL_MASK,
TCA_FLOWER_KEY_ENC_OPTS,
TCA_FLOWER_KEY_ENC_OPTS_MASK,
+ TCA_FLOWER_IN_HW_COUNT,
__TCA_FLOWER_MAX,
};
#define TCA_FLOWER_MAX (__TCA_FLOWER_MAX - 1)
diff --git a/libc/kernel/uapi/linux/pkt_sched.h b/libc/kernel/uapi/linux/pkt_sched.h
index 4efbc1c..e7d4942 100644
--- a/libc/kernel/uapi/linux/pkt_sched.h
+++ b/libc/kernel/uapi/linux/pkt_sched.h
@@ -283,8 +283,8 @@
__u32 lends;
__u32 borrows;
__u32 giants;
- __u32 tokens;
- __u32 ctokens;
+ __s32 tokens;
+ __s32 ctokens;
};
struct tc_hfsc_qopt {
__u16 defcls;
@@ -828,4 +828,35 @@
CAKE_ATM_PTM,
CAKE_ATM_MAX
};
+enum {
+ TC_TAPRIO_CMD_SET_GATES = 0x00,
+ TC_TAPRIO_CMD_SET_AND_HOLD = 0x01,
+ TC_TAPRIO_CMD_SET_AND_RELEASE = 0x02,
+};
+enum {
+ TCA_TAPRIO_SCHED_ENTRY_UNSPEC,
+ TCA_TAPRIO_SCHED_ENTRY_INDEX,
+ TCA_TAPRIO_SCHED_ENTRY_CMD,
+ TCA_TAPRIO_SCHED_ENTRY_GATE_MASK,
+ TCA_TAPRIO_SCHED_ENTRY_INTERVAL,
+ __TCA_TAPRIO_SCHED_ENTRY_MAX,
+};
+#define TCA_TAPRIO_SCHED_ENTRY_MAX (__TCA_TAPRIO_SCHED_ENTRY_MAX - 1)
+enum {
+ TCA_TAPRIO_SCHED_UNSPEC,
+ TCA_TAPRIO_SCHED_ENTRY,
+ __TCA_TAPRIO_SCHED_MAX,
+};
+#define TCA_TAPRIO_SCHED_MAX (__TCA_TAPRIO_SCHED_MAX - 1)
+enum {
+ TCA_TAPRIO_ATTR_UNSPEC,
+ TCA_TAPRIO_ATTR_PRIOMAP,
+ TCA_TAPRIO_ATTR_SCHED_ENTRY_LIST,
+ TCA_TAPRIO_ATTR_SCHED_BASE_TIME,
+ TCA_TAPRIO_ATTR_SCHED_SINGLE_ENTRY,
+ TCA_TAPRIO_ATTR_SCHED_CLOCKID,
+ TCA_TAPRIO_PAD,
+ __TCA_TAPRIO_ATTR_MAX,
+};
+#define TCA_TAPRIO_ATTR_MAX (__TCA_TAPRIO_ATTR_MAX - 1)
#endif
diff --git a/libc/kernel/uapi/linux/prctl.h b/libc/kernel/uapi/linux/prctl.h
index ba50b14..44a088d 100644
--- a/libc/kernel/uapi/linux/prctl.h
+++ b/libc/kernel/uapi/linux/prctl.h
@@ -137,6 +137,7 @@
#define PR_GET_SPECULATION_CTRL 52
#define PR_SET_SPECULATION_CTRL 53
#define PR_SPEC_STORE_BYPASS 0
+#define PR_SPEC_INDIRECT_BRANCH 1
#define PR_SPEC_NOT_AFFECTED 0
#define PR_SPEC_PRCTL (1UL << 0)
#define PR_SPEC_ENABLE (1UL << 1)
diff --git a/libc/kernel/uapi/linux/sctp.h b/libc/kernel/uapi/linux/sctp.h
index 6ba738e..dc07d78 100644
--- a/libc/kernel/uapi/linux/sctp.h
+++ b/libc/kernel/uapi/linux/sctp.h
@@ -314,6 +314,8 @@
};
#define SCTP_ASSOC_CHANGE_DENIED 0x0004
#define SCTP_ASSOC_CHANGE_FAILED 0x0008
+#define SCTP_STREAM_CHANGE_DENIED SCTP_ASSOC_CHANGE_DENIED
+#define SCTP_STREAM_CHANGE_FAILED SCTP_ASSOC_CHANGE_FAILED
struct sctp_stream_change_event {
__u16 strchange_type;
__u16 strchange_flags;
@@ -655,6 +657,7 @@
};
enum sctp_sched_type {
SCTP_SS_FCFS,
+ SCTP_SS_DEFAULT = SCTP_SS_FCFS,
SCTP_SS_PRIO,
SCTP_SS_RR,
SCTP_SS_MAX = SCTP_SS_RR
diff --git a/libc/kernel/uapi/linux/serial.h b/libc/kernel/uapi/linux/serial.h
index 79f11e3..e4e903d 100644
--- a/libc/kernel/uapi/linux/serial.h
+++ b/libc/kernel/uapi/linux/serial.h
@@ -100,4 +100,15 @@
__u32 delay_rts_after_send;
__u32 padding[5];
};
+struct serial_iso7816 {
+ __u32 flags;
+#define SER_ISO7816_ENABLED (1 << 0)
+#define SER_ISO7816_T_PARAM (0x0f << 4)
+#define SER_ISO7816_T(t) (((t) & 0x0f) << 4)
+ __u32 tg;
+ __u32 sc_fi;
+ __u32 sc_di;
+ __u32 clk;
+ __u32 reserved[5];
+};
#endif
diff --git a/libc/kernel/uapi/linux/taskstats.h b/libc/kernel/uapi/linux/taskstats.h
index b7bc744..dc7791d 100644
--- a/libc/kernel/uapi/linux/taskstats.h
+++ b/libc/kernel/uapi/linux/taskstats.h
@@ -19,7 +19,7 @@
#ifndef _LINUX_TASKSTATS_H
#define _LINUX_TASKSTATS_H
#include <linux/types.h>
-#define TASKSTATS_VERSION 8
+#define TASKSTATS_VERSION 9
#define TS_COMM_LEN 32
struct taskstats {
__u16 version;
@@ -66,6 +66,8 @@
__u64 cpu_scaled_run_real_total;
__u64 freepages_count;
__u64 freepages_delay_total;
+ __u64 thrashing_count;
+ __u64 thrashing_delay_total;
};
enum {
TASKSTATS_CMD_UNSPEC = 0,
diff --git a/libc/kernel/uapi/linux/udmabuf.h b/libc/kernel/uapi/linux/udmabuf.h
new file mode 100644
index 0000000..70cf49f
--- /dev/null
+++ b/libc/kernel/uapi/linux/udmabuf.h
@@ -0,0 +1,43 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ *** To edit the content of this header, modify the corresponding
+ *** source file (e.g. under external/kernel-headers/original/) then
+ *** run bionic/libc/kernel/tools/update_all.py
+ ***
+ *** Any manual change here will be lost the next time this script will
+ *** be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _UAPI_LINUX_UDMABUF_H
+#define _UAPI_LINUX_UDMABUF_H
+#include <linux/types.h>
+#include <linux/ioctl.h>
+#define UDMABUF_FLAGS_CLOEXEC 0x01
+struct udmabuf_create {
+ __u32 memfd;
+ __u32 flags;
+ __u64 offset;
+ __u64 size;
+};
+struct udmabuf_create_item {
+ __u32 memfd;
+ __u32 __pad;
+ __u64 offset;
+ __u64 size;
+};
+struct udmabuf_create_list {
+ __u32 flags;
+ __u32 count;
+ struct udmabuf_create_item list[];
+};
+#define UDMABUF_CREATE _IOW('u', 0x42, struct udmabuf_create)
+#define UDMABUF_CREATE_LIST _IOW('u', 0x43, struct udmabuf_create_list)
+#endif
diff --git a/libc/kernel/uapi/linux/usb/tmc.h b/libc/kernel/uapi/linux/usb/tmc.h
index 6e276de..20c061b 100644
--- a/libc/kernel/uapi/linux/usb/tmc.h
+++ b/libc/kernel/uapi/linux/usb/tmc.h
@@ -37,10 +37,30 @@
#define USBTMC488_REQUEST_REN_CONTROL 160
#define USBTMC488_REQUEST_GOTO_LOCAL 161
#define USBTMC488_REQUEST_LOCAL_LOCKOUT 162
+struct usbtmc_request {
+ __u8 bRequestType;
+ __u8 bRequest;
+ __u16 wValue;
+ __u16 wIndex;
+ __u16 wLength;
+} __attribute__((packed));
+struct usbtmc_ctrlrequest {
+ struct usbtmc_request req;
+ void __user * data;
+} __attribute__((packed));
struct usbtmc_termchar {
__u8 term_char;
__u8 term_char_enabled;
} __attribute__((packed));
+#define USBTMC_FLAG_ASYNC 0x0001
+#define USBTMC_FLAG_APPEND 0x0002
+#define USBTMC_FLAG_IGNORE_TRAILER 0x0004
+struct usbtmc_message {
+ __u32 transfer_size;
+ __u32 transferred;
+ __u32 flags;
+ void __user * message;
+} __attribute__((packed));
#define USBTMC_IOC_NR 91
#define USBTMC_IOCTL_INDICATOR_PULSE _IO(USBTMC_IOC_NR, 1)
#define USBTMC_IOCTL_CLEAR _IO(USBTMC_IOC_NR, 2)
@@ -48,16 +68,26 @@
#define USBTMC_IOCTL_ABORT_BULK_IN _IO(USBTMC_IOC_NR, 4)
#define USBTMC_IOCTL_CLEAR_OUT_HALT _IO(USBTMC_IOC_NR, 6)
#define USBTMC_IOCTL_CLEAR_IN_HALT _IO(USBTMC_IOC_NR, 7)
+#define USBTMC_IOCTL_CTRL_REQUEST _IOWR(USBTMC_IOC_NR, 8, struct usbtmc_ctrlrequest)
#define USBTMC_IOCTL_GET_TIMEOUT _IOR(USBTMC_IOC_NR, 9, __u32)
#define USBTMC_IOCTL_SET_TIMEOUT _IOW(USBTMC_IOC_NR, 10, __u32)
#define USBTMC_IOCTL_EOM_ENABLE _IOW(USBTMC_IOC_NR, 11, __u8)
#define USBTMC_IOCTL_CONFIG_TERMCHAR _IOW(USBTMC_IOC_NR, 12, struct usbtmc_termchar)
+#define USBTMC_IOCTL_WRITE _IOWR(USBTMC_IOC_NR, 13, struct usbtmc_message)
+#define USBTMC_IOCTL_READ _IOWR(USBTMC_IOC_NR, 14, struct usbtmc_message)
+#define USBTMC_IOCTL_WRITE_RESULT _IOWR(USBTMC_IOC_NR, 15, __u32)
+#define USBTMC_IOCTL_API_VERSION _IOR(USBTMC_IOC_NR, 16, __u32)
#define USBTMC488_IOCTL_GET_CAPS _IOR(USBTMC_IOC_NR, 17, unsigned char)
#define USBTMC488_IOCTL_READ_STB _IOR(USBTMC_IOC_NR, 18, unsigned char)
#define USBTMC488_IOCTL_REN_CONTROL _IOW(USBTMC_IOC_NR, 19, unsigned char)
#define USBTMC488_IOCTL_GOTO_LOCAL _IO(USBTMC_IOC_NR, 20)
#define USBTMC488_IOCTL_LOCAL_LOCKOUT _IO(USBTMC_IOC_NR, 21)
#define USBTMC488_IOCTL_TRIGGER _IO(USBTMC_IOC_NR, 22)
+#define USBTMC488_IOCTL_WAIT_SRQ _IOW(USBTMC_IOC_NR, 23, __u32)
+#define USBTMC_IOCTL_MSG_IN_ATTR _IOR(USBTMC_IOC_NR, 24, __u8)
+#define USBTMC_IOCTL_AUTO_ABORT _IOW(USBTMC_IOC_NR, 25, __u8)
+#define USBTMC_IOCTL_CANCEL_IO _IO(USBTMC_IOC_NR, 35)
+#define USBTMC_IOCTL_CLEANUP_IO _IO(USBTMC_IOC_NR, 36)
#define USBTMC488_CAPABILITY_TRIGGER 1
#define USBTMC488_CAPABILITY_SIMPLE 2
#define USBTMC488_CAPABILITY_REN_CONTROL 2
diff --git a/libc/kernel/uapi/linux/usb/video.h b/libc/kernel/uapi/linux/usb/video.h
index fb34483..cd2ede9 100644
--- a/libc/kernel/uapi/linux/usb/video.h
+++ b/libc/kernel/uapi/linux/usb/video.h
@@ -148,22 +148,22 @@
__u8 bLength;
__u8 bDescriptorType;
__u8 bDescriptorSubType;
- __u16 bcdUVC;
- __u16 wTotalLength;
- __u32 dwClockFrequency;
+ __le16 bcdUVC;
+ __le16 wTotalLength;
+ __le32 dwClockFrequency;
__u8 bInCollection;
__u8 baInterfaceNr[];
} __attribute__((__packed__));
#define UVC_DT_HEADER_SIZE(n) (12 + (n))
#define UVC_HEADER_DESCRIPTOR(n) uvc_header_descriptor_ ##n
-#define DECLARE_UVC_HEADER_DESCRIPTOR(n) struct UVC_HEADER_DESCRIPTOR(n) { __u8 bLength; __u8 bDescriptorType; __u8 bDescriptorSubType; __u16 bcdUVC; __u16 wTotalLength; __u32 dwClockFrequency; __u8 bInCollection; __u8 baInterfaceNr[n]; \
+#define DECLARE_UVC_HEADER_DESCRIPTOR(n) struct UVC_HEADER_DESCRIPTOR(n) { __u8 bLength; __u8 bDescriptorType; __u8 bDescriptorSubType; __le16 bcdUVC; __le16 wTotalLength; __le32 dwClockFrequency; __u8 bInCollection; __u8 baInterfaceNr[n]; \
} __attribute__((packed))
struct uvc_input_terminal_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u8 bDescriptorSubType;
__u8 bTerminalID;
- __u16 wTerminalType;
+ __le16 wTerminalType;
__u8 bAssocTerminal;
__u8 iTerminal;
} __attribute__((__packed__));
@@ -173,7 +173,7 @@
__u8 bDescriptorType;
__u8 bDescriptorSubType;
__u8 bTerminalID;
- __u16 wTerminalType;
+ __le16 wTerminalType;
__u8 bAssocTerminal;
__u8 bSourceID;
__u8 iTerminal;
@@ -184,12 +184,12 @@
__u8 bDescriptorType;
__u8 bDescriptorSubType;
__u8 bTerminalID;
- __u16 wTerminalType;
+ __le16 wTerminalType;
__u8 bAssocTerminal;
__u8 iTerminal;
- __u16 wObjectiveFocalLengthMin;
- __u16 wObjectiveFocalLengthMax;
- __u16 wOcularFocalLength;
+ __le16 wObjectiveFocalLengthMin;
+ __le16 wObjectiveFocalLengthMax;
+ __le16 wOcularFocalLength;
__u8 bControlSize;
__u8 bmControls[3];
} __attribute__((__packed__));
@@ -213,7 +213,7 @@
__u8 bDescriptorSubType;
__u8 bUnitID;
__u8 bSourceID;
- __u16 wMaxMultiplier;
+ __le16 wMaxMultiplier;
__u8 bControlSize;
__u8 bmControls[2];
__u8 iProcessing;
@@ -240,7 +240,7 @@
__u8 bLength;
__u8 bDescriptorType;
__u8 bDescriptorSubType;
- __u16 wMaxTransferSize;
+ __le16 wMaxTransferSize;
} __attribute__((__packed__));
#define UVC_DT_CONTROL_ENDPOINT_SIZE 5
struct uvc_input_header_descriptor {
@@ -248,7 +248,7 @@
__u8 bDescriptorType;
__u8 bDescriptorSubType;
__u8 bNumFormats;
- __u16 wTotalLength;
+ __le16 wTotalLength;
__u8 bEndpointAddress;
__u8 bmInfo;
__u8 bTerminalLink;
@@ -260,14 +260,14 @@
} __attribute__((__packed__));
#define UVC_DT_INPUT_HEADER_SIZE(n,p) (13 + (n * p))
#define UVC_INPUT_HEADER_DESCRIPTOR(n,p) uvc_input_header_descriptor_ ##n_ ##p
-#define DECLARE_UVC_INPUT_HEADER_DESCRIPTOR(n,p) struct UVC_INPUT_HEADER_DESCRIPTOR(n, p) { __u8 bLength; __u8 bDescriptorType; __u8 bDescriptorSubType; __u8 bNumFormats; __u16 wTotalLength; __u8 bEndpointAddress; __u8 bmInfo; __u8 bTerminalLink; __u8 bStillCaptureMethod; __u8 bTriggerSupport; __u8 bTriggerUsage; __u8 bControlSize; __u8 bmaControls[p][n]; \
+#define DECLARE_UVC_INPUT_HEADER_DESCRIPTOR(n,p) struct UVC_INPUT_HEADER_DESCRIPTOR(n, p) { __u8 bLength; __u8 bDescriptorType; __u8 bDescriptorSubType; __u8 bNumFormats; __le16 wTotalLength; __u8 bEndpointAddress; __u8 bmInfo; __u8 bTerminalLink; __u8 bStillCaptureMethod; __u8 bTriggerSupport; __u8 bTriggerUsage; __u8 bControlSize; __u8 bmaControls[p][n]; \
} __attribute__((packed))
struct uvc_output_header_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u8 bDescriptorSubType;
__u8 bNumFormats;
- __u16 wTotalLength;
+ __le16 wTotalLength;
__u8 bEndpointAddress;
__u8 bTerminalLink;
__u8 bControlSize;
@@ -275,7 +275,7 @@
} __attribute__((__packed__));
#define UVC_DT_OUTPUT_HEADER_SIZE(n,p) (9 + (n * p))
#define UVC_OUTPUT_HEADER_DESCRIPTOR(n,p) uvc_output_header_descriptor_ ##n_ ##p
-#define DECLARE_UVC_OUTPUT_HEADER_DESCRIPTOR(n,p) struct UVC_OUTPUT_HEADER_DESCRIPTOR(n, p) { __u8 bLength; __u8 bDescriptorType; __u8 bDescriptorSubType; __u8 bNumFormats; __u16 wTotalLength; __u8 bEndpointAddress; __u8 bTerminalLink; __u8 bControlSize; __u8 bmaControls[p][n]; \
+#define DECLARE_UVC_OUTPUT_HEADER_DESCRIPTOR(n,p) struct UVC_OUTPUT_HEADER_DESCRIPTOR(n, p) { __u8 bLength; __u8 bDescriptorType; __u8 bDescriptorSubType; __u8 bNumFormats; __le16 wTotalLength; __u8 bEndpointAddress; __u8 bTerminalLink; __u8 bControlSize; __u8 bmaControls[p][n]; \
} __attribute__((packed))
struct uvc_color_matching_descriptor {
__u8 bLength;
@@ -325,18 +325,18 @@
__u8 bDescriptorSubType;
__u8 bFrameIndex;
__u8 bmCapabilities;
- __u16 wWidth;
- __u16 wHeight;
- __u32 dwMinBitRate;
- __u32 dwMaxBitRate;
- __u32 dwMaxVideoFrameBufferSize;
- __u32 dwDefaultFrameInterval;
+ __le16 wWidth;
+ __le16 wHeight;
+ __le32 dwMinBitRate;
+ __le32 dwMaxBitRate;
+ __le32 dwMaxVideoFrameBufferSize;
+ __le32 dwDefaultFrameInterval;
__u8 bFrameIntervalType;
- __u32 dwFrameInterval[];
+ __le32 dwFrameInterval[];
} __attribute__((__packed__));
#define UVC_DT_FRAME_UNCOMPRESSED_SIZE(n) (26 + 4 * (n))
#define UVC_FRAME_UNCOMPRESSED(n) uvc_frame_uncompressed_ ##n
-#define DECLARE_UVC_FRAME_UNCOMPRESSED(n) struct UVC_FRAME_UNCOMPRESSED(n) { __u8 bLength; __u8 bDescriptorType; __u8 bDescriptorSubType; __u8 bFrameIndex; __u8 bmCapabilities; __u16 wWidth; __u16 wHeight; __u32 dwMinBitRate; __u32 dwMaxBitRate; __u32 dwMaxVideoFrameBufferSize; __u32 dwDefaultFrameInterval; __u8 bFrameIntervalType; __u32 dwFrameInterval[n]; \
+#define DECLARE_UVC_FRAME_UNCOMPRESSED(n) struct UVC_FRAME_UNCOMPRESSED(n) { __u8 bLength; __u8 bDescriptorType; __u8 bDescriptorSubType; __u8 bFrameIndex; __u8 bmCapabilities; __le16 wWidth; __le16 wHeight; __le32 dwMinBitRate; __le32 dwMaxBitRate; __le32 dwMaxVideoFrameBufferSize; __le32 dwDefaultFrameInterval; __u8 bFrameIntervalType; __le32 dwFrameInterval[n]; \
} __attribute__((packed))
struct uvc_format_mjpeg {
__u8 bLength;
@@ -358,17 +358,17 @@
__u8 bDescriptorSubType;
__u8 bFrameIndex;
__u8 bmCapabilities;
- __u16 wWidth;
- __u16 wHeight;
- __u32 dwMinBitRate;
- __u32 dwMaxBitRate;
- __u32 dwMaxVideoFrameBufferSize;
- __u32 dwDefaultFrameInterval;
+ __le16 wWidth;
+ __le16 wHeight;
+ __le32 dwMinBitRate;
+ __le32 dwMaxBitRate;
+ __le32 dwMaxVideoFrameBufferSize;
+ __le32 dwDefaultFrameInterval;
__u8 bFrameIntervalType;
- __u32 dwFrameInterval[];
+ __le32 dwFrameInterval[];
} __attribute__((__packed__));
#define UVC_DT_FRAME_MJPEG_SIZE(n) (26 + 4 * (n))
#define UVC_FRAME_MJPEG(n) uvc_frame_mjpeg_ ##n
-#define DECLARE_UVC_FRAME_MJPEG(n) struct UVC_FRAME_MJPEG(n) { __u8 bLength; __u8 bDescriptorType; __u8 bDescriptorSubType; __u8 bFrameIndex; __u8 bmCapabilities; __u16 wWidth; __u16 wHeight; __u32 dwMinBitRate; __u32 dwMaxBitRate; __u32 dwMaxVideoFrameBufferSize; __u32 dwDefaultFrameInterval; __u8 bFrameIntervalType; __u32 dwFrameInterval[n]; \
+#define DECLARE_UVC_FRAME_MJPEG(n) struct UVC_FRAME_MJPEG(n) { __u8 bLength; __u8 bDescriptorType; __u8 bDescriptorSubType; __u8 bFrameIndex; __u8 bmCapabilities; __le16 wWidth; __le16 wHeight; __le32 dwMinBitRate; __le32 dwMaxBitRate; __le32 dwMaxVideoFrameBufferSize; __le32 dwDefaultFrameInterval; __u8 bFrameIntervalType; __le32 dwFrameInterval[n]; \
} __attribute__((packed))
#endif
diff --git a/libc/kernel/uapi/linux/v4l2-controls.h b/libc/kernel/uapi/linux/v4l2-controls.h
index 45590a2..3c2d2b2 100644
--- a/libc/kernel/uapi/linux/v4l2-controls.h
+++ b/libc/kernel/uapi/linux/v4l2-controls.h
@@ -18,6 +18,7 @@
****************************************************************************/
#ifndef __LINUX_V4L2_CONTROLS_H
#define __LINUX_V4L2_CONTROLS_H
+#include <linux/types.h>
#define V4L2_CTRL_CLASS_USER 0x00980000
#define V4L2_CTRL_CLASS_MPEG 0x00990000
#define V4L2_CTRL_CLASS_CAMERA 0x009a0000
diff --git a/libc/kernel/uapi/linux/version.h b/libc/kernel/uapi/linux/version.h
index a234744..6b1ef1b 100644
--- a/libc/kernel/uapi/linux/version.h
+++ b/libc/kernel/uapi/linux/version.h
@@ -16,5 +16,5 @@
***
****************************************************************************
****************************************************************************/
-#define LINUX_VERSION_CODE 267008
+#define LINUX_VERSION_CODE 267265
#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
diff --git a/libc/kernel/uapi/linux/vfio.h b/libc/kernel/uapi/linux/vfio.h
index 8b397f4..d282a52 100644
--- a/libc/kernel/uapi/linux/vfio.h
+++ b/libc/kernel/uapi/linux/vfio.h
@@ -57,6 +57,7 @@
#define VFIO_DEVICE_FLAGS_PLATFORM (1 << 2)
#define VFIO_DEVICE_FLAGS_AMBA (1 << 3)
#define VFIO_DEVICE_FLAGS_CCW (1 << 4)
+#define VFIO_DEVICE_FLAGS_AP (1 << 5)
__u32 num_regions;
__u32 num_irqs;
};
@@ -65,6 +66,7 @@
#define VFIO_DEVICE_API_PLATFORM_STRING "vfio-platform"
#define VFIO_DEVICE_API_AMBA_STRING "vfio-amba"
#define VFIO_DEVICE_API_CCW_STRING "vfio-ccw"
+#define VFIO_DEVICE_API_AP_STRING "vfio-ap"
struct vfio_region_info {
__u32 argsz;
__u32 flags;
@@ -100,6 +102,18 @@
#define VFIO_REGION_SUBTYPE_INTEL_IGD_OPREGION (1)
#define VFIO_REGION_SUBTYPE_INTEL_IGD_HOST_CFG (2)
#define VFIO_REGION_SUBTYPE_INTEL_IGD_LPC_CFG (3)
+#define VFIO_REGION_TYPE_GFX (1)
+#define VFIO_REGION_SUBTYPE_GFX_EDID (1)
+struct vfio_region_gfx_edid {
+ __u32 edid_offset;
+ __u32 edid_max_size;
+ __u32 edid_size;
+ __u32 max_xres;
+ __u32 max_yres;
+ __u32 link_state;
+#define VFIO_DEVICE_GFX_LINK_STATE_UP 1
+#define VFIO_DEVICE_GFX_LINK_STATE_DOWN 2
+};
#define VFIO_REGION_INFO_CAP_MSIX_MAPPABLE 3
struct vfio_irq_info {
__u32 argsz;
diff --git a/libc/kernel/uapi/linux/videodev2.h b/libc/kernel/uapi/linux/videodev2.h
index 51faa1e..ef89b08 100644
--- a/libc/kernel/uapi/linux/videodev2.h
+++ b/libc/kernel/uapi/linux/videodev2.h
@@ -86,7 +86,7 @@
V4L2_COLORSPACE_470_SYSTEM_BG = 6,
V4L2_COLORSPACE_JPEG = 7,
V4L2_COLORSPACE_SRGB = 8,
- V4L2_COLORSPACE_ADOBERGB = 9,
+ V4L2_COLORSPACE_OPRGB = 9,
V4L2_COLORSPACE_BT2020 = 10,
V4L2_COLORSPACE_RAW = 11,
V4L2_COLORSPACE_DCI_P3 = 12,
@@ -96,13 +96,13 @@
V4L2_XFER_FUNC_DEFAULT = 0,
V4L2_XFER_FUNC_709 = 1,
V4L2_XFER_FUNC_SRGB = 2,
- V4L2_XFER_FUNC_ADOBERGB = 3,
+ V4L2_XFER_FUNC_OPRGB = 3,
V4L2_XFER_FUNC_SMPTE240M = 4,
V4L2_XFER_FUNC_NONE = 5,
V4L2_XFER_FUNC_DCI_P3 = 6,
V4L2_XFER_FUNC_SMPTE2084 = 7,
};
-#define V4L2_MAP_XFER_FUNC_DEFAULT(colsp) ((colsp) == V4L2_COLORSPACE_ADOBERGB ? V4L2_XFER_FUNC_ADOBERGB : ((colsp) == V4L2_COLORSPACE_SMPTE240M ? V4L2_XFER_FUNC_SMPTE240M : ((colsp) == V4L2_COLORSPACE_DCI_P3 ? V4L2_XFER_FUNC_DCI_P3 : ((colsp) == V4L2_COLORSPACE_RAW ? V4L2_XFER_FUNC_NONE : ((colsp) == V4L2_COLORSPACE_SRGB || (colsp) == V4L2_COLORSPACE_JPEG ? V4L2_XFER_FUNC_SRGB : V4L2_XFER_FUNC_709)))))
+#define V4L2_MAP_XFER_FUNC_DEFAULT(colsp) ((colsp) == V4L2_COLORSPACE_OPRGB ? V4L2_XFER_FUNC_OPRGB : ((colsp) == V4L2_COLORSPACE_SMPTE240M ? V4L2_XFER_FUNC_SMPTE240M : ((colsp) == V4L2_COLORSPACE_DCI_P3 ? V4L2_XFER_FUNC_DCI_P3 : ((colsp) == V4L2_COLORSPACE_RAW ? V4L2_XFER_FUNC_NONE : ((colsp) == V4L2_COLORSPACE_SRGB || (colsp) == V4L2_COLORSPACE_JPEG ? V4L2_XFER_FUNC_SRGB : V4L2_XFER_FUNC_709)))))
enum v4l2_ycbcr_encoding {
V4L2_YCBCR_ENC_DEFAULT = 0,
V4L2_YCBCR_ENC_601 = 1,
@@ -125,6 +125,8 @@
V4L2_QUANTIZATION_LIM_RANGE = 2,
};
#define V4L2_MAP_QUANTIZATION_DEFAULT(is_rgb_or_hsv,colsp,ycbcr_enc) (((is_rgb_or_hsv) && (colsp) == V4L2_COLORSPACE_BT2020) ? V4L2_QUANTIZATION_LIM_RANGE : (((is_rgb_or_hsv) || (colsp) == V4L2_COLORSPACE_JPEG) ? V4L2_QUANTIZATION_FULL_RANGE : V4L2_QUANTIZATION_LIM_RANGE))
+#define V4L2_COLORSPACE_ADOBERGB V4L2_COLORSPACE_OPRGB
+#define V4L2_XFER_FUNC_ADOBERGB V4L2_XFER_FUNC_OPRGB
enum v4l2_priority {
V4L2_PRIORITY_UNSET = 0,
V4L2_PRIORITY_BACKGROUND = 1,
@@ -313,6 +315,7 @@
#define V4L2_PIX_FMT_H263 v4l2_fourcc('H', '2', '6', '3')
#define V4L2_PIX_FMT_MPEG1 v4l2_fourcc('M', 'P', 'G', '1')
#define V4L2_PIX_FMT_MPEG2 v4l2_fourcc('M', 'P', 'G', '2')
+#define V4L2_PIX_FMT_MPEG2_SLICE v4l2_fourcc('M', 'G', '2', 'S')
#define V4L2_PIX_FMT_MPEG4 v4l2_fourcc('M', 'P', 'G', '4')
#define V4L2_PIX_FMT_XVID v4l2_fourcc('X', 'V', 'I', 'D')
#define V4L2_PIX_FMT_VC1_ANNEX_G v4l2_fourcc('V', 'C', '1', 'G')
@@ -352,6 +355,7 @@
#define V4L2_PIX_FMT_Z16 v4l2_fourcc('Z', '1', '6', ' ')
#define V4L2_PIX_FMT_MT21C v4l2_fourcc('M', 'T', '2', '1')
#define V4L2_PIX_FMT_INZI v4l2_fourcc('I', 'N', 'Z', 'I')
+#define V4L2_PIX_FMT_SUNXI_TILED_NV12 v4l2_fourcc('S', 'T', '1', '2')
#define V4L2_PIX_FMT_IPU3_SBGGR10 v4l2_fourcc('i', 'p', '3', 'b')
#define V4L2_PIX_FMT_IPU3_SGBRG10 v4l2_fourcc('i', 'p', '3', 'g')
#define V4L2_PIX_FMT_IPU3_SGRBG10 v4l2_fourcc('i', 'p', '3', 'G')
@@ -371,6 +375,7 @@
#define V4L2_META_FMT_VSP1_HGO v4l2_fourcc('V', 'S', 'P', 'H')
#define V4L2_META_FMT_VSP1_HGT v4l2_fourcc('V', 'S', 'P', 'T')
#define V4L2_META_FMT_UVC v4l2_fourcc('U', 'V', 'C', 'H')
+#define V4L2_META_FMT_D4XX v4l2_fourcc('D', '4', 'X', 'X')
#define V4L2_PIX_FMT_PRIV_MAGIC 0xfeedcafe
#define V4L2_PIX_FMT_FLAG_PREMUL_ALPHA 0x00000001
struct v4l2_fmtdesc {
@@ -469,8 +474,13 @@
__u32 count;
__u32 type;
__u32 memory;
- __u32 reserved[2];
+ __u32 capabilities;
+ __u32 reserved[1];
};
+#define V4L2_BUF_CAP_SUPPORTS_MMAP (1 << 0)
+#define V4L2_BUF_CAP_SUPPORTS_USERPTR (1 << 1)
+#define V4L2_BUF_CAP_SUPPORTS_DMABUF (1 << 2)
+#define V4L2_BUF_CAP_SUPPORTS_REQUESTS (1 << 3)
struct v4l2_plane {
__u32 bytesused;
__u32 length;
@@ -500,7 +510,10 @@
} m;
__u32 length;
__u32 reserved2;
- __u32 reserved;
+ union {
+ __s32 request_fd;
+ __u32 reserved;
+ };
};
#define V4L2_BUF_FLAG_MAPPED 0x00000001
#define V4L2_BUF_FLAG_QUEUED 0x00000002
@@ -509,6 +522,7 @@
#define V4L2_BUF_FLAG_PFRAME 0x00000010
#define V4L2_BUF_FLAG_BFRAME 0x00000020
#define V4L2_BUF_FLAG_ERROR 0x00000040
+#define V4L2_BUF_FLAG_IN_REQUEST 0x00000080
#define V4L2_BUF_FLAG_TIMECODE 0x00000100
#define V4L2_BUF_FLAG_PREPARED 0x00000400
#define V4L2_BUF_FLAG_NO_CACHE_INVALIDATE 0x00000800
@@ -521,6 +535,7 @@
#define V4L2_BUF_FLAG_TSTAMP_SRC_EOF 0x00000000
#define V4L2_BUF_FLAG_TSTAMP_SRC_SOE 0x00010000
#define V4L2_BUF_FLAG_LAST 0x00100000
+#define V4L2_BUF_FLAG_REQUEST_FD 0x00800000
struct v4l2_exportbuffer {
__u32 type;
__u32 index;
@@ -702,6 +717,7 @@
#define V4L2_DV_FL_HAS_PICTURE_ASPECT (1 << 6)
#define V4L2_DV_FL_HAS_CEA861_VIC (1 << 7)
#define V4L2_DV_FL_HAS_HDMI_VIC (1 << 8)
+#define V4L2_DV_FL_CAN_DETECT_REDUCED_FPS (1 << 9)
#define V4L2_DV_BT_BLANKING_WIDTH(bt) ((bt)->hfrontporch + (bt)->hsync + (bt)->hbackporch)
#define V4L2_DV_BT_FRAME_WIDTH(bt) ((bt)->width + V4L2_DV_BT_BLANKING_WIDTH(bt))
#define V4L2_DV_BT_BLANKING_HEIGHT(bt) ((bt)->vfrontporch + (bt)->vsync + (bt)->vbackporch + (bt)->il_vfrontporch + (bt)->il_vsync + (bt)->il_vbackporch)
@@ -819,7 +835,8 @@
};
__u32 count;
__u32 error_idx;
- __u32 reserved[2];
+ __s32 request_fd;
+ __u32 reserved[1];
struct v4l2_ext_control * controls;
};
#define V4L2_CTRL_ID_MASK (0x0fffffff)
@@ -829,6 +846,7 @@
#define V4L2_CTRL_MAX_DIMS (4)
#define V4L2_CTRL_WHICH_CUR_VAL 0
#define V4L2_CTRL_WHICH_DEF_VAL 0x0f000000
+#define V4L2_CTRL_WHICH_REQUEST_VAL 0x0f010000
enum v4l2_ctrl_type {
V4L2_CTRL_TYPE_INTEGER = 1,
V4L2_CTRL_TYPE_BOOLEAN = 2,
@@ -1274,7 +1292,8 @@
__u32 count;
__u32 memory;
struct v4l2_format format;
- __u32 reserved[8];
+ __u32 capabilities;
+ __u32 reserved[7];
};
#define VIDIOC_QUERYCAP _IOR('V', 0, struct v4l2_capability)
#define VIDIOC_ENUM_FMT _IOWR('V', 2, struct v4l2_fmtdesc)
diff --git a/libc/kernel/uapi/linux/virtio_balloon.h b/libc/kernel/uapi/linux/virtio_balloon.h
index 5969fa0..806e757 100644
--- a/libc/kernel/uapi/linux/virtio_balloon.h
+++ b/libc/kernel/uapi/linux/virtio_balloon.h
@@ -25,10 +25,16 @@
#define VIRTIO_BALLOON_F_MUST_TELL_HOST 0
#define VIRTIO_BALLOON_F_STATS_VQ 1
#define VIRTIO_BALLOON_F_DEFLATE_ON_OOM 2
+#define VIRTIO_BALLOON_F_FREE_PAGE_HINT 3
+#define VIRTIO_BALLOON_F_PAGE_POISON 4
#define VIRTIO_BALLOON_PFN_SHIFT 12
+#define VIRTIO_BALLOON_CMD_ID_STOP 0
+#define VIRTIO_BALLOON_CMD_ID_DONE 1
struct virtio_balloon_config {
__u32 num_pages;
__u32 actual;
+ __u32 free_page_report_cmd_id;
+ __u32 poison_val;
};
#define VIRTIO_BALLOON_S_SWAP_IN 0
#define VIRTIO_BALLOON_S_SWAP_OUT 1
diff --git a/libc/kernel/uapi/rdma/ib_user_verbs.h b/libc/kernel/uapi/rdma/ib_user_verbs.h
index 3baf4ed..6ca4413 100644
--- a/libc/kernel/uapi/rdma/ib_user_verbs.h
+++ b/libc/kernel/uapi/rdma/ib_user_verbs.h
@@ -619,6 +619,22 @@
__u32 length;
__u32 lkey;
};
+enum ib_uverbs_wr_opcode {
+ IB_UVERBS_WR_RDMA_WRITE = 0,
+ IB_UVERBS_WR_RDMA_WRITE_WITH_IMM = 1,
+ IB_UVERBS_WR_SEND = 2,
+ IB_UVERBS_WR_SEND_WITH_IMM = 3,
+ IB_UVERBS_WR_RDMA_READ = 4,
+ IB_UVERBS_WR_ATOMIC_CMP_AND_SWP = 5,
+ IB_UVERBS_WR_ATOMIC_FETCH_AND_ADD = 6,
+ IB_UVERBS_WR_LOCAL_INV = 7,
+ IB_UVERBS_WR_BIND_MW = 8,
+ IB_UVERBS_WR_SEND_WITH_INV = 9,
+ IB_UVERBS_WR_TSO = 10,
+ IB_UVERBS_WR_RDMA_READ_WITH_INV = 11,
+ IB_UVERBS_WR_MASKED_ATOMIC_CMP_AND_SWP = 12,
+ IB_UVERBS_WR_MASKED_ATOMIC_FETCH_AND_ADD = 13,
+};
struct ib_uverbs_send_wr {
__aligned_u64 wr_id;
__u32 num_sge;
diff --git a/libc/kernel/uapi/rdma/mlx5-abi.h b/libc/kernel/uapi/rdma/mlx5-abi.h
index 50ecd2f..77e14f6 100644
--- a/libc/kernel/uapi/rdma/mlx5-abi.h
+++ b/libc/kernel/uapi/rdma/mlx5-abi.h
@@ -28,6 +28,9 @@
MLX5_QP_FLAG_BFREG_INDEX = 1 << 3,
MLX5_QP_FLAG_TYPE_DCT = 1 << 4,
MLX5_QP_FLAG_TYPE_DCI = 1 << 5,
+ MLX5_QP_FLAG_TIR_ALLOW_SELF_LB_UC = 1 << 6,
+ MLX5_QP_FLAG_TIR_ALLOW_SELF_LB_MC = 1 << 7,
+ MLX5_QP_FLAG_ALLOW_SCATTER_CQE = 1 << 8,
};
enum {
MLX5_SRQ_FLAG_SIGNATURE = 1 << 0,
@@ -252,9 +255,21 @@
__u32 comp_mask;
__u32 flags;
};
+enum mlx5_ib_create_qp_resp_mask {
+ MLX5_IB_CREATE_QP_RESP_MASK_TIRN = 1UL << 0,
+ MLX5_IB_CREATE_QP_RESP_MASK_TISN = 1UL << 1,
+ MLX5_IB_CREATE_QP_RESP_MASK_RQN = 1UL << 2,
+ MLX5_IB_CREATE_QP_RESP_MASK_SQN = 1UL << 3,
+};
struct mlx5_ib_create_qp_resp {
__u32 bfreg_index;
__u32 reserved;
+ __u32 comp_mask;
+ __u32 tirn;
+ __u32 tisn;
+ __u32 rqn;
+ __u32 sqn;
+ __u32 reserved1;
};
struct mlx5_ib_alloc_mw {
__u32 comp_mask;
diff --git a/libc/kernel/uapi/rdma/mlx5_user_ioctl_cmds.h b/libc/kernel/uapi/rdma/mlx5_user_ioctl_cmds.h
index 11ff576..902816b 100644
--- a/libc/kernel/uapi/rdma/mlx5_user_ioctl_cmds.h
+++ b/libc/kernel/uapi/rdma/mlx5_user_ioctl_cmds.h
@@ -93,6 +93,7 @@
MLX5_IB_ATTR_FLOW_MATCHER_MATCH_MASK,
MLX5_IB_ATTR_FLOW_MATCHER_FLOW_TYPE,
MLX5_IB_ATTR_FLOW_MATCHER_MATCH_CRITERIA,
+ MLX5_IB_ATTR_FLOW_MATCHER_FLOW_FLAGS,
};
enum mlx5_ib_flow_matcher_destroy_attrs {
MLX5_IB_ATTR_FLOW_MATCHER_DESTROY_HANDLE = (1U << UVERBS_ID_NS_SHIFT),
@@ -117,6 +118,8 @@
MLX5_IB_ATTR_CREATE_FLOW_DEST_QP,
MLX5_IB_ATTR_CREATE_FLOW_DEST_DEVX,
MLX5_IB_ATTR_CREATE_FLOW_MATCHER,
+ MLX5_IB_ATTR_CREATE_FLOW_ARR_FLOW_ACTIONS,
+ MLX5_IB_ATTR_CREATE_FLOW_TAG,
};
enum mlx5_ib_destoy_flow_attrs {
MLX5_IB_ATTR_DESTROY_FLOW_HANDLE = (1U << UVERBS_ID_NS_SHIFT),
@@ -125,4 +128,19 @@
MLX5_IB_METHOD_CREATE_FLOW = (1U << UVERBS_ID_NS_SHIFT),
MLX5_IB_METHOD_DESTROY_FLOW,
};
+enum mlx5_ib_flow_action_methods {
+ MLX5_IB_METHOD_FLOW_ACTION_CREATE_MODIFY_HEADER = (1U << UVERBS_ID_NS_SHIFT),
+ MLX5_IB_METHOD_FLOW_ACTION_CREATE_PACKET_REFORMAT,
+};
+enum mlx5_ib_create_flow_action_create_modify_header_attrs {
+ MLX5_IB_ATTR_CREATE_MODIFY_HEADER_HANDLE = (1U << UVERBS_ID_NS_SHIFT),
+ MLX5_IB_ATTR_CREATE_MODIFY_HEADER_ACTIONS_PRM,
+ MLX5_IB_ATTR_CREATE_MODIFY_HEADER_FT_TYPE,
+};
+enum mlx5_ib_create_flow_action_create_packet_reformat_attrs {
+ MLX5_IB_ATTR_CREATE_PACKET_REFORMAT_HANDLE = (1U << UVERBS_ID_NS_SHIFT),
+ MLX5_IB_ATTR_CREATE_PACKET_REFORMAT_TYPE,
+ MLX5_IB_ATTR_CREATE_PACKET_REFORMAT_FT_TYPE,
+ MLX5_IB_ATTR_CREATE_PACKET_REFORMAT_DATA_BUF,
+};
#endif
diff --git a/libc/kernel/uapi/rdma/mlx5_user_ioctl_verbs.h b/libc/kernel/uapi/rdma/mlx5_user_ioctl_verbs.h
index c9a83cf..dc246e5 100644
--- a/libc/kernel/uapi/rdma/mlx5_user_ioctl_verbs.h
+++ b/libc/kernel/uapi/rdma/mlx5_user_ioctl_verbs.h
@@ -22,4 +22,14 @@
enum mlx5_ib_uapi_flow_action_flags {
MLX5_IB_UAPI_FLOW_ACTION_FLAGS_REQUIRE_METADATA = 1 << 0,
};
+enum mlx5_ib_uapi_flow_table_type {
+ MLX5_IB_UAPI_FLOW_TABLE_TYPE_NIC_RX = 0x0,
+ MLX5_IB_UAPI_FLOW_TABLE_TYPE_NIC_TX = 0x1,
+};
+enum mlx5_ib_uapi_flow_action_packet_reformat_type {
+ MLX5_IB_UAPI_FLOW_ACTION_PACKET_REFORMAT_TYPE_L2_TUNNEL_TO_L2 = 0x0,
+ MLX5_IB_UAPI_FLOW_ACTION_PACKET_REFORMAT_TYPE_L2_TO_L2_TUNNEL = 0x1,
+ MLX5_IB_UAPI_FLOW_ACTION_PACKET_REFORMAT_TYPE_L3_TUNNEL_TO_L2 = 0x2,
+ MLX5_IB_UAPI_FLOW_ACTION_PACKET_REFORMAT_TYPE_L2_TO_L3_TUNNEL = 0x3,
+};
#endif
diff --git a/libc/kernel/uapi/rdma/rdma_netlink.h b/libc/kernel/uapi/rdma/rdma_netlink.h
index 48cbc3d..69805f1 100644
--- a/libc/kernel/uapi/rdma/rdma_netlink.h
+++ b/libc/kernel/uapi/rdma/rdma_netlink.h
@@ -173,6 +173,7 @@
enum rdma_nldev_command {
RDMA_NLDEV_CMD_UNSPEC,
RDMA_NLDEV_CMD_GET,
+ RDMA_NLDEV_CMD_SET,
RDMA_NLDEV_CMD_PORT_GET = 5,
RDMA_NLDEV_CMD_RES_GET = 9,
RDMA_NLDEV_CMD_RES_QP_GET,
diff --git a/libc/kernel/uapi/scsi/scsi_bsg_ufs.h b/libc/kernel/uapi/scsi/scsi_bsg_ufs.h
new file mode 100644
index 0000000..177cae9
--- /dev/null
+++ b/libc/kernel/uapi/scsi/scsi_bsg_ufs.h
@@ -0,0 +1,62 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ *** To edit the content of this header, modify the corresponding
+ *** source file (e.g. under external/kernel-headers/original/) then
+ *** run bionic/libc/kernel/tools/update_all.py
+ ***
+ *** Any manual change here will be lost the next time this script will
+ *** be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef SCSI_BSG_UFS_H
+#define SCSI_BSG_UFS_H
+#include <linux/types.h>
+#define UFS_CDB_SIZE 16
+#define UPIU_TRANSACTION_UIC_CMD 0x1F
+#define UIC_CMD_SIZE (sizeof(__u32) * 4)
+struct utp_upiu_header {
+ __be32 dword_0;
+ __be32 dword_1;
+ __be32 dword_2;
+};
+struct utp_upiu_query {
+ __u8 opcode;
+ __u8 idn;
+ __u8 index;
+ __u8 selector;
+ __be16 reserved_osf;
+ __be16 length;
+ __be32 value;
+ __be32 reserved[2];
+};
+struct utp_upiu_cmd {
+ __be32 exp_data_transfer_len;
+ __u8 cdb[UFS_CDB_SIZE];
+};
+struct utp_upiu_req {
+ struct utp_upiu_header header;
+ union {
+ struct utp_upiu_cmd sc;
+ struct utp_upiu_query qr;
+ struct utp_upiu_query tr;
+ struct utp_upiu_query uc;
+ };
+};
+struct ufs_bsg_request {
+ __u32 msgcode;
+ struct utp_upiu_req upiu_req;
+};
+struct ufs_bsg_reply {
+ __u32 result;
+ __u32 reply_payload_rcv_len;
+ struct utp_upiu_req upiu_rsp;
+};
+#endif
diff --git a/libc/libc.map.txt b/libc/libc.map.txt
index 9dfdbc0..c27f884 100644
--- a/libc/libc.map.txt
+++ b/libc/libc.map.txt
@@ -1481,14 +1481,6 @@
# Used by libandroid_runtime
gMallocLeakZygoteChild; # apex
-
- # TODO(b/120266448) hide these symbols again
- # Used by libndk_translation
- __getdents64; # arm x86 mips apex
- tkill; # arm x86 mips apex
- # Used by PtsBionicDeviceTestCases
- __bionic_brk; # arm x86 mips apex
- __system_property_add; # apex
} LIBC_P;
LIBC_PRIVATE {
@@ -1565,6 +1557,7 @@
__arm_fadvise64_64; # arm
__ashldi3; # arm
__ashrdi3; # arm
+ __bionic_brk; # arm x86 mips
__bionic_libgcc_compat_symbols; # arm x86
__cmpdf2; # arm
__divdf3; # arm
@@ -1590,6 +1583,7 @@
__gedf2; # arm
__get_thread; # arm x86 mips
__get_tls; # arm x86 mips
+ __getdents64; # arm x86 mips
__gnu_ldivmod_helper; # arm
__gnu_uldivmod_helper; # arm
__gnu_Unwind_Backtrace; # arm
@@ -1697,6 +1691,7 @@
strntoumax; # arm x86 mips
strtotimeval; # arm x86 mips
sysv_signal; # arm x86 mips
+ tkill; # arm x86 mips
wait3; # arm x86 mips
wcswcs; # arm x86 mips
} LIBC_Q;
@@ -1708,6 +1703,7 @@
LIBC_PLATFORM {
global:
+ __system_property_add;
__system_property_area__; # var
__system_property_area_init;
__system_property_set_filename;
diff --git a/libc/malloc_debug/Config.cpp b/libc/malloc_debug/Config.cpp
index 926b265..dd20b5c 100644
--- a/libc/malloc_debug/Config.cpp
+++ b/libc/malloc_debug/Config.cpp
@@ -132,6 +132,9 @@
{
"verify_pointers", {TRACK_ALLOCS, &Config::VerifyValueEmpty},
},
+ {
+ "abort_on_error", {ABORT_ON_ERROR, &Config::VerifyValueEmpty},
+ },
};
bool Config::ParseValue(const std::string& option, const std::string& value, size_t min_value,
diff --git a/libc/malloc_debug/Config.h b/libc/malloc_debug/Config.h
index 86d1ee4..011dc77 100644
--- a/libc/malloc_debug/Config.h
+++ b/libc/malloc_debug/Config.h
@@ -44,6 +44,7 @@
constexpr uint64_t LEAK_TRACK = 0x100;
constexpr uint64_t RECORD_ALLOCS = 0x200;
constexpr uint64_t BACKTRACE_FULL = 0x400;
+constexpr uint64_t ABORT_ON_ERROR = 0x800;
// In order to guarantee posix compliance, set the minimum alignment
// to 8 bytes for 32 bit systems and 16 bytes for 64 bit systems.
diff --git a/libc/malloc_debug/GuardData.cpp b/libc/malloc_debug/GuardData.cpp
index debc14e..c307dc9 100644
--- a/libc/malloc_debug/GuardData.cpp
+++ b/libc/malloc_debug/GuardData.cpp
@@ -64,6 +64,9 @@
error_log("Backtrace at time of failure:");
BacktraceAndLog();
error_log(LOG_DIVIDER);
+ if (g_debug->config().options() & ABORT_ON_ERROR) {
+ abort();
+ }
}
FrontGuardData::FrontGuardData(DebugData* debug_data, const Config& config, size_t* offset)
diff --git a/libc/malloc_debug/PointerData.cpp b/libc/malloc_debug/PointerData.cpp
index b0e2fc8..638061b 100644
--- a/libc/malloc_debug/PointerData.cpp
+++ b/libc/malloc_debug/PointerData.cpp
@@ -206,7 +206,7 @@
std::lock_guard<std::mutex> pointer_guard(pointer_mutex_);
auto entry = pointers_.find(pointer);
if (entry == pointers_.end()) {
- // Error.
+ // Attempt to remove unknown pointer.
error_log("No tracked pointer found for 0x%" PRIxPTR, pointer);
return;
}
@@ -283,6 +283,9 @@
}
error_log(LOG_DIVIDER);
+ if (g_debug->config().options() & ABORT_ON_ERROR) {
+ abort();
+ }
}
void PointerData::VerifyFreedPointer(const FreePointerInfoType& info) {
@@ -295,6 +298,9 @@
error_log("+++ ALLOCATION 0x%" PRIxPTR " HAS CORRUPTED HEADER TAG 0x%x AFTER FREE",
info.pointer, header->tag);
error_log(LOG_DIVIDER);
+ if (g_debug->config().options() & ABORT_ON_ERROR) {
+ abort();
+ }
// Stop processing here, it is impossible to tell how the header
// may have been damaged.
diff --git a/libc/malloc_debug/README.md b/libc/malloc_debug/README.md
index a8289b3..93b9b1e 100644
--- a/libc/malloc_debug/README.md
+++ b/libc/malloc_debug/README.md
@@ -394,6 +394,13 @@
**NOTE**: This option is not available until the P release of Android.
+### abort\_on\_error
+When malloc debug detects an error, abort after sending the error
+log message.
+
+**NOTE**: If leak\_track is enabled, no abort occurs if leaks have been
+detected when the process is exiting.
+
Additional Errors
-----------------
There are a few other error messages that might appear in the log.
diff --git a/libc/malloc_debug/malloc_debug.cpp b/libc/malloc_debug/malloc_debug.cpp
index 9075a9c..2e6afff 100644
--- a/libc/malloc_debug/malloc_debug.cpp
+++ b/libc/malloc_debug/malloc_debug.cpp
@@ -154,6 +154,9 @@
error_log("Backtrace at time of failure:");
BacktraceAndLog();
error_log(LOG_DIVIDER);
+ if (g_debug->config().options() & ABORT_ON_ERROR) {
+ abort();
+ }
}
static bool VerifyPointer(const void* pointer, const char* function_name) {
diff --git a/libc/malloc_debug/tests/malloc_debug_config_tests.cpp b/libc/malloc_debug/tests/malloc_debug_config_tests.cpp
index a083b4f..fb54ee5 100644
--- a/libc/malloc_debug/tests/malloc_debug_config_tests.cpp
+++ b/libc/malloc_debug/tests/malloc_debug_config_tests.cpp
@@ -725,3 +725,21 @@
"value must be <= 50000000: 100000000\n");
ASSERT_STREQ((log_msg + usage_string).c_str(), getFakeLogPrint().c_str());
}
+
+TEST_F(MallocDebugConfigTest, abort_on_error) {
+ ASSERT_TRUE(InitConfig("abort_on_error")) << getFakeLogPrint();
+ ASSERT_EQ(ABORT_ON_ERROR, config->options());
+
+ ASSERT_STREQ("", getFakeLogBuf().c_str());
+ ASSERT_STREQ("", getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugConfigTest, trigger_abort_fail) {
+ ASSERT_FALSE(InitConfig("abort_on_error=200")) << getFakeLogPrint();
+
+ ASSERT_STREQ("", getFakeLogBuf().c_str());
+ std::string log_msg(
+ "6 malloc_debug malloc_testing: value set for option 'abort_on_error' "
+ "which does not take a value\n");
+ ASSERT_STREQ((log_msg + usage_string).c_str(), getFakeLogPrint().c_str());
+}
diff --git a/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp b/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
index 2d6346f..44f9795 100644
--- a/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
+++ b/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
@@ -2380,3 +2380,59 @@
expected_log += DIVIDER;
ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
}
+
+TEST_F(MallocDebugTest, abort_on_error_log_error) {
+ Init("abort_on_error verify_pointers");
+
+ void* pointer = debug_malloc(10);
+ memset(pointer, 0, 10);
+ debug_free(pointer);
+
+ ASSERT_STREQ("", getFakeLogBuf().c_str());
+ ASSERT_STREQ("", getFakeLogPrint().c_str());
+
+ EXPECT_DEATH(debug_free(pointer), "");
+}
+
+TEST_F(MallocDebugTest, abort_on_error_guard_corrupted) {
+ Init("abort_on_error front_guard=32");
+
+ uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100));
+ ASSERT_TRUE(pointer != nullptr);
+ pointer[-16] = 0x00;
+ EXPECT_DEATH(debug_free(pointer), "");
+ pointer[-16] = 0xaa;
+ debug_free(pointer);
+}
+
+TEST_F(MallocDebugTest, abort_on_error_use_after_free) {
+ Init("abort_on_error free_track=100 free_track_backtrace_num_frames=0");
+
+ uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100));
+ ASSERT_TRUE(pointer != nullptr);
+ memset(pointer, 0, 100);
+ debug_free(pointer);
+
+ pointer[56] = 0x91;
+
+ EXPECT_DEATH(debug_finalize(), "");
+
+ pointer[56] = 0xef;
+}
+
+TEST_F(MallocDebugTest, abort_on_error_header_tag_corrupted) {
+ Init("abort_on_error free_track=100 free_track_backtrace_num_frames=0 rear_guard");
+
+ uint8_t* pointer = reinterpret_cast<uint8_t*>(debug_malloc(100));
+ ASSERT_TRUE(pointer != nullptr);
+ memset(pointer, 0, 100);
+ debug_free(pointer);
+
+ uint8_t tag_value = pointer[-get_tag_offset()];
+ pointer[-get_tag_offset()] = 0x00;
+
+ EXPECT_DEATH(debug_finalize(), "");
+
+ pointer[-get_tag_offset()] = tag_value;
+}
+
diff --git a/libc/private/ScopedRWLock.h b/libc/private/ScopedRWLock.h
new file mode 100644
index 0000000..f034505
--- /dev/null
+++ b/libc/private/ScopedRWLock.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2008 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.
+ */
+
+#pragma once
+
+#include <pthread.h>
+
+#include "private/bionic_macros.h"
+
+template <bool write> class ScopedRWLock {
+ public:
+ explicit ScopedRWLock(pthread_rwlock_t* rwlock) : rwlock_(rwlock) {
+ (write ? pthread_rwlock_wrlock : pthread_rwlock_rdlock)(rwlock_);
+ }
+
+ ~ScopedRWLock() {
+ pthread_rwlock_unlock(rwlock_);
+ }
+
+ private:
+ pthread_rwlock_t* rwlock_;
+ BIONIC_DISALLOW_IMPLICIT_CONSTRUCTORS(ScopedRWLock);
+};
+
+typedef ScopedRWLock<true> ScopedWriteLock;
+typedef ScopedRWLock<false> ScopedReadLock;
diff --git a/libc/private/bionic_asm_tls.h b/libc/private/bionic_asm_tls.h
index 06e3dce..0f0873f 100644
--- a/libc/private/bionic_asm_tls.h
+++ b/libc/private/bionic_asm_tls.h
@@ -87,11 +87,9 @@
#define TLS_SLOT_STACK_GUARD 5
#define TLS_SLOT_SANITIZER 6 // was historically used for dlerror
#define TLS_SLOT_ART_THREAD_SELF 7
-#define TLS_SLOT_TSAN 8 // should be replaced with TLS_SLOT_SANITIZER
// The maximum slot is fixed by the minimum TLS alignment in Bionic executables.
-// It should be changed to 7 once TLS_SLOT_TSAN is removed.
-#define MAX_TLS_SLOT 8
+#define MAX_TLS_SLOT 7
#elif defined(__i386__) || defined(__x86_64__)
@@ -109,10 +107,9 @@
#define TLS_SLOT_STACK_GUARD 5
#define TLS_SLOT_SANITIZER 6 // was historically used for dlerror
#define TLS_SLOT_ART_THREAD_SELF 7
-#define TLS_SLOT_TSAN 8 // should be replaced with TLS_SLOT_SANITIZER
-#define TLS_SLOT_DTV 9
-#define TLS_SLOT_BIONIC_TLS 10
-#define MAX_TLS_SLOT 10 // update this value when reserving a slot
+#define TLS_SLOT_DTV 8
+#define TLS_SLOT_BIONIC_TLS 9
+#define MAX_TLS_SLOT 9 // update this value when reserving a slot
#endif
diff --git a/libc/private/bionic_elf_tls.h b/libc/private/bionic_elf_tls.h
index e847669..09e1958 100644
--- a/libc/private/bionic_elf_tls.h
+++ b/libc/private/bionic_elf_tls.h
@@ -28,7 +28,23 @@
#pragma once
+#include <link.h>
+#include <pthread.h>
+#include <stdatomic.h>
#include <stdint.h>
+#include <sys/cdefs.h>
+
+struct TlsSegment {
+ size_t size = 0;
+ size_t alignment = 1;
+ const void* init_ptr = ""; // Field is non-null even when init_size is 0.
+ size_t init_size = 0;
+};
+
+__LIBC_HIDDEN__ bool __bionic_get_tls_segment(const ElfW(Phdr)* phdr_table, size_t phdr_count,
+ ElfW(Addr) load_bias, TlsSegment* out);
+
+__LIBC_HIDDEN__ bool __bionic_check_tls_alignment(size_t* alignment);
struct StaticTlsLayout {
constexpr StaticTlsLayout() {}
@@ -45,13 +61,17 @@
public:
size_t offset_bionic_tcb() const { return offset_bionic_tcb_; }
size_t offset_bionic_tls() const { return offset_bionic_tls_; }
+ size_t offset_thread_pointer() const;
size_t size() const { return offset_; }
size_t alignment() const { return alignment_; }
bool overflowed() const { return overflowed_; }
- void reserve_tcb();
+ size_t reserve_exe_segment_and_tcb(const TlsSegment* exe_segment, const char* progname);
void reserve_bionic_tls();
+ size_t reserve_solib_segment(const TlsSegment& segment) {
+ return reserve(segment.size, segment.alignment);
+ }
void finish_layout();
private:
@@ -63,3 +83,39 @@
size_t round_up_with_overflow_check(size_t value, size_t alignment);
};
+
+// A descriptor for a single ELF TLS module.
+struct TlsModule {
+ TlsSegment segment;
+
+ // Offset into the static TLS block or SIZE_MAX for a dynamic module.
+ size_t static_offset = SIZE_MAX;
+
+ // The generation in which this module was loaded. Dynamic TLS lookups use
+ // this field to detect when a module has been unloaded.
+ size_t first_generation = 0;
+
+ // Used by the dynamic linker to track the associated soinfo* object.
+ void* soinfo_ptr = nullptr;
+};
+
+// Table of the ELF TLS modules. Either the dynamic linker or the static
+// initialization code prepares this table, and it's then used during thread
+// creation and for dynamic TLS lookups.
+struct TlsModules {
+ constexpr TlsModules() {}
+
+ // A generation counter. The value is incremented each time an solib is loaded
+ // or unloaded.
+ _Atomic(size_t) generation = 0;
+
+ // Access to the TlsModule[] table requires taking this lock.
+ pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER;
+
+ // Pointer to a block of TlsModule objects. The first module has ID 1 and
+ // is stored at index 0 in this table.
+ size_t module_count = 0;
+ TlsModule* module_table = nullptr;
+};
+
+void __init_static_tls(void* static_tls);
diff --git a/libc/private/bionic_globals.h b/libc/private/bionic_globals.h
index b5e677e..4d40476 100644
--- a/libc/private/bionic_globals.h
+++ b/libc/private/bionic_globals.h
@@ -69,6 +69,7 @@
abort_msg_t* abort_msg = nullptr;
StaticTlsLayout static_tls_layout;
+ TlsModules tls_modules;
// Values passed from the linker to libc.so.
const char* init_progname = nullptr;
diff --git a/libc/seccomp/include/seccomp_policy.h b/libc/seccomp/include/seccomp_policy.h
index 49280f4..fd0fb60 100644
--- a/libc/seccomp/include/seccomp_policy.h
+++ b/libc/seccomp/include/seccomp_policy.h
@@ -17,8 +17,14 @@
#pragma once
#include <stddef.h>
+#include <stdint.h>
#include <linux/filter.h>
bool set_app_seccomp_filter();
+bool set_app_zygote_seccomp_filter();
bool set_system_seccomp_filter();
bool set_global_seccomp_filter();
+
+// Installs a filter that limits setresuid/setresgid to a range of
+// [uid_gid_min..uid_gid_max] (for the real-, effective- and super-ids).
+bool install_setuidgid_seccomp_filter(uint32_t uid_gid_min, uint32_t uid_gid_max);
diff --git a/libc/seccomp/seccomp_bpfs.h b/libc/seccomp/seccomp_bpfs.h
index 797dfc5..d9e8047 100644
--- a/libc/seccomp/seccomp_bpfs.h
+++ b/libc/seccomp/seccomp_bpfs.h
@@ -21,6 +21,8 @@
extern const struct sock_filter arm_app_filter[];
extern const size_t arm_app_filter_size;
+extern const struct sock_filter arm_app_zygote_filter[];
+extern const size_t arm_app_zygote_filter_size;
extern const struct sock_filter arm_system_filter[];
extern const size_t arm_system_filter_size;
extern const struct sock_filter arm_global_filter[];
@@ -28,6 +30,8 @@
extern const struct sock_filter arm64_app_filter[];
extern const size_t arm64_app_filter_size;
+extern const struct sock_filter arm64_app_zygote_filter[];
+extern const size_t arm64_app_zygote_filter_size;
extern const struct sock_filter arm64_system_filter[];
extern const size_t arm64_system_filter_size;
extern const struct sock_filter arm64_global_filter[];
@@ -35,6 +39,8 @@
extern const struct sock_filter x86_app_filter[];
extern const size_t x86_app_filter_size;
+extern const struct sock_filter x86_app_zygote_filter[];
+extern const size_t x86_app_zygote_filter_size;
extern const struct sock_filter x86_system_filter[];
extern const size_t x86_system_filter_size;
extern const struct sock_filter x86_global_filter[];
@@ -42,6 +48,8 @@
extern const struct sock_filter x86_64_app_filter[];
extern const size_t x86_64_app_filter_size;
+extern const struct sock_filter x86_64_app_zygote_filter[];
+extern const size_t x86_64_app_zygote_filter_size;
extern const struct sock_filter x86_64_system_filter[];
extern const size_t x86_64_system_filter_size;
extern const struct sock_filter x86_64_global_filter[];
@@ -49,6 +57,8 @@
extern const struct sock_filter mips_app_filter[];
extern const size_t mips_app_filter_size;
+extern const struct sock_filter mips_app_zygote_filter[];
+extern const size_t mips_app_zygote_filter_size;
extern const struct sock_filter mips_system_filter[];
extern const size_t mips_system_filter_size;
extern const struct sock_filter mips_global_filter[];
@@ -56,6 +66,8 @@
extern const struct sock_filter mips64_app_filter[];
extern const size_t mips64_app_filter_size;
+extern const struct sock_filter mips64_app_zygote_filter[];
+extern const size_t mips64_app_zygote_filter_size;
extern const struct sock_filter mips64_system_filter[];
extern const size_t mips64_system_filter_size;
extern const struct sock_filter mips64_global_filter[];
diff --git a/libc/seccomp/seccomp_policy.cpp b/libc/seccomp/seccomp_policy.cpp
index 3d617be..222a2c8 100644
--- a/libc/seccomp/seccomp_policy.cpp
+++ b/libc/seccomp/seccomp_policy.cpp
@@ -20,78 +20,111 @@
#include <linux/audit.h>
#include <linux/seccomp.h>
#include <sys/prctl.h>
+#include <sys/syscall.h>
#include <vector>
#include <android-base/logging.h>
+#include "func_to_syscall_nrs.h"
#include "seccomp_bpfs.h"
-
#if defined __arm__ || defined __aarch64__
#define DUAL_ARCH
#define PRIMARY_ARCH AUDIT_ARCH_AARCH64
static const struct sock_filter* primary_app_filter = arm64_app_filter;
static const size_t primary_app_filter_size = arm64_app_filter_size;
+static const struct sock_filter* primary_app_zygote_filter = arm64_app_zygote_filter;
+static const size_t primary_app_zygote_filter_size = arm64_app_zygote_filter_size;
static const struct sock_filter* primary_system_filter = arm64_system_filter;
static const size_t primary_system_filter_size = arm64_system_filter_size;
static const struct sock_filter* primary_global_filter = arm64_global_filter;
static const size_t primary_global_filter_size = arm64_global_filter_size;
+
+static const long primary_setresgid = __arm64_setresgid;
+static const long primary_setresuid = __arm64_setresuid;
#define SECONDARY_ARCH AUDIT_ARCH_ARM
static const struct sock_filter* secondary_app_filter = arm_app_filter;
static const size_t secondary_app_filter_size = arm_app_filter_size;
+static const struct sock_filter* secondary_app_zygote_filter = arm_app_zygote_filter;
+static const size_t secondary_app_zygote_filter_size = arm_app_zygote_filter_size;
static const struct sock_filter* secondary_system_filter = arm_system_filter;
static const size_t secondary_system_filter_size = arm_system_filter_size;
static const struct sock_filter* secondary_global_filter = arm_global_filter;
static const size_t secondary_global_filter_size = arm_global_filter_size;
+static const long secondary_setresgid = __arm_setresgid;
+static const long secondary_setresuid = __arm_setresuid;
#elif defined __i386__ || defined __x86_64__
#define DUAL_ARCH
#define PRIMARY_ARCH AUDIT_ARCH_X86_64
static const struct sock_filter* primary_app_filter = x86_64_app_filter;
static const size_t primary_app_filter_size = x86_64_app_filter_size;
+static const struct sock_filter* primary_app_zygote_filter = x86_64_app_zygote_filter;
+static const size_t primary_app_zygote_filter_size = x86_64_app_zygote_filter_size;
static const struct sock_filter* primary_system_filter = x86_64_system_filter;
static const size_t primary_system_filter_size = x86_64_system_filter_size;
static const struct sock_filter* primary_global_filter = x86_64_global_filter;
static const size_t primary_global_filter_size = x86_64_global_filter_size;
+
+static const long primary_setresgid = __x86_64_setresgid;
+static const long primary_setresuid = __x86_64_setresuid;
#define SECONDARY_ARCH AUDIT_ARCH_I386
static const struct sock_filter* secondary_app_filter = x86_app_filter;
static const size_t secondary_app_filter_size = x86_app_filter_size;
+static const struct sock_filter* secondary_app_zygote_filter = x86_app_zygote_filter;
+static const size_t secondary_app_zygote_filter_size = x86_app_zygote_filter_size;
static const struct sock_filter* secondary_system_filter = x86_system_filter;
static const size_t secondary_system_filter_size = x86_system_filter_size;
static const struct sock_filter* secondary_global_filter = x86_global_filter;
static const size_t secondary_global_filter_size = x86_global_filter_size;
+static const long secondary_setresgid = __x86_setresgid;
+static const long secondary_setresuid = __x86_setresuid;
#elif defined __mips__ || defined __mips64__
#define DUAL_ARCH
#define PRIMARY_ARCH AUDIT_ARCH_MIPSEL64
static const struct sock_filter* primary_app_filter = mips64_app_filter;
static const size_t primary_app_filter_size = mips64_app_filter_size;
+static const struct sock_filter* primary_app_zygote_filter = mips64_app_zygote_filter;
+static const size_t primary_app_zygote_filter_size = mips64_app_zygote_filter_size;
static const struct sock_filter* primary_system_filter = mips64_system_filter;
static const size_t primary_system_filter_size = mips64_system_filter_size;
static const struct sock_filter* primary_global_filter = mips64_global_filter;
static const size_t primary_global_filter_size = mips64_global_filter_size;
+
+static const long primary_setresgid = __mips64_setresgid;
+static const long primary_setresuid = __mips64_setresuid;
#define SECONDARY_ARCH AUDIT_ARCH_MIPSEL
static const struct sock_filter* secondary_app_filter = mips_app_filter;
static const size_t secondary_app_filter_size = mips_app_filter_size;
+static const struct sock_filter* secondary_app_zygote_filter = mips_app_zygote_filter;
+static const size_t secondary_app_zygote_filter_size = mips_app_zygote_filter_size;
static const struct sock_filter* secondary_system_filter = mips_system_filter;
static const size_t secondary_system_filter_size = mips_system_filter_size;
static const struct sock_filter* secondary_global_filter = mips_global_filter;
static const size_t secondary_global_filter_size = mips_global_filter_size;
+static const long secondary_setresgid = __mips_setresgid;
+static const long secondary_setresuid = __mips_setresuid;
#else
#error No architecture was defined!
#endif
#define syscall_nr (offsetof(struct seccomp_data, nr))
+#define syscall_arg(_n) (offsetof(struct seccomp_data, args[_n]))
#define arch_nr (offsetof(struct seccomp_data, arch))
typedef std::vector<sock_filter> filter;
+inline void Allow(filter& f) {
+ f.push_back(BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW));
+}
+
inline void Disallow(filter& f) {
f.push_back(BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_TRAP));
}
@@ -128,6 +161,49 @@
}
#endif
+static void ValidateSyscallArgInRange(filter& f, __u32 arg_num, __u32 range_min, __u32 range_max) {
+ const __u32 syscall_arg = syscall_arg(arg_num);
+
+ if (range_max == UINT32_MAX) {
+ LOG(FATAL) << "range_max exceeds maximum argument range.";
+ return;
+ }
+
+ f.push_back(BPF_STMT(BPF_LD|BPF_W|BPF_ABS, syscall_arg));
+ f.push_back(BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, range_min, 0, 1));
+ f.push_back(BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, range_max + 1, 0, 1));
+ Disallow(f);
+}
+
+// This filter is meant to be installed in addition to a regular whitelist filter.
+// Therefore, it's default action has to be Allow, except when the evaluated
+// system call matches setresuid/setresgid and the arguments don't fall within the
+// passed in range.
+//
+// The regular whitelist only allows setresuid/setresgid for UID/GID changes, so
+// that's the only system call we need to check here. A CTS test ensures the other
+// calls will remain blocked.
+static void ValidateSetUidGid(filter& f, uint32_t uid_gid_min, uint32_t uid_gid_max, bool primary) {
+ // Check setresuid(ruid, euid, sguid) fall within range
+ ExamineSyscall(f);
+ __u32 setresuid_nr = primary ? primary_setresuid : secondary_setresuid;
+ f.push_back(BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, setresuid_nr, 0, 12));
+ for (int arg = 0; arg < 3; arg++) {
+ ValidateSyscallArgInRange(f, arg, uid_gid_min, uid_gid_max);
+ }
+
+ // Check setresgid(rgid, egid, sgid) fall within range
+ ExamineSyscall(f);
+ __u32 setresgid_nr = primary ? primary_setresgid : secondary_setresgid;
+ f.push_back(BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, setresgid_nr, 0, 12));
+ for (int arg = 0; arg < 3; arg++) {
+ ValidateSyscallArgInRange(f, arg, uid_gid_min, uid_gid_max);
+ }
+
+ // Default is to allow; other filters may still reject this call.
+ Allow(f);
+}
+
static bool install_filter(filter const& f) {
struct sock_fprog prog = {
static_cast<unsigned short>(f.size()),
@@ -141,8 +217,33 @@
return true;
}
+bool _install_setuidgid_filter(uint32_t uid_gid_min, uint32_t uid_gid_max) {
+ filter f;
+#ifdef DUAL_ARCH
+ // Note that for mixed 64/32 bit architectures, ValidateArchitecture inserts a
+ // jump that must be changed to point to the start of the 32-bit policy
+ // 32 bit syscalls will not hit the policy between here and the call to SetJump
+ auto offset_to_secondary_filter = ValidateArchitectureAndJumpIfNeeded(f);
+#else
+ ValidateArchitecture(f);
+#endif
+
+ ValidateSetUidGid(f, uid_gid_min, uid_gid_max, true /* primary */);
+
+#ifdef DUAL_ARCH
+ if (!SetValidateArchitectureJumpTarget(offset_to_secondary_filter, f)) {
+ return false;
+ }
+
+ ValidateSetUidGid(f, uid_gid_min, uid_gid_max, false /* primary */);
+#endif
+
+ return install_filter(f);
+}
+
enum FilterType {
APP,
+ APP_ZYGOTE,
SYSTEM,
GLOBAL
};
@@ -159,6 +260,12 @@
s = secondary_app_filter;
s_size = secondary_app_filter_size;
break;
+ case APP_ZYGOTE:
+ p = primary_app_zygote_filter;
+ p_size = primary_app_zygote_filter_size;
+ s = secondary_app_zygote_filter;
+ s_size = secondary_app_zygote_filter_size;
+ break;
case SYSTEM:
p = primary_system_filter;
p_size = primary_system_filter_size;
@@ -210,6 +317,10 @@
return _set_seccomp_filter(FilterType::APP);
}
+bool set_app_zygote_seccomp_filter() {
+ return _set_seccomp_filter(FilterType::APP_ZYGOTE);
+}
+
bool set_system_seccomp_filter() {
return _set_seccomp_filter(FilterType::SYSTEM);
}
@@ -217,3 +328,7 @@
bool set_global_seccomp_filter() {
return _set_seccomp_filter(FilterType::GLOBAL);
}
+
+bool install_setuidgid_seccomp_filter(uint32_t uid_gid_min, uint32_t uid_gid_max) {
+ return _install_setuidgid_filter(uid_gid_min, uid_gid_max);
+}
diff --git a/libc/symbol_ordering b/libc/symbol_ordering
new file mode 100644
index 0000000..5b365f0
--- /dev/null
+++ b/libc/symbol_ordering
@@ -0,0 +1,210 @@
+# This file is generated by sorting symbols in the .bss section in libc.so by
+# their sizes and taking out symbols that are unique to a target. By sorting
+# symbols by size, we usually have less dirty pages at runtime, because small
+# symbols are grouped together.
+
+je_background_thread_enabled_state
+je_can_enable_background_thread
+_ZZ17__find_icu_symbolPKcE9found_icu
+_ZL28g_heapprofd_init_in_progress
+_ZL31g_heapprofd_init_hook_installed
+je_opt_abort
+je_opt_abort_conf
+je_opt_junk_alloc
+je_opt_junk_free
+je_opt_utrace
+je_opt_xmalloc
+je_opt_zero
+malloc_disabled_tcache
+had_conf_error
+malloc_slow_flags
+je_opt_background_thread
+background_thread_enabled_at_fork
+ctl_initialized
+je_log_init_done
+mmap_flags
+os_overcommits
+je_opt_stats_print
+je_tsd_booted
+global_hashtable_initialized
+gmtcheck.gmt_is_set
+restartloop
+_ZZ12bindresvportE4port
+ru_counter
+ru_a
+ru_x
+ru_b
+ru_seed
+ru_g
+ru_seed2
+ru_msb
+je_narenas_auto
+je_ncpus
+je_init_system_thp_mode
+je_nhbins
+je_tsd_tsd
+optreset
+_rs_forked
+daylight
+_ZL17g_icudata_version
+gMallocLeakZygoteChild
+_ZL18netdClientInitOnce
+je_opt_narenas
+narenas_total
+je_malloc_disable.once_control
+je_opt_metadata_thp
+je_opt_thp
+stack_nelms
+tcaches_past
+ncleanups
+error_message_count
+error_one_per_line
+_ZZ13error_at_lineE9last_line
+_ZL13g_locale_once
+_ZL30g_propservice_protocol_version
+_res_cache_once
+_res_key
+_rs_forkdetect._rs_pid
+ru_pid
+lcl_is_set
+__cxa_finalize.call_depth
+seed48.sseed
+ether_aton.addr
+je_background_thread_info
+je_max_background_threads
+je_n_background_threads
+je_malloc_message
+je_tcache_bin_info
+je_tcache_maxclass
+je_tcaches
+optarg
+suboptarg
+timezone
+_ZGVZ17__find_icu_symbolPKcE9found_icu
+_ZL17g_libicuuc_handle
+__malloc_hook
+__realloc_hook
+__free_hook
+__memalign_hook
+_ZL21g_heapprofd_init_func
+je_malloc_conf
+malloc_initializer
+a0
+je_opt_dirty_decay_ms
+je_opt_muzzy_decay_ms
+dirty_decay_ms_default.0
+muzzy_decay_ms_default.0
+pthread_create_fptr
+b0
+ctl_arenas
+ctl_stats
+je_hooks_arena_new_hook
+os_page
+tcaches_avail
+_ZN9prop_area8pa_size_E
+_ZN9prop_area13pa_data_size_E
+_ZL6g_lock
+_ZL6g_tags
+_ZZ8c16rtombE15__private_state
+_ZZ8c32rtombE15__private_state
+environ
+error_print_progname
+_ZZ13error_at_lineE9last_file
+_ZZ14__icu_charTypejE10u_charType
+_ZGVZ14__icu_charTypejE10u_charType
+_ZZ25__icu_getIntPropertyValuej9UPropertyE21u_getIntPropertyValue
+_ZGVZ25__icu_getIntPropertyValuej9UPropertyE21u_getIntPropertyValue
+_ZZ23__icu_hasBinaryPropertyj9UPropertyPFiiEE19u_hasBinaryProperty
+_ZGVZ23__icu_hasBinaryPropertyj9UPropertyPFiiEE19u_hasBinaryProperty
+__progname
+_ZZ8mbrtoc16E15__private_state
+_ZZ8mbrtoc32E15__private_state
+_ZL14syslog_log_tag
+__system_property_area__
+_ZZ7mbrtowcE15__private_state
+_ZZ10mbsnrtowcsE15__private_state
+_ZZ7wcrtombE15__private_state
+_ZZ10wcsnrtombsE15__private_state
+_ZZ8iswcntrlE10u_charType
+_ZGVZ8iswcntrlE10u_charType
+_ZZ8iswdigitE9u_isdigit
+_ZGVZ8iswdigitE9u_isdigit
+_ZZ8iswpunctE9u_ispunct
+_ZGVZ8iswpunctE9u_ispunct
+_ZZ8towlowerE9u_tolower
+_ZGVZ8towlowerE9u_tolower
+_ZZ8towupperE9u_toupper
+_ZGVZ8towupperE9u_toupper
+global_hashtable
+handlers
+p5s
+ut
+rs
+rsx
+mbrlen.mbs
+mbtowc.mbs
+wctomb.mbs
+ru_reseed
+ru_prf
+tmpnam.tmpcount
+lastenv
+strtok.last
+__stack_chk_guard
+lclptr
+gmtptr
+_ZGVZ14tzset_unlockedE20persist_sys_timezone
+_ZL13g_thread_list
+__atexit
+je_opt_stats_print_opts
+nuls
+precsize_ntoa.retbuf
+__p_secstodate.output
+_ZL13g_atfork_list
+inet_ntoa.b
+ether_ntoa.buf
+__sym_ntos.unname
+__sym_ntop.unname
+__p_type.typebuf
+__p_class.classbuf
+malloc_disabled_lock
+_ZL11g_arc4_lock
+_res_cache_list_lock
+__p_option.nbuf
+__p_time.nbuf
+atexit_mutex
+random_mutex
+__res_randomid.__libc_mutex_random
+locallock
+g_atexit_lock
+_ZL11g_functions
+_ZL13vendor_passwd
+_ZL12vendor_group
+tm
+_ZL18g_thread_list_lock
+buf_asctime
+__dtoa_locks
+freelist
+__loc_ntoa.tmpbuf
+_ZL8g_locale
+je_arenas_lock
+je_background_thread_lock
+init_lock
+ctl_mtx
+tcaches_mtx
+je_tsd_init_head
+_ZZ14tzset_unlockedE20persist_sys_timezone
+arena_binind_div_info
+__hexdig_D2A
+lcl_TZname
+utmp
+inet_nsap_ntoa_tmpbuf
+_ZL17system_properties
+_ZL7key_map
+private_mem
+__libc_globals
+tmpnam.buf
+_res_cache_list
+_nres
+je_extent_mutex_pool
+je_arenas
+je_extents_rtree
diff --git a/libc/tools/genfunctosyscallnrs.py b/libc/tools/genfunctosyscallnrs.py
new file mode 100755
index 0000000..6a456f2
--- /dev/null
+++ b/libc/tools/genfunctosyscallnrs.py
@@ -0,0 +1,60 @@
+#!/usr/bin/env python
+
+import argparse
+import collections
+import logging
+import os
+import re
+import subprocess
+import textwrap
+
+from gensyscalls import SysCallsTxtParser
+from genseccomp import parse_syscall_NRs
+
+def load_syscall_names_from_file(file_path, architecture):
+ parser = SysCallsTxtParser()
+ parser.parse_open_file(open(file_path))
+ arch_map = {}
+ for syscall in parser.syscalls:
+ if syscall.get(architecture):
+ arch_map[syscall["func"]] = syscall["name"];
+
+ return arch_map
+
+def gen_syscall_nrs(out_file, base_syscall_file, syscall_NRs):
+ for arch in ('arm', 'arm64', 'mips', 'mips64', 'x86', 'x86_64'):
+ base_names = load_syscall_names_from_file(base_syscall_file, arch)
+
+ for func,syscall in base_names.iteritems():
+ out_file.write("#define __" + arch + "_" + func + " " + str(syscall_NRs[arch][syscall]) + ";\n")
+
+def main():
+ parser = argparse.ArgumentParser(
+ description="Generates a mapping of bionic functions to system call numbers per architecture.")
+ parser.add_argument("--verbose", "-v", help="Enables verbose logging.")
+ parser.add_argument("--out-dir",
+ help="The output directory for the output files")
+ parser.add_argument("base_file", metavar="base-file", type=str,
+ help="The path of the base syscall list (SYSCALLS.TXT).")
+ parser.add_argument("files", metavar="FILE", type=str, nargs="+",
+ help=("A syscall name-number mapping file for an architecture.\n"))
+ args = parser.parse_args()
+
+ if args.verbose:
+ logging.basicConfig(level=logging.DEBUG)
+ else:
+ logging.basicConfig(level=logging.INFO)
+
+ syscall_files = []
+ syscall_NRs = {}
+ for filename in args.files:
+ m = re.search(r"libseccomp_gen_syscall_nrs_([^/]+)", filename)
+ syscall_NRs[m.group(1)] = parse_syscall_NRs(filename)
+
+ output_path = os.path.join(args.out_dir, "func_to_syscall_nrs.h")
+ with open(output_path, "w") as output_file:
+ gen_syscall_nrs(out_file=output_file,
+ syscall_NRs=syscall_NRs, base_syscall_file=args.base_file)
+
+if __name__ == "__main__":
+ main()
diff --git a/linker/Android.bp b/linker/Android.bp
index 38a53f8..e103ade 100644
--- a/linker/Android.bp
+++ b/linker/Android.bp
@@ -176,6 +176,11 @@
"-Wextra",
"-Wunused",
"-Werror",
+
+ // Define _USING_LIBCXX so <stdatomic.h> defers to the <atomic> header. When a Soong module
+ // uses the platform libc++, Soong automatically passes this macro, but the dynamic linker
+ // links against libc++ manually.
+ "-D_USING_LIBCXX",
],
// TODO: split out the asflags.
diff --git a/linker/linker.cpp b/linker/linker.cpp
index 1f259e1..412b8eb 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -65,8 +65,10 @@
#include "linker_phdr.h"
#include "linker_relocs.h"
#include "linker_reloc_iterators.h"
+#include "linker_tls.h"
#include "linker_utils.h"
+#include "private/bionic_globals.h"
#include "android-base/macros.h"
#include "android-base/strings.h"
#include "android-base/stringprintf.h"
@@ -601,6 +603,9 @@
}
void set_fd(int fd, bool assume_ownership) {
+ if (fd_ != -1 && close_fd_) {
+ close(fd_);
+ }
fd_ = fd;
close_fd_ = assume_ownership;
}
@@ -1652,6 +1657,7 @@
if (!si->is_linked() && !si->prelink_image()) {
return false;
}
+ register_soinfo_tls(si);
}
// Step 4: Construct the global group. Note: DF_1_GLOBAL bit of a library is
@@ -1887,6 +1893,7 @@
si->get_realpath(),
si);
notify_gdb_of_unload(si);
+ unregister_soinfo_tls(si);
get_cfi_shadow()->BeforeUnload(si);
soinfo_free(si);
}
@@ -2666,16 +2673,32 @@
#else
static ElfW(Addr) get_addend(ElfW(Rel)* rel, ElfW(Addr) reloc_addr) {
if (ELFW(R_TYPE)(rel->r_info) == R_GENERIC_RELATIVE ||
- ELFW(R_TYPE)(rel->r_info) == R_GENERIC_IRELATIVE) {
+ ELFW(R_TYPE)(rel->r_info) == R_GENERIC_IRELATIVE ||
+ ELFW(R_TYPE)(rel->r_info) == R_GENERIC_TLS_DTPREL ||
+ ELFW(R_TYPE)(rel->r_info) == R_GENERIC_TLS_TPREL) {
return *reinterpret_cast<ElfW(Addr)*>(reloc_addr);
}
return 0;
}
#endif
+static bool is_tls_reloc(ElfW(Word) type) {
+ switch (type) {
+ case R_GENERIC_TLS_DTPMOD:
+ case R_GENERIC_TLS_DTPREL:
+ case R_GENERIC_TLS_TPREL:
+ case R_GENERIC_TLSDESC:
+ return true;
+ default:
+ return false;
+ }
+}
+
template<typename ElfRelIteratorT>
bool soinfo::relocate(const VersionTracker& version_tracker, ElfRelIteratorT&& rel_iterator,
const soinfo_list_t& global_group, const soinfo_list_t& local_group) {
+ const size_t tls_tp_base = __libc_shared_globals()->static_tls_layout.offset_thread_pointer();
+
for (size_t idx = 0; rel_iterator.has_next(); ++idx) {
const auto rel = rel_iterator.next();
if (rel == nullptr) {
@@ -2698,7 +2721,22 @@
const ElfW(Sym)* s = nullptr;
soinfo* lsi = nullptr;
- if (sym != 0) {
+ if (sym == 0) {
+ // Do nothing.
+ } else if (ELF_ST_BIND(symtab_[sym].st_info) == STB_LOCAL && is_tls_reloc(type)) {
+ // In certain situations, the Gold linker accesses a TLS symbol using a
+ // relocation to an STB_LOCAL symbol in .dynsym of either STT_SECTION or
+ // STT_TLS type. Bionic doesn't support these relocations, so issue an
+ // error. References:
+ // - https://groups.google.com/d/topic/generic-abi/dJ4_Y78aQ2M/discussion
+ // - https://sourceware.org/bugzilla/show_bug.cgi?id=17699
+ s = &symtab_[sym];
+ sym_name = get_string(s->st_name);
+ DL_ERR("unexpected TLS reference to local symbol \"%s\": "
+ "sym type %d, rel type %u (idx %zu of \"%s\")",
+ sym_name, ELF_ST_TYPE(s->st_info), type, idx, get_realpath());
+ return false;
+ } else {
sym_name = get_string(symtab_[sym].st_name);
const version_info* vi = nullptr;
@@ -2735,6 +2773,10 @@
case R_GENERIC_GLOB_DAT:
case R_GENERIC_RELATIVE:
case R_GENERIC_IRELATIVE:
+ case R_GENERIC_TLS_DTPMOD:
+ case R_GENERIC_TLS_DTPREL:
+ case R_GENERIC_TLS_TPREL:
+ case R_GENERIC_TLSDESC:
#if defined(__aarch64__)
case R_AARCH64_ABS64:
case R_AARCH64_ABS32:
@@ -2782,12 +2824,21 @@
}
}
#endif
- if (ELF_ST_TYPE(s->st_info) == STT_TLS) {
- DL_ERR("unsupported ELF TLS symbol \"%s\" referenced by \"%s\"",
- sym_name, get_realpath());
- return false;
+ if (is_tls_reloc(type)) {
+ if (ELF_ST_TYPE(s->st_info) != STT_TLS) {
+ DL_ERR("reference to non-TLS symbol \"%s\" from TLS relocation in \"%s\"",
+ sym_name, get_realpath());
+ return false;
+ }
+ sym_addr = s->st_value;
+ } else {
+ if (ELF_ST_TYPE(s->st_info) == STT_TLS) {
+ DL_ERR("reference to TLS symbol \"%s\" from non-TLS relocation in \"%s\"",
+ sym_name, get_realpath());
+ return false;
+ }
+ sym_addr = lsi->resolve_symbol_address(s);
}
- sym_addr = lsi->resolve_symbol_address(s);
#if !defined(__LP64__)
if (protect_segments) {
if (phdr_table_unprotect_segments(phdr, phnum, load_bias) < 0) {
@@ -2860,6 +2911,40 @@
*reinterpret_cast<ElfW(Addr)*>(reloc) = ifunc_addr;
}
break;
+ case R_GENERIC_TLS_TPREL:
+ count_relocation(kRelocRelative);
+ MARK(rel->r_offset);
+ {
+ ElfW(Addr) tpoff = 0;
+ if (sym == 0) {
+ // By convention in ld.bfd and lld, an omitted symbol
+ // (ELFW(R_SYM) == 0) refers to the local module.
+ lsi = this;
+ }
+ if (lsi == nullptr) {
+ // Unresolved weak relocation. Leave tpoff at 0 to resolve
+ // &weak_tls_symbol to __get_tls().
+ } else if (soinfo_tls* lsi_tls = lsi->get_tls()) {
+ const TlsModule& mod = get_tls_module(lsi_tls->module_id);
+ if (mod.static_offset != SIZE_MAX) {
+ tpoff += mod.static_offset - tls_tp_base;
+ } else {
+ DL_ERR("TLS symbol \"%s\" in dlopened \"%s\" referenced from \"%s\" using IE access model",
+ sym_name, lsi->get_realpath(), get_realpath());
+ return false;
+ }
+ } else {
+ DL_ERR("TLS relocation refers to symbol \"%s\" in solib \"%s\" with no TLS segment",
+ sym_name, lsi->get_realpath());
+ return false;
+ }
+ tpoff += sym_addr + addend;
+ TRACE_TYPE(RELO, "RELO TLS_TPREL %16p <- %16p %s\n",
+ reinterpret_cast<void*>(reloc),
+ reinterpret_cast<void*>(tpoff), sym_name);
+ *reinterpret_cast<ElfW(Addr)*>(reloc) = tpoff;
+ }
+ break;
#if defined(__aarch64__)
case R_AARCH64_ABS64:
@@ -2961,14 +3046,6 @@
*/
DL_ERR("%s R_AARCH64_COPY relocations are not supported", get_realpath());
return false;
- case R_AARCH64_TLS_TPREL64:
- TRACE_TYPE(RELO, "RELO TLS_TPREL64 *** %16llx <- %16llx - %16llx\n",
- reloc, (sym_addr + addend), rel->r_offset);
- break;
- case R_AARCH64_TLSDESC:
- TRACE_TYPE(RELO, "RELO TLSDESC *** %16llx <- %16llx - %16llx\n",
- reloc, (sym_addr + addend), rel->r_offset);
- break;
#elif defined(__x86_64__)
case R_X86_64_32:
count_relocation(kRelocRelative);
@@ -3073,6 +3150,19 @@
&ARM_exidx, &ARM_exidx_count);
#endif
+ TlsSegment tls_segment;
+ if (__bionic_get_tls_segment(phdr, phnum, load_bias, &tls_segment)) {
+ if (!__bionic_check_tls_alignment(&tls_segment.alignment)) {
+ if (!relocating_linker) {
+ DL_ERR("TLS segment alignment in \"%s\" is not a power of 2: %zu",
+ get_realpath(), tls_segment.alignment);
+ }
+ return false;
+ }
+ tls_ = std::make_unique<soinfo_tls>();
+ tls_->segment = tls_segment;
+ }
+
// Extract useful information from dynamic section.
// Note that: "Except for the DT_NULL element at the end of the array,
// and the relative order of DT_NEEDED elements, entries may appear in any order."
diff --git a/linker/linker_logger.cpp b/linker/linker_logger.cpp
index d0e5072..ec07a55 100644
--- a/linker/linker_logger.cpp
+++ b/linker/linker_logger.cpp
@@ -118,11 +118,7 @@
flags_ |= ParseProperty(debug_ld_app);
}
-void LinkerLogger::Log(uint32_t type, const char* format, ...) {
- if ((flags_ & type) == 0) {
- return;
- }
-
+void LinkerLogger::Log(const char* format, ...) {
va_list ap;
va_start(ap, format);
async_safe_format_log_va_list(ANDROID_LOG_DEBUG, "linker", format, ap);
diff --git a/linker/linker_logger.h b/linker/linker_logger.h
index 1828799..f9fc38e 100644
--- a/linker/linker_logger.h
+++ b/linker/linker_logger.h
@@ -35,10 +35,10 @@
#include <android-base/macros.h>
-#define LD_LOG(type, x...) \
- { \
- g_linker_logger.Log(type, x); \
- }
+#define LD_LOG(type, x...) \
+ do { \
+ if (g_linker_logger.IsEnabled(type)) g_linker_logger.Log(x); \
+ } while (0)
constexpr const uint32_t kLogErrors = 1 << 0;
constexpr const uint32_t kLogDlopen = 1 << 1;
@@ -49,7 +49,12 @@
LinkerLogger() : flags_(0) { }
void ResetState();
- void Log(uint32_t type, const char* format, ...);
+ void Log(const char* format, ...);
+
+ uint32_t IsEnabled(uint32_t type) {
+ return flags_ & type;
+ }
+
private:
uint32_t flags_;
diff --git a/linker/linker_main.cpp b/linker/linker_main.cpp
index 9b4ce47..b0c27dc 100644
--- a/linker/linker_main.cpp
+++ b/linker/linker_main.cpp
@@ -415,6 +415,8 @@
}
}
+ linker_setup_exe_static_tls(g_argv[0]);
+
// Load ld_preloads and dependencies.
std::vector<const char*> needed_library_name_list;
size_t ld_preloads_count = 0;
@@ -452,8 +454,7 @@
si->increment_ref_count();
}
- layout_linker_static_tls();
-
+ linker_finalize_static_tls();
__libc_init_main_thread_final();
if (!get_cfi_shadow()->InitialLinkDone(solist)) __linker_cannot_link(g_argv[0]);
diff --git a/linker/linker_soinfo.cpp b/linker/linker_soinfo.cpp
index 93079ca..dcc6bf3 100644
--- a/linker/linker_soinfo.cpp
+++ b/linker/linker_soinfo.cpp
@@ -628,6 +628,10 @@
return secondary_namespaces_;
}
+soinfo_tls* soinfo::get_tls() const {
+ return has_min_version(5) ? tls_.get() : nullptr;
+}
+
ElfW(Addr) soinfo::resolve_symbol_address(const ElfW(Sym)* s) const {
if (ELF_ST_TYPE(s->st_info) == STT_GNU_IFUNC) {
return call_ifunc_resolver(s->st_value + load_bias);
diff --git a/linker/linker_soinfo.h b/linker/linker_soinfo.h
index 44bff28..14571de 100644
--- a/linker/linker_soinfo.h
+++ b/linker/linker_soinfo.h
@@ -30,8 +30,10 @@
#include <link.h>
+#include <memory>
#include <string>
+#include "private/bionic_elf_tls.h"
#include "linker_namespaces.h"
#define FLAG_LINKED 0x00000001
@@ -61,7 +63,7 @@
// unset.
#define FLAG_NEW_SOINFO 0x40000000 // new soinfo format
-#define SOINFO_VERSION 4
+#define SOINFO_VERSION 5
typedef void (*linker_dtor_function_t)();
typedef void (*linker_ctor_function_t)(int, char**, char**);
@@ -100,6 +102,16 @@
// TODO(dimitry): remove reference from soinfo member functions to this class.
class VersionTracker;
+// The first ELF TLS module has ID 1. Zero is reserved for the first word of
+// the DTV, a generation count, and unresolved weak symbols also use module
+// ID 0.
+static constexpr size_t kUninitializedModuleId = 0;
+
+struct soinfo_tls {
+ TlsSegment segment;
+ size_t module_id = kUninitializedModuleId;
+};
+
#if defined(__work_around_b_24465209__)
#define SOINFO_NAME_LEN 128
#endif
@@ -284,6 +296,8 @@
void add_secondary_namespace(android_namespace_t* secondary_ns);
android_namespace_list_t& get_secondary_namespaces();
+ soinfo_tls* get_tls() const;
+
void set_mapped_by_caller(bool reserved_map);
bool is_mapped_by_caller() const;
@@ -366,6 +380,9 @@
// version >= 4
ElfW(Relr)* relr_;
size_t relr_count_;
+
+ // version >= 5
+ std::unique_ptr<soinfo_tls> tls_;
};
// This function is used by dlvsym() to calculate hash of sym_ver
diff --git a/linker/linker_tls.cpp b/linker/linker_tls.cpp
index 3327453..0d1796b 100644
--- a/linker/linker_tls.cpp
+++ b/linker/linker_tls.cpp
@@ -28,20 +28,83 @@
#include "linker_tls.h"
+#include <vector>
+
+#include "private/ScopedRWLock.h"
#include "private/bionic_defs.h"
#include "private/bionic_elf_tls.h"
#include "private/bionic_globals.h"
#include "private/linker_native_bridge.h"
+#include "linker_main.h"
+#include "linker_soinfo.h"
+
+static bool g_static_tls_finished;
+static std::vector<TlsModule> g_tls_modules;
+
+static inline size_t module_id_to_idx(size_t id) { return id - 1; }
+static inline size_t module_idx_to_id(size_t idx) { return idx + 1; }
+
+static size_t get_unused_module_index() {
+ for (size_t i = 0; i < g_tls_modules.size(); ++i) {
+ if (g_tls_modules[i].soinfo_ptr == nullptr) {
+ return i;
+ }
+ }
+ g_tls_modules.push_back({});
+ __libc_shared_globals()->tls_modules.module_count = g_tls_modules.size();
+ __libc_shared_globals()->tls_modules.module_table = g_tls_modules.data();
+ return g_tls_modules.size() - 1;
+}
+
+static void register_tls_module(soinfo* si, size_t static_offset) {
+ // The global TLS module table points at the std::vector of modules declared
+ // in this file, so acquire a write lock before modifying the std::vector.
+ ScopedWriteLock locker(&__libc_shared_globals()->tls_modules.rwlock);
+
+ size_t module_idx = get_unused_module_index();
+
+ soinfo_tls* si_tls = si->get_tls();
+ si_tls->module_id = module_idx_to_id(module_idx);
+
+ g_tls_modules[module_idx] = {
+ .segment = si_tls->segment,
+ .static_offset = static_offset,
+ .first_generation = ++__libc_shared_globals()->tls_modules.generation,
+ .soinfo_ptr = si,
+ };
+}
+
+static void unregister_tls_module(soinfo* si) {
+ ScopedWriteLock locker(&__libc_shared_globals()->tls_modules.rwlock);
+
+ soinfo_tls* si_tls = si->get_tls();
+ TlsModule& mod = g_tls_modules[module_id_to_idx(si_tls->module_id)];
+ CHECK(mod.static_offset == SIZE_MAX);
+ CHECK(mod.soinfo_ptr == si);
+ mod = {};
+ si_tls->module_id = kUninitializedModuleId;
+}
+
+// The reference is valid until a TLS module is registered or unregistered.
+const TlsModule& get_tls_module(size_t module_id) {
+ size_t module_idx = module_id_to_idx(module_id);
+ CHECK(module_idx < g_tls_modules.size());
+ return g_tls_modules[module_idx];
+}
__BIONIC_WEAK_FOR_NATIVE_BRIDGE
extern "C" void __linker_reserve_bionic_tls_in_static_tls() {
__libc_shared_globals()->static_tls_layout.reserve_bionic_tls();
}
-// Stub for linker static TLS layout.
-void layout_linker_static_tls() {
+void linker_setup_exe_static_tls(const char* progname) {
+ soinfo* somain = solist_get_somain();
StaticTlsLayout& layout = __libc_shared_globals()->static_tls_layout;
- layout.reserve_tcb();
+ if (somain->get_tls() == nullptr) {
+ layout.reserve_exe_segment_and_tcb(nullptr, progname);
+ } else {
+ register_tls_module(somain, layout.reserve_exe_segment_and_tcb(&somain->get_tls()->segment, progname));
+ }
// The pthread key data is located at the very front of bionic_tls. As a
// temporary workaround, allocate bionic_tls just after the thread pointer so
@@ -49,8 +112,32 @@
// small enough. Specifically, Golang scans forward 384 words from the TP on
// ARM.
// - http://b/118381796
- // - https://groups.google.com/d/msg/golang-dev/yVrkFnYrYPE/2G3aFzYqBgAJ
+ // - https://github.com/golang/go/issues/29674
__linker_reserve_bionic_tls_in_static_tls();
+}
- layout.finish_layout();
+void linker_finalize_static_tls() {
+ g_static_tls_finished = true;
+ __libc_shared_globals()->static_tls_layout.finish_layout();
+}
+
+void register_soinfo_tls(soinfo* si) {
+ soinfo_tls* si_tls = si->get_tls();
+ if (si_tls == nullptr || si_tls->module_id != kUninitializedModuleId) {
+ return;
+ }
+ size_t static_offset = SIZE_MAX;
+ if (!g_static_tls_finished) {
+ StaticTlsLayout& layout = __libc_shared_globals()->static_tls_layout;
+ static_offset = layout.reserve_solib_segment(si_tls->segment);
+ }
+ register_tls_module(si, static_offset);
+}
+
+void unregister_soinfo_tls(soinfo* si) {
+ soinfo_tls* si_tls = si->get_tls();
+ if (si_tls == nullptr || si_tls->module_id == kUninitializedModuleId) {
+ return;
+ }
+ return unregister_tls_module(si);
}
diff --git a/linker/linker_tls.h b/linker/linker_tls.h
index 2f0a57d..fbb1dcf 100644
--- a/linker/linker_tls.h
+++ b/linker/linker_tls.h
@@ -28,4 +28,15 @@
#pragma once
-void layout_linker_static_tls();
+#include <stdlib.h>
+
+struct TlsModule;
+struct soinfo;
+
+void linker_setup_exe_static_tls(const char* progname);
+void linker_finalize_static_tls();
+
+void register_soinfo_tls(soinfo* si);
+void unregister_soinfo_tls(soinfo* si);
+
+const TlsModule& get_tls_module(size_t module_id);
diff --git a/tests/Android.bp b/tests/Android.bp
index beed07a..8ac0531 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -218,6 +218,44 @@
generated_headers: ["generated_android_ids"],
}
+cc_test_library {
+ name: "libBionicElfTlsTests",
+ defaults: ["bionic_tests_defaults"],
+ srcs: [
+ "elftls_test.cpp",
+ ],
+ include_dirs: [
+ "bionic/libc",
+ ],
+ shared: {
+ enabled: false,
+ },
+ cflags: [
+ "-fno-emulated-tls",
+ ],
+}
+
+cc_test_library {
+ name: "libBionicElfTlsLoaderTests",
+ defaults: ["bionic_tests_defaults"],
+ srcs: [
+ "elftls_dl_test.cpp",
+ ],
+ include_dirs: [
+ "bionic/libc",
+ ],
+ static_libs: [
+ "liblog",
+ "libbase",
+ ],
+ shared: {
+ enabled: false,
+ },
+ cflags: [
+ "-fno-emulated-tls",
+ ],
+}
+
// -----------------------------------------------------------------------------
// Fortify tests.
// -----------------------------------------------------------------------------
@@ -306,6 +344,7 @@
defaults: ["bionic_tests_defaults"],
whole_static_libs: [
"libBionicStandardTests",
+ "libBionicElfTlsTests",
"libfortify1-tests-clang",
"libfortify2-tests-clang",
],
@@ -389,6 +428,7 @@
whole_static_libs: [
"libBionicTests",
"libBionicLoaderTests",
+ "libBionicElfTlsLoaderTests",
],
static_libs: [
@@ -423,6 +463,8 @@
"libdl_preempt_test_1",
"libdl_preempt_test_2",
"libdl_test_df_1_global",
+ "libtest_elftls_shared_var",
+ "libtest_elftls_tprel",
],
static_libs: [
// The order of these libraries matters, do not shuffle them.
@@ -471,6 +513,7 @@
required: [
"cfi_test_helper",
"cfi_test_helper2",
+ "elftls_dlopen_ie_error_helper",
"exec_linker_helper",
"exec_linker_helper_lib",
"libtest_dt_runpath_a",
@@ -528,6 +571,9 @@
"libtest_dlsym_from_this",
"libtest_dlsym_weak_func",
"libtest_dt_runpath_d",
+ "libtest_elftls_shared_var",
+ "libtest_elftls_shared_var_ie",
+ "libtest_elftls_tprel",
"libtest_empty",
"libtest_ifunc_variable_impl",
"libtest_ifunc_variable",
@@ -629,6 +675,8 @@
"libbase",
"libdebuggerd_handler",
"libgtest_isolated",
+ "libtest_elftls_shared_var",
+ "libtest_elftls_tprel",
],
static_executable: true,
@@ -662,12 +710,15 @@
shared_libs: [
"libdl_preempt_test_1",
"libdl_preempt_test_2",
-
"libdl_test_df_1_global",
+ "libtest_elftls_shared_var",
+ "libtest_elftls_tprel",
],
whole_static_libs: [
"libBionicStandardTests",
+ "libBionicElfTlsTests",
+ "libBionicElfTlsLoaderTests",
"libfortify1-tests-clang",
"libfortify2-tests-clang",
],
diff --git a/tests/__aeabi_read_tp_test.cpp b/tests/__aeabi_read_tp_test.cpp
index ab96af9..6974658 100644
--- a/tests/__aeabi_read_tp_test.cpp
+++ b/tests/__aeabi_read_tp_test.cpp
@@ -32,7 +32,12 @@
#if defined(__arm__)
extern "C" void* __aeabi_read_tp();
-TEST(aeabi, read_tp) {
- ASSERT_EQ(__aeabi_read_tp(), static_cast<void*>(__get_tls()));
-}
#endif
+
+TEST(aeabi, read_tp) {
+#if defined(__arm__)
+ ASSERT_EQ(__aeabi_read_tp(), static_cast<void*>(__get_tls()));
+#else
+ GTEST_LOG_(INFO) << "__aeabi_read_tp is only available on arm32.\n";
+#endif
+}
diff --git a/tests/dlfcn_test.cpp b/tests/dlfcn_test.cpp
index 5f48e67..176a6f8 100644
--- a/tests/dlfcn_test.cpp
+++ b/tests/dlfcn_test.cpp
@@ -1086,7 +1086,7 @@
dlerror(); // Clear any pending errors.
void* handle = dlopen("libelf-tls-library.so", RTLD_NOW);
ASSERT_TRUE(handle == nullptr);
- ASSERT_SUBSTR("unsupported ELF TLS", dlerror());
+ ASSERT_SUBSTR("unknown reloc type ", dlerror());
}
TEST(dlfcn, dlopen_bad_flags) {
diff --git a/tests/elftls_dl_test.cpp b/tests/elftls_dl_test.cpp
new file mode 100644
index 0000000..0a97c28
--- /dev/null
+++ b/tests/elftls_dl_test.cpp
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2019 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 <dlfcn.h>
+#include <gtest/gtest.h>
+
+#include <thread>
+
+#include "gtest_globals.h"
+#include "utils.h"
+
+// Access libtest_elftls_shared_var.so's TLS variable using an IE access.
+__attribute__((tls_model("initial-exec"))) extern "C" __thread int elftls_shared_var;
+
+TEST(elftls_dl, dlopen_shared_var_ie) {
+ // libtest_elftls_shared_var_ie.so can be dlopen'ed, even though it contains a
+ // TLS IE access, because its IE access references a TLS variable from
+ // libtest_elftls_shared_var.so, which is DT_NEEDED by the executable. This
+ // pattern appears in sanitizers, which use TLS IE instrumentation in shared
+ // objects to access special variables exported from the executable or from a
+ // preloaded solib.
+ void* lib = dlopen("libtest_elftls_shared_var_ie.so", RTLD_LOCAL | RTLD_NOW);
+ ASSERT_NE(nullptr, lib);
+
+ auto bump_shared_var = reinterpret_cast<int(*)()>(dlsym(lib, "bump_shared_var"));
+ ASSERT_NE(nullptr, bump_shared_var);
+
+ ASSERT_EQ(21, ++elftls_shared_var);
+ ASSERT_EQ(22, bump_shared_var());
+
+ std::thread([bump_shared_var] {
+ ASSERT_EQ(21, ++elftls_shared_var);
+ ASSERT_EQ(22, bump_shared_var());
+ }).join();
+}
+
+TEST(elftls_dl, dlopen_ie_error) {
+ std::string helper = GetTestlibRoot() +
+ "/elftls_dlopen_ie_error_helper/elftls_dlopen_ie_error_helper";
+ std::string src_path = GetTestlibRoot() + "/libtest_elftls_shared_var_ie.so";
+ std::string dst_path = GetTestlibRoot() + "/libtest_elftls_shared_var.so";
+#if defined(__BIONIC__)
+ std::string error =
+ "dlerror: dlopen failed: TLS symbol \"elftls_shared_var\" in dlopened \"" + dst_path + "\" " +
+ "referenced from \"" + src_path + "\" using IE access model\n";
+#else
+ // glibc will reserve some surplus static TLS memory, allowing this test to pass.
+ std::string error = "success\n";
+#endif
+
+ chmod(helper.c_str(), 0755); // TODO: "x" lost in CTS, b/34945607
+ ExecTestHelper eth;
+ eth.SetArgs({ helper.c_str(), nullptr });
+ eth.Run([&]() { execve(helper.c_str(), eth.GetArgs(), eth.GetEnv()); }, 0, error.c_str());
+}
diff --git a/tests/elftls_test.cpp b/tests/elftls_test.cpp
new file mode 100644
index 0000000..11d41ce
--- /dev/null
+++ b/tests/elftls_test.cpp
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2019 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 <gtest/gtest.h>
+
+#include <thread>
+
+#include "private/__get_tls.h"
+
+// Specify the LE access model explicitly. This file is compiled into the
+// bionic-unit-tests executable, but the compiler sees an -fpic object file
+// output into a static library, so it defaults to dynamic TLS accesses.
+
+// This variable will be zero-initialized (.tbss)
+__attribute__((tls_model("local-exec"))) static __thread int tlsvar_le_zero;
+
+// This variable will have an initializer (.tdata)
+__attribute__((tls_model("local-exec"))) static __thread int tlsvar_le_init = 10;
+
+// Access libtest_elftls_shared_var's TLS variable using an IE access.
+__attribute__((tls_model("initial-exec"))) extern "C" __thread int elftls_shared_var;
+
+TEST(elftls, basic_le) {
+ // Check the variables on the main thread.
+ ASSERT_EQ(11, ++tlsvar_le_init);
+ ASSERT_EQ(1, ++tlsvar_le_zero);
+
+ // Check variables on a new thread.
+ std::thread([] {
+ ASSERT_EQ(11, ++tlsvar_le_init);
+ ASSERT_EQ(1, ++tlsvar_le_zero);
+ }).join();
+}
+
+TEST(elftls, shared_ie) {
+ ASSERT_EQ(21, ++elftls_shared_var);
+ std::thread([] {
+ ASSERT_EQ(21, ++elftls_shared_var);
+ }).join();
+}
+
+extern "C" int* missing_weak_tls_addr();
+extern "C" int bump_static_tls_var_1();
+extern "C" int bump_static_tls_var_2();
+
+TEST(elftls, tprel_missing_weak) {
+ ASSERT_EQ(static_cast<void*>(__get_tls()), missing_weak_tls_addr());
+ std::thread([] {
+ ASSERT_EQ(static_cast<void*>(__get_tls()), missing_weak_tls_addr());
+ }).join();
+}
+
+TEST(elftls, tprel_addend) {
+ ASSERT_EQ(4, bump_static_tls_var_1());
+ ASSERT_EQ(8, bump_static_tls_var_2());
+ std::thread([] {
+ ASSERT_EQ(4, bump_static_tls_var_1());
+ ASSERT_EQ(8, bump_static_tls_var_2());
+ }).join();
+}
diff --git a/tests/grp_pwd_test.cpp b/tests/grp_pwd_test.cpp
index ca34205..4b207b6 100644
--- a/tests/grp_pwd_test.cpp
+++ b/tests/grp_pwd_test.cpp
@@ -198,7 +198,7 @@
}
TEST(pwd, getpwnam_app_id_u0_i1) {
- check_get_passwd("u0_i1", 99001, TYPE_APP);
+ check_get_passwd("u0_i1", 90001, TYPE_APP);
}
TEST(pwd, getpwnam_app_id_u1_root) {
@@ -218,9 +218,8 @@
}
TEST(pwd, getpwnam_app_id_u1_i0) {
- check_get_passwd("u1_i0", 199000, TYPE_APP);
+ check_get_passwd("u1_i0", 190000, TYPE_APP);
}
-
#if defined(__BIONIC__)
template <typename T>
static void expect_ids(const T& ids) {
@@ -464,7 +463,7 @@
}
TEST(grp, getgrnam_app_id_u0_i1) {
- check_get_group("u0_i1", 99001);
+ check_get_group("u0_i1", 90001);
}
TEST(grp, getgrnam_app_id_u1_root) {
@@ -484,7 +483,7 @@
}
TEST(grp, getgrnam_app_id_u1_i0) {
- check_get_group("u1_i0", 199000);
+ check_get_group("u1_i0", 190000);
}
TEST(grp, getgrnam_r_reentrancy) {
diff --git a/tests/libs/Android.bp b/tests/libs/Android.bp
index 79c9a06..05d1ed2 100644
--- a/tests/libs/Android.bp
+++ b/tests/libs/Android.bp
@@ -40,7 +40,7 @@
}
// -----------------------------------------------------------------------------
-// Library to test ELF TLS
+// Libraries and helper binaries for ELF TLS
// -----------------------------------------------------------------------------
cc_test_library {
name: "libelf-tls-library",
@@ -50,6 +50,35 @@
allow_undefined_symbols: true, // __tls_get_addr is undefined.
}
+cc_test_library {
+ name: "libtest_elftls_shared_var",
+ defaults: ["bionic_testlib_defaults"],
+ srcs: ["elftls_shared_var.cpp"],
+ cflags: ["-fno-emulated-tls"],
+}
+
+cc_test_library {
+ name: "libtest_elftls_shared_var_ie",
+ defaults: ["bionic_testlib_defaults"],
+ srcs: ["elftls_shared_var_ie.cpp"],
+ cflags: ["-fno-emulated-tls"],
+ shared_libs: ["libtest_elftls_shared_var"],
+}
+
+cc_test_library {
+ name: "libtest_elftls_tprel",
+ defaults: ["bionic_testlib_defaults"],
+ srcs: ["elftls_tprel.cpp"],
+ cflags: ["-fno-emulated-tls"],
+}
+
+cc_test {
+ name: "elftls_dlopen_ie_error_helper",
+ defaults: ["bionic_testlib_defaults"],
+ srcs: ["elftls_dlopen_ie_error_helper.cpp"],
+ ldflags: ["-Wl,--rpath,${ORIGIN}/.."],
+}
+
// -----------------------------------------------------------------------------
// Library to test gnu-styled hash
// -----------------------------------------------------------------------------
@@ -237,6 +266,10 @@
"libnstest_public",
"libnstest_private",
],
+ // The dlext.ns_anonymous test copies the loaded segments of this shared
+ // object into a new mapping, so every segment must be readable. Turn off
+ // eXecute-Only-Memory. See http://b/123034666.
+ xom: false,
}
cc_test_library {
diff --git a/tests/libs/elftls_dlopen_ie_error_helper.cpp b/tests/libs/elftls_dlopen_ie_error_helper.cpp
new file mode 100644
index 0000000..5902e07
--- /dev/null
+++ b/tests/libs/elftls_dlopen_ie_error_helper.cpp
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2019 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 <dlfcn.h>
+#include <stdio.h>
+
+// This helper executable attempts to load libtest_elftls_shared_var_ie.so,
+// then reports success or failure. With Bionic, it is expected to fail, because
+// libtest_elftls_shared_var_ie.so tries to access a dynamically-allocated TLS
+// variable using the IE access model intended for static TLS.
+
+int main() {
+ void* lib = dlopen("libtest_elftls_shared_var_ie.so", RTLD_LOCAL | RTLD_NOW);
+ if (lib) {
+ printf("success\n");
+ } else {
+ printf("dlerror: %s\n", dlerror());
+ }
+ return 0;
+}
diff --git a/tests/libs/elftls_shared_var.cpp b/tests/libs/elftls_shared_var.cpp
new file mode 100644
index 0000000..27a15f0
--- /dev/null
+++ b/tests/libs/elftls_shared_var.cpp
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+// This shared object merely declares a global TLS variable without accessing
+// it.
+
+extern "C" __thread int elftls_shared_var = 20;
diff --git a/tests/libs/elftls_shared_var_ie.cpp b/tests/libs/elftls_shared_var_ie.cpp
new file mode 100644
index 0000000..14e2ab0
--- /dev/null
+++ b/tests/libs/elftls_shared_var_ie.cpp
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+// Accessing a symbol in libtest_elftls_shared_var.so using an IE access should
+// work iff the solib is part of static TLS.
+__attribute__((tls_model("initial-exec"))) extern "C" __thread int elftls_shared_var;
+
+extern "C" int bump_shared_var() {
+ return ++elftls_shared_var;
+}
diff --git a/tests/libs/elftls_tprel.cpp b/tests/libs/elftls_tprel.cpp
new file mode 100644
index 0000000..eb2fd93
--- /dev/null
+++ b/tests/libs/elftls_tprel.cpp
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+// This shared object tests TPREL relocations in the dynamic linker. It's always
+// part of static TLS.
+
+// For accesses to these variables, the bfd and lld linkers generate a TPREL
+// relocation with no symbol but a non-zero addend.
+__attribute__((tls_model("initial-exec"))) static __thread int tls_var_1 = 3;
+__attribute__((tls_model("initial-exec"))) static __thread int tls_var_2 = 7;
+
+extern "C" int bump_static_tls_var_1() {
+ return ++tls_var_1;
+}
+
+extern "C" int bump_static_tls_var_2() {
+ return ++tls_var_2;
+}
+
+__attribute__((tls_model("initial-exec"), weak)) extern "C" __thread int missing_weak_tls;
+
+extern "C" int* missing_weak_tls_addr() {
+ // The dynamic linker should resolve a TPREL relocation to this symbol to 0,
+ // which this function adds to the thread pointer.
+ return &missing_weak_tls;
+}
diff --git a/tests/sys_time_test.cpp b/tests/sys_time_test.cpp
index d033364..5dda7ab 100644
--- a/tests/sys_time_test.cpp
+++ b/tests/sys_time_test.cpp
@@ -147,7 +147,7 @@
tv2.tv_usec += 1000000;
}
- // Should be less than (a very generous, to try to avoid flakiness) 5ms (5000us).
+ // To try to avoid flakiness we'll accept answers within 10,000us (0.01s).
ASSERT_EQ(0, tv2.tv_sec);
- ASSERT_LT(tv2.tv_usec, 5000);
+ ASSERT_LT(tv2.tv_usec, 10'000);
}
diff --git a/tests/time_test.cpp b/tests/time_test.cpp
index 4ec5976..50830ee 100644
--- a/tests/time_test.cpp
+++ b/tests/time_test.cpp
@@ -607,9 +607,9 @@
ts2.tv_nsec += NS_PER_S;
}
- // Should be less than (a very generous, to try to avoid flakiness) 1000000ns.
+ // To try to avoid flakiness we'll accept answers within 10,000,000ns (0.01s).
ASSERT_EQ(0, ts2.tv_sec);
- ASSERT_LT(ts2.tv_nsec, 1000000);
+ ASSERT_LT(ts2.tv_nsec, 10'000'000);
}
TEST(time, clock_gettime_CLOCK_REALTIME) {