diff options
123 files changed, 2470 insertions, 288 deletions
diff --git a/libc/Android.bp b/libc/Android.bp index e0d0fee9b..6f2e347e4 100644 --- a/libc/Android.bp +++ b/libc/Android.bp @@ -1612,6 +1612,8 @@ cc_library { symbol_file: "libc.map.txt", versions: ["10000"], }, + + symbol_ordering_file: "symbol_ordering", } genrule { @@ -1646,6 +1648,59 @@ genrule { 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 @@ llndk_library { 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 { }, } +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_genrule { 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 832911189..0b17d646f 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 0a83cc7c8..6acd64b8d 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 @@ ENTRY(vfork) __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 79d789955..24ede3d73 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 @@ __BIONIC_WEAK_ASM_FOR_NATIVE_BRIDGE(vfork) // __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 ce96a8c16..e32b5178c 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 @@ __BIONIC_WEAK_ASM_FOR_NATIVE_BRIDGE(vfork) // __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 29f90d170..a54d3b0c0 100644 --- a/libc/async_safe/Android.bp +++ b/libc/async_safe/Android.bp @@ -12,6 +12,7 @@ cc_library_static { 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 2b90c9073..6279e6569 100644 --- a/libc/bionic/__libc_init_main_thread.cpp +++ b/libc/bionic/__libc_init_main_thread.cpp @@ -126,6 +126,7 @@ extern "C" void __libc_init_main_thread_final() { 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 55c2c310c..4253b9720 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::reserve_bionic_tls() { 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 @@ size_t StaticTlsLayout::round_up_with_overflow_check(size_t value, size_t alignm 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 68650ed83..8fbc20e97 100644 --- a/libc/bionic/libc_init_static.cpp +++ b/libc/bionic/libc_init_static.cpp @@ -83,10 +83,29 @@ static void apply_gnu_relro() { } } -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 @@ __noreturn static void __real_libc_init(void *raw_args, __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 d530fa40c..4cc5df9d0 100644 --- a/libc/bionic/malloc_common.cpp +++ b/libc/bionic/malloc_common.cpp @@ -641,6 +641,33 @@ static void install_hooks(libc_globals* globals, const char* options, } } +// 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 +// (g_heapprofd_init_hook_installed is false), InitHeapprofdHook is +// installed and g_heapprofd_init_in_progress is set to true. +// +// On the next subsequent malloc, InitHeapprofdHook is called and +// 3a. If the signal is currently being handled (g_heapprofd_init_in_progress +// is true), no action is taken. +// 3b. Otherwise, The signal handler (InstallInitHeapprofdHook) installs a +// temporary malloc hook (InitHeapprofdHook). +// 4. When this hook gets run the first time, it uninstalls itself and spawns +// a thread running InitHeapprofd that loads heapprofd.so and installs the +// hooks within. +// 5. g_heapprofd_init_in_progress and g_heapprofd_init_hook_installed are +// reset to false so heapprofd can be reinitialized. Reinitialization +// means that a new profiling session is started and any still active is +// torn down. +// +// This roundabout way is needed because we are running non AS-safe code, so +// we cannot run it directly in the signal handler. The other approach of +// running a standby thread and signalling through write(2) and read(2) would +// significantly increase the number of active threads in the system. + +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. @@ -667,7 +694,10 @@ static void malloc_init_impl(libc_globals* globals) { } else { return; } - install_hooks(globals, options, prefix, shared_lib); + 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. @@ -677,33 +707,6 @@ __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 -// (g_heapprofd_init_hook_installed is false), InitHeapprofdHook is -// installed and g_heapprofd_init_in_progress is set to true. -// -// On the next subsequent malloc, InitHeapprofdHook is called and -// 3a. If the signal is currently being handled (g_heapprofd_init_in_progress -// is true), no action is taken. -// 3b. Otherwise, The signal handler (InstallInitHeapprofdHook) installs a -// temporary malloc hook (InitHeapprofdHook). -// 4. When this hook gets run the first time, it uninstalls itself and spawns -// a thread running InitHeapprofd that loads heapprofd.so and installs the -// hooks within. -// 5. g_heapprofd_init_in_progress and g_heapprofd_init_hook_installed are -// reset to false so heapprofd can be reinitialized. Reinitialization -// means that a new profiling session is started and any still active is -// torn down. -// -// This roundabout way is needed because we are running non AS-safe code, so -// we cannot run it directly in the signal handler. The other approach of -// running a standby thread and signalling through write(2) and read(2) would -// significantly increase the number of active threads in the system. - -static _Atomic bool g_heapprofd_init_in_progress = false; -static _Atomic bool g_heapprofd_init_hook_installed = false; - 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 8676a455b..31e03786c 100644 --- a/libc/bionic/pthread_create.cpp +++ b/libc/bionic/pthread_create.cpp @@ -288,7 +288,8 @@ static int __allocate_thread(pthread_attr_t* attr, bionic_tcb** tcbp, void** chi 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 870a5260a..46fa6309c 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 e9d0e4b88..a919a7922 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 a7cd560f3..8f50b1d53 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 4e6c7558b..e1cfb4889 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 111a21554..a31ebb2d6 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 cc151fd1e..0648b02a5 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 41dbce209..f8a435772 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 166193b84..829ffad4f 100644 --- a/libc/kernel/uapi/asm-generic/siginfo.h +++ b/libc/kernel/uapi/asm-generic/siginfo.h @@ -24,13 +24,7 @@ typedef union sigval { 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 @@ typedef union sigval { #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 @@ typedef struct siginfo { #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 52f0b5756..fddf1d0d4 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 a4a40b007..694546fd1 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 c37107b7a..c9efb21a2 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 b010277a4..dc90f57d6 100644 --- a/libc/kernel/uapi/asm-x86/asm/bootparam.h +++ b/libc/kernel/uapi/asm-x86/asm/bootparam.h @@ -135,7 +135,8 @@ struct boot_params { __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 1d7f767e7..4386f7676 100644 --- a/libc/kernel/uapi/asm-x86/asm/kvm.h +++ b/libc/kernel/uapi/asm-x86/asm/kvm.h @@ -248,6 +248,7 @@ struct kvm_reinject_control { #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 @@ struct kvm_vcpu_events { __u8 injected; __u8 nr; __u8 has_error_code; - __u8 pad; + __u8 pending; __u32 error_code; } exception; struct { @@ -278,7 +279,9 @@ struct kvm_vcpu_events { __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 @@ struct kvm_sync_regs { #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 1da80663b..0de5283d9 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 2013fa721..8d65fd430 100644 --- a/libc/kernel/uapi/drm/amdgpu_drm.h +++ b/libc/kernel/uapi/drm/amdgpu_drm.h @@ -406,6 +406,7 @@ struct drm_amdgpu_cs_chunk_data { #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 4589cfe76..df89cd16b 100644 --- a/libc/kernel/uapi/drm/drm_fourcc.h +++ b/libc/kernel/uapi/drm/drm_fourcc.h @@ -24,6 +24,7 @@ extern "C" { #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 @@ extern "C" { #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 53d15480f..89fa52913 100644 --- a/libc/kernel/uapi/drm/i915_drm.h +++ b/libc/kernel/uapi/drm/i915_drm.h @@ -335,6 +335,7 @@ typedef struct drm_i915_irq_wait { #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 538a4414c..2d00a790f 100644 --- a/libc/kernel/uapi/linux/android/binder.h +++ b/libc/kernel/uapi/linux/android/binder.h @@ -103,6 +103,14 @@ struct binder_node_debug_info { __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 @@ struct binder_node_debug_info { #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 eaff1d80e..62f826f42 100644 --- a/libc/kernel/uapi/linux/blkzoned.h +++ b/libc/kernel/uapi/linux/blkzoned.h @@ -57,4 +57,6 @@ struct blk_zone_range { }; #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 a1879135a..d70a409f0 100644 --- a/libc/kernel/uapi/linux/bpf.h +++ b/libc/kernel/uapi/linux/bpf.h @@ -91,6 +91,7 @@ enum bpf_cmd { 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 @@ enum bpf_map_type { 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 @@ enum bpf_prog_type { 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 @@ enum bpf_attach_type { 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 @@ union bpf_attr { __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 @@ enum bpf_func_id { #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 @@ enum bpf_lwt_encap_mode { 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 @@ struct __sk_buff { __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 @@ struct bpf_sock { __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 @@ enum sk_action { 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 @@ struct sk_msg_md { __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 @@ enum bpf_task_fd_type { 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 fd0f82481..05af5295e 100644 --- a/libc/kernel/uapi/linux/cec.h +++ b/libc/kernel/uapi/linux/cec.h @@ -44,9 +44,12 @@ struct cec_msg { #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 15c46d86c..816fb05dd 100644 --- a/libc/kernel/uapi/linux/cryptouser.h +++ b/libc/kernel/uapi/linux/cryptouser.h @@ -24,6 +24,7 @@ enum { 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 @@ enum crypto_attr_type_t { 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 @@ struct crypto_user_alg { __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 000000000..21cb5c032 --- /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 b7c89da4e..5b54e18c1 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 73d92cae2..00a18714c 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 a727580c2..3c3a124fc 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 @@ struct fuse_file_lock { #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 @@ struct fuse_file_lock { #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 @@ enum fuse_opcode { 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 @@ struct fuse_init_out { 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_in { 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 127ae88c8..0b6c22841 100644 --- a/libc/kernel/uapi/linux/gen_stats.h +++ b/libc/kernel/uapi/linux/gen_stats.h @@ -27,6 +27,7 @@ enum { 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 0a4b0aeb4..6a6b64036 100644 --- a/libc/kernel/uapi/linux/if_addr.h +++ b/libc/kernel/uapi/linux/if_addr.h @@ -38,6 +38,7 @@ enum { 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 0b1959d0d..eda888fdb 100644 --- a/libc/kernel/uapi/linux/if_arp.h +++ b/libc/kernel/uapi/linux/if_arp.h @@ -98,7 +98,7 @@ struct arpreq { 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 4efd7f833..4b5074bdc 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 4bbf21da5..2c80d3d99 100644 --- a/libc/kernel/uapi/linux/if_link.h +++ b/libc/kernel/uapi/linux/if_link.h @@ -138,6 +138,7 @@ enum { 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 @@ enum { 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 @@ enum { 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 61d0a3aa5..300aa7be6 100644 --- a/libc/kernel/uapi/linux/if_packet.h +++ b/libc/kernel/uapi/linux/if_packet.h @@ -63,6 +63,7 @@ struct sockaddr_ll { #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 d41dc499f..8e1847fba 100644 --- a/libc/kernel/uapi/linux/if_tunnel.h +++ b/libc/kernel/uapi/linux/if_tunnel.h @@ -154,4 +154,20 @@ enum { __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 788a6d902..78bd72afe 100644 --- a/libc/kernel/uapi/linux/in.h +++ b/libc/kernel/uapi/linux/in.h @@ -200,9 +200,12 @@ struct sockaddr_in { #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 9da111cd1..3627f52ad 100644 --- a/libc/kernel/uapi/linux/in6.h +++ b/libc/kernel/uapi/linux/in6.h @@ -132,6 +132,7 @@ struct in6_flowlabel_req { #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 d8ae4c8a0..11e6d5b08 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 0cc7f5579..53f046889 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 @@ struct keyctl_kdf_params { __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 55aff047b..525f672b2 100644 --- a/libc/kernel/uapi/linux/kfd_ioctl.h +++ b/libc/kernel/uapi/linux/kfd_ioctl.h @@ -64,6 +64,13 @@ struct kfd_ioctl_set_cu_mask_args { __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 @@ struct kfd_hsa_memory_exception_data { __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 @@ struct kfd_ioctl_unmap_memory_from_gpu_args { #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 14e882be7..b70bcd942 100644 --- a/libc/kernel/uapi/linux/kvm.h +++ b/libc/kernel/uapi/linux/kvm.h @@ -316,12 +316,18 @@ struct kvm_run { 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 @@ struct kvm_ppc_one_seg_page_size { }; #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 @@ struct kvm_ppc_resize_hpt { #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 @@ struct kvm_ppc_resize_hpt { #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 68b4c65f2..bf57a58f9 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 eefc07a12..4ba0ef669 100644 --- a/libc/kernel/uapi/linux/media.h +++ b/libc/kernel/uapi/linux/media.h @@ -198,6 +198,9 @@ struct media_v2_topology { #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 6b128e4e6..23cdf1bb8 100644 --- a/libc/kernel/uapi/linux/ncsi.h +++ b/libc/kernel/uapi/linux/ncsi.h @@ -23,6 +23,7 @@ enum ncsi_nl_commands { 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 @@ enum ncsi_nl_attrs { 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 bee0b1c5c..742fbad59 100644 --- a/libc/kernel/uapi/linux/ndctl.h +++ b/libc/kernel/uapi/linux/ndctl.h @@ -140,9 +140,6 @@ enum nd_driver_flags { 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 cf32a1227..632921154 100644 --- a/libc/kernel/uapi/linux/neighbour.h +++ b/libc/kernel/uapi/linux/neighbour.h @@ -51,6 +51,7 @@ enum { #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 2f022ea3a..375906ae9 100644 --- a/libc/kernel/uapi/linux/net_tstamp.h +++ b/libc/kernel/uapi/linux/net_tstamp.h @@ -80,7 +80,7 @@ enum txtime_flags { 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 63394e0ca..2bb7c863b 100644 --- a/libc/kernel/uapi/linux/netfilter/nf_tables.h +++ b/libc/kernel/uapi/linux/netfilter/nf_tables.h @@ -419,6 +419,7 @@ enum nft_rt_keys { 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 @@ enum nft_quota_attributes { __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 @@ enum nft_ct_timeout_timeout_attributes { #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_flowtable_hook_attributes { 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 @@ enum nft_devices_attributes { __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 ccc03490b..6d939ea34 100644 --- a/libc/kernel/uapi/linux/netfilter/xt_cgroup.h +++ b/libc/kernel/uapi/linux/netfilter/xt_cgroup.h @@ -33,4 +33,16 @@ struct xt_cgroup_info_v1 { __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 6da98f5b5..e1434f46f 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 4f35c0277..4c0fd1fe6 100644 --- a/libc/kernel/uapi/linux/netlink.h +++ b/libc/kernel/uapi/linux/netlink.h @@ -112,6 +112,7 @@ enum nlmsgerr_attrs { #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 1f2f77ddd..471e65f02 100644 --- a/libc/kernel/uapi/linux/nl80211.h +++ b/libc/kernel/uapi/linux/nl80211.h @@ -163,6 +163,7 @@ enum nl80211_commands { 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 @@ enum nl80211_attrs { 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 @@ enum nl80211_sta_info { 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 @@ enum nl80211_ext_feature_index { 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 @@ enum nl80211_external_auth_action { 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 7b234f53a..8122fbb26 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 c106b5b4a..bf517850a 100644 --- a/libc/kernel/uapi/linux/perf_event.h +++ b/libc/kernel/uapi/linux/perf_event.h @@ -286,6 +286,7 @@ struct perf_event_mmap_page { #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 1ede89254..ac80a0a4a 100644 --- a/libc/kernel/uapi/linux/pkt_cls.h +++ b/libc/kernel/uapi/linux/pkt_cls.h @@ -388,6 +388,7 @@ enum { 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 4efbc1c37..e7d4942cf 100644 --- a/libc/kernel/uapi/linux/pkt_sched.h +++ b/libc/kernel/uapi/linux/pkt_sched.h @@ -283,8 +283,8 @@ struct tc_htb_xstats { __u32 lends; __u32 borrows; __u32 giants; - __u32 tokens; - __u32 ctokens; + __s32 tokens; + __s32 ctokens; }; struct tc_hfsc_qopt { __u16 defcls; @@ -828,4 +828,35 @@ enum { 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 ba50b1404..44a088dc2 100644 --- a/libc/kernel/uapi/linux/prctl.h +++ b/libc/kernel/uapi/linux/prctl.h @@ -137,6 +137,7 @@ struct prctl_mm_map { #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 6ba738e0f..dc07d787a 100644 --- a/libc/kernel/uapi/linux/sctp.h +++ b/libc/kernel/uapi/linux/sctp.h @@ -314,6 +314,8 @@ struct sctp_assoc_reset_event { }; #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 @@ struct sctp_add_streams { }; 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 79f11e3a5..e4e903d8e 100644 --- a/libc/kernel/uapi/linux/serial.h +++ b/libc/kernel/uapi/linux/serial.h @@ -100,4 +100,15 @@ struct serial_rs485 { __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 b7bc7442d..dc7791ddf 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 @@ struct taskstats { __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 000000000..70cf49fe7 --- /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 6e276de34..20c061b5e 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 @@ struct usbtmc_termchar { #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 fb3448370..cd2ede906 100644 --- a/libc/kernel/uapi/linux/usb/video.h +++ b/libc/kernel/uapi/linux/usb/video.h @@ -148,22 +148,22 @@ struct uvc_header_descriptor { __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 @@ struct uvc_output_terminal_descriptor { __u8 bDescriptorType; __u8 bDescriptorSubType; __u8 bTerminalID; - __u16 wTerminalType; + __le16 wTerminalType; __u8 bAssocTerminal; __u8 bSourceID; __u8 iTerminal; @@ -184,12 +184,12 @@ struct uvc_camera_terminal_descriptor { __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 @@ struct uvc_processing_unit_descriptor { __u8 bDescriptorSubType; __u8 bUnitID; __u8 bSourceID; - __u16 wMaxMultiplier; + __le16 wMaxMultiplier; __u8 bControlSize; __u8 bmControls[2]; __u8 iProcessing; @@ -240,7 +240,7 @@ struct uvc_control_endpoint_descriptor { __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 @@ struct uvc_input_header_descriptor { __u8 bDescriptorType; __u8 bDescriptorSubType; __u8 bNumFormats; - __u16 wTotalLength; + __le16 wTotalLength; __u8 bEndpointAddress; __u8 bmInfo; __u8 bTerminalLink; @@ -260,14 +260,14 @@ struct uvc_input_header_descriptor { } __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 @@ struct uvc_output_header_descriptor { } __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 @@ struct uvc_frame_uncompressed { __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 @@ struct uvc_frame_mjpeg { __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 45590a2b7..3c2d2b2ac 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 a2347449b..6b1ef1b71 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 8b397f401..d282a527b 100644 --- a/libc/kernel/uapi/linux/vfio.h +++ b/libc/kernel/uapi/linux/vfio.h @@ -57,6 +57,7 @@ struct vfio_device_info { #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 @@ struct vfio_device_info { #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 @@ struct vfio_region_info_cap_type { #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 51faa1e07..ef89b08de 100644 --- a/libc/kernel/uapi/linux/videodev2.h +++ b/libc/kernel/uapi/linux/videodev2.h @@ -86,7 +86,7 @@ enum v4l2_colorspace { 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 @@ enum v4l2_xfer_func { 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 @@ enum v4l2_quantization { 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 @@ struct v4l2_pix_format { #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 @@ struct v4l2_pix_format { #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 @@ struct v4l2_pix_format { #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 @@ struct v4l2_requestbuffers { __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 @@ struct v4l2_buffer { } 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 @@ struct v4l2_buffer { #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 @@ struct v4l2_buffer { #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 @@ struct v4l2_bt_timings { #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 @@ struct v4l2_ext_controls { }; __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 @@ struct v4l2_ext_controls { #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 @@ struct v4l2_create_buffers { __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 5969fa062..806e757b2 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 3baf4ed5c..6ca441316 100644 --- a/libc/kernel/uapi/rdma/ib_user_verbs.h +++ b/libc/kernel/uapi/rdma/ib_user_verbs.h @@ -619,6 +619,22 @@ struct ib_uverbs_sge { __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 50ecd2fed..77e14f6bf 100644 --- a/libc/kernel/uapi/rdma/mlx5-abi.h +++ b/libc/kernel/uapi/rdma/mlx5-abi.h @@ -28,6 +28,9 @@ enum { 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 @@ struct mlx5_ib_create_qp_rss { __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 11ff5760c..902816b72 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 @@ enum mlx5_ib_flow_matcher_create_attrs { 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 @@ enum mlx5_ib_create_flow_attrs { 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 @@ enum mlx5_ib_flow_methods { 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 c9a83cfe1..dc246e576 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 48cbc3d3e..69805f121 100644 --- a/libc/kernel/uapi/rdma/rdma_netlink.h +++ b/libc/kernel/uapi/rdma/rdma_netlink.h @@ -173,6 +173,7 @@ struct rdma_nla_ls_gid { 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 000000000..177cae984 --- /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 9dfdbc0e7..c27f88491 100644 --- a/libc/libc.map.txt +++ b/libc/libc.map.txt @@ -1481,14 +1481,6 @@ LIBC_Q { # introduced=Q # 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 @@ LIBC_PRIVATE { __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 @@ LIBC_PRIVATE { __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 @@ LIBC_PRIVATE { 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_DEPRECATED { 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 926b26581..dd20b5cd5 100644 --- a/libc/malloc_debug/Config.cpp +++ b/libc/malloc_debug/Config.cpp @@ -132,6 +132,9 @@ const std::unordered_map<std::string, Config::OptionInfo> Config::kOptions = { { "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 86d1ee4e0..011dc77bd 100644 --- a/libc/malloc_debug/Config.h +++ b/libc/malloc_debug/Config.h @@ -44,6 +44,7 @@ constexpr uint64_t TRACK_ALLOCS = 0x80; 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 debc14e0c..c307dc996 100644 --- a/libc/malloc_debug/GuardData.cpp +++ b/libc/malloc_debug/GuardData.cpp @@ -64,6 +64,9 @@ void GuardData::LogFailure(const Header* header, const void* pointer, const void 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 b0e2fc849..638061b11 100644 --- a/libc/malloc_debug/PointerData.cpp +++ b/libc/malloc_debug/PointerData.cpp @@ -206,7 +206,7 @@ void PointerData::Remove(const void* ptr) { 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 @@ void PointerData::LogFreeError(const FreePointerInfoType& info, size_t usable_si } error_log(LOG_DIVIDER); + if (g_debug->config().options() & ABORT_ON_ERROR) { + abort(); + } } void PointerData::VerifyFreedPointer(const FreePointerInfoType& info) { @@ -295,6 +298,9 @@ void PointerData::VerifyFreedPointer(const FreePointerInfoType& info) { 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 a8289b3d1..93b9b1ea1 100644 --- a/libc/malloc_debug/README.md +++ b/libc/malloc_debug/README.md @@ -394,6 +394,13 @@ malloc\_usable\_size, realloc. **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 9075a9caa..2e6afff55 100644 --- a/libc/malloc_debug/malloc_debug.cpp +++ b/libc/malloc_debug/malloc_debug.cpp @@ -154,6 +154,9 @@ static void LogError(const void* pointer, const char* error_str) { 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 a083b4f05..fb54ee54f 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 @@ TEST_F(MallocDebugConfigTest, record_allocs_max_error) { "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 2d6346fea..44f9795bc 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 @@ TEST_F(MallocDebugTest, verify_pointers) { 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 000000000..f0345051c --- /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 06e3dce00..0f0873fdd 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 e847669ee..09e1958ef 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 @@ private: 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 @@ private: 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 b5e677e55..4d40476a5 100644 --- a/libc/private/bionic_globals.h +++ b/libc/private/bionic_globals.h @@ -69,6 +69,7 @@ struct libc_shared_globals { 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 49280f4cc..fd0fb6035 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 797dfc5e8..d9e80479c 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 size_t arm_global_filter_size; 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 size_t arm64_global_filter_size; 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 size_t x86_global_filter_size; 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 size_t x86_64_global_filter_size; 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 size_t mips_global_filter_size; 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 3d617bef6..222a2c87d 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 @@ static void ValidateArchitecture(filter& f) { } #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 @@ static bool install_filter(filter const& f) { 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 @@ bool _set_seccomp_filter(FilterType type) { 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 @@ bool set_app_seccomp_filter() { 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_system_seccomp_filter() { 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 000000000..5b365f060 --- /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 000000000..6a456f269 --- /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 38a53f81f..e103adebc 100644 --- a/linker/Android.bp +++ b/linker/Android.bp @@ -176,6 +176,11 @@ cc_defaults { "-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 1f259e16c..412b8eb8e 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 @@ class LoadTask { } 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 @@ bool find_libraries(android_namespace_t* ns, 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 @@ static void soinfo_unload_impl(soinfo* root) { 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 @@ static ElfW(Addr) get_addend(ElfW(Rela)* rela, ElfW(Addr) reloc_addr __unused) { #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 @@ bool soinfo::relocate(const VersionTracker& version_tracker, ElfRelIteratorT&& r 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 @@ bool soinfo::relocate(const VersionTracker& version_tracker, ElfRelIteratorT&& r 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 @@ bool soinfo::relocate(const VersionTracker& version_tracker, ElfRelIteratorT&& r } } #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 @@ bool soinfo::relocate(const VersionTracker& version_tracker, ElfRelIteratorT&& r *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 @@ bool soinfo::relocate(const VersionTracker& version_tracker, ElfRelIteratorT&& r */ 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 @@ bool soinfo::prelink_image() { &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 d0e507218..ec07a5547 100644 --- a/linker/linker_logger.cpp +++ b/linker/linker_logger.cpp @@ -118,11 +118,7 @@ void LinkerLogger::ResetState() { 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 18287996e..f9fc38e6e 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 @@ class LinkerLogger { 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 9b4ce47c3..b0c27dcd6 100644 --- a/linker/linker_main.cpp +++ b/linker/linker_main.cpp @@ -415,6 +415,8 @@ static ElfW(Addr) linker_main(KernelArgumentBlock& args, const char* exe_to_load } } + 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 @@ static ElfW(Addr) linker_main(KernelArgumentBlock& args, const char* exe_to_load 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 93079cae6..dcc6bf305 100644 --- a/linker/linker_soinfo.cpp +++ b/linker/linker_soinfo.cpp @@ -628,6 +628,10 @@ android_namespace_list_t& soinfo::get_secondary_namespaces() { 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 44bff28f1..14571de5b 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 @@ struct version_info { // 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 @@ struct soinfo { 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 @@ struct soinfo { // 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 33274535c..0d1796b63 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 @@ void layout_linker_static_tls() { // 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(); +} + +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); +} - layout.finish_layout(); +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 2f0a57d32..fbb1dcf52 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 beed07ae9..8ac0531ca 100644 --- a/tests/Android.bp +++ b/tests/Android.bp @@ -218,6 +218,44 @@ cc_test_library { 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 @@ cc_test_library { defaults: ["bionic_tests_defaults"], whole_static_libs: [ "libBionicStandardTests", + "libBionicElfTlsTests", "libfortify1-tests-clang", "libfortify2-tests-clang", ], @@ -389,6 +428,7 @@ cc_defaults { whole_static_libs: [ "libBionicTests", "libBionicLoaderTests", + "libBionicElfTlsLoaderTests", ], static_libs: [ @@ -423,6 +463,8 @@ cc_defaults { "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 @@ cc_test { 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 @@ cc_test { "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 @@ cc_test { "libbase", "libdebuggerd_handler", "libgtest_isolated", + "libtest_elftls_shared_var", + "libtest_elftls_tprel", ], static_executable: true, @@ -662,12 +710,15 @@ cc_test_host { 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 ab96af9a9..697465879 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(); +#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 5f48e675f..176a6f809 100644 --- a/tests/dlfcn_test.cpp +++ b/tests/dlfcn_test.cpp @@ -1086,7 +1086,7 @@ TEST(dlfcn, dlopen_library_with_ELF_TLS) { 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 000000000..0a97c281d --- /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 000000000..11d41ce43 --- /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 ca34205a5..4b207b698 100644 --- a/tests/grp_pwd_test.cpp +++ b/tests/grp_pwd_test.cpp @@ -198,7 +198,7 @@ TEST(pwd, getpwnam_app_id_u0_a49999) { } 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_a40000) { } 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_all_a9999) { } 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_a40000) { } 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 79c9a060c..05d1ed2f9 100644 --- a/tests/libs/Android.bp +++ b/tests/libs/Android.bp @@ -40,7 +40,7 @@ cc_defaults { } // ----------------------------------------------------------------------------- -// Library to test ELF TLS +// Libraries and helper binaries for ELF TLS // ----------------------------------------------------------------------------- cc_test_library { name: "libelf-tls-library", @@ -50,6 +50,35 @@ cc_test_library { 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 @@ cc_test_library { "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 000000000..5902e0710 --- /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 000000000..27a15f07e --- /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 000000000..14e2ab03c --- /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 000000000..eb2fd9355 --- /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 d033364b8..5dda7ab35 100644 --- a/tests/sys_time_test.cpp +++ b/tests/sys_time_test.cpp @@ -147,7 +147,7 @@ TEST(sys_time, gettimeofday) { 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 4ec5976b4..50830ee1a 100644 --- a/tests/time_test.cpp +++ b/tests/time_test.cpp @@ -607,9 +607,9 @@ TEST(time, clock_gettime) { 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) { |