diff options
209 files changed, 5275 insertions, 1561 deletions
@@ -169,8 +169,7 @@ Adding a system call usually involves: relevant file or files. 3. Add function declarations to the appropriate header file. Don't forget to include the appropriate `__INTRODUCED_IN()`. - 4. Add the function name to the correct section in libc/libc.map.txt and - run `./libc/tools/genversion-scripts.py`. + 4. Add the function name to the correct section in libc/libc.map.txt. 5. Add at least basic tests. Even a test that deliberately supplies an invalid argument helps check that we're generating the right symbol and have the right declaration in the header file, and that you correctly diff --git a/android-changes-for-ndk-developers.md b/android-changes-for-ndk-developers.md index 1fdb1e48f..84456f988 100644 --- a/android-changes-for-ndk-developers.md +++ b/android-changes-for-ndk-developers.md @@ -1,8 +1,11 @@ -# Android changes for NDK developers +# Android linker changes for NDK developers This document details important changes related to native code loading in various Android releases. +See also [bionic status](docs/status.md) for general libc/libm/libdl +behavior changes. + Required tools: the NDK has an _arch_-linux-android-readelf binary (e.g. arm-linux-androideabi-readelf or i686-linux-android-readelf) for each architecture (under toolchains/), but you can use readelf for @@ -46,6 +49,10 @@ versions older than JB-MR2, you might want to consider [ReLinker](https://github.com/KeepSafe/ReLinker) which claims to solve these problems automatically. +Alternatively, if you don't have too many dependencies, it can be easiest to +simply link all of your code into one big library and sidestep the details of +library and symbol lookup changes on all past (and future) Android versions. + ## Changes to library search order We have made various fixes to library search order when resolving symbols. @@ -66,6 +73,14 @@ the local group. This allows ASAN, for example, to ensure that it can intercept any symbol. +## LD_PRELOAD and 32/64 bit + +LD_PRELOAD applies to both 32- and 64-bit processes. This means that you +should avoid saying something like `/system/lib/libfoo.so` and just say +`libfoo.so` instead, letting the dynamic linker find the correct library +on its search path. + + ## RTLD_LOCAL (Available in API level >= 23) The dlopen(3) RTLD_LOCAL flag used to be ignored but is implemented diff --git a/docs/native_allocator.md b/docs/native_allocator.md new file mode 100644 index 000000000..82a98fe48 --- /dev/null +++ b/docs/native_allocator.md @@ -0,0 +1,348 @@ +# Native Memory Allocator Verification +This document describes how to verify the native memory allocator on Android. +This procedure should be followed when upgrading or moving to a new allocator. +A small minor upgrade might not need to run all of the benchmarks, however, +at least the +[SQL Allocation Trace Benchmark](#sql-allocation-trace-benchmark), +[Memory Replay Benchmarks](#memory-replay-benchmarks) and +[Performance Trace Benchmarks](#performance-trace-benchmarks) should be run. + +It is important to note that there are two modes for a native allocator +to run in on Android. The first is the normal allocator, the second is +called the svelte config, which is designed to run on memory constrained +systems and be a bit slower, but take less RSS. To enable the svelte config, +add this line to the `BoardConfig.mk` for the given target: + + MALLOC_SVELTE := true + +The `BoardConfig.mk` file is usually found in the directory +`device/<DEVICE_NAME>/` or in a sub directory. + +When evaluating a native allocator, make sure that you benchmark both +versions. + +## Android Extensions +Android supports a few non-standard functions and mallopt controls that +a native allocator needs to implement. + +### Iterator Functions +These are functions that are used to implement a memory leak detector +called `libmemunreachable`. + +#### malloc\_disable +This function, when called, should pause all threads that are making a +call to an allocation function (malloc/free/etc). When a call +is made to `malloc_enable`, the paused threads should start running again. + +#### malloc\_enable +This function, when called, does nothing unless there was a previous call +to `malloc_disable`. This call will unpause any thread which is making +a call to an allocation function (malloc/free/etc) when `malloc_disable` +was called previously. + +#### malloc\_iterate +This function enumerates all of the allocations currently live in the +system. It is meant to be called after a call to `malloc_disable` to +prevent further allocations while this call is being executed. To +see what is expected for this function, the best description is the +tests for this funcion in `bionic/tests/malloc_itearte_test.cpp`. + +### Mallopt Extensions +These are mallopt options that Android requires for a native allocator +to work efficiently. + +#### M\_DECAY\_TIME +When set to zero, `mallopt(M_DECAY_TIME, 0)`, it is expected that an +allocator will attempt to purge and release any unused memory back to the +kernel on free calls. This is important in Android to avoid consuming extra +RSS. + +When set to non-zero, `mallopt(M_DECAY_TIME, 1)`, an allocator can delay the +purge and release action. The amount of delay is up to the allocator +implementation, but it should be a reasonable amount of time. The jemalloc +allocator was implemented to have a one second delay. + +The drawback to this option is that most allocators do not have a separate +thread to handle the purge, so the decay is only handled when an +allocation operation occurs. For server processes, this can mean that +RSS is slightly higher when the server is waiting for the next connection +and no other allocation calls are made. The `M_PURGE` option is used to +force a purge in this case. + +For all applications on Android, the call `mallopt(M_DECAY_TIME, 1)` is +made by default. The idea is that it allows application frees to run a +bit faster, while only increasing RSS a bit. + +#### M\_PURGE +When called, `mallopt(M_PURGE, 0)`, an allocator should purge and release +any unused memory immediately. The argument for this call is ignored. If +possible, this call should clear thread cached memory if it exists. The +idea is that this can be called to purge memory that has not been +purged when `M_DECAY_TIME` is set to one. This is useful if you have a +server application that does a lot of native allocations and the +application wants to purge that memory before waiting for the next connection. + +## Correctness Tests +These are the tests that should be run to verify an allocator is +working properly according to Android. + +### Bionic Unit Tests +The bionic unit tests contain a small number of allocator tests. These +tests are primarily verifying Android extensions and non-standard behavior +of allocation routines such as what happens when a non-power of two alignment +is passed to memalign. + +To run all of the compliance tests: + + adb shell /data/nativetest64/bionic-unit-tests/bionic-unit-tests --gtest_filter="malloc*" + adb shell /data/nativetest/bionic-unit-tests/bionic-unit-tests --gtest_filter="malloc*" + +The allocation tests are not meant to be complete, so it is expected +that a native allocator will have its own set of tests that can be run. + +### CTS Entropy Test +In addition to the bionic tests, there is also a CTS test that is designed +to verify that the addresses returned by malloc are sufficiently randomized +to help defeat potential security bugs. + +Run this test thusly: + + atest AslrMallocTest + +If there are multiple devices connected to the system, use `-s <SERIAL>` +to specify a device. + +## Performance +There are multiple different ways to evaluate the performance of a native +allocator on Android. One is allocation speed in various different scenarios, +another is total RSS taken by the allocator. + +The last is virtual address space consumed in 32 bit applications. There is +a limited amount of address space available in 32 bit apps, and there have +been allocator bugs that cause memory failures when too much virtual +address space is consumed. For 64 bit executables, this can be ignored. + +### Bionic Benchmarks +These are the microbenchmarks that are part of the bionic benchmarks suite of +benchmarks. These benchmarks can be built using this command: + + mmma -j bionic/benchmarks + +These benchmarks are only used to verify the speed of the allocator and +ignore anything related to RSS and virtual address space consumed. + +#### Allocate/Free Benchmarks +These are the benchmarks to verify the allocation speed of a loop doing a +single allocation, touching every page in the allocation to make it resident +and then freeing the allocation. + +To run the benchmarks with `mallopt(M_DECAY_TIME, 0)`, use these commands: + + adb shell /data/benchmarktest64/bionic-benchmarks/bionic-benchmarks --benchmark_filter=stdlib_malloc_free_default + adb shell /data/benchmarktest/bionic-benchmarks/bionic-benchmarks --benchmark_filter=malloc_free_default + +To run the benchmarks with `mallopt(M_DECAY_TIME, 1)`, use these commands: + + adb shell /data/benchmarktest64/bionic-benchmarks/bionic-benchmarks --benchmark_filter=stdlib_malloc_free_decay1 + adb shell /data/benchmarktest/bionic-benchmarks/bionic-benchmarks --benchmark_filter=malloc_free_decay1 + +The last value in the output is the size of the allocation in bytes. It is +useful to look at these kinds of benchmarks to make sure that there are +no outliers, but these numbers should not be used to make a final decision. +If these numbers are slightly worse than the current allocator, the +single thread numbers from trace data is a better representative of +real world situations. + +#### Multiple Allocations Retained Benchmarks +These are the benchmarks that examine how the allocator handles multiple +allocations of the same size at the same time. + +The first set of these benchmarks does a set number of 8192 byte allocations +in one loop, and then frees all of the allocations at the end of the loop. +Only the time it takes to do the allocations is recorded, the frees are not +counted. The value of 8192 was chosen since the jemalloc native allocator +had issues with this size. It is possible other sizes might show different +results, but, as mentioned before, these microbenchmark numbers should +not be used as absolutes for determining if an allocator is worth using. + +This benchmark is designed to verify that there is no performance issue +related to having multiple allocations alive at the same time. + +To run the benchmarks with `mallopt(M_DECAY_TIME, 0)`, use these commands: + + adb shell /data/benchmarktest64/bionic-benchmarks/bionic-benchmarks --benchmark_filter=stdlib_malloc_multiple_8192_allocs_default + adb shell /data/benchmarktest/bionic-benchmarks/bionic-benchmarks --benchmark_filter=stdlib_malloc_multiple_8192_allocs_default + +To run the benchmarks with `mallopt(M_DECAY_TIME, 1)`, use these commands: + + adb shell /data/benchmarktest64/bionic-benchmarks/bionic-benchmarks --benchmark_filter=stdlib_malloc_multiple_8192_allocs_decay1 + adb shell /data/benchmarktest/bionic-benchmarks/bionic-benchmarks --benchmark_filter=stdlib_malloc_multiple_8192_allocs_decay1 + +For these benchmarks, the last parameter is the total number of allocations to +do in each loop. + +The other variation of this benchmark is to always do forty allocations in +each loop, but vary the size of the forty allocations. As with the other +benchmark, only the time it takes to do the allocations is tracked, the +frees are not counted. Forty allocations is an arbitrary number that could +be modified in the future. It was chosen because a version of the native +allocator, jemalloc, showed a problem at forty allocations. + +To run the benchmarks with `mallopt(M_DECAY_TIME, 0)`, use these commands: + + adb shell /data/benchmarktest64/bionic-benchmarks/bionic-benchmarks --benchmark_filter=stdlib_malloc_forty_default + adb shell /data/benchmarktest/bionic-benchmarks/bionic-benchmarks --benchmark_filter=stdlib_malloc_forty_default + +To run the benchmarks with `mallopt(M_DECAY_TIME, 1)`, use these command: + + adb shell /data/benchmarktest64/bionic-benchmarks/bionic-benchmarks --benchmark_filter=stdlib_malloc_forty_decay1 + adb shell /data/benchmarktest/bionic-benchmarks/bionic-benchmarks --benchmark_filter=stdlib_malloc_forty_decay1 + +For these benchmarks, the last parameter in the output is the size of the +allocation in bytes. + +As with the other microbenchmarks, an allocator with numbers in the same +proximity of the current values is usually sufficient to consider making +a switch. The trace benchmarks are more important than these benchmarks +since they simulate real world allocation profiles. + +#### SQL Allocation Trace Benchmark +This benchmark is a trace of the allocations performed when running +the SQLite BenchMark app. + +This benchmark is designed to verify that the allocator will be performant +in a real world allocation scenario. SQL operations were chosen as a +benchmark because these operations tend to do lots of malloc/realloc/free +calls, and they tend to be on the critical path of applications. + +To run the benchmarks with `mallopt(M_DECAY_TIME, 0)`, use these commands: + + adb shell /data/benchmarktest64/bionic-benchmarks/bionic-benchmarks --benchmark_filter=malloc_sql_trace_default + adb shell /data/benchmarktest/bionic-benchmarks/bionic-benchmarks --benchmark_filter=malloc_sql_trace_default + +To run the benchmarks with `mallopt(M_DECAY_TIME, 1)`, use these commands: + + adb shell /data/benchmarktest64/bionic-benchmarks/bionic-benchmarks --benchmark_filter=malloc_sql_trace_decay1 + adb shell /data/benchmarktest/bionic-benchmarks/bionic-benchmarks --benchmark_filter=malloc_sql_trace_decay1 + +These numbers should be as performant as the current allocator. + +### Memory Trace Benchmarks +These benchmarks measure all three axes of a native allocator, RSS, virtual +address space consumed, speed of allocation. They are designed to +run on a trace of the allocations from a real world application or system +process. + +To build this benchmark: + + mmma -j system/extras/memory_replay + +This will build two executables: + + /system/bin/memory_replay32 + /system/bin/memory_replay64 + +And these two benchmark executables: + + /data/benchmarktest64/trace_benchmark/trace_benchmark + /data/benchmarktest/trace_benchmark/trace_benchmark + +#### Memory Replay Benchmarks +These benchmarks display RSS, virtual memory consumed (VA space), and do a +bit of performance testing on actual traces taken from running applications. + +The trace data includes what thread does each operation, so the replay +mechanism will simulate this by creating threads and replaying the operations +on a thread as if it was rerunning the real trace. The only issue is that +this is a worst case scenario for allocations happening at the same time +in all threads since it collapses all of the allocation operations to occur +one after another. This will cause a lot of threads allocating at the same +time. The trace data does not include timestamps, +so it is not possible to create a completely accurate replay. + +To generate these traces, see the [Malloc Debug documentation](https://android.googlesource.com/platform/bionic/+/master/libc/malloc_debug/README.md), +the option [record\_allocs](https://android.googlesource.com/platform/bionic/+/master/libc/malloc_debug/README.md#record_allocs_total_entries). + +To run these benchmarks, first copy the trace files to the target and +unzip them using these commands: + + adb shell push system/extras/traces /data/local/tmp + adb shell 'cd /data/local/tmp/traces && for name in *.zip; do unzip $name; done' + +Since all of the traces come from applications, the `memory_replay` program +will always call `mallopt(M_DECAY_TIME, 1)' before running the trace. + +Run the benchmark thusly: + + adb shell memory_replay64 /data/local/tmp/traces/XXX.txt + adb shell memory_replay32 /data/local/tmp/traces/XXX.txt + +Where XXX.txt is the name of a trace file. + +Every 100000 allocation operations, a dump of the RSS and VA space will be +performed. At the end, a final RSS and VA space number will be printed. +For the most part, the intermediate data can be ignored, but it is always +a good idea to look over the data to verify that no strange spikes are +occurring. + +The performance number is a measure of the time it takes to perform all of +the allocation calls (malloc/memalign/posix_memalign/realloc/free/etc). +For any call that allocates a pointer, the time for the call and the time +it takes to make the pointer completely resident in memory is included. + +The performance numbers for these runs tend to have a wide variability so +they should not be used as absolute value for comparison against the +current allocator. But, they should be in the same range as the current +values. + +When evaluating an allocator, one of the most important traces is the +camera.txt trace. The camera application does very large allocations, +and some allocators might leave large virtual address maps around +rather than delete them. When that happens, it can lead to allocation +failures and would cause the camera app to abort/crash. It is +important to verify that when running this trace using the 32 bit replay +executable, the virtual address space consumed is not much larger than the +current allocator. A small increase (on the order of a few MBs) would be okay. + +There is no specific benchmark for memory fragmentation, instead, the RSS +when running the memory traces acts as a proxy for this. An allocator that +is fragmenting badly will show an increase in RSS. The best trace for +tracking fragmentation is system\_server.txt which is an extremely long +trace (~13 million operations). The total number of live allocations goes +up and down a bit, but stays mostly the same so an allocator that fragments +badly would likely show an abnormal increase in RSS on this trace. + +NOTE: When a native allocator calls mmap, it is expected that the allocator +will name the map using the call: + + prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, <PTR>, <SIZE>, "libc_malloc"); + +If the native allocator creates a different name, then it necessary to +modify the file: + + system/extras/memory_replay/NativeInfo.cpp + +The `GetNativeInfo` function needs to be modified to include the name +of the maps that this allocator includes. + +In addition, in order for the frameworks code to keep track of the memory +of a process, any named maps must be added to the file: + + frameworks/base/core/jni/android_os_Debug.cpp + +Modify the `load_maps` function and add a check of the new expected name. + +#### Performance Trace Benchmarks +This is a benchmark that treats the trace data as if all allocations +occurred in a single thread. This is the scenario that could +happen if all of the allocations are spaced out in time so no thread +every does an allocation at the same time as another thread. + +Run these benchmarks thusly: + + adb shell /data/benchmarktest64/trace_benchmark/trace_benchmark + adb shell /data/benchmarktest/trace_benchmark/trace_benchmark + +When run without any arguments, the benchmark will run over all of the +traces and display data. It takes many minutes to complete these runs in +order to get as accurate a number as possible. diff --git a/docs/status.md b/docs/status.md index e1a5d349d..6968a1800 100644 --- a/docs/status.md +++ b/docs/status.md @@ -1,5 +1,11 @@ # Android bionic status +This document details libc/libm/libdl additions and behavior changes. + +See also +[Android linker changes for NDK developers](../android-changes-for-ndk-developers.md) +for changes related to native code loading in various Android releases. + ## Bionic function availability ### POSIX @@ -39,6 +45,9 @@ Current libc symbols: https://android.googlesource.com/platform/bionic/+/master/ New libc functions in R (API level 30): * Full C11 `<threads.h>` (available as inlines for older API levels). + * `memfd_create` and `mlock2` (GNU extensions). + * `renameat2` (GNU extension). + * `pthread_cond_clockwait`/`pthread_mutex_clocklock`/`pthread_rwlock_clockrdlock`/`pthread_rwlock_clockwrlock`/`sem_clockwait` New libc functions in Q (API level 29): * `timespec_get` (C11 `<time.h>` addition) @@ -301,7 +310,7 @@ targets N or later. The `_FORTIFY_SOURCE` macro can be used to enable extra automatic bounds checking for common libc functions. If a buffer overrun is detected, the program is safely aborted as in this -(example)[https://source.android.com/devices/tech/debug/native-crash#fortify]. +[example](https://source.android.com/devices/tech/debug/native-crash#fortify). Note that in recent releases Android's FORTIFY has been extended to cover other issues. It can now detect, for example, passing `O_CREAT` @@ -313,7 +322,7 @@ printf(3) family, or using the scanf(3) `m` modifier incorrectly will all result in FORTIFY failures even for code not built with FORTIFY. More background information is available in our -(FORTIFY in Android)[https://android-developers.googleblog.com/2017/04/fortify-in-android.html] +[FORTIFY in Android](https://android-developers.googleblog.com/2017/04/fortify-in-android.html) blog post. The Android platform is built with `-D_FORTIFY_SOURCE=2`, but NDK users diff --git a/libc/Android.bp b/libc/Android.bp index 0c955ad9b..7f1ac5d58 100644 --- a/libc/Android.bp +++ b/libc/Android.bp @@ -73,6 +73,8 @@ cc_defaults { sanitize: { address: false, integer_overflow: false, + // TODO(b/132640749): Fix broken fuzzer support. + fuzzer: false, }, native_coverage: false, recovery_available: true, @@ -271,6 +273,7 @@ cc_library_static { "upstream-freebsd/lib/libc/string/wcscat.c", "upstream-freebsd/lib/libc/string/wcscpy.c", "upstream-freebsd/lib/libc/string/wmemcmp.c", + "upstream-freebsd/lib/libc/string/wmemset.c", ], }, }, @@ -768,6 +771,7 @@ cc_library_static { arch: { arm: { + asflags: libc_common_flags + ["-mno-restrict-it"], srcs: [ "arch-arm/generic/bionic/memcmp.S", "arch-arm/generic/bionic/memmove.S", @@ -941,6 +945,7 @@ cc_library_static { "arch-x86/generic/string/wcscat.c", "arch-x86/generic/string/wcscpy.c", "arch-x86/generic/string/wmemcmp.c", + "arch-x86/generic/string/wmemset.c", "arch-x86/atom/string/sse2-memchr-atom.S", "arch-x86/atom/string/sse2-memrchr-atom.S", @@ -989,6 +994,9 @@ cc_library_static { "arch-x86/atom/string/ssse3-strcpy-atom.S", "arch-x86/atom/string/ssse3-strncpy-atom.S", "arch-x86/atom/string/ssse3-wmemcmp-atom.S", + + // avx2 functions + "arch-x86/kabylake/string/avx2-wmemset-kbl.S", ], exclude_srcs: [ @@ -1011,6 +1019,7 @@ cc_library_static { "arch-x86_64/string/sse4-memcmp-slm.S", "arch-x86_64/string/ssse3-strcmp-slm.S", "arch-x86_64/string/ssse3-strncmp-slm.S", + "arch-x86_64/string/avx2-wmemset-kbl.S", "arch-x86_64/bionic/__bionic_clone.S", "arch-x86_64/bionic/_exit_with_stack_teardown.S", @@ -1052,7 +1061,6 @@ cc_library_static { "bionic/__libc_current_sigrtmin.cpp", "bionic/abort.cpp", "bionic/accept.cpp", - "bionic/accept4.cpp", "bionic/access.cpp", "bionic/arpa_inet.cpp", "bionic/assert.cpp", @@ -1073,7 +1081,6 @@ cc_library_static { "bionic/clock_getcpuclockid.cpp", "bionic/clock_nanosleep.cpp", "bionic/clone.cpp", - "bionic/connect.cpp", "bionic/ctype.cpp", "bionic/dirent.cpp", "bionic/dup2.cpp", @@ -1166,7 +1173,6 @@ cc_library_static { "bionic/sigaction.cpp", "bionic/signal.cpp", "bionic/sigprocmask.cpp", - "bionic/socket.cpp", "bionic/spawn.cpp", "bionic/stat.cpp", "bionic/statvfs.cpp", @@ -1711,7 +1717,9 @@ cc_library { versions: ["10000"], }, - symbol_ordering_file: "symbol_ordering", + // Sorting bss symbols by size usually results in less dirty pages at run + // time, because small symbols are grouped together. + sort_bss_symbols_by_size: true, } genrule { @@ -1746,6 +1754,19 @@ genrule { cmd: "$(location :bionic-generate-version-script) x86_64 $(in) $(out)", } +// Makes bionic_tls.h available for art to use in its implementation of Thread::Current(). +cc_library_headers { + name: "bionic_libc_private_headers", + visibility: [ + "//art:__subpackages__", + ], + host_supported: true, + export_include_dirs: [ + "private", + ], + sdk_version: "current", +} + // libc_headers for libasync_safe and libpropertyinfoparser cc_library_headers { name: "libc_headers", @@ -1756,7 +1777,6 @@ cc_library_headers { native_bridge_supported: true, no_libcrt: true, - no_libgcc: true, stl: "none", system_shared_libs: [], diff --git a/libc/NOTICE b/libc/NOTICE index ef3173387..d9ac638ba 100644 --- a/libc/NOTICE +++ b/libc/NOTICE @@ -1025,6 +1025,22 @@ SUCH DAMAGE. ------------------------------------------------------------------- Copyright (C) 2019 The Android Open Source Project + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +------------------------------------------------------------------- + +Copyright (C) 2019 The Android Open Source Project All rights reserved. Redistribution and use in source and binary forms, with or without @@ -1052,6 +1068,34 @@ SUCH DAMAGE. ------------------------------------------------------------------- +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. + +------------------------------------------------------------------- + Copyright (c) 1980, 1983, 1988, 1993 The Regents of the University of California. All rights reserved. diff --git a/libc/SECCOMP_WHITELIST_COMMON.TXT b/libc/SECCOMP_WHITELIST_COMMON.TXT index 2faa559a2..07f84a8fb 100644 --- a/libc/SECCOMP_WHITELIST_COMMON.TXT +++ b/libc/SECCOMP_WHITELIST_COMMON.TXT @@ -32,6 +32,7 @@ int ioprio_set:ioprio_set(int which, int who, int ioprio) arm64,x86_64,mips64 pid_t gettid:gettid() all int futex:futex(int *uaddr, int futex_op, int val, const struct timespec *timeout, int *uaddr2, int val3) all int clone:clone(int (*fn)(void *), void *child_stack, int flags, void *arg, ..) all +int sigreturn:sigreturn(unsigned long __unused) arm,x86,mips int rt_sigreturn:rt_sigreturn(unsigned long __unused) all int rt_tgsigqueueinfo:int rt_tgsigqueueinfo(pid_t tgid, pid_t tid, int sig, siginfo_t *uinfo) all int restart_syscall:int restart_syscall() all @@ -54,33 +55,54 @@ int seccomp:seccomp(unsigned int operation, unsigned int flags, void *args) all # Needed for debugging 32-bit Chrome int pipe:pipe(int pipefd[2]) arm,x86,mips -# b/34813887 +# Needed by breakpad (b/34813887). int open:open(const char *path, int oflag, ... ) arm,x86,x86_64,mips int getdents:getdents(unsigned int fd, struct linux_dirent *dirp, unsigned int count) arm,x86,x86_64,mips -# syscalls needed to boot android -int sigreturn:sigreturn(unsigned long __unused) arm,x86,mips - -# Needed by sanitizers (b/34606909) -# 5 (__NR_open) and 195 (__NR_stat64) are also required, but they are -# already allowed. -ssize_t readlink:readlink(const char *path, char *buf, size_t bufsiz) arm,x86,x86_64,mips - -# Probed for and conditionally used by ART. -int membarrier(int cmd, int flags) all +# Needed by sanitizers (b/34606909, b/136777266). +int open:open(const char*, int, ...) arm,x86,x86_64 +int stat64:stat64(const char*, struct stat64*) arm,x86 +ssize_t readlink:readlink(const char*, char*, size_t) arm,x86,x86_64 +# # Useful new syscalls which we don't yet use in bionic. +# + +# Since Linux 2.5, not in glibc. +int io_setup(unsigned nr, aio_context_t *ctxp) all +int io_destroy(aio_context_t ctx) all +int io_submit(aio_context_t ctx, long nr, struct iocb **iocbpp) all +int io_getevents(aio_context_t ctx, long min_nr, long max_nr, struct io_event *events, struct timespec *timeout) all +int io_cancel(aio_context_t ctx, struct iocb *, struct io_event *result) all +# Since Linux 3.14, not in glibc. int sched_getattr(pid_t pid, struct sched_attr* attr, unsigned int flags) all int sched_setattr(pid_t pid, struct sched_attr* attr, unsigned int size, unsigned int flags) all -int memfd_create(const char* name, unsigned int flags) all -int renameat2(int olddirfd, const char* oldpath, int newdirfd, const char* newpath, unsigned int flags) all +# Since Linux 3.19, not in glibc (and not really needed to implement fexecve). int execveat(int dirfd, const char* pathname, char* const* argv, char* const* envp, int flags) all +# Since Linux 4.3, not in glibc. Probed for and conditionally used by ART. +int membarrier(int cmd, int flags) all +# Since Linux 4.5, glibc 2.27. ssize_t copy_file_range(int fd_in, loff_t* off_in, int fd_out, loff_t* off_out, size_t len, unsigned int flags) all -int mlock2(const void* addr, size_t len, int flags) all +# Since Linux 4.6, glibc 2.26. ssize_t preadv2(int fd, const struct iovec* iov, int iovcnt, off_t offset, int flags) all ssize_t pwritev2(int fd, const struct iovec* iov, int iovcnt, off_t offset, int flags) all -int io_setup(unsigned nr, aio_context_t *ctxp) all -int io_destroy(aio_context_t ctx) all -int io_submit(aio_context_t ctx, long nr, struct iocb **iocbpp) all -int io_getevents(aio_context_t ctx, long min_nr, long max_nr, struct io_event *events, struct timespec *timeout) all -int io_cancel(aio_context_t ctx, struct iocb *, struct io_event *result) all +# Since Linux 4.11, glibc 2.30. +int statx(int, const char*, int, unsigned int, statx*) all +# Since Linux 5.1, not in glibc. +int clock_gettime64(clockid_t, timespec64*) lp32 +int clock_settime64(clockid_t, const timespec64*) lp32 +int clock_adjtime64(clockid_t, timex64*) lp32 +int clock_getres_time64(clockid_t, timespec64*) lp32 +int clock_nanosleep_time64(clockid_t, int, const timespec64*, timespec*) lp32 +int timer_gettime64(__kernel_timer_t, itimerspec64*) lp32 +int timer_settime64(__kernel_timer_t, int, const itimerspec64*, itimerspec64*) lp32 +int timerfd_gettime64(int, itimerspec64*) lp32 +int timerfd_settime64(int, int, const itimerspec64*, itimerspec64*) lp32 +int utimensat_time64(int, const char*, const timespec64[2], int) lp32 +int pselect6_time64(int, fd_set*, fd_set*, timespec64*, void*) lp32 +int ppoll_time64(pollfd*, unsigned int, timespec64*, const sigset64_t*, size_t) lp32 +int recvmmsg_time64(int, mmsghdr*, unsigned int, int, const timespec64*) lp32 +int semtimedop_time64(int, sembuf*, size_t, const timespec64*) lp32 +int rt_sigtimedwait_time64(const sigset64_t*, siginfo_t*, const timespec64*, size_t) lp32 +int futex_time64(int*, int, int, const timespec64*, int*, int) lp32 +int sched_rr_get_interval_time64(pid_t, timespec64*) lp32 diff --git a/libc/SYSCALLS.TXT b/libc/SYSCALLS.TXT index e2ea0656b..21ebdbd8e 100644 --- a/libc/SYSCALLS.TXT +++ b/libc/SYSCALLS.TXT @@ -105,14 +105,16 @@ ssize_t preadv|preadv64(int, const struct iovec*, int, off_t) lp64 ssize_t __pwritev64:pwritev(int, const struct iovec*, int, long, long) lp32 ssize_t pwritev|pwritev64(int, const struct iovec*, int, off_t) lp64 -int ___close:close(int) all +int __close:close(int) all pid_t __getpid:getpid() all +int memfd_create(const char*, unsigned) all int munmap(void*, size_t) all -void* ___mremap:mremap(void*, size_t, size_t, int, void*) all +void* __mremap:mremap(void*, size_t, size_t, int, void*) all int msync(const void*, size_t, int) all int mprotect(const void*, size_t, int) all int madvise(void*, size_t, int) all -int mlock(const void* addr, size_t len) all +int mlock(const void* addr, size_t len) all +int mlock2(const void* addr, size_t len, int flags) all int munlock(const void* addr, size_t len) all int mlockall(int flags) all int munlockall() all @@ -123,7 +125,7 @@ ssize_t writev(int, const struct iovec*, int) all int __fcntl64:fcntl64(int, int, void*) lp32 int fcntl(int, int, void*) lp64 int flock(int, int) all -int ___fchmod:fchmod(int, mode_t) all +int __fchmod:fchmod(int, mode_t) all int dup(int) all int pipe2(int*, int) all int dup3(int, int, int) all @@ -133,16 +135,16 @@ int fchown:fchown32(int, uid_t, gid_t) arm,x86 int fchown:fchown(int, uid_t, gid_t) arm64,mips,mips64,x86_64 void sync(void) all int syncfs(int) all -int ___fsetxattr:fsetxattr(int, const char*, const void*, size_t, int) all -ssize_t ___fgetxattr:fgetxattr(int, const char*, void*, size_t) all -ssize_t ___flistxattr:flistxattr(int, char*, size_t) all +int __fsetxattr:fsetxattr(int, const char*, const void*, size_t, int) all +ssize_t __fgetxattr:fgetxattr(int, const char*, void*, size_t) all +ssize_t __flistxattr:flistxattr(int, char*, size_t) all int fremovexattr(int, const char*) all int __getdents64:getdents64(unsigned int, struct dirent*, unsigned int) arm,arm64,mips,mips64,x86,x86_64 int __openat:openat(int, const char*, int, mode_t) all -int ___faccessat:faccessat(int, const char*, int) all -int ___fchmodat:fchmodat(int, const char*, mode_t) all +int __faccessat:faccessat(int, const char*, int) all +int __fchmodat:fchmodat(int, const char*, mode_t) all int fchownat(int, const char*, uid_t, gid_t, int) all int fstatat64|fstatat:fstatat64(int, const char*, struct stat*, int) lp32 int fstatat64|fstatat:newfstatat(int, const char*, struct stat*, int) arm64,x86_64 @@ -151,6 +153,7 @@ int mkdirat(int, const char*, mode_t) all int mknodat(int, const char*, mode_t, dev_t) all int readlinkat(int, const char*, char*, size_t) all int renameat(int, const char*, int, const char*) all +int renameat2(int, const char*, int, const char*, unsigned) all int symlinkat(const char*, int, const char*) all int unlinkat(int, const char*, int) all int utimensat(int, const char*, const struct timespec times[2], int) all @@ -213,7 +216,7 @@ int settimeofday(const struct timeval*, const struct timezone*) all clock_t times(struct tms*) all int nanosleep(const struct timespec*, struct timespec*) all int clock_settime(clockid_t, const struct timespec*) all -int ___clock_nanosleep:clock_nanosleep(clockid_t, int, const struct timespec*, struct timespec*) all +int __clock_nanosleep:clock_nanosleep(clockid_t, int, const struct timespec*, struct timespec*) all int getitimer(int, const struct itimerval*) all int setitimer(int, const struct itimerval*, struct itimerval*) all int __timer_create:timer_create(clockid_t clockid, struct sigevent* evp, __kernel_timer_t* timerid) all @@ -234,7 +237,7 @@ int __rt_sigpending:rt_sigpending(sigset64_t*, size_t) all int __rt_sigprocmask:rt_sigprocmask(int, const sigset64_t*, sigset64_t*, size_t) all int __rt_sigsuspend:rt_sigsuspend(const sigset64_t*, size_t) all int __rt_sigtimedwait:rt_sigtimedwait(const sigset64_t*, siginfo_t*, const timespec*, size_t) all -int ___rt_sigqueueinfo:rt_sigqueueinfo(pid_t, int, siginfo_t*) all +int __rt_sigqueueinfo:rt_sigqueueinfo(pid_t, int, siginfo_t*) all int __signalfd4:signalfd4(int, const sigset64_t*, size_t, int) all # sockets @@ -246,15 +249,15 @@ int listen(int, int) arm,arm64,mips,mips64,x86_64 int __accept4:accept4(int, struct sockaddr*, socklen_t*, int) arm,arm64,mips,mips64,x86_64 int getsockname(int, struct sockaddr*, socklen_t*) arm,arm64,mips,mips64,x86_64 int getpeername(int, struct sockaddr*, socklen_t*) arm,arm64,mips,mips64,x86_64 -int sendto(int, const void*, size_t, int, const struct sockaddr*, socklen_t) arm,arm64,mips,mips64,x86_64 +int __sendto:sendto(int, const void*, size_t, int, const struct sockaddr*, socklen_t) arm,arm64,mips,mips64,x86_64 int recvfrom(int, void*, size_t, unsigned int, struct sockaddr*, socklen_t*) arm,arm64,mips,mips64,x86_64 int shutdown(int, int) arm,arm64,mips,mips64,x86_64 int setsockopt(int, int, int, const void*, socklen_t) arm,arm64,mips,mips64,x86_64 int getsockopt(int, int, int, void*, socklen_t*) arm,arm64,mips,mips64,x86_64 ssize_t recvmsg(int, struct msghdr*, unsigned int) arm,arm64,mips,mips64,x86_64 -ssize_t sendmsg(int, const struct msghdr*, unsigned int) arm,arm64,mips,mips64,x86_64 +ssize_t __sendmsg:sendmsg(int, const struct msghdr*, unsigned int) arm,arm64,mips,mips64,x86_64 int recvmmsg(int, struct mmsghdr*, unsigned int, int, const struct timespec*) arm,arm64,mips,mips64,x86_64 -int sendmmsg(int, struct mmsghdr*, unsigned int, int) arm,arm64,mips,mips64,x86_64 +int __sendmmsg:sendmmsg(int, struct mmsghdr*, unsigned int, int) arm,arm64,mips,mips64,x86_64 # sockets for x86. These are done as an "indexed" call to socketcall syscall. int __socket:socketcall:1(int, int, int) x86 @@ -264,16 +267,16 @@ int listen:socketcall:4(int, int) x86 int getsockname:socketcall:6(int, struct sockaddr*, socklen_t*) x86 int getpeername:socketcall:7(int, struct sockaddr*, socklen_t*) x86 int socketpair:socketcall:8(int, int, int, int*) x86 -int sendto:socketcall:11(int, const void*, size_t, int, const struct sockaddr*, socklen_t) x86 +int __sendto:socketcall:11(int, const void*, size_t, int, const struct sockaddr*, socklen_t) x86 int recvfrom:socketcall:12(int, void*, size_t, unsigned int, struct sockaddr*, socklen_t*) x86 int shutdown:socketcall:13(int, int) x86 int setsockopt:socketcall:14(int, int, int, const void*, socklen_t) x86 int getsockopt:socketcall:15(int, int, int, void*, socklen_t*) x86 -int sendmsg:socketcall:16(int, const struct msghdr*, unsigned int) x86 +int __sendmsg:socketcall:16(int, const struct msghdr*, unsigned int) x86 int recvmsg:socketcall:17(int, struct msghdr*, unsigned int) x86 int __accept4:socketcall:18(int, struct sockaddr*, socklen_t*, int) x86 int recvmmsg:socketcall:19(int, struct mmsghdr*, unsigned int, int, const struct timespec*) x86 -int sendmmsg:socketcall:20(int, struct mmsghdr*, unsigned int, int) x86 +int __sendmmsg:socketcall:20(int, struct mmsghdr*, unsigned int, int) x86 # scheduler & real-time int sched_setscheduler(pid_t pid, int policy, const struct sched_param* param) all diff --git a/libc/arch-common/bionic/crtbegin.c b/libc/arch-common/bionic/crtbegin.c index c4d2a5a35..3630b5ed0 100644 --- a/libc/arch-common/bionic/crtbegin.c +++ b/libc/arch-common/bionic/crtbegin.c @@ -63,6 +63,45 @@ __asm__(PRE "movq %rsp,%rdi; andq $~0xf,%rsp; callq _start_main" POST); #undef PRE #undef POST +// On arm32 and arm64, when targeting Q and up, overalign the TLS segment to +// (8 * sizeof(void*)), which reserves enough space between the thread pointer +// and the executable's TLS segment for Bionic's TLS slots. It has the side +// effect of placing a 0-sized TLS segment into Android executables that don't +// use TLS, but this should be harmless. +// +// To ensure that the .tdata input section isn't deleted, the .text input +// section (which contains _start) has a relocation to the .tdata input section. +// +// TODO: This file currently uses TPREL relocations from .text to ensure that +// --gc-sections doesn't remove the .tdata input section. The relocations are +// resolved by the static linker. (They don't appear in the executable.) Replace +// the TPREL relocations with R_{ARM,AARCH64}_NONE once the toolchain has been +// updated to support them: +// - https://reviews.llvm.org/D61992 (Support .reloc *, R_ARM_NONE, *) +// - https://reviews.llvm.org/D61973 (Support .reloc *, R_AARCH64_NONE, *) +// - https://reviews.llvm.org/D62052 (lld -r: fix R_*_NONE to section symbols on Elf*_Rel targets) +#if __ANDROID_API__ >= __ANDROID_API_Q__ +#if defined(__arm__) +asm(" .section .tdata,\"awT\",%progbits\n" + " .p2align 5\n" + "__tls_align:\n" + " .text\n" + " .type __tls_align_reference,%function\n" + "__tls_align_reference:\n" + " .long __tls_align(TPOFF)\n" + " .size __tls_align_reference, .-__tls_align_reference\n"); +#elif defined(__aarch64__) +asm(" .section .tdata,\"awT\",@progbits\n" + " .p2align 6\n" + "__tls_align:\n" + " .text\n" + " .type __tls_align_reference,%function\n" + "__tls_align_reference:\n" + " add x0, x0, :tprel_lo12_nc:__tls_align\n" + " .size __tls_align_reference, .-__tls_align_reference\n"); +#endif +#endif + #include "__dso_handle.h" #include "atexit.h" #include "pthread_atfork.h" diff --git a/libc/arch-x86/dynamic_function_dispatch.cpp b/libc/arch-x86/dynamic_function_dispatch.cpp index 70f4b3e70..370b37204 100644 --- a/libc/arch-x86/dynamic_function_dispatch.cpp +++ b/libc/arch-x86/dynamic_function_dispatch.cpp @@ -107,6 +107,13 @@ DEFINE_IFUNC_FOR(wmemcmp) { RETURN_FUNC(wmemcmp_func, wmemcmp_freebsd); } +typedef int wmemset_func(const wchar_t* __lhs, const wchar_t* __rhs, size_t __n); +DEFINE_IFUNC_FOR(wmemset) { + __builtin_cpu_init(); + if (__builtin_cpu_supports("avx2")) RETURN_FUNC(wmemset_func, wmemset_avx2); + RETURN_FUNC(wmemset_func, wmemset_freebsd); +} + typedef int strcmp_func(const char* __lhs, const char* __rhs); DEFINE_IFUNC_FOR(strcmp) { __builtin_cpu_init(); diff --git a/libc/bionic/socket.cpp b/libc/arch-x86/generic/string/wmemset.c index 2f9e14562..eff533c10 100644 --- a/libc/bionic/socket.cpp +++ b/libc/arch-x86/generic/string/wmemset.c @@ -1,23 +1,19 @@ /* - * Copyright (C) 2014 The Android Open Source Project + * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - */ +*/ -#include "private/NetdClientDispatch.h" +#define wmemset wmemset_freebsd -#include <sys/socket.h> - -int socket(int domain, int type, int protocol) { - return __netdClientDispatch.socket(domain, type, protocol); -} +#include <upstream-freebsd/lib/libc/string/wmemset.c> diff --git a/libc/arch-x86/kabylake/string/avx2-wmemset-kbl.S b/libc/arch-x86/kabylake/string/avx2-wmemset-kbl.S new file mode 100644 index 000000000..69b66c795 --- /dev/null +++ b/libc/arch-x86/kabylake/string/avx2-wmemset-kbl.S @@ -0,0 +1,148 @@ +/* +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 <private/bionic_asm.h> + +#ifndef WMEMSET + #define WMEMSET wmemset_avx2 +#endif + +ENTRY(WMEMSET) +# BB#0: + pushl %ebp + pushl %ebx + pushl %edi + pushl %esi + pushl %eax + movl 32(%esp), %ecx + movl 24(%esp), %eax + testl %ecx, %ecx + je .LBB0_12 +# BB#1: + movl 28(%esp), %edx + xorl %edi, %edi + movl %eax, %esi + cmpl $32, %ecx + jb .LBB0_10 +# BB#2: + movl %ecx, %eax + andl $-32, %eax + vmovd %edx, %xmm0 + vpbroadcastd %xmm0, %ymm0 + movl %eax, (%esp) # 4-byte Spill + leal -32(%eax), %esi + movl %esi, %eax + shrl $5, %eax + leal 1(%eax), %edi + andl $7, %edi + xorl %ebx, %ebx + cmpl $224, %esi + jb .LBB0_5 +# BB#3: + movl 24(%esp), %esi + leal 992(%esi), %ebp + leal -1(%edi), %esi + subl %eax, %esi + xorl %ebx, %ebx + .p2align 4, 0x90 +.LBB0_4: # =>This Inner Loop Header: Depth=1 + vmovdqu %ymm0, -992(%ebp,%ebx,4) + vmovdqu %ymm0, -960(%ebp,%ebx,4) + vmovdqu %ymm0, -928(%ebp,%ebx,4) + vmovdqu %ymm0, -896(%ebp,%ebx,4) + vmovdqu %ymm0, -864(%ebp,%ebx,4) + vmovdqu %ymm0, -832(%ebp,%ebx,4) + vmovdqu %ymm0, -800(%ebp,%ebx,4) + vmovdqu %ymm0, -768(%ebp,%ebx,4) + vmovdqu %ymm0, -736(%ebp,%ebx,4) + vmovdqu %ymm0, -704(%ebp,%ebx,4) + vmovdqu %ymm0, -672(%ebp,%ebx,4) + vmovdqu %ymm0, -640(%ebp,%ebx,4) + vmovdqu %ymm0, -608(%ebp,%ebx,4) + vmovdqu %ymm0, -576(%ebp,%ebx,4) + vmovdqu %ymm0, -544(%ebp,%ebx,4) + vmovdqu %ymm0, -512(%ebp,%ebx,4) + vmovdqu %ymm0, -480(%ebp,%ebx,4) + vmovdqu %ymm0, -448(%ebp,%ebx,4) + vmovdqu %ymm0, -416(%ebp,%ebx,4) + vmovdqu %ymm0, -384(%ebp,%ebx,4) + vmovdqu %ymm0, -352(%ebp,%ebx,4) + vmovdqu %ymm0, -320(%ebp,%ebx,4) + vmovdqu %ymm0, -288(%ebp,%ebx,4) + vmovdqu %ymm0, -256(%ebp,%ebx,4) + vmovdqu %ymm0, -224(%ebp,%ebx,4) + vmovdqu %ymm0, -192(%ebp,%ebx,4) + vmovdqu %ymm0, -160(%ebp,%ebx,4) + vmovdqu %ymm0, -128(%ebp,%ebx,4) + vmovdqu %ymm0, -96(%ebp,%ebx,4) + vmovdqu %ymm0, -64(%ebp,%ebx,4) + vmovdqu %ymm0, -32(%ebp,%ebx,4) + vmovdqu %ymm0, (%ebp,%ebx,4) + addl $256, %ebx # imm = 0x100 + addl $8, %esi + jne .LBB0_4 +.LBB0_5: + testl %edi, %edi + movl 24(%esp), %eax + je .LBB0_8 +# BB#6: + leal (%eax,%ebx,4), %esi + addl $96, %esi + negl %edi + .p2align 4, 0x90 +.LBB0_7: # =>This Inner Loop Header: Depth=1 + vmovdqu %ymm0, -96(%esi) + vmovdqu %ymm0, -64(%esi) + vmovdqu %ymm0, -32(%esi) + vmovdqu %ymm0, (%esi) + subl $-128, %esi + addl $1, %edi + jne .LBB0_7 +.LBB0_8: + movl (%esp), %edi # 4-byte Reload + cmpl %ecx, %edi + je .LBB0_12 +# BB#9: + leal (%eax,%edi,4), %esi +.LBB0_10: + subl %edi, %ecx + .p2align 4, 0x90 +.LBB0_11: # =>This Inner Loop Header: Depth=1 + movl %edx, (%esi) + addl $4, %esi + addl $-1, %ecx + jne .LBB0_11 +.LBB0_12: + addl $4, %esp + popl %esi + popl %edi + popl %ebx + popl %ebp + vzeroupper + retl +END(WMEMSET) diff --git a/libc/arch-x86/static_function_dispatch.S b/libc/arch-x86/static_function_dispatch.S index 7e8e63d47..1560c042e 100644 --- a/libc/arch-x86/static_function_dispatch.S +++ b/libc/arch-x86/static_function_dispatch.S @@ -45,6 +45,7 @@ FUNCTION_DELEGATE(strcmp, strcmp_generic) FUNCTION_DELEGATE(strncmp, strncmp_generic) FUNCTION_DELEGATE(strcat, strcat_generic) FUNCTION_DELEGATE(wmemcmp, wmemcmp_freebsd) +FUNCTION_DELEGATE(wmemset, wmemset_freebsd) FUNCTION_DELEGATE(wcscat, wcscat_freebsd) FUNCTION_DELEGATE(strncat, strncat_openbsd) FUNCTION_DELEGATE(strlcat, strlcat_openbsd) diff --git a/libc/arch-x86_64/string/avx2-wmemset-kbl.S b/libc/arch-x86_64/string/avx2-wmemset-kbl.S new file mode 100644 index 000000000..7c485cf70 --- /dev/null +++ b/libc/arch-x86_64/string/avx2-wmemset-kbl.S @@ -0,0 +1,140 @@ +/* +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 <private/bionic_asm.h> + +#ifndef WMEMSET + #define WMEMSET wmemset_avx2 +#endif + + .section .text.avx2,"ax",@progbits + +ENTRY (WMEMSET) +# BB#0: + testq %rdx, %rdx + je .LBB0_14 +# BB#1: + cmpq $32, %rdx + jae .LBB0_3 +# BB#2: + xorl %r8d, %r8d + movq %rdi, %rax + jmp .LBB0_12 +.LBB0_3: + movq %rdx, %r8 + andq $-32, %r8 + vmovd %esi, %xmm0 + vpbroadcastd %xmm0, %ymm0 + leaq -32(%r8), %rcx + movq %rcx, %rax + shrq $5, %rax + leal 1(%rax), %r9d + andl $7, %r9d + cmpq $224, %rcx + jae .LBB0_5 +# BB#4: + xorl %eax, %eax + testq %r9, %r9 + jne .LBB0_8 + jmp .LBB0_10 +.LBB0_5: + leaq 992(%rdi), %rcx + leaq -1(%r9), %r10 + subq %rax, %r10 + xorl %eax, %eax + .p2align 4, 0x90 +.LBB0_6: # =>This Inner Loop Header: Depth=1 + vmovdqu %ymm0, -992(%rcx,%rax,4) + vmovdqu %ymm0, -960(%rcx,%rax,4) + vmovdqu %ymm0, -928(%rcx,%rax,4) + vmovdqu %ymm0, -896(%rcx,%rax,4) + vmovdqu %ymm0, -864(%rcx,%rax,4) + vmovdqu %ymm0, -832(%rcx,%rax,4) + vmovdqu %ymm0, -800(%rcx,%rax,4) + vmovdqu %ymm0, -768(%rcx,%rax,4) + vmovdqu %ymm0, -736(%rcx,%rax,4) + vmovdqu %ymm0, -704(%rcx,%rax,4) + vmovdqu %ymm0, -672(%rcx,%rax,4) + vmovdqu %ymm0, -640(%rcx,%rax,4) + vmovdqu %ymm0, -608(%rcx,%rax,4) + vmovdqu %ymm0, -576(%rcx,%rax,4) + vmovdqu %ymm0, -544(%rcx,%rax,4) + vmovdqu %ymm0, -512(%rcx,%rax,4) + vmovdqu %ymm0, -480(%rcx,%rax,4) + vmovdqu %ymm0, -448(%rcx,%rax,4) + vmovdqu %ymm0, -416(%rcx,%rax,4) + vmovdqu %ymm0, -384(%rcx,%rax,4) + vmovdqu %ymm0, -352(%rcx,%rax,4) + vmovdqu %ymm0, -320(%rcx,%rax,4) + vmovdqu %ymm0, -288(%rcx,%rax,4) + vmovdqu %ymm0, -256(%rcx,%rax,4) + vmovdqu %ymm0, -224(%rcx,%rax,4) + vmovdqu %ymm0, -192(%rcx,%rax,4) + vmovdqu %ymm0, -160(%rcx,%rax,4) + vmovdqu %ymm0, -128(%rcx,%rax,4) + vmovdqu %ymm0, -96(%rcx,%rax,4) + vmovdqu %ymm0, -64(%rcx,%rax,4) + vmovdqu %ymm0, -32(%rcx,%rax,4) + vmovdqu %ymm0, (%rcx,%rax,4) + addq $256, %rax # imm = 0x100 + addq $8, %r10 + jne .LBB0_6 +# BB#7: + testq %r9, %r9 + je .LBB0_10 +.LBB0_8: + leaq (%rdi,%rax,4), %rax + addq $96, %rax + negq %r9 + .p2align 4, 0x90 +.LBB0_9: # =>This Inner Loop Header: Depth=1 + vmovdqu %ymm0, -96(%rax) + vmovdqu %ymm0, -64(%rax) + vmovdqu %ymm0, -32(%rax) + vmovdqu %ymm0, (%rax) + subq $-128, %rax + addq $1, %r9 + jne .LBB0_9 +.LBB0_10: + cmpq %rdx, %r8 + je .LBB0_14 +# BB#11: + leaq (%rdi,%r8,4), %rax +.LBB0_12: + subq %r8, %rdx + .p2align 4, 0x90 +.LBB0_13: # =>This Inner Loop Header: Depth=1 + movl %esi, (%rax) + addq $4, %rax + addq $-1, %rdx + jne .LBB0_13 +.LBB0_14: + movq %rdi, %rax + vzeroupper + retq +END(WMEMSET) diff --git a/libc/bionic/NetdClient.cpp b/libc/bionic/NetdClient.cpp index 87eec27b5..d9debbfcd 100644 --- a/libc/bionic/NetdClient.cpp +++ b/libc/bionic/NetdClient.cpp @@ -31,7 +31,7 @@ template <typename FunctionType> static void netdClientInitFunction(void* handle, const char* symbol, FunctionType* function) { typedef void (*InitFunctionType)(FunctionType*); InitFunctionType initFunction = reinterpret_cast<InitFunctionType>(dlsym(handle, symbol)); - if (initFunction != NULL) { + if (initFunction != nullptr) { initFunction(function); } } @@ -45,20 +45,23 @@ static void netdClientInitImpl() { return; } - void* netdClientHandle = dlopen("libnetd_client.so", RTLD_NOW); - if (netdClientHandle == NULL) { + void* handle = dlopen("libnetd_client.so", RTLD_NOW); + if (handle == nullptr) { // If the library is not available, it's not an error. We'll just use // default implementations of functions that it would've overridden. return; } - netdClientInitFunction(netdClientHandle, "netdClientInitAccept4", - &__netdClientDispatch.accept4); - netdClientInitFunction(netdClientHandle, "netdClientInitConnect", - &__netdClientDispatch.connect); - netdClientInitFunction(netdClientHandle, "netdClientInitNetIdForResolv", + + netdClientInitFunction(handle, "netdClientInitAccept4", &__netdClientDispatch.accept4); + netdClientInitFunction(handle, "netdClientInitConnect", &__netdClientDispatch.connect); + netdClientInitFunction(handle, "netdClientInitSendmmsg", &__netdClientDispatch.sendmmsg); + netdClientInitFunction(handle, "netdClientInitSendmsg", &__netdClientDispatch.sendmsg); + netdClientInitFunction(handle, "netdClientInitSendto", &__netdClientDispatch.sendto); + netdClientInitFunction(handle, "netdClientInitSocket", &__netdClientDispatch.socket); + + netdClientInitFunction(handle, "netdClientInitNetIdForResolv", &__netdClientDispatch.netIdForResolv); - netdClientInitFunction(netdClientHandle, "netdClientInitSocket", &__netdClientDispatch.socket); - netdClientInitFunction(netdClientHandle, "netdClientInitDnsOpenProxy", + netdClientInitFunction(handle, "netdClientInitDnsOpenProxy", &__netdClientDispatch.dnsOpenProxy); } diff --git a/libc/bionic/NetdClientDispatch.cpp b/libc/bionic/NetdClientDispatch.cpp index a8731730f..463ef3690 100644 --- a/libc/bionic/NetdClientDispatch.cpp +++ b/libc/bionic/NetdClientDispatch.cpp @@ -16,6 +16,8 @@ #include "private/NetdClientDispatch.h" +#include <sys/socket.h> + #ifdef __i386__ #define __socketcall __attribute__((__cdecl__)) #else @@ -24,6 +26,9 @@ extern "C" __socketcall int __accept4(int, sockaddr*, socklen_t*, int); extern "C" __socketcall int __connect(int, const sockaddr*, socklen_t); +extern "C" __socketcall int __sendmmsg(int, const mmsghdr*, unsigned int, int); +extern "C" __socketcall ssize_t __sendmsg(int, const msghdr*, unsigned int); +extern "C" __socketcall int __sendto(int, const void*, size_t, int, const sockaddr*, socklen_t); extern "C" __socketcall int __socket(int, int, int); static unsigned fallBackNetIdForResolv(unsigned netId) { @@ -39,7 +44,35 @@ static int fallBackDnsOpenProxy() { __LIBC_HIDDEN__ NetdClientDispatch __netdClientDispatch __attribute__((aligned(32))) = { __accept4, __connect, + __sendmmsg, + __sendmsg, + __sendto, __socket, fallBackNetIdForResolv, fallBackDnsOpenProxy, }; + +int accept4(int fd, sockaddr* addr, socklen_t* addr_length, int flags) { + return __netdClientDispatch.accept4(fd, addr, addr_length, flags); +} + +int connect(int fd, const sockaddr* addr, socklen_t addr_length) { + return __netdClientDispatch.connect(fd, addr, addr_length); +} + +int sendmmsg(int fd, const struct mmsghdr* msgs, unsigned int msg_count, int flags) { + return __netdClientDispatch.sendmmsg(fd, msgs, msg_count, flags); +} + +ssize_t sendmsg(int fd, const struct msghdr* msg, int flags) { + return __netdClientDispatch.sendmsg(fd, msg, flags); +} + +ssize_t sendto(int fd, const void* buf, size_t n, int flags, + const struct sockaddr* dst_addr, socklen_t dst_addr_length) { + return __netdClientDispatch.sendto(fd, buf, n, flags, dst_addr, dst_addr_length); +} + +int socket(int domain, int type, int protocol) { + return __netdClientDispatch.socket(domain, type, protocol); +} diff --git a/libc/bionic/__cxa_guard.cpp b/libc/bionic/__cxa_guard.cpp index 30b5f41bd..e2e747791 100644 --- a/libc/bionic/__cxa_guard.cpp +++ b/libc/bionic/__cxa_guard.cpp @@ -16,9 +16,7 @@ #include <endian.h> #include <limits.h> -#undef _USING_LIBCXX // Prevent using of <atomic>. #include <stdatomic.h> - #include <stddef.h> #include "private/bionic_futex.h" diff --git a/libc/bionic/__libc_init_main_thread.cpp b/libc/bionic/__libc_init_main_thread.cpp index 4984e38a1..6e1b0de25 100644 --- a/libc/bionic/__libc_init_main_thread.cpp +++ b/libc/bionic/__libc_init_main_thread.cpp @@ -135,8 +135,11 @@ extern "C" void __libc_init_main_thread_final() { main_thread.mmap_base = mapping.mmap_base; main_thread.mmap_size = mapping.mmap_size; + main_thread.mmap_base_unguarded = mapping.mmap_base_unguarded; + main_thread.mmap_size_unguarded = mapping.mmap_size_unguarded; __set_tls(&new_tcb->tls_slot(0)); + __set_stack_and_tls_vma_name(true); __free_temp_bionic_tls(temp_tls); } diff --git a/libc/bionic/accept4.cpp b/libc/bionic/accept4.cpp deleted file mode 100644 index 9f58dc192..000000000 --- a/libc/bionic/accept4.cpp +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "private/NetdClientDispatch.h" - -#include <sys/socket.h> - -int accept4(int sockfd, sockaddr* addr, socklen_t* addrlen, int flags) { - return __netdClientDispatch.accept4(sockfd, addr, addrlen, flags); -} diff --git a/libc/bionic/bionic_systrace.cpp b/libc/bionic/bionic_systrace.cpp index 6182ed801..1140d2d83 100644 --- a/libc/bionic/bionic_systrace.cpp +++ b/libc/bionic/bionic_systrace.cpp @@ -24,6 +24,7 @@ #include "private/bionic_systrace.h" #include "private/CachedProperty.h" +#include <async_safe/log.h> #include <cutils/trace.h> // For ATRACE_TAG_BIONIC. #define WRITE_OFFSET 32 @@ -65,7 +66,7 @@ void bionic_trace_begin(const char* message) { // kernel trace_marker. int length = strlen(message); char buf[length + WRITE_OFFSET]; - size_t len = snprintf(buf, length + WRITE_OFFSET, "B|%d|%s", getpid(), message); + size_t len = async_safe_format_buffer(buf, length + WRITE_OFFSET, "B|%d|%s", getpid(), message); // Tracing may stop just after checking property and before writing the message. // So the write is acceptable to fail. See b/20666100. diff --git a/libc/bionic/clock_nanosleep.cpp b/libc/bionic/clock_nanosleep.cpp index eade850a0..6f77d83ff 100644 --- a/libc/bionic/clock_nanosleep.cpp +++ b/libc/bionic/clock_nanosleep.cpp @@ -30,11 +30,11 @@ #include "private/ErrnoRestorer.h" -extern "C" int ___clock_nanosleep(clockid_t, int, const timespec*, timespec*); +extern "C" int __clock_nanosleep(clockid_t, int, const timespec*, timespec*); int clock_nanosleep(clockid_t clock_id, int flags, const timespec* in, timespec* out) { if (clock_id == CLOCK_THREAD_CPUTIME_ID) return EINVAL; ErrnoRestorer errno_restorer; - return (___clock_nanosleep(clock_id, flags, in, out) == 0) ? 0 : errno; + return (__clock_nanosleep(clock_id, flags, in, out) == 0) ? 0 : errno; } diff --git a/libc/bionic/connect.cpp b/libc/bionic/connect.cpp deleted file mode 100644 index 1673f4afe..000000000 --- a/libc/bionic/connect.cpp +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "private/NetdClientDispatch.h" - -#include <sys/socket.h> - -int connect(int sockfd, const sockaddr* addr, socklen_t addrlen) { - return __netdClientDispatch.connect(sockfd, addr, addrlen); -} diff --git a/libc/bionic/faccessat.cpp b/libc/bionic/faccessat.cpp index a86aeb2b6..bfaec51fe 100644 --- a/libc/bionic/faccessat.cpp +++ b/libc/bionic/faccessat.cpp @@ -30,7 +30,7 @@ #include <unistd.h> #include <errno.h> -extern "C" int ___faccessat(int, const char*, int); +extern "C" int __faccessat(int, const char*, int); int faccessat(int dirfd, const char* pathname, int mode, int flags) { // "The mode specifies the accessibility check(s) to be performed, @@ -56,5 +56,5 @@ int faccessat(int dirfd, const char* pathname, int mode, int flags) { return -1; } - return ___faccessat(dirfd, pathname, mode); + return __faccessat(dirfd, pathname, mode); } diff --git a/libc/bionic/fchmod.cpp b/libc/bionic/fchmod.cpp index a486aaed1..0326fc2a2 100644 --- a/libc/bionic/fchmod.cpp +++ b/libc/bionic/fchmod.cpp @@ -35,11 +35,11 @@ #include "private/FdPath.h" -extern "C" int ___fchmod(int, mode_t); +extern "C" int __fchmod(int, mode_t); int fchmod(int fd, mode_t mode) { int saved_errno = errno; - int result = ___fchmod(fd, mode); + int result = __fchmod(fd, mode); if (result == 0 || errno != EBADF) { return result; } diff --git a/libc/bionic/fchmodat.cpp b/libc/bionic/fchmodat.cpp index 1f83c4b9b..c28e15ac7 100644 --- a/libc/bionic/fchmodat.cpp +++ b/libc/bionic/fchmodat.cpp @@ -34,7 +34,7 @@ #include "private/ErrnoRestorer.h" -extern "C" int ___fchmodat(int, const char*, mode_t); +extern "C" int __fchmodat(int, const char*, mode_t); int fchmodat(int dirfd, const char* pathname, mode_t mode, int flags) { if ((flags & ~AT_SYMLINK_NOFOLLOW) != 0) { @@ -63,5 +63,5 @@ int fchmodat(int dirfd, const char* pathname, mode_t mode, int flags) { return result; } - return ___fchmodat(dirfd, pathname, mode); + return __fchmodat(dirfd, pathname, mode); } diff --git a/libc/bionic/fdsan.cpp b/libc/bionic/fdsan.cpp index 6440ae059..4ebc796d2 100644 --- a/libc/bionic/fdsan.cpp +++ b/libc/bionic/fdsan.cpp @@ -46,7 +46,7 @@ #include "private/bionic_inline_raise.h" #include "pthread_internal.h" -extern "C" int ___close(int fd); +extern "C" int __close(int fd); pid_t __get_cached_pid(); static constexpr const char* kFdsanPropertyName = "debug.fdsan"; @@ -106,30 +106,8 @@ FdEntry* FdTableImpl<inline_fds>::at(size_t idx) { } void __libc_init_fdsan() { - constexpr auto default_level = ANDROID_FDSAN_ERROR_LEVEL_WARN_ONCE; - const prop_info* pi = __system_property_find(kFdsanPropertyName); - if (!pi) { - android_fdsan_set_error_level(default_level); - return; - } - __system_property_read_callback( - pi, - [](void*, const char*, const char* value, uint32_t) { - if (strcasecmp(value, "1") == 0 || strcasecmp(value, "fatal") == 0) { - android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_FATAL); - } else if (strcasecmp(value, "warn") == 0) { - android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_WARN_ALWAYS); - } else if (strcasecmp(value, "warn_once") == 0) { - android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_WARN_ONCE); - } else { - if (strlen(value) != 0 && strcasecmp(value, "0") != 0) { - async_safe_format_log(ANDROID_LOG_ERROR, "libc", - "debug.fdsan set to unknown value '%s', disabling", value); - } - android_fdsan_set_error_level(default_level); - } - }, - nullptr); + constexpr auto default_level = ANDROID_FDSAN_ERROR_LEVEL_FATAL; + android_fdsan_set_error_level_from_property(default_level); } static FdTable& GetFdTable() { @@ -269,7 +247,7 @@ uint64_t android_fdsan_get_tag_value(uint64_t tag) { int android_fdsan_close_with_tag(int fd, uint64_t expected_tag) { FdEntry* fde = GetFdEntry(fd); if (!fde) { - return ___close(fd); + return __close(fd); } uint64_t tag = expected_tag; @@ -299,7 +277,7 @@ int android_fdsan_close_with_tag(int fd, uint64_t expected_tag) { } } - int rc = ___close(fd); + int rc = __close(fd); // If we were expecting to close with a tag, abort on EBADF. if (expected_tag && rc == -1 && errno == EBADF) { fdsan_error("double-close of file descriptor %d detected", fd); @@ -355,6 +333,45 @@ android_fdsan_error_level android_fdsan_set_error_level(android_fdsan_error_leve return atomic_exchange(&GetFdTable().error_level, new_level); } +android_fdsan_error_level android_fdsan_set_error_level_from_property( + android_fdsan_error_level default_level) { + const prop_info* pi = __system_property_find(kFdsanPropertyName); + if (!pi) { + return android_fdsan_set_error_level(default_level); + } + + struct callback_data { + android_fdsan_error_level default_value; + android_fdsan_error_level result; + }; + + callback_data data; + data.default_value = default_level; + + __system_property_read_callback( + pi, + [](void* arg, const char*, const char* value, uint32_t) { + callback_data* data = static_cast<callback_data*>(arg); + + if (strcasecmp(value, "1") == 0 || strcasecmp(value, "fatal") == 0) { + data->result = android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_FATAL); + } else if (strcasecmp(value, "warn") == 0) { + data->result = android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_WARN_ALWAYS); + } else if (strcasecmp(value, "warn_once") == 0) { + data->result = android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_WARN_ONCE); + } else { + if (strlen(value) != 0 && strcasecmp(value, "0") != 0) { + async_safe_format_log(ANDROID_LOG_ERROR, "libc", + "debug.fdsan set to unknown value '%s', disabling", value); + } + data->result = android_fdsan_set_error_level(data->default_value); + } + }, + &data); + + return data.result; +} + int close(int fd) { int rc = android_fdsan_close_with_tag(fd, 0); if (rc == -1 && errno == EINTR) { diff --git a/libc/bionic/fgetxattr.cpp b/libc/bionic/fgetxattr.cpp index 38b7ac3d5..c7532355b 100644 --- a/libc/bionic/fgetxattr.cpp +++ b/libc/bionic/fgetxattr.cpp @@ -35,11 +35,11 @@ #include "private/FdPath.h" -extern "C" ssize_t ___fgetxattr(int, const char*, void*, size_t); +extern "C" ssize_t __fgetxattr(int, const char*, void*, size_t); ssize_t fgetxattr(int fd, const char *name, void *value, size_t size) { int saved_errno = errno; - ssize_t result = ___fgetxattr(fd, name, value, size); + ssize_t result = __fgetxattr(fd, name, value, size); if (result != -1 || errno != EBADF) { return result; diff --git a/libc/bionic/flistxattr.cpp b/libc/bionic/flistxattr.cpp index 8ad9b857f..3bad3835d 100644 --- a/libc/bionic/flistxattr.cpp +++ b/libc/bionic/flistxattr.cpp @@ -35,11 +35,11 @@ #include "private/FdPath.h" -extern "C" ssize_t ___flistxattr(int, char*, size_t); +extern "C" ssize_t __flistxattr(int, char*, size_t); ssize_t flistxattr(int fd, char *list, size_t size) { int saved_errno = errno; - ssize_t result = ___flistxattr(fd, list, size); + ssize_t result = __flistxattr(fd, list, size); if (result != -1 || errno != EBADF) { return result; } diff --git a/libc/bionic/fork.cpp b/libc/bionic/fork.cpp index fc0020798..cda5e8533 100644 --- a/libc/bionic/fork.cpp +++ b/libc/bionic/fork.cpp @@ -55,6 +55,10 @@ int fork() { // fork, close all of their fds blindly, and then exec. android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_DISABLED); + // Reset the stack_and_tls VMA name so it doesn't end with a tid from the + // parent process. + __set_stack_and_tls_vma_name(true); + __bionic_atfork_run_child(); } else { __bionic_atfork_run_parent(); diff --git a/libc/bionic/fortify.cpp b/libc/bionic/fortify.cpp index 20e265e40..3b804b0b2 100644 --- a/libc/bionic/fortify.cpp +++ b/libc/bionic/fortify.cpp @@ -249,7 +249,7 @@ extern "C" char* __stpncpy_chk(char* dst, const char* src, size_t len, size_t ds // This is a variant of __stpncpy_chk, but it also checks to make // sure we don't read beyond the end of "src". The code for this is // based on the original version of stpncpy, but modified to check -// how much we read from "src" at the end of the copy operation. +// how much we read from "src" during the copy operation. char* __stpncpy_chk2(char* dst, const char* src, size_t n, size_t dst_len, size_t src_len) { __check_buffer_access("stpncpy", "write into", n, dst_len); if (n != 0) { @@ -257,6 +257,11 @@ char* __stpncpy_chk2(char* dst, const char* src, size_t n, size_t dst_len, size_ const char* s = src; do { + size_t s_copy_len = static_cast<size_t>(s - src); + if (__predict_false(s_copy_len >= src_len)) { + __fortify_fatal("stpncpy: detected read past end of %zu-byte buffer", src_len); + } + if ((*d++ = *s++) == 0) { // NUL pad the remaining n-1 bytes. while (--n != 0) { @@ -265,11 +270,6 @@ char* __stpncpy_chk2(char* dst, const char* src, size_t n, size_t dst_len, size_ break; } } while (--n != 0); - - size_t s_copy_len = static_cast<size_t>(s - src); - if (__predict_false(s_copy_len > src_len)) { - __fortify_fatal("stpncpy: detected read past end of %zu-byte buffer", src_len); - } } return dst; @@ -360,7 +360,7 @@ extern "C" char* __strncpy_chk(char* dst, const char* src, size_t len, size_t ds // This is a variant of __strncpy_chk, but it also checks to make // sure we don't read beyond the end of "src". The code for this is // based on the original version of strncpy, but modified to check -// how much we read from "src" at the end of the copy operation. +// how much we read from "src" during the copy operation. char* __strncpy_chk2(char* dst, const char* src, size_t n, size_t dst_len, size_t src_len) { __check_buffer_access("strncpy", "write into", n, dst_len); if (n != 0) { @@ -368,6 +368,11 @@ char* __strncpy_chk2(char* dst, const char* src, size_t n, size_t dst_len, size_ const char* s = src; do { + size_t s_copy_len = static_cast<size_t>(s - src); + if (__predict_false(s_copy_len >= src_len)) { + __fortify_fatal("strncpy: detected read past end of %zu-byte buffer", src_len); + } + if ((*d++ = *s++) == 0) { // NUL pad the remaining n-1 bytes. while (--n != 0) { @@ -376,11 +381,6 @@ char* __strncpy_chk2(char* dst, const char* src, size_t n, size_t dst_len, size_ break; } } while (--n != 0); - - size_t s_copy_len = static_cast<size_t>(s - src); - if (__predict_false(s_copy_len > src_len)) { - __fortify_fatal("strncpy: detected read past end of %zu-byte buffer", src_len); - } } return dst; @@ -500,3 +500,10 @@ extern "C" void* __memcpy_chk(void* dst, const void* src, size_t count, size_t d return memcpy(dst, src, count); } #endif // NO___MEMCPY_CHK + +// Runtime implementation of __mempcpy_chk (used directly by compiler, not in headers). +extern "C" void* __mempcpy_chk(void* dst, const void* src, size_t count, size_t dst_len) { + __check_count("mempcpy", "count", count); + __check_buffer_access("mempcpy", "write into", count, dst_len); + return mempcpy(dst, src, count); +} diff --git a/libc/bionic/fsetxattr.cpp b/libc/bionic/fsetxattr.cpp index 9ad0c76d4..00955bd16 100644 --- a/libc/bionic/fsetxattr.cpp +++ b/libc/bionic/fsetxattr.cpp @@ -35,11 +35,11 @@ #include "private/FdPath.h" -extern "C" int ___fsetxattr(int, const char*, const void*, size_t, int); +extern "C" int __fsetxattr(int, const char*, const void*, size_t, int); int fsetxattr(int fd, const char* name, const void* value, size_t size, int flags) { int saved_errno = errno; - int result = ___fsetxattr(fd, name, value, size, flags); + int result = __fsetxattr(fd, name, value, size, flags); if (result == 0 || errno != EBADF) { return result; } diff --git a/libc/bionic/grp_pwd.cpp b/libc/bionic/grp_pwd.cpp index bd5c27dd1..6f8c07e48 100644 --- a/libc/bionic/grp_pwd.cpp +++ b/libc/bionic/grp_pwd.cpp @@ -26,6 +26,8 @@ * SUCH DAMAGE. */ +#include "private/grp_pwd.h" + #include <android/api-level.h> #include <ctype.h> #include <errno.h> @@ -37,19 +39,32 @@ #include <stdlib.h> #include <string.h> #include <sys/system_properties.h> +#include <sys/types.h> #include <unistd.h> +#include "private/ErrnoRestorer.h" #include "private/android_filesystem_config.h" #include "private/bionic_macros.h" -#include "private/grp_pwd.h" -#include "private/ErrnoRestorer.h" // Generated android_ids array #include "generated_android_ids.h" #include "grp_pwd_file.h" -static PasswdFile vendor_passwd("/vendor/etc/passwd", "vendor_"); -static GroupFile vendor_group("/vendor/etc/group", "vendor_"); +static PasswdFile passwd_files[] = { + { "/system/etc/passwd", "system_" }, + { "/vendor/etc/passwd", "vendor_" }, + { "/odm/etc/passwd", "odm_" }, + { "/product/etc/passwd", "product_" }, + { "/system_ext/etc/passwd", "system_ext_" }, +}; + +static GroupFile group_files[] = { + { "/system/etc/group", "system_" }, + { "/vendor/etc/group", "vendor_" }, + { "/odm/etc/group", "odm_" }, + { "/product/etc/group", "product_" }, + { "/system_ext/etc/group", "system_ext_" }, +}; // POSIX seems to envisage an implementation where the <pwd.h> functions are // implemented by brute-force searching with getpwent(3), and the <grp.h> @@ -89,7 +104,7 @@ static passwd* android_iinfo_to_passwd(passwd_state_t* state, const android_id_info* iinfo) { snprintf(state->name_buffer_, sizeof(state->name_buffer_), "%s", iinfo->name); snprintf(state->dir_buffer_, sizeof(state->dir_buffer_), "/"); - snprintf(state->sh_buffer_, sizeof(state->sh_buffer_), "/system/bin/sh"); + snprintf(state->sh_buffer_, sizeof(state->sh_buffer_), "/bin/sh"); passwd* pw = &state->passwd_; pw->pw_uid = iinfo->aid; @@ -127,10 +142,17 @@ static const android_id_info* find_android_id_info(const char* name) { // These are a list of the reserved app ranges, and should never contain anything below // AID_APP_START. They exist per user, so a given uid/gid modulo AID_USER_OFFSET will map // to these ranges. -static constexpr struct { - uid_t start; - uid_t end; -} user_ranges[] = { +struct IdRange { + id_t start; + id_t end; +}; + +static constexpr IdRange user_ranges[] = { + { AID_APP_START, AID_APP_END }, + { AID_ISOLATED_START, AID_ISOLATED_END }, +}; + +static constexpr IdRange group_ranges[] = { { AID_APP_START, AID_APP_END }, { AID_CACHE_GID_START, AID_CACHE_GID_END }, { AID_EXT_GID_START, AID_EXT_GID_END }, @@ -139,22 +161,40 @@ static constexpr struct { { AID_ISOLATED_START, AID_ISOLATED_END }, }; -static constexpr bool verify_user_ranges_ascending() { - auto array_size = arraysize(user_ranges); +template <class T, size_t N> +static constexpr bool verify_user_ranges_ascending(T (&ranges)[N]) { + auto array_size = N; if (array_size < 2) return false; - if (user_ranges[0].start > user_ranges[0].end) return false; + if (ranges[0].start > ranges[0].end) return false; for (size_t i = 1; i < array_size; ++i) { - if (user_ranges[i].start > user_ranges[i].end) return false; - if (user_ranges[i - 1].end > user_ranges[i].start) return false; + if (ranges[i].start > ranges[i].end) return false; + if (ranges[i - 1].end > ranges[i].start) return false; } return true; } -static_assert(verify_user_ranges_ascending(), "user_ranges must have ascending ranges"); +static_assert(verify_user_ranges_ascending(user_ranges), "user_ranges must have ascending ranges"); +static_assert(verify_user_ranges_ascending(group_ranges), "user_ranges must have ascending ranges"); -static bool is_valid_app_id(id_t id) { +// This list comes from PackageManagerService.java, where platform AIDs are added to list of valid +// AIDs for packages via addSharedUserLPw(). +static constexpr const id_t secondary_user_platform_ids[] = { + AID_SYSTEM, AID_RADIO, AID_LOG, AID_NFC, AID_BLUETOOTH, + AID_SHELL, AID_SECURE_ELEMENT, AID_NETWORK_STACK, +}; + +static bool platform_id_secondary_user_allowed(id_t id) { + for (const auto& allowed_id : secondary_user_platform_ids) { + if (allowed_id == id) { + return true; + } + } + return false; +} + +static bool is_valid_app_id(id_t id, bool is_group) { id_t appid = id % AID_USER_OFFSET; // AID_OVERFLOWUID is never a valid app id, so we explicitly return false to ensure this. @@ -163,15 +203,23 @@ static bool is_valid_app_id(id_t id) { return false; } - // If we've resolved to something before app_start, we have already checked against - // android_ids, so no need to check again. - if (appid < user_ranges[0].start) { + auto ranges_size = is_group ? arraysize(group_ranges) : arraysize(user_ranges); + auto ranges = is_group ? group_ranges : user_ranges; + + // If we're checking an appid that resolves below the user range, then it's a platform AID for a + // seconary user. We only allow a reduced set of these, so we must check that it is allowed. + if (appid < ranges[0].start && platform_id_secondary_user_allowed(appid)) { return true; } + // The shared GID range is only valid for the first user. + if (appid >= AID_SHARED_GID_START && appid <= AID_SHARED_GID_END && appid != id) { + return false; + } + // Otherwise check that the appid is in one of the reserved ranges. - for (size_t i = 0; i < arraysize(user_ranges); ++i) { - if (appid >= user_ranges[i].start && appid <= user_ranges[i].end) { + for (size_t i = 0; i < ranges_size; ++i) { + if (appid >= ranges[i].start && appid <= ranges[i].end) { return true; } } @@ -180,26 +228,29 @@ static bool is_valid_app_id(id_t id) { } // This provides an iterater for app_ids within the first user's app id's. -static uid_t get_next_app_id(uid_t current_id) { - // If current_id is below the first of the user_ranges, then we're uninitialized, and return the - // first valid id. - if (current_id < user_ranges[0].start) { - return user_ranges[0].start; +static id_t get_next_app_id(id_t current_id, bool is_group) { + auto ranges_size = is_group ? arraysize(group_ranges) : arraysize(user_ranges); + auto ranges = is_group ? group_ranges : user_ranges; + + // If current_id is below the first of the ranges, then we're uninitialized, and return the first + // valid id. + if (current_id < ranges[0].start) { + return ranges[0].start; } - uid_t incremented_id = current_id + 1; + id_t incremented_id = current_id + 1; // Check to see if our incremented_id is between two ranges, and if so, return the beginning of // the next valid range. - for (size_t i = 1; i < arraysize(user_ranges); ++i) { - if (incremented_id > user_ranges[i - 1].end && incremented_id < user_ranges[i].start) { - return user_ranges[i].start; + for (size_t i = 1; i < ranges_size; ++i) { + if (incremented_id > ranges[i - 1].end && incremented_id < ranges[i].start) { + return ranges[i].start; } } // Check to see if our incremented_id is above final range, and return -1 to indicate that we've // completed if so. - if (incremented_id > user_ranges[arraysize(user_ranges) - 1].end) { + if (incremented_id > ranges[ranges_size - 1].end) { return -1; } @@ -209,6 +260,8 @@ static uid_t get_next_app_id(uid_t current_id) { // Translate a user/group name to the corresponding user/group id. // all_a1234 -> 0 * AID_USER_OFFSET + AID_SHARED_GID_START + 1234 (group name only) +// u0_a1234_ext_cache -> 0 * AID_USER_OFFSET + AID_EXT_CACHE_GID_START + 1234 (group name only) +// u0_a1234_ext -> 0 * AID_USER_OFFSET + AID_EXT_GID_START + 1234 (group name only) // u0_a1234_cache -> 0 * AID_USER_OFFSET + AID_CACHE_GID_START + 1234 (group name only) // u0_a1234 -> 0 * AID_USER_OFFSET + AID_APP_START + 1234 // u2_i1000 -> 2 * AID_USER_OFFSET + AID_ISOLATED_START + 1000 @@ -247,9 +300,19 @@ static id_t app_id_from_name(const char* name, bool is_group) { } else { // end will point to \0 if the strtoul below succeeds. appid = strtoul(end+2, &end, 10); - if (is_group && !strcmp(end, "_cache")) { - end += 6; - appid += AID_CACHE_GID_START; + if (is_group) { + if (!strcmp(end, "_ext_cache")) { + end += 10; + appid += AID_EXT_CACHE_GID_START; + } else if (!strcmp(end, "_ext")) { + end += 4; + appid += AID_EXT_GID_START; + } else if (!strcmp(end, "_cache")) { + end += 6; + appid += AID_CACHE_GID_START; + } else { + appid += AID_APP_START; + } } else { appid += AID_APP_START; } @@ -260,6 +323,10 @@ static id_t app_id_from_name(const char* name, bool is_group) { } else if (auto* android_id_info = find_android_id_info(end + 1); android_id_info != nullptr) { appid = android_id_info->aid; end += strlen(android_id_info->name) + 1; + if (!platform_id_secondary_user_allowed(appid)) { + errno = ENOENT; + return 0; + } } // Check that the entire string was consumed by one of the 3 cases above. @@ -304,6 +371,10 @@ static void print_app_name_from_gid(const gid_t gid, char* buffer, const int buf snprintf(buffer, bufferlen, "u%u_i%u", userid, appid - AID_ISOLATED_START); } else if (userid == 0 && appid >= AID_SHARED_GID_START && appid <= AID_SHARED_GID_END) { snprintf(buffer, bufferlen, "all_a%u", appid - AID_SHARED_GID_START); + } else if (appid >= AID_EXT_CACHE_GID_START && appid <= AID_EXT_CACHE_GID_END) { + snprintf(buffer, bufferlen, "u%u_a%u_ext_cache", userid, appid - AID_EXT_CACHE_GID_START); + } else if (appid >= AID_EXT_GID_START && appid <= AID_EXT_GID_END) { + snprintf(buffer, bufferlen, "u%u_a%u_ext", userid, appid - AID_EXT_GID_START); } else if (appid >= AID_CACHE_GID_START && appid <= AID_CACHE_GID_END) { snprintf(buffer, bufferlen, "u%u_a%u_cache", userid, appid - AID_CACHE_GID_START); } else if (appid < AID_APP_START) { @@ -363,17 +434,19 @@ static id_t oem_id_from_name(const char* name) { } static passwd* oem_id_to_passwd(uid_t uid, passwd_state_t* state) { - if (!is_oem_id(uid)) { - return nullptr; + for (auto& passwd_file : passwd_files) { + if (passwd_file.FindById(uid, state)) { + return &state->passwd_; + } } - if (vendor_passwd.FindById(uid, state)) { - return &state->passwd_; + if (!is_oem_id(uid)) { + return nullptr; } snprintf(state->name_buffer_, sizeof(state->name_buffer_), "oem_%u", uid); snprintf(state->dir_buffer_, sizeof(state->dir_buffer_), "/"); - snprintf(state->sh_buffer_, sizeof(state->sh_buffer_), "/vendor/bin/sh"); + snprintf(state->sh_buffer_, sizeof(state->sh_buffer_), "/bin/sh"); passwd* pw = &state->passwd_; pw->pw_uid = uid; @@ -382,12 +455,14 @@ static passwd* oem_id_to_passwd(uid_t uid, passwd_state_t* state) { } static group* oem_id_to_group(gid_t gid, group_state_t* state) { - if (!is_oem_id(gid)) { - return nullptr; + for (auto& group_file : group_files) { + if (group_file.FindById(gid, state)) { + return &state->group_; + } } - if (vendor_group.FindById(gid, state)) { - return &state->group_; + if (!is_oem_id(gid)) { + return nullptr; } snprintf(state->group_name_buffer_, sizeof(state->group_name_buffer_), @@ -405,7 +480,7 @@ static group* oem_id_to_group(gid_t gid, group_state_t* state) { // AID_USER_OFFSET+ -> u1_radio, u1_a1234, u2_i1234, etc. // returns a passwd structure (sets errno to ENOENT on failure). static passwd* app_id_to_passwd(uid_t uid, passwd_state_t* state) { - if (uid < AID_APP_START || !is_valid_app_id(uid)) { + if (uid < AID_APP_START || !is_valid_app_id(uid, false)) { errno = ENOENT; return nullptr; } @@ -419,7 +494,7 @@ static passwd* app_id_to_passwd(uid_t uid, passwd_state_t* state) { snprintf(state->dir_buffer_, sizeof(state->dir_buffer_), "/data"); } - snprintf(state->sh_buffer_, sizeof(state->sh_buffer_), "/system/bin/sh"); + snprintf(state->sh_buffer_, sizeof(state->sh_buffer_), "/bin/sh"); passwd* pw = &state->passwd_; pw->pw_uid = uid; @@ -430,7 +505,7 @@ static passwd* app_id_to_passwd(uid_t uid, passwd_state_t* state) { // Translate a gid into the corresponding app_<gid> // group structure (sets errno to ENOENT on failure). static group* app_id_to_group(gid_t gid, group_state_t* state) { - if (gid < AID_APP_START || !is_valid_app_id(gid)) { + if (gid < AID_APP_START || !is_valid_app_id(gid, true)) { errno = ENOENT; return nullptr; } @@ -465,8 +540,8 @@ passwd* getpwnam_internal(const char* login, passwd_state_t* state) { return android_iinfo_to_passwd(state, android_id_info); } - if (vendor_passwd.FindByName(login, state)) { - if (is_oem_id(state->passwd_.pw_uid)) { + for (auto& passwd_file : passwd_files) { + if (passwd_file.FindByName(login, state)) { return &state->passwd_; } } @@ -575,7 +650,23 @@ passwd* getpwent() { state->getpwent_idx++ - start + AID_OEM_RESERVED_2_START, state); } - state->getpwent_idx = get_next_app_id(state->getpwent_idx); + start = end; + end += AID_SYSTEM_EXT_RESERVED_END - AID_SYSTEM_RESERVED_START + 1; + + if (state->getpwent_idx < end) { + // No one calls this enough to worry about how inefficient the below is. + auto* oem_passwd = + oem_id_to_passwd(state->getpwent_idx++ - start + AID_SYSTEM_RESERVED_START, state); + while (oem_passwd == nullptr && state->getpwent_idx < end) { + oem_passwd = + oem_id_to_passwd(state->getpwent_idx++ - start + AID_SYSTEM_RESERVED_START, state); + } + if (oem_passwd != nullptr) { + return oem_passwd; + } + } + + state->getpwent_idx = get_next_app_id(state->getpwent_idx, false); if (state->getpwent_idx != -1) { return app_id_to_passwd(state->getpwent_idx, state); @@ -608,8 +699,8 @@ static group* getgrnam_internal(const char* name, group_state_t* state) { return android_iinfo_to_group(state, android_id_info); } - if (vendor_group.FindByName(name, state)) { - if (is_oem_id(state->group_.gr_gid)) { + for (auto& group_file : group_files) { + if (group_file.FindByName(name, state)) { return &state->group_; } } @@ -696,9 +787,25 @@ group* getgrent() { } start = end; + end += AID_SYSTEM_EXT_RESERVED_END - AID_SYSTEM_RESERVED_START + 1; + + if (state->getgrent_idx < end) { + // No one calls this enough to worry about how inefficient the below is. + init_group_state(state); + auto* oem_group = + oem_id_to_group(state->getgrent_idx++ - start + AID_SYSTEM_RESERVED_START, state); + while (oem_group == nullptr && state->getgrent_idx < end) { + oem_group = oem_id_to_group(state->getgrent_idx++ - start + AID_SYSTEM_RESERVED_START, state); + } + if (oem_group != nullptr) { + return oem_group; + } + } + + start = end; end += AID_USER_OFFSET - AID_APP_START; // Do not expose higher groups - state->getgrent_idx = get_next_app_id(state->getgrent_idx); + state->getgrent_idx = get_next_app_id(state->getgrent_idx, true); if (state->getgrent_idx != -1) { return app_id_to_group(state->getgrent_idx, state); diff --git a/libc/bionic/grp_pwd_file.cpp b/libc/bionic/grp_pwd_file.cpp index 201c9d084..e13604e68 100644 --- a/libc/bionic/grp_pwd_file.cpp +++ b/libc/bionic/grp_pwd_file.cpp @@ -270,8 +270,8 @@ bool MmapFile::Find(Line* line, Predicate predicate) { while (line_beginning < end) { line_beginning = ParseLine(line_beginning, end, line->fields, line->kNumFields); - // To comply with Treble, users/groups from the vendor partition need to be prefixed with - // vendor_. + // To comply with Treble, users/groups from each partition need to be prefixed with + // the partition name. if (required_prefix_ != nullptr) { if (strncmp(line->fields[0], required_prefix_, strlen(required_prefix_)) != 0) { char name[kGrpPwdBufferSize]; diff --git a/libc/bionic/jemalloc.h b/libc/bionic/jemalloc.h index b9a4e993c..ef77c9c99 100644 --- a/libc/bionic/jemalloc.h +++ b/libc/bionic/jemalloc.h @@ -30,7 +30,7 @@ __BEGIN_DECLS void* je_aligned_alloc_wrapper(size_t, size_t); int je_iterate(uintptr_t, size_t, void (*)(uintptr_t, size_t, void*), void*); -int je_mallctl(const char *name, void *oldp, size_t *oldlenp, void *newp, size_t newlen); +int je_mallctl(const char *name, void *oldp, size_t *oldlenp, void *newp, size_t newlen) __attribute__((nothrow)); struct mallinfo je_mallinfo(); void je_malloc_disable(); void je_malloc_enable(); diff --git a/libc/bionic/libc_init_dynamic.cpp b/libc/bionic/libc_init_dynamic.cpp index 4f3b4f7d1..d6d5552d1 100644 --- a/libc/bionic/libc_init_dynamic.cpp +++ b/libc/bionic/libc_init_dynamic.cpp @@ -69,6 +69,13 @@ extern "C" { __LIBC_HIDDEN__ void* __libc_sysinfo = reinterpret_cast<void*>(__libc_int0x80); #endif +extern "C" __attribute__((weak)) void __hwasan_library_loaded(ElfW(Addr) base, + const ElfW(Phdr)* phdr, + ElfW(Half) phnum); +extern "C" __attribute__((weak)) void __hwasan_library_unloaded(ElfW(Addr) base, + const ElfW(Phdr)* phdr, + ElfW(Half) phnum); + // We need a helper function for __libc_preinit because compiling with LTO may // inline functions requiring a stack protector check, but __stack_chk_guard is // not initialized at the start of __libc_preinit. __libc_preinit_impl will run @@ -91,6 +98,14 @@ static void __libc_preinit_impl() { // Hooks for various libraries to let them know that we're starting up. __libc_globals.mutate(__libc_init_malloc); + +#if __has_feature(hwaddress_sanitizer) + // Notify the HWASan runtime library whenever a library is loaded or unloaded + // so that it can update its shadow memory. + __libc_shared_globals()->load_hook = __hwasan_library_loaded; + __libc_shared_globals()->unload_hook = __hwasan_library_unloaded; +#endif + netdClientInit(); } diff --git a/libc/bionic/malloc_heapprofd.cpp b/libc/bionic/malloc_heapprofd.cpp index 5d3735d27..d0117f382 100644 --- a/libc/bionic/malloc_heapprofd.cpp +++ b/libc/bionic/malloc_heapprofd.cpp @@ -116,6 +116,7 @@ static void MaybeInstallInitHeapprofdHook(int) { // Zygote child processes must be marked profileable. if (gZygoteChild && !atomic_load_explicit(&gZygoteChildProfileable, memory_order_acquire)) { + error_log("%s: not enabling heapprofd, not marked profileable.", getprogname()); return; } diff --git a/libc/bionic/malloc_limit.cpp b/libc/bionic/malloc_limit.cpp index b42865bf1..6a67cae95 100644 --- a/libc/bionic/malloc_limit.cpp +++ b/libc/bionic/malloc_limit.cpp @@ -113,7 +113,7 @@ static inline void* IncrementLimit(void* mem) { void* LimitCalloc(size_t n_elements, size_t elem_size) { size_t total; - if (__builtin_add_overflow(n_elements, elem_size, &total) || !CheckLimit(total)) { + if (__builtin_mul_overflow(n_elements, elem_size, &total) || !CheckLimit(total)) { warning_log("malloc_limit: calloc(%zu, %zu) exceeds limit %" PRId64, n_elements, elem_size, gAllocLimit); return nullptr; diff --git a/libc/bionic/mremap.cpp b/libc/bionic/mremap.cpp index 896ccef16..a4e5323f7 100644 --- a/libc/bionic/mremap.cpp +++ b/libc/bionic/mremap.cpp @@ -34,7 +34,7 @@ #include "private/bionic_macros.h" -extern "C" void* ___mremap(void*, size_t, size_t, int, void*); +extern "C" void* __mremap(void*, size_t, size_t, int, void*); void* mremap(void* old_address, size_t old_size, size_t new_size, int flags, ...) { // prevent allocations large enough for `end - start` to overflow @@ -53,5 +53,5 @@ void* mremap(void* old_address, size_t old_size, size_t new_size, int flags, ... new_address = va_arg(ap, void*); va_end(ap); } - return ___mremap(old_address, old_size, new_size, flags, new_address); + return __mremap(old_address, old_size, new_size, flags, new_address); } diff --git a/libc/bionic/ndk_cruft.cpp b/libc/bionic/ndk_cruft.cpp index 2c3299f7b..f0a7026c7 100644 --- a/libc/bionic/ndk_cruft.cpp +++ b/libc/bionic/ndk_cruft.cpp @@ -243,15 +243,23 @@ sighandler_t bsd_signal(int signum, sighandler_t handler) { return signal(signum, handler); } +// bcopy/bzero were previously `#define`d, so we only have `static` wrappers in +// Bionic headers. Since we have header definitions, we need some way to +// overload these implementations; __never_call will ensure that any calls to +// bcopy/bzero call the in-header implementation. Since the implementations +// should end up functionally identical, it doesn't matter which we actually +// call. +#define __never_call __attribute__((enable_if(false, "never selected"))) + // This was removed from POSIX 2008. -#undef bcopy -void bcopy(const void* src, void* dst, size_t n) { +void bcopy(const void* src, void* dst, size_t n) __never_call __RENAME(bcopy); +void bcopy(const void* src, void* dst, size_t n) __never_call { memmove(dst, src, n); } // This was removed from POSIX 2008. -#undef bzero -void bzero(void* dst, size_t n) { +void bzero(void* dst, size_t n) __never_call __RENAME(bzero); +void bzero(void* dst, size_t n) __never_call { memset(dst, 0, n); } diff --git a/libc/bionic/open.cpp b/libc/bionic/open.cpp index 222e5d3f4..df5ab215b 100644 --- a/libc/bionic/open.cpp +++ b/libc/bionic/open.cpp @@ -70,6 +70,7 @@ int __open_2(const char* pathname, int flags) { if (needs_mode(flags)) __fortify_fatal("open: called with O_CREAT/O_TMPFILE but no mode"); return __openat(AT_FDCWD, pathname, force_O_LARGEFILE(flags), 0); } +__strong_alias(__open64_2, __open_2); int openat(int fd, const char *pathname, int flags, ...) { mode_t mode = 0; @@ -89,3 +90,4 @@ int __openat_2(int fd, const char* pathname, int flags) { if (needs_mode(flags)) __fortify_fatal("open: called with O_CREAT/O_TMPFILE but no mode"); return __openat(fd, pathname, force_O_LARGEFILE(flags), 0); } +__strong_alias(__openat64_2, __openat_2); diff --git a/libc/bionic/pthread_cond.cpp b/libc/bionic/pthread_cond.cpp index 9f0f8fa3c..e85706902 100644 --- a/libc/bionic/pthread_cond.cpp +++ b/libc/bionic/pthread_cond.cpp @@ -215,6 +215,18 @@ extern "C" int pthread_cond_timedwait_monotonic_np(pthread_cond_t* cond_interfac return __pthread_cond_timedwait(__get_internal_cond(cond_interface), mutex, false, abs_timeout); } +int pthread_cond_clockwait(pthread_cond_t* cond_interface, pthread_mutex_t* mutex, clockid_t clock, + const struct timespec* abs_timeout) { + switch (clock) { + case CLOCK_MONOTONIC: + return pthread_cond_timedwait_monotonic_np(cond_interface, mutex, abs_timeout); + case CLOCK_REALTIME: + return __pthread_cond_timedwait(__get_internal_cond(cond_interface), mutex, true, abs_timeout); + default: + return EINVAL; + } +} + #if !defined(__LP64__) // TODO: this exists only for backward binary compatibility on 32 bit platforms. extern "C" int pthread_cond_timedwait_monotonic(pthread_cond_t* cond_interface, diff --git a/libc/bionic/pthread_create.cpp b/libc/bionic/pthread_create.cpp index 4cf14ad72..0dbf53949 100644 --- a/libc/bionic/pthread_create.cpp +++ b/libc/bionic/pthread_create.cpp @@ -254,6 +254,8 @@ ThreadMapping __allocate_thread_mapping(size_t stack_size, size_t stack_guard_si ThreadMapping result = {}; result.mmap_base = space; result.mmap_size = mmap_size; + result.mmap_base_unguarded = space + stack_guard_size; + result.mmap_size_unguarded = mmap_size - stack_guard_size - PTHREAD_GUARD_SIZE; result.static_tls = space + mmap_size - PTHREAD_GUARD_SIZE - layout.size(); result.stack_base = space; result.stack_top = result.static_tls; @@ -315,12 +317,33 @@ static int __allocate_thread(pthread_attr_t* attr, bionic_tcb** tcbp, void** chi thread->attr = *attr; thread->mmap_base = mapping.mmap_base; thread->mmap_size = mapping.mmap_size; + thread->mmap_base_unguarded = mapping.mmap_base_unguarded; + thread->mmap_size_unguarded = mapping.mmap_size_unguarded; *tcbp = tcb; *child_stack = stack_top; return 0; } +void __set_stack_and_tls_vma_name(bool is_main_thread) { + // Name the thread's stack-and-tls area to help with debugging. This mapped area also includes + // static TLS data, which is typically a few pages (e.g. bionic_tls). + pthread_internal_t* thread = __get_thread(); + const char* name; + if (is_main_thread) { + name = "stack_and_tls:main"; + } else { + // The kernel doesn't copy the name string, but this variable will last at least as long as the + // mapped area. The mapped area's VMAs are unmapped with a single call to munmap. + auto& name_buffer = thread->vma_name_buffer; + static_assert(arraysize(name_buffer) >= arraysize("stack_and_tls:") + 11 + 1); + async_safe_format_buffer(name_buffer, arraysize(name_buffer), "stack_and_tls:%d", thread->tid); + name = name_buffer; + } + prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, thread->mmap_base_unguarded, thread->mmap_size_unguarded, + name); +} + __attribute__((no_sanitize("hwaddress"))) static int __pthread_start(void* arg) { pthread_internal_t* thread = reinterpret_cast<pthread_internal_t*>(arg); @@ -333,6 +356,7 @@ static int __pthread_start(void* arg) { // accesses previously made by the creating thread are visible to us. thread->startup_handshake_lock.lock(); + __set_stack_and_tls_vma_name(false); __init_additional_stacks(thread); void* result = thread->start_routine(thread->start_routine_arg); diff --git a/libc/bionic/pthread_internal.h b/libc/bionic/pthread_internal.h index a1e0c450a..22cc4000d 100644 --- a/libc/bionic/pthread_internal.h +++ b/libc/bionic/pthread_internal.h @@ -129,6 +129,11 @@ class pthread_internal_t { void* mmap_base; size_t mmap_size; + // The location of the VMA to label as the thread's stack_and_tls. + void* mmap_base_unguarded; + size_t mmap_size_unguarded; + char vma_name_buffer[32]; + thread_local_dtor* thread_local_dtors; /* @@ -147,6 +152,8 @@ class pthread_internal_t { struct ThreadMapping { char* mmap_base; size_t mmap_size; + char* mmap_base_unguarded; + size_t mmap_size_unguarded; char* static_tls; char* stack_base; @@ -162,6 +169,7 @@ __LIBC_HIDDEN__ void __free_temp_bionic_tls(bionic_tls* tls); __LIBC_HIDDEN__ void __init_additional_stacks(pthread_internal_t*); __LIBC_HIDDEN__ int __init_thread(pthread_internal_t* thread); __LIBC_HIDDEN__ ThreadMapping __allocate_thread_mapping(size_t stack_size, size_t stack_guard_size); +__LIBC_HIDDEN__ void __set_stack_and_tls_vma_name(bool is_main_thread); __LIBC_HIDDEN__ pthread_t __pthread_internal_add(pthread_internal_t* thread); __LIBC_HIDDEN__ pthread_internal_t* __pthread_internal_find(pthread_t pthread_id, const char* caller); diff --git a/libc/bionic/pthread_mutex.cpp b/libc/bionic/pthread_mutex.cpp index 37031ad6b..de62a5c01 100644 --- a/libc/bionic/pthread_mutex.cpp +++ b/libc/bionic/pthread_mutex.cpp @@ -989,6 +989,24 @@ int pthread_mutex_timedlock_monotonic_np(pthread_mutex_t* mutex_interface, return __pthread_mutex_timedlock(mutex_interface, false, abs_timeout, __FUNCTION__); } +int pthread_mutex_clocklock(pthread_mutex_t* mutex_interface, clockid_t clock, + const struct timespec* abs_timeout) { + switch (clock) { + case CLOCK_MONOTONIC: + return __pthread_mutex_timedlock(mutex_interface, false, abs_timeout, __FUNCTION__); + case CLOCK_REALTIME: + return __pthread_mutex_timedlock(mutex_interface, true, abs_timeout, __FUNCTION__); + default: { + pthread_mutex_internal_t* mutex = __get_internal_mutex(mutex_interface); + uint16_t old_state = atomic_load_explicit(&mutex->state, memory_order_relaxed); + if (IsMutexDestroyed(old_state)) { + return HandleUsingDestroyedMutex(mutex_interface, __FUNCTION__); + } + return EINVAL; + } + } +} + int pthread_mutex_destroy(pthread_mutex_t* mutex_interface) { pthread_mutex_internal_t* mutex = __get_internal_mutex(mutex_interface); uint16_t old_state = atomic_load_explicit(&mutex->state, memory_order_relaxed); diff --git a/libc/bionic/pthread_rwlock.cpp b/libc/bionic/pthread_rwlock.cpp index 2b9be98d7..ebf6697a0 100644 --- a/libc/bionic/pthread_rwlock.cpp +++ b/libc/bionic/pthread_rwlock.cpp @@ -429,6 +429,18 @@ int pthread_rwlock_timedrdlock_monotonic_np(pthread_rwlock_t* rwlock_interface, return __pthread_rwlock_timedrdlock(rwlock, false, abs_timeout); } +int pthread_rwlock_clockrdlock(pthread_rwlock_t* rwlock_interface, clockid_t clock, + const struct timespec* abs_timeout) { + switch (clock) { + case CLOCK_MONOTONIC: + return pthread_rwlock_timedrdlock_monotonic_np(rwlock_interface, abs_timeout); + case CLOCK_REALTIME: + return pthread_rwlock_timedrdlock(rwlock_interface, abs_timeout); + default: + return EINVAL; + } +} + int pthread_rwlock_tryrdlock(pthread_rwlock_t* rwlock_interface) { return __pthread_rwlock_tryrdlock(__get_internal_rwlock(rwlock_interface)); } @@ -455,6 +467,18 @@ int pthread_rwlock_timedwrlock_monotonic_np(pthread_rwlock_t* rwlock_interface, return __pthread_rwlock_timedwrlock(rwlock, false, abs_timeout); } +int pthread_rwlock_clockwrlock(pthread_rwlock_t* rwlock_interface, clockid_t clock, + const struct timespec* abs_timeout) { + switch (clock) { + case CLOCK_MONOTONIC: + return pthread_rwlock_timedwrlock_monotonic_np(rwlock_interface, abs_timeout); + case CLOCK_REALTIME: + return pthread_rwlock_timedwrlock(rwlock_interface, abs_timeout); + default: + return EINVAL; + } +} + int pthread_rwlock_trywrlock(pthread_rwlock_t* rwlock_interface) { return __pthread_rwlock_trywrlock(__get_internal_rwlock(rwlock_interface)); } diff --git a/libc/bionic/semaphore.cpp b/libc/bionic/semaphore.cpp index e0486b4dd..455e36b27 100644 --- a/libc/bionic/semaphore.cpp +++ b/libc/bionic/semaphore.cpp @@ -275,6 +275,17 @@ int sem_timedwait_monotonic_np(sem_t* sem, const timespec* abs_timeout) { return __sem_timedwait(sem, abs_timeout, false); } +int sem_clockwait(sem_t* sem, clockid_t clock, const timespec* abs_timeout) { + switch (clock) { + case CLOCK_MONOTONIC: + return sem_timedwait_monotonic_np(sem, abs_timeout); + case CLOCK_REALTIME: + return sem_timedwait(sem, abs_timeout); + default: + return EINVAL; + } +} + int sem_post(sem_t* sem) { atomic_uint* sem_count_ptr = SEM_TO_ATOMIC_POINTER(sem); unsigned int shared = SEM_GET_SHARED(sem_count_ptr); diff --git a/libc/bionic/signal.cpp b/libc/bionic/signal.cpp index d6be09a6f..8246cb4af 100644 --- a/libc/bionic/signal.cpp +++ b/libc/bionic/signal.cpp @@ -41,7 +41,7 @@ #include "private/sigrtmin.h" extern "C" int __rt_sigpending(const sigset64_t*, size_t); -extern "C" int ___rt_sigqueueinfo(pid_t, int, siginfo_t*); +extern "C" int __rt_sigqueueinfo(pid_t, int, siginfo_t*); extern "C" int __rt_sigsuspend(const sigset64_t*, size_t); extern "C" int __rt_sigtimedwait(const sigset64_t*, siginfo_t*, const timespec*, size_t); @@ -216,7 +216,7 @@ int sigqueue(pid_t pid, int sig, const sigval value) { info.si_pid = getpid(); info.si_uid = getuid(); info.si_value = value; - return ___rt_sigqueueinfo(pid, sig, &info); + return __rt_sigqueueinfo(pid, sig, &info); } int sigrelse(int sig) { diff --git a/libc/include/android/fdsan.h b/libc/include/android/fdsan.h index 1169ed046..83b9318ba 100644 --- a/libc/include/android/fdsan.h +++ b/libc/include/android/fdsan.h @@ -197,4 +197,8 @@ enum android_fdsan_error_level android_fdsan_get_error_level() __INTRODUCED_IN(2 */ enum android_fdsan_error_level android_fdsan_set_error_level(enum android_fdsan_error_level new_level) __INTRODUCED_IN(29) __attribute__((__weak__)); +/* + * Set the error level to the global setting if available, or a default value. + */ +enum android_fdsan_error_level android_fdsan_set_error_level_from_property(enum android_fdsan_error_level default_level) __INTRODUCED_IN(30) __attribute__((__weak__)); __END_DECLS diff --git a/libc/include/android/legacy_signal_inlines.h b/libc/include/android/legacy_signal_inlines.h index 5ca9813f3..d2c767703 100644 --- a/libc/include/android/legacy_signal_inlines.h +++ b/libc/include/android/legacy_signal_inlines.h @@ -52,7 +52,7 @@ static __inline int __ndk_legacy___libc_current_sigrtmax() { static __inline int __ndk_legacy___libc_current_sigrtmin() { if (__libc_current_sigrtmin) return __libc_current_sigrtmin(); - return __SIGRTMIN + 6; /* Should match __libc_current_sigrtmin. */ + return __SIGRTMIN + 7; /* Should match __libc_current_sigrtmin. */ } #undef SIGRTMAX diff --git a/libc/include/arpa/nameser.h b/libc/include/arpa/nameser.h index e0b5c4514..89ece1c5e 100644 --- a/libc/include/arpa/nameser.h +++ b/libc/include/arpa/nameser.h @@ -591,33 +591,29 @@ int ns_samename(const char* __lhs, const char* __rhs); /* The names of these symbols were accidentally prefixed with __ in L. */ /* The duplication here is intentional to avoid declaring different symbols with the same * declaration. */ -int ns_msg_getflag(ns_msg __handle, int __flag) __INTRODUCED_IN_64(23); -uint16_t ns_get16(const u_char* __src) __INTRODUCED_IN_64(23); -uint32_t ns_get32(const u_char* __src) __INTRODUCED_IN_64(23); -void ns_put16(uint16_t __src, u_char* __dst) __INTRODUCED_IN_64(23); -void ns_put32(uint32_t __src, u_char* __dst) __INTRODUCED_IN_64(23); -int ns_initparse(const u_char* __msg, int __msg_size, ns_msg* __handle) __INTRODUCED_IN_64(23); -int ns_skiprr(const u_char* __ptr, const u_char* __eom, ns_sect __section, int __count) __INTRODUCED_IN_64(23); -int ns_parserr(ns_msg* __handle, ns_sect __section, int __rr_number, ns_rr* __rr) __INTRODUCED_IN_64(23); -int ns_sprintrr(const ns_msg* __handle, const ns_rr* __rr, const char* __name_ctx, const char* __origin, char* __buf, size_t __buf_size) - __INTRODUCED_IN_64(23); -int ns_sprintrrf(const u_char* __msg, size_t __msg_size, const char* __name, ns_class __class, ns_type __type, u_long __ttl, const u_char* __rdata, size_t __rdata_size, const char* __name_ctx, const char* __origin, char* __buf, size_t __buf_size) __INTRODUCED_IN_64(23); -int ns_format_ttl(u_long __ttl, char* __dst, size_t __dst_size) __INTRODUCED_IN_64(23); -int ns_name_ntol(const u_char* __src, u_char* __dst, size_t __dst_size) __INTRODUCED_IN_64(23); -int ns_name_ntop(const u_char* __src, char* __dst, size_t __dst_size) __INTRODUCED_IN_64(23); -int ns_name_pton(const char* __src, u_char* __dst, size_t __dst_size) __INTRODUCED_IN_64(23); -int ns_name_unpack(const u_char* __msg, const u_char* __eom, const u_char* __src, u_char* __dst, size_t __dst_size) - __INTRODUCED_IN_64(23); -int ns_name_pack(const u_char* __src, u_char* __dst, int __dst_size, const u_char** __dn_ptrs, const u_char** __last_dn_ptr) __INTRODUCED_IN_64(23); -int ns_name_uncompress(const u_char* __msg, const u_char* __eom, const u_char* __src, char* __dst, size_t __dst_size) - __INTRODUCED_IN_64(23); -int ns_name_compress(const char* __src, u_char* __dst, size_t __dst_size, const u_char** __dn_ptrs, const u_char** __last_dn_ptr) - __INTRODUCED_IN_64(23); -int ns_name_skip(const u_char** __ptr_ptr, const u_char* __eom) __INTRODUCED_IN_64(23); -void ns_name_rollback(const u_char* __src, const u_char** __dn_ptrs, const u_char** __last_dn_ptr) __INTRODUCED_IN_64(23); - -int ns_makecanon(const char* __src, char* __dst, size_t __dst_size) __INTRODUCED_IN_64(23); -int ns_samename(const char* __lhs, const char* __rhs) __INTRODUCED_IN_64(23); +int ns_msg_getflag(ns_msg __handle, int __flag) __INTRODUCED_IN_64(22); +uint16_t ns_get16(const u_char* __src) __INTRODUCED_IN_64(22); +uint32_t ns_get32(const u_char* __src) __INTRODUCED_IN_64(22); +void ns_put16(uint16_t __src, u_char* __dst) __INTRODUCED_IN_64(22); +void ns_put32(uint32_t __src, u_char* __dst) __INTRODUCED_IN_64(22); +int ns_initparse(const u_char* __msg, int __msg_size, ns_msg* __handle) __INTRODUCED_IN_64(22); +int ns_skiprr(const u_char* __ptr, const u_char* __eom, ns_sect __section, int __count) __INTRODUCED_IN_64(22); +int ns_parserr(ns_msg* __handle, ns_sect __section, int __rr_number, ns_rr* __rr) __INTRODUCED_IN_64(22); +int ns_sprintrr(const ns_msg* __handle, const ns_rr* __rr, const char* __name_ctx, const char* __origin, char* __buf, size_t __buf_size) __INTRODUCED_IN_64(22); +int ns_sprintrrf(const u_char* __msg, size_t __msg_size, const char* __name, ns_class __class, ns_type __type, u_long __ttl, const u_char* __rdata, size_t __rdata_size, const char* __name_ctx, const char* __origin, char* __buf, size_t __buf_size) __INTRODUCED_IN_64(22); +int ns_format_ttl(u_long __ttl, char* __dst, size_t __dst_size) __INTRODUCED_IN_64(22); +int ns_name_ntol(const u_char* __src, u_char* __dst, size_t __dst_size) __INTRODUCED_IN_64(22); +int ns_name_ntop(const u_char* __src, char* __dst, size_t __dst_size) __INTRODUCED_IN_64(22); +int ns_name_pton(const char* __src, u_char* __dst, size_t __dst_size) __INTRODUCED_IN_64(22); +int ns_name_unpack(const u_char* __msg, const u_char* __eom, const u_char* __src, u_char* __dst, size_t __dst_size) __INTRODUCED_IN_64(22); +int ns_name_pack(const u_char* __src, u_char* __dst, int __dst_size, const u_char** __dn_ptrs, const u_char** __last_dn_ptr) __INTRODUCED_IN_64(22); +int ns_name_uncompress(const u_char* __msg, const u_char* __eom, const u_char* __src, char* __dst, size_t __dst_size) __INTRODUCED_IN_64(22); +int ns_name_compress(const char* __src, u_char* __dst, size_t __dst_size, const u_char** __dn_ptrs, const u_char** __last_dn_ptr) __INTRODUCED_IN_64(22); +int ns_name_skip(const u_char** __ptr_ptr, const u_char* __eom) __INTRODUCED_IN_64(22); +void ns_name_rollback(const u_char* __src, const u_char** __dn_ptrs, const u_char** __last_dn_ptr) __INTRODUCED_IN_64(22); + +int ns_makecanon(const char* __src, char* __dst, size_t __dst_size) __INTRODUCED_IN_64(22); +int ns_samename(const char* __lhs, const char* __rhs) __INTRODUCED_IN_64(22); #endif /* !defined(__LP64__) */ __END_DECLS diff --git a/libc/include/bits/elf_arm64.h b/libc/include/bits/elf_arm64.h index d838c0b2d..6bb8384e4 100644 --- a/libc/include/bits/elf_arm64.h +++ b/libc/include/bits/elf_arm64.h @@ -83,9 +83,9 @@ #define R_AARCH64_GLOB_DAT 1025 /* Create GOT entry. */ #define R_AARCH64_JUMP_SLOT 1026 /* Create PLT entry. */ #define R_AARCH64_RELATIVE 1027 /* Adjust by program base. */ -#define R_AARCH64_TLS_DTPREL64 1028 /* Module-relative offset. */ -#define R_AARCH64_TLS_DTPMOD64 1029 /* Module index. */ -#define R_AARCH64_TLS_TPREL64 1030 /* TP-relative offset. */ +#define R_AARCH64_TLS_DTPMOD 1028 /* Module index. */ +#define R_AARCH64_TLS_DTPREL 1029 /* Module-relative offset. */ +#define R_AARCH64_TLS_TPREL 1030 /* TP-relative offset. */ #define R_AARCH64_TLSDESC 1031 /* 16-byte descriptor: resolver func + arg. */ #define R_AARCH64_IRELATIVE 1032 diff --git a/libc/include/bits/fortify/fcntl.h b/libc/include/bits/fortify/fcntl.h index e7f2c8263..4bb441eee 100644 --- a/libc/include/bits/fortify/fcntl.h +++ b/libc/include/bits/fortify/fcntl.h @@ -92,6 +92,52 @@ int openat(int dirfd, const char* const __pass_object_size pathname, int flags, } #endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */ +#if __ANDROID_API__ >= __ANDROID_API_R__ +int __open64_2(const char*, int) __INTRODUCED_IN(30); +int __openat64_2(int, const char*, int) __INTRODUCED_IN(30); +int __open64_real(const char* __path, int __flags, ...) __RENAME(open64); +int __openat64_real(int, const char*, int, ...) __RENAME(openat64); + +__BIONIC_ERROR_FUNCTION_VISIBILITY +int open64(const char* pathname, int flags, mode_t modes, ...) __overloadable + __errorattr(__open_too_many_args_error); + +__BIONIC_FORTIFY_INLINE +int open64(const char* const __pass_object_size pathname, int flags) + __overloadable + __clang_error_if(__open_modes_useful(flags), "'open64' " __open_too_few_args_error) { + return __open64_2(pathname, flags); +} + +__BIONIC_FORTIFY_INLINE +int open64(const char* const __pass_object_size pathname, int flags, mode_t modes) + __overloadable + __clang_warning_if(!__open_modes_useful(flags) && modes, + "'open64' " __open_useless_modes_warning) { + return __open64_real(pathname, flags, modes); +} + +__BIONIC_ERROR_FUNCTION_VISIBILITY +int openat64(int dirfd, const char* pathname, int flags, mode_t modes, ...) + __overloadable + __errorattr(__open_too_many_args_error); + +__BIONIC_FORTIFY_INLINE +int openat64(int dirfd, const char* const __pass_object_size pathname, int flags) + __overloadable + __clang_error_if(__open_modes_useful(flags), "'openat64' " __open_too_few_args_error) { + return __openat64_2(dirfd, pathname, flags); +} + +__BIONIC_FORTIFY_INLINE +int openat64(int dirfd, const char* const __pass_object_size pathname, int flags, mode_t modes) + __overloadable + __clang_warning_if(!__open_modes_useful(flags) && modes, + "'openat64' " __open_useless_modes_warning) { + return __openat64_real(dirfd, pathname, flags, modes); +} +#endif /* __ANDROID_API__ >= __ANDROID_API_R__ */ + #undef __open_too_many_args_error #undef __open_too_few_args_error #undef __open_useless_modes_warning diff --git a/libc/include/bits/fortify/stdio.h b/libc/include/bits/fortify/stdio.h index 6e47dafee..e766b2007 100644 --- a/libc/include/bits/fortify/stdio.h +++ b/libc/include/bits/fortify/stdio.h @@ -39,6 +39,8 @@ size_t __fwrite_chk(const void*, size_t, size_t, FILE*, size_t) __INTRODUCED_IN( #if __ANDROID_API__ >= __ANDROID_API_J_MR1__ __BIONIC_FORTIFY_INLINE __printflike(3, 0) int vsnprintf(char* const __pass_object_size dest, size_t size, const char* format, va_list ap) + __clang_error_if(__bos_unevaluated_lt(__bos(dest), size), + "in call to 'vsnprintf', size is larger than the destination buffer") __overloadable { return __builtin___vsnprintf_chk(dest, size, 0, __bos(dest), format, ap); } @@ -50,19 +52,10 @@ int vsprintf(char* const __pass_object_size dest, const char* format, va_list ap #endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */ #if __ANDROID_API__ >= __ANDROID_API_J_MR1__ -/* - * Simple case: `format` can't have format specifiers, so we can just compare - * its length to the length of `dest` - */ -__BIONIC_ERROR_FUNCTION_VISIBILITY -int snprintf(char* dest, size_t size, const char* format) - __overloadable - __enable_if(__bos_unevaluated_lt(__bos(dest), __builtin_strlen(format)), - "format string will always overflow destination buffer") - __errorattr("format string will always overflow destination buffer"); - __BIONIC_FORTIFY_VARIADIC __printflike(3, 4) int snprintf(char* const __pass_object_size dest, size_t size, const char* format, ...) + __clang_error_if(__bos_unevaluated_lt(__bos(dest), size), + "in call to 'snprintf', size is larger than the destination buffer") __overloadable { va_list va; va_start(va, format); diff --git a/libc/include/bits/fortify/stdlib.h b/libc/include/bits/fortify/stdlib.h index 0bb3d0d66..623be583b 100644 --- a/libc/include/bits/fortify/stdlib.h +++ b/libc/include/bits/fortify/stdlib.h @@ -36,10 +36,11 @@ #define __PATH_MAX 4096 char* realpath(const char* path, char* resolved) + __clang_error_if(!path, "'realpath': NULL path is never correct; flipped arguments?") __clang_error_if(__bos_unevaluated_lt(__bos(resolved), __PATH_MAX), "'realpath' output parameter must be NULL or a pointer to a buffer " - "with >= PATH_MAX bytes") - __clang_error_if(!path, "'realpath': NULL path is never correct; flipped arguments?"); + "with >= PATH_MAX bytes"); + /* No need for a definition; the only issues we can catch are at compile-time. */ #undef __PATH_MAX diff --git a/libc/include/bits/fortify/string.h b/libc/include/bits/fortify/string.h index 1e129868c..70e4476b4 100644 --- a/libc/include/bits/fortify/string.h +++ b/libc/include/bits/fortify/string.h @@ -66,6 +66,22 @@ void* memmove(void* const dst __pass_object_size0, const void* src, size_t len) } #endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */ +#if defined(__USE_GNU) +#if __ANDROID_API__ >= __ANDROID_API_R__ +__BIONIC_FORTIFY_INLINE +void* mempcpy(void* const dst __pass_object_size0, const void* src, size_t copy_amount) + __overloadable + __clang_error_if(__bos_unevaluated_lt(__bos0(dst), copy_amount), + "'mempcpy' called with size bigger than buffer") { + size_t bos_dst = __bos0(dst); + if (__bos_trivially_not_lt(bos_dst, copy_amount)) { + return __builtin_mempcpy(dst, src, copy_amount); + } + return __builtin___mempcpy_chk(dst, src, copy_amount, bos_dst); +} +#endif /* __ANDROID_API__ >= __ANDROID_API_R__ */ +#endif + #if __ANDROID_API__ >= __ANDROID_API_L__ __BIONIC_FORTIFY_INLINE char* stpcpy(char* const dst __pass_object_size, const char* src) @@ -94,12 +110,18 @@ char* strcpy(char* const dst __pass_object_size, const char* src) } __BIONIC_FORTIFY_INLINE -char* strcat(char* const dst __pass_object_size, const char* src) __overloadable { +char* strcat(char* const dst __pass_object_size, const char* src) + __overloadable + __clang_error_if(__bos_unevaluated_le(__bos(dst), __builtin_strlen(src)), + "'strcat' called with string bigger than buffer") { return __builtin___strcat_chk(dst, src, __bos(dst)); } __BIONIC_FORTIFY_INLINE -char* strncat(char* const dst __pass_object_size, const char* src, size_t n) __overloadable { +char* strncat(char* const dst __pass_object_size, const char* src, size_t n) + __overloadable + __clang_error_if(__bos_unevaluated_lt(__bos(dst), n), + "'strncat' called with size bigger than buffer") { return __builtin___strncat_chk(dst, src, n, __bos(dst)); } @@ -145,7 +167,9 @@ void* __memrchr_fortify(const void* const __pass_object_size s, int c, size_t n) #if __ANDROID_API__ >= __ANDROID_API_L__ __BIONIC_FORTIFY_INLINE char* stpncpy(char* const dst __pass_object_size, const char* const src __pass_object_size, size_t n) - __overloadable { + __overloadable + __clang_error_if(__bos_unevaluated_lt(__bos(dst), n), + "'stpncpy' called with size bigger than buffer") { size_t bos_dst = __bos(dst); size_t bos_src = __bos(src); @@ -159,7 +183,9 @@ char* stpncpy(char* const dst __pass_object_size, const char* const src __pass_o __BIONIC_FORTIFY_INLINE char* strncpy(char* const dst __pass_object_size, const char* const src __pass_object_size, size_t n) - __overloadable { + __overloadable + __clang_error_if(__bos_unevaluated_lt(__bos(dst), n), + "'strncpy' called with size bigger than buffer") { size_t bos_dst = __bos(dst); size_t bos_src = __bos(src); @@ -174,7 +200,10 @@ char* strncpy(char* const dst __pass_object_size, const char* const src __pass_o #if __ANDROID_API__ >= __ANDROID_API_J_MR1__ __BIONIC_FORTIFY_INLINE -size_t strlcpy(char* const dst __pass_object_size, const char* src, size_t size) __overloadable { +size_t strlcpy(char* const dst __pass_object_size, const char* src, size_t size) + __overloadable + __clang_error_if(__bos_unevaluated_lt(__bos(dst), size), + "'strlcpy' called with size bigger than buffer") { size_t bos = __bos(dst); if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) { @@ -185,7 +214,10 @@ size_t strlcpy(char* const dst __pass_object_size, const char* src, size_t size) } __BIONIC_FORTIFY_INLINE -size_t strlcat(char* const dst __pass_object_size, const char* src, size_t size) __overloadable { +size_t strlcat(char* const dst __pass_object_size, const char* src, size_t size) + __overloadable + __clang_error_if(__bos_unevaluated_lt(__bos(dst), size), + "'strlcat' called with size bigger than buffer") { size_t bos = __bos(dst); if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) { diff --git a/libc/include/bits/fortify/strings.h b/libc/include/bits/fortify/strings.h new file mode 100644 index 000000000..6bda295f3 --- /dev/null +++ b/libc/include/bits/fortify/strings.h @@ -0,0 +1,59 @@ +/* + * 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. + */ + +#if defined(__BIONIC_FORTIFY) + +#if __ANDROID_API__ >= __ANDROID_API_J_MR1__ +__BIONIC_FORTIFY_INLINE +void bcopy(const void *src, void* const dst __pass_object_size0, size_t len) + __overloadable + __clang_error_if(__bos_unevaluated_lt(__bos0(dst), len), + "'bcopy' called with size bigger than buffer") { + size_t bos = __bos0(dst); + if (__bos_trivially_not_lt(bos, len)) { + __builtin_memmove(dst, src, len); + } else { + __builtin___memmove_chk(dst, src, len, bos); + } +} + +__BIONIC_FORTIFY_INLINE +void bzero(void* const b __pass_object_size0, size_t len) + __overloadable + __clang_error_if(__bos_unevaluated_lt(__bos0(b), len), + "'bzero' called with size bigger than buffer") { + size_t bos = __bos0(b); + if (__bos_trivially_not_lt(bos, len)) { + __builtin_memset(b, 0, len); + } else { + __builtin___memset_chk(b, 0, len, bos); + } +} +#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */ + +#endif /* defined(__BIONIC_FORTIFY) */ diff --git a/libc/include/bits/fortify/unistd.h b/libc/include/bits/fortify/unistd.h index 543c3c748..547a1686c 100644 --- a/libc/include/bits/fortify/unistd.h +++ b/libc/include/bits/fortify/unistd.h @@ -67,7 +67,8 @@ ssize_t __readlinkat_chk(int dirfd, const char*, char*, size_t, size_t) __INTROD "in call to '" #fn "', '" #what "' bytes overflows the given object") #define __bos_trivially_not_lt_no_overflow(bos_val, index) \ - __bos_dynamic_check_impl_and((bos_val), >=, (index), (bos_val) <= SSIZE_MAX) + ((__bos_dynamic_check_impl_and((bos_val), >=, (index), (bos_val) <= SSIZE_MAX) && \ + __builtin_constant_p(index) && (index) <= SSIZE_MAX)) #if __ANDROID_API__ >= __ANDROID_API_N__ __BIONIC_FORTIFY_INLINE diff --git a/libc/include/bits/glibc-syscalls.h b/libc/include/bits/glibc-syscalls.h index 6940b3e1c..6b3e347c2 100644 --- a/libc/include/bits/glibc-syscalls.h +++ b/libc/include/bits/glibc-syscalls.h @@ -243,9 +243,21 @@ #if defined(__NR_fremovexattr) #define SYS_fremovexattr __NR_fremovexattr #endif +#if defined(__NR_fsconfig) + #define SYS_fsconfig __NR_fsconfig +#endif #if defined(__NR_fsetxattr) #define SYS_fsetxattr __NR_fsetxattr #endif +#if defined(__NR_fsmount) + #define SYS_fsmount __NR_fsmount +#endif +#if defined(__NR_fsopen) + #define SYS_fsopen __NR_fsopen +#endif +#if defined(__NR_fspick) + #define SYS_fspick __NR_fspick +#endif #if defined(__NR_fstat) #define SYS_fstat __NR_fstat #endif @@ -582,6 +594,9 @@ #if defined(__NR_mount) #define SYS_mount __NR_mount #endif +#if defined(__NR_move_mount) + #define SYS_move_mount __NR_move_mount +#endif #if defined(__NR_move_pages) #define SYS_move_pages __NR_move_pages #endif @@ -678,6 +693,9 @@ #if defined(__NR_open_by_handle_at) #define SYS_open_by_handle_at __NR_open_by_handle_at #endif +#if defined(__NR_open_tree) + #define SYS_open_tree __NR_open_tree +#endif #if defined(__NR_openat) #define SYS_openat __NR_openat #endif diff --git a/libc/include/bits/stdatomic.h b/libc/include/bits/stdatomic.h new file mode 100644 index 000000000..633cb8665 --- /dev/null +++ b/libc/include/bits/stdatomic.h @@ -0,0 +1,286 @@ +/*- + * Copyright (c) 2011 Ed Schouten <ed@FreeBSD.org> + * David Chisnall <theraven@FreeBSD.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + * + * $FreeBSD$ + */ + +#pragma once + +#include <sys/cdefs.h> +#include <sys/types.h> +#include <stdbool.h> + +/* + * C: Do it ourselves. + * Note that the runtime representation defined here should be compatible + * with the C++ one, i.e. an _Atomic(T) needs to contain the same + * bits as a T. + */ + +#include <stddef.h> /* For ptrdiff_t. */ +#include <stdint.h> /* TODO: don't drag in all the macros, just the types. */ +// Include uchar.h only when available. Bionic's stdatomic.h is also used for +// the host (via a copy in prebuilts/clang) and uchar.h is not available in the +// glibc used for the host. +#if defined(__BIONIC__) +# include <uchar.h> /* For char16_t and char32_t. */ +#endif + +/* + * 7.17.1 Atomic lock-free macros. + */ + +#ifdef __GCC_ATOMIC_BOOL_LOCK_FREE +#define ATOMIC_BOOL_LOCK_FREE __GCC_ATOMIC_BOOL_LOCK_FREE +#endif +#ifdef __GCC_ATOMIC_CHAR_LOCK_FREE +#define ATOMIC_CHAR_LOCK_FREE __GCC_ATOMIC_CHAR_LOCK_FREE +#endif +#ifdef __GCC_ATOMIC_CHAR16_T_LOCK_FREE +#define ATOMIC_CHAR16_T_LOCK_FREE __GCC_ATOMIC_CHAR16_T_LOCK_FREE +#endif +#ifdef __GCC_ATOMIC_CHAR32_T_LOCK_FREE +#define ATOMIC_CHAR32_T_LOCK_FREE __GCC_ATOMIC_CHAR32_T_LOCK_FREE +#endif +#ifdef __GCC_ATOMIC_WCHAR_T_LOCK_FREE +#define ATOMIC_WCHAR_T_LOCK_FREE __GCC_ATOMIC_WCHAR_T_LOCK_FREE +#endif +#ifdef __GCC_ATOMIC_SHORT_LOCK_FREE +#define ATOMIC_SHORT_LOCK_FREE __GCC_ATOMIC_SHORT_LOCK_FREE +#endif +#ifdef __GCC_ATOMIC_INT_LOCK_FREE +#define ATOMIC_INT_LOCK_FREE __GCC_ATOMIC_INT_LOCK_FREE +#endif +#ifdef __GCC_ATOMIC_LONG_LOCK_FREE +#define ATOMIC_LONG_LOCK_FREE __GCC_ATOMIC_LONG_LOCK_FREE +#endif +#ifdef __GCC_ATOMIC_LLONG_LOCK_FREE +#define ATOMIC_LLONG_LOCK_FREE __GCC_ATOMIC_LLONG_LOCK_FREE +#endif +#ifdef __GCC_ATOMIC_POINTER_LOCK_FREE +#define ATOMIC_POINTER_LOCK_FREE __GCC_ATOMIC_POINTER_LOCK_FREE +#endif + +/* + * 7.17.2 Initialization. + */ + +#define ATOMIC_VAR_INIT(value) (value) +#define atomic_init(obj, value) __c11_atomic_init(obj, value) + +/* + * Clang and recent GCC both provide predefined macros for the memory + * orderings. If we are using a compiler that doesn't define them, use the + * clang values - these will be ignored in the fallback path. + */ + +#ifndef __ATOMIC_RELAXED +#define __ATOMIC_RELAXED 0 +#endif +#ifndef __ATOMIC_CONSUME +#define __ATOMIC_CONSUME 1 +#endif +#ifndef __ATOMIC_ACQUIRE +#define __ATOMIC_ACQUIRE 2 +#endif +#ifndef __ATOMIC_RELEASE +#define __ATOMIC_RELEASE 3 +#endif +#ifndef __ATOMIC_ACQ_REL +#define __ATOMIC_ACQ_REL 4 +#endif +#ifndef __ATOMIC_SEQ_CST +#define __ATOMIC_SEQ_CST 5 +#endif + +/* + * 7.17.3 Order and consistency. + * + * The memory_order_* constants that denote the barrier behaviour of the + * atomic operations. + * The enum values must be identical to those used by the + * C++ <atomic> header. + */ + +typedef enum { + memory_order_relaxed = __ATOMIC_RELAXED, + memory_order_consume = __ATOMIC_CONSUME, + memory_order_acquire = __ATOMIC_ACQUIRE, + memory_order_release = __ATOMIC_RELEASE, + memory_order_acq_rel = __ATOMIC_ACQ_REL, + memory_order_seq_cst = __ATOMIC_SEQ_CST +} memory_order; + +/* + * 7.17.4 Fences. + */ + +static __inline void atomic_thread_fence(memory_order __order __attribute__((unused))) { + __c11_atomic_thread_fence(__order); +} + +static __inline void atomic_signal_fence(memory_order __order __attribute__((unused))) { + __c11_atomic_signal_fence(__order); +} + +/* + * 7.17.5 Lock-free property. + */ + +#define atomic_is_lock_free(obj) __c11_atomic_is_lock_free(sizeof(*(obj))) + +/* + * 7.17.6 Atomic integer types. + */ + +typedef _Atomic(bool) atomic_bool; +typedef _Atomic(char) atomic_char; +typedef _Atomic(signed char) atomic_schar; +typedef _Atomic(unsigned char) atomic_uchar; +typedef _Atomic(short) atomic_short; +typedef _Atomic(unsigned short) atomic_ushort; +typedef _Atomic(int) atomic_int; +typedef _Atomic(unsigned int) atomic_uint; +typedef _Atomic(long) atomic_long; +typedef _Atomic(unsigned long) atomic_ulong; +typedef _Atomic(long long) atomic_llong; +typedef _Atomic(unsigned long long) atomic_ullong; +#if defined(__BIONIC__) || (defined(__cplusplus) && __cplusplus >= 201103L) + typedef _Atomic(char16_t) atomic_char16_t; + typedef _Atomic(char32_t) atomic_char32_t; +#endif +typedef _Atomic(wchar_t) atomic_wchar_t; +typedef _Atomic(int_least8_t) atomic_int_least8_t; +typedef _Atomic(uint_least8_t) atomic_uint_least8_t; +typedef _Atomic(int_least16_t) atomic_int_least16_t; +typedef _Atomic(uint_least16_t) atomic_uint_least16_t; +typedef _Atomic(int_least32_t) atomic_int_least32_t; +typedef _Atomic(uint_least32_t) atomic_uint_least32_t; +typedef _Atomic(int_least64_t) atomic_int_least64_t; +typedef _Atomic(uint_least64_t) atomic_uint_least64_t; +typedef _Atomic(int_fast8_t) atomic_int_fast8_t; +typedef _Atomic(uint_fast8_t) atomic_uint_fast8_t; +typedef _Atomic(int_fast16_t) atomic_int_fast16_t; +typedef _Atomic(uint_fast16_t) atomic_uint_fast16_t; +typedef _Atomic(int_fast32_t) atomic_int_fast32_t; +typedef _Atomic(uint_fast32_t) atomic_uint_fast32_t; +typedef _Atomic(int_fast64_t) atomic_int_fast64_t; +typedef _Atomic(uint_fast64_t) atomic_uint_fast64_t; +typedef _Atomic(intptr_t) atomic_intptr_t; +typedef _Atomic(uintptr_t) atomic_uintptr_t; +typedef _Atomic(size_t) atomic_size_t; +typedef _Atomic(ptrdiff_t) atomic_ptrdiff_t; +typedef _Atomic(intmax_t) atomic_intmax_t; +typedef _Atomic(uintmax_t) atomic_uintmax_t; + +/* + * 7.17.7 Operations on atomic types. + */ + +/* + * Compiler-specific operations. + */ + +#define atomic_compare_exchange_strong_explicit(object, expected, \ + desired, success, failure) \ + __c11_atomic_compare_exchange_strong(object, expected, desired, \ + success, failure) +#define atomic_compare_exchange_weak_explicit(object, expected, \ + desired, success, failure) \ + __c11_atomic_compare_exchange_weak(object, expected, desired, \ + success, failure) +#define atomic_exchange_explicit(object, desired, order) \ + __c11_atomic_exchange(object, desired, order) +#define atomic_fetch_add_explicit(object, operand, order) \ + __c11_atomic_fetch_add(object, operand, order) +#define atomic_fetch_and_explicit(object, operand, order) \ + __c11_atomic_fetch_and(object, operand, order) +#define atomic_fetch_or_explicit(object, operand, order) \ + __c11_atomic_fetch_or(object, operand, order) +#define atomic_fetch_sub_explicit(object, operand, order) \ + __c11_atomic_fetch_sub(object, operand, order) +#define atomic_fetch_xor_explicit(object, operand, order) \ + __c11_atomic_fetch_xor(object, operand, order) +#define atomic_load_explicit(object, order) \ + __c11_atomic_load(object, order) +#define atomic_store_explicit(object, desired, order) \ + __c11_atomic_store(object, desired, order) + +/* + * Convenience functions. + */ + +#define atomic_compare_exchange_strong(object, expected, desired) \ + atomic_compare_exchange_strong_explicit(object, expected, \ + desired, memory_order_seq_cst, memory_order_seq_cst) +#define atomic_compare_exchange_weak(object, expected, desired) \ + atomic_compare_exchange_weak_explicit(object, expected, \ + desired, memory_order_seq_cst, memory_order_seq_cst) +#define atomic_exchange(object, desired) \ + atomic_exchange_explicit(object, desired, memory_order_seq_cst) +#define atomic_fetch_add(object, operand) \ + atomic_fetch_add_explicit(object, operand, memory_order_seq_cst) +#define atomic_fetch_and(object, operand) \ + atomic_fetch_and_explicit(object, operand, memory_order_seq_cst) +#define atomic_fetch_or(object, operand) \ + atomic_fetch_or_explicit(object, operand, memory_order_seq_cst) +#define atomic_fetch_sub(object, operand) \ + atomic_fetch_sub_explicit(object, operand, memory_order_seq_cst) +#define atomic_fetch_xor(object, operand) \ + atomic_fetch_xor_explicit(object, operand, memory_order_seq_cst) +#define atomic_load(object) \ + atomic_load_explicit(object, memory_order_seq_cst) +#define atomic_store(object, desired) \ + atomic_store_explicit(object, desired, memory_order_seq_cst) + +/* + * 7.17.8 Atomic flag type and operations. + * + * XXX: Assume atomic_bool can be used as an atomic_flag. Is there some + * kind of compiler built-in type we could use? + */ + +typedef struct { + atomic_bool __flag; +} atomic_flag; + +#define ATOMIC_FLAG_INIT { ATOMIC_VAR_INIT(false) } + +static __inline bool atomic_flag_test_and_set_explicit(volatile atomic_flag *__object, memory_order __order) { + return (atomic_exchange_explicit(&__object->__flag, 1, __order)); +} + +static __inline void atomic_flag_clear_explicit(volatile atomic_flag *__object, memory_order __order) { + atomic_store_explicit(&__object->__flag, 0, __order); +} + +static __inline bool atomic_flag_test_and_set(volatile atomic_flag *__object) { + return (atomic_flag_test_and_set_explicit(__object, memory_order_seq_cst)); +} + +static __inline void atomic_flag_clear(volatile atomic_flag *__object) { + atomic_flag_clear_explicit(__object, memory_order_seq_cst); +} diff --git a/libc/include/bits/timespec.h b/libc/include/bits/timespec.h index 0497cfe1f..daad03f52 100644 --- a/libc/include/bits/timespec.h +++ b/libc/include/bits/timespec.h @@ -46,7 +46,7 @@ struct timespec { /** Number of seconds. */ time_t tv_sec; - /** Number of nanoseconds. Must be less than 1,000,000. */ + /** Number of nanoseconds. Must be less than 1,000,000,000. */ long tv_nsec; }; #endif diff --git a/libc/include/pthread.h b/libc/include/pthread.h index 724e5b71d..31509b49f 100644 --- a/libc/include/pthread.h +++ b/libc/include/pthread.h @@ -121,6 +121,8 @@ int pthread_condattr_setclock(pthread_condattr_t* __attr, clockid_t __clock) __I int pthread_condattr_setpshared(pthread_condattr_t* __attr, int __shared); int pthread_cond_broadcast(pthread_cond_t* __cond); +int pthread_cond_clockwait(pthread_cond_t* __cond, pthread_mutex_t* __mutex, clockid_t __clock, + const struct timespec* __timeout) __INTRODUCED_IN(30); int pthread_cond_destroy(pthread_cond_t* __cond); int pthread_cond_init(pthread_cond_t* __cond, const pthread_condattr_t* __attr); int pthread_cond_signal(pthread_cond_t* __cond); @@ -130,8 +132,10 @@ int pthread_cond_timedwait(pthread_cond_t* __cond, pthread_mutex_t* __mutex, con * typically inappropriate, since that clock can change dramatically, causing the timeout to * either expire earlier or much later than intended. * Condition variables have an initialization option to use CLOCK_MONOTONIC, and in addition, - * Android provides this API to use CLOCK_MONOTONIC on a condition variable for this single wait - * no matter how it was initialized. + * Android provides pthread_cond_timedwait_monotonic_np to use CLOCK_MONOTONIC on a condition + * variable for this single wait no matter how it was initialized. + * Note that pthread_cond_clockwait() allows specifying an arbitrary clock and has superseded this + * function. */ int pthread_cond_timedwait_monotonic_np(pthread_cond_t* __cond, pthread_mutex_t* __mutex, const struct timespec* __timeout) __INTRODUCED_IN_64(28); @@ -181,6 +185,8 @@ int pthread_mutexattr_setpshared(pthread_mutexattr_t* __attr, int __shared); int pthread_mutexattr_settype(pthread_mutexattr_t* __attr, int __type); int pthread_mutexattr_setprotocol(pthread_mutexattr_t* __attr, int __protocol) __INTRODUCED_IN(28); +int pthread_mutex_clocklock(pthread_mutex_t* __mutex, clockid_t __clock, + const struct timespec* __abstime) __INTRODUCED_IN(30); int pthread_mutex_destroy(pthread_mutex_t* __mutex); int pthread_mutex_init(pthread_mutex_t* __mutex, const pthread_mutexattr_t* __attr); int pthread_mutex_lock(pthread_mutex_t* __mutex); @@ -188,11 +194,13 @@ int pthread_mutex_timedlock(pthread_mutex_t* __mutex, const struct timespec* __t __INTRODUCED_IN(21); /* - * POSIX only supports using pthread_mutex_timedlock() with CLOCK_REALTIME, however that is - * typically inappropriate, since that clock can change dramatically, causing the timeout to + * POSIX historically only supported using pthread_mutex_timedlock() with CLOCK_REALTIME, however + * that is typically inappropriate, since that clock can change dramatically, causing the timeout to * either expire earlier or much later than intended. * This function is added to use a timespec based on CLOCK_MONOTONIC that does not suffer * from this issue. + * Note that pthread_mutex_clocklock() allows specifying an arbitrary clock and has superseded this + * function. */ int pthread_mutex_timedlock_monotonic_np(pthread_mutex_t* __mutex, const struct timespec* __timeout) __INTRODUCED_IN(28); @@ -226,6 +234,10 @@ int pthread_rwlockattr_getkind_np(const pthread_rwlockattr_t* __attr, int* __kin __INTRODUCED_IN(23); int pthread_rwlockattr_setkind_np(pthread_rwlockattr_t* __attr, int __kind) __INTRODUCED_IN(23); +int pthread_rwlock_clockrdlock(pthread_rwlock_t* __rwlock, clockid_t __clock, + const struct timespec* __timeout) __INTRODUCED_IN(30); +int pthread_rwlock_clockwrlock(pthread_rwlock_t* __rwlock, clockid_t __clock, + const struct timespec* __timeout) __INTRODUCED_IN(30); int pthread_rwlock_destroy(pthread_rwlock_t* __rwlock); int pthread_rwlock_init(pthread_rwlock_t* __rwlock, const pthread_rwlockattr_t* __attr); int pthread_rwlock_rdlock(pthread_rwlock_t* __rwlock); diff --git a/libc/include/semaphore.h b/libc/include/semaphore.h index 01d685b4b..5d66f7ec0 100644 --- a/libc/include/semaphore.h +++ b/libc/include/semaphore.h @@ -30,6 +30,7 @@ #define _SEMAPHORE_H #include <sys/cdefs.h> +#include <sys/types.h> __BEGIN_DECLS @@ -44,16 +45,19 @@ typedef struct { #define SEM_FAILED __BIONIC_CAST(reinterpret_cast, sem_t*, 0) +int sem_clockwait(sem_t* __sem, clockid_t __clock, const struct timespec* __ts) __INTRODUCED_IN(30); int sem_destroy(sem_t* __sem); int sem_getvalue(sem_t* __sem, int* __value); int sem_init(sem_t* __sem, int __shared, unsigned int __value); int sem_post(sem_t* __sem); int sem_timedwait(sem_t* __sem, const struct timespec* __ts); /* - * POSIX only supports using sem_timedwait() with CLOCK_REALTIME, however that is typically - * inappropriate, since that clock can change dramatically, causing the timeout to either + * POSIX historically only supported using sem_timedwait() with CLOCK_REALTIME, however that is + * typically inappropriate, since that clock can change dramatically, causing the timeout to either * expire earlier or much later than intended. This function is added to use a timespec based * on CLOCK_MONOTONIC that does not suffer from this issue. + * Note that sem_clockwait() allows specifying an arbitrary clock and has superseded this + * function. */ int sem_timedwait_monotonic_np(sem_t* __sem, const struct timespec* __ts) __INTRODUCED_IN(28); int sem_trywait(sem_t* __sem); diff --git a/libc/include/stdatomic.h b/libc/include/stdatomic.h index 3c613346d..b7dac4a44 100644 --- a/libc/include/stdatomic.h +++ b/libc/include/stdatomic.h @@ -32,7 +32,7 @@ #include <sys/cdefs.h> -#if defined(__cplusplus) && __cplusplus >= 201103L && defined(_USING_LIBCXX) +#if defined(__cplusplus) && __cplusplus >= 201103L && __has_include(<atomic>) # if __has_feature(cxx_atomic) # define _STDATOMIC_HAVE_ATOMIC # endif @@ -127,260 +127,8 @@ using std::atomic_uintmax_t; #else /* <atomic> unavailable, possibly because this is C, not C++ */ -#include <sys/types.h> -#include <stdbool.h> - -/* - * C: Do it ourselves. - * Note that the runtime representation defined here should be compatible - * with the C++ one, i.e. an _Atomic(T) needs to contain the same - * bits as a T. - */ - -#include <stddef.h> /* For ptrdiff_t. */ -#include <stdint.h> /* TODO: don't drag in all the macros, just the types. */ -// Include uchar.h only when available. Bionic's stdatomic.h is also used for -// the host (via a copy in prebuilts/clang) and uchar.h is not available in the -// glibc used for the host. -#if defined(__BIONIC__) -# include <uchar.h> /* For char16_t and char32_t. */ -#endif - -/* - * 7.17.1 Atomic lock-free macros. - */ - -#ifdef __GCC_ATOMIC_BOOL_LOCK_FREE -#define ATOMIC_BOOL_LOCK_FREE __GCC_ATOMIC_BOOL_LOCK_FREE -#endif -#ifdef __GCC_ATOMIC_CHAR_LOCK_FREE -#define ATOMIC_CHAR_LOCK_FREE __GCC_ATOMIC_CHAR_LOCK_FREE -#endif -#ifdef __GCC_ATOMIC_CHAR16_T_LOCK_FREE -#define ATOMIC_CHAR16_T_LOCK_FREE __GCC_ATOMIC_CHAR16_T_LOCK_FREE -#endif -#ifdef __GCC_ATOMIC_CHAR32_T_LOCK_FREE -#define ATOMIC_CHAR32_T_LOCK_FREE __GCC_ATOMIC_CHAR32_T_LOCK_FREE -#endif -#ifdef __GCC_ATOMIC_WCHAR_T_LOCK_FREE -#define ATOMIC_WCHAR_T_LOCK_FREE __GCC_ATOMIC_WCHAR_T_LOCK_FREE -#endif -#ifdef __GCC_ATOMIC_SHORT_LOCK_FREE -#define ATOMIC_SHORT_LOCK_FREE __GCC_ATOMIC_SHORT_LOCK_FREE -#endif -#ifdef __GCC_ATOMIC_INT_LOCK_FREE -#define ATOMIC_INT_LOCK_FREE __GCC_ATOMIC_INT_LOCK_FREE -#endif -#ifdef __GCC_ATOMIC_LONG_LOCK_FREE -#define ATOMIC_LONG_LOCK_FREE __GCC_ATOMIC_LONG_LOCK_FREE -#endif -#ifdef __GCC_ATOMIC_LLONG_LOCK_FREE -#define ATOMIC_LLONG_LOCK_FREE __GCC_ATOMIC_LLONG_LOCK_FREE -#endif -#ifdef __GCC_ATOMIC_POINTER_LOCK_FREE -#define ATOMIC_POINTER_LOCK_FREE __GCC_ATOMIC_POINTER_LOCK_FREE -#endif - -/* - * 7.17.2 Initialization. - */ - -#define ATOMIC_VAR_INIT(value) (value) -#define atomic_init(obj, value) __c11_atomic_init(obj, value) - -/* - * Clang and recent GCC both provide predefined macros for the memory - * orderings. If we are using a compiler that doesn't define them, use the - * clang values - these will be ignored in the fallback path. - */ - -#ifndef __ATOMIC_RELAXED -#define __ATOMIC_RELAXED 0 -#endif -#ifndef __ATOMIC_CONSUME -#define __ATOMIC_CONSUME 1 -#endif -#ifndef __ATOMIC_ACQUIRE -#define __ATOMIC_ACQUIRE 2 -#endif -#ifndef __ATOMIC_RELEASE -#define __ATOMIC_RELEASE 3 -#endif -#ifndef __ATOMIC_ACQ_REL -#define __ATOMIC_ACQ_REL 4 -#endif -#ifndef __ATOMIC_SEQ_CST -#define __ATOMIC_SEQ_CST 5 -#endif - -/* - * 7.17.3 Order and consistency. - * - * The memory_order_* constants that denote the barrier behaviour of the - * atomic operations. - * The enum values must be identical to those used by the - * C++ <atomic> header. - */ - -typedef enum { - memory_order_relaxed = __ATOMIC_RELAXED, - memory_order_consume = __ATOMIC_CONSUME, - memory_order_acquire = __ATOMIC_ACQUIRE, - memory_order_release = __ATOMIC_RELEASE, - memory_order_acq_rel = __ATOMIC_ACQ_REL, - memory_order_seq_cst = __ATOMIC_SEQ_CST -} memory_order; - -/* - * 7.17.4 Fences. - */ - -static __inline void atomic_thread_fence(memory_order __order __attribute__((unused))) { - __c11_atomic_thread_fence(__order); -} - -static __inline void atomic_signal_fence(memory_order __order __attribute__((unused))) { - __c11_atomic_signal_fence(__order); -} - -/* - * 7.17.5 Lock-free property. - */ - -#define atomic_is_lock_free(obj) __c11_atomic_is_lock_free(sizeof(*(obj))) - -/* - * 7.17.6 Atomic integer types. - */ - -typedef _Atomic(bool) atomic_bool; -typedef _Atomic(char) atomic_char; -typedef _Atomic(signed char) atomic_schar; -typedef _Atomic(unsigned char) atomic_uchar; -typedef _Atomic(short) atomic_short; -typedef _Atomic(unsigned short) atomic_ushort; -typedef _Atomic(int) atomic_int; -typedef _Atomic(unsigned int) atomic_uint; -typedef _Atomic(long) atomic_long; -typedef _Atomic(unsigned long) atomic_ulong; -typedef _Atomic(long long) atomic_llong; -typedef _Atomic(unsigned long long) atomic_ullong; -#if defined(__BIONIC__) || (defined(__cplusplus) && __cplusplus >= 201103L) - typedef _Atomic(char16_t) atomic_char16_t; - typedef _Atomic(char32_t) atomic_char32_t; -#endif -typedef _Atomic(wchar_t) atomic_wchar_t; -typedef _Atomic(int_least8_t) atomic_int_least8_t; -typedef _Atomic(uint_least8_t) atomic_uint_least8_t; -typedef _Atomic(int_least16_t) atomic_int_least16_t; -typedef _Atomic(uint_least16_t) atomic_uint_least16_t; -typedef _Atomic(int_least32_t) atomic_int_least32_t; -typedef _Atomic(uint_least32_t) atomic_uint_least32_t; -typedef _Atomic(int_least64_t) atomic_int_least64_t; -typedef _Atomic(uint_least64_t) atomic_uint_least64_t; -typedef _Atomic(int_fast8_t) atomic_int_fast8_t; -typedef _Atomic(uint_fast8_t) atomic_uint_fast8_t; -typedef _Atomic(int_fast16_t) atomic_int_fast16_t; -typedef _Atomic(uint_fast16_t) atomic_uint_fast16_t; -typedef _Atomic(int_fast32_t) atomic_int_fast32_t; -typedef _Atomic(uint_fast32_t) atomic_uint_fast32_t; -typedef _Atomic(int_fast64_t) atomic_int_fast64_t; -typedef _Atomic(uint_fast64_t) atomic_uint_fast64_t; -typedef _Atomic(intptr_t) atomic_intptr_t; -typedef _Atomic(uintptr_t) atomic_uintptr_t; -typedef _Atomic(size_t) atomic_size_t; -typedef _Atomic(ptrdiff_t) atomic_ptrdiff_t; -typedef _Atomic(intmax_t) atomic_intmax_t; -typedef _Atomic(uintmax_t) atomic_uintmax_t; - -/* - * 7.17.7 Operations on atomic types. - */ - -/* - * Compiler-specific operations. - */ - -#define atomic_compare_exchange_strong_explicit(object, expected, \ - desired, success, failure) \ - __c11_atomic_compare_exchange_strong(object, expected, desired, \ - success, failure) -#define atomic_compare_exchange_weak_explicit(object, expected, \ - desired, success, failure) \ - __c11_atomic_compare_exchange_weak(object, expected, desired, \ - success, failure) -#define atomic_exchange_explicit(object, desired, order) \ - __c11_atomic_exchange(object, desired, order) -#define atomic_fetch_add_explicit(object, operand, order) \ - __c11_atomic_fetch_add(object, operand, order) -#define atomic_fetch_and_explicit(object, operand, order) \ - __c11_atomic_fetch_and(object, operand, order) -#define atomic_fetch_or_explicit(object, operand, order) \ - __c11_atomic_fetch_or(object, operand, order) -#define atomic_fetch_sub_explicit(object, operand, order) \ - __c11_atomic_fetch_sub(object, operand, order) -#define atomic_fetch_xor_explicit(object, operand, order) \ - __c11_atomic_fetch_xor(object, operand, order) -#define atomic_load_explicit(object, order) \ - __c11_atomic_load(object, order) -#define atomic_store_explicit(object, desired, order) \ - __c11_atomic_store(object, desired, order) - -/* - * Convenience functions. - */ - -#define atomic_compare_exchange_strong(object, expected, desired) \ - atomic_compare_exchange_strong_explicit(object, expected, \ - desired, memory_order_seq_cst, memory_order_seq_cst) -#define atomic_compare_exchange_weak(object, expected, desired) \ - atomic_compare_exchange_weak_explicit(object, expected, \ - desired, memory_order_seq_cst, memory_order_seq_cst) -#define atomic_exchange(object, desired) \ - atomic_exchange_explicit(object, desired, memory_order_seq_cst) -#define atomic_fetch_add(object, operand) \ - atomic_fetch_add_explicit(object, operand, memory_order_seq_cst) -#define atomic_fetch_and(object, operand) \ - atomic_fetch_and_explicit(object, operand, memory_order_seq_cst) -#define atomic_fetch_or(object, operand) \ - atomic_fetch_or_explicit(object, operand, memory_order_seq_cst) -#define atomic_fetch_sub(object, operand) \ - atomic_fetch_sub_explicit(object, operand, memory_order_seq_cst) -#define atomic_fetch_xor(object, operand) \ - atomic_fetch_xor_explicit(object, operand, memory_order_seq_cst) -#define atomic_load(object) \ - atomic_load_explicit(object, memory_order_seq_cst) -#define atomic_store(object, desired) \ - atomic_store_explicit(object, desired, memory_order_seq_cst) - -/* - * 7.17.8 Atomic flag type and operations. - * - * XXX: Assume atomic_bool can be used as an atomic_flag. Is there some - * kind of compiler built-in type we could use? - */ - -typedef struct { - atomic_bool __flag; -} atomic_flag; - -#define ATOMIC_FLAG_INIT { ATOMIC_VAR_INIT(false) } - -static __inline bool atomic_flag_test_and_set_explicit(volatile atomic_flag *__object, memory_order __order) { - return (atomic_exchange_explicit(&__object->__flag, 1, __order)); -} - -static __inline void atomic_flag_clear_explicit(volatile atomic_flag *__object, memory_order __order) { - atomic_store_explicit(&__object->__flag, 0, __order); -} - -static __inline bool atomic_flag_test_and_set(volatile atomic_flag *__object) { - return (atomic_flag_test_and_set_explicit(__object, memory_order_seq_cst)); -} - -static __inline void atomic_flag_clear(volatile atomic_flag *__object) { - atomic_flag_clear_explicit(__object, memory_order_seq_cst); -} +/* Actual implementation is in bits/stdatomic.h since our test code is C++. */ +#include <bits/stdatomic.h> #endif /* <atomic> unavailable */ diff --git a/libc/include/stdio.h b/libc/include/stdio.h index 8bd690fec..6632c0170 100644 --- a/libc/include/stdio.h +++ b/libc/include/stdio.h @@ -165,9 +165,53 @@ char* tmpnam(char* __s) char* tempnam(const char* __dir, const char* __prefix) __warnattr("tempnam is unsafe, use mkstemp or tmpfile instead"); +/** + * [rename(2)](http://man7.org/linux/man-pages/man2/rename.2.html) changes + * the name or location of a file. + * + * Returns 0 on success, and returns -1 and sets `errno` on failure. + */ int rename(const char* __old_path, const char* __new_path); + +/** + * [renameat(2)](http://man7.org/linux/man-pages/man2/renameat.2.html) changes + * the name or location of a file, interpreting relative paths using an fd. + * + * Returns 0 on success, and returns -1 and sets `errno` on failure. + */ int renameat(int __old_dir_fd, const char* __old_path, int __new_dir_fd, const char* __new_path); +#if defined(__USE_GNU) + +/** + * Flag for [renameat2(2)](http://man7.org/linux/man-pages/man2/renameat2.2.html) + * to fail if the new path already exists. + */ +#define RENAME_NOREPLACE (1<<0) + +/** + * Flag for [renameat2(2)](http://man7.org/linux/man-pages/man2/renameat2.2.html) + * to atomically exchange the two paths. + */ +#define RENAME_EXCHANGE (1<<1) + +/** + * Flag for [renameat2(2)](http://man7.org/linux/man-pages/man2/renameat2.2.html) + * to create a union/overlay filesystem object. + */ +#define RENAME_WHITEOUT (1<<2) + +/** + * [renameat2(2)](http://man7.org/linux/man-pages/man2/renameat2.2.html) changes + * the name or location of a file, interpreting relative paths using an fd, + * with optional `RENAME_` flags. + * + * Returns 0 on success, and returns -1 and sets `errno` on failure. + */ +int renameat2(int __old_dir_fd, const char* __old_path, int __new_dir_fd, const char* __new_path, unsigned __flags) __INTRODUCED_IN(30); + +#endif + int fseek(FILE* __fp, long __offset, int __whence); long ftell(FILE* __fp); diff --git a/libc/include/stdlib.h b/libc/include/stdlib.h index d5b861983..b66e3c64e 100644 --- a/libc/include/stdlib.h +++ b/libc/include/stdlib.h @@ -90,7 +90,7 @@ int atoi(const char* __s) __attribute_pure__; long atol(const char* __s) __attribute_pure__; long long atoll(const char* __s) __attribute_pure__; -char* realpath(const char* __path, char* __resolved); +__wur char* realpath(const char* __path, char* __resolved); int system(const char* __command); void* bsearch(const void* __key, const void* __base, size_t __nmemb, size_t __size, int (*__comparator)(const void* __lhs, const void* __rhs)); diff --git a/libc/include/strings.h b/libc/include/strings.h index ccdac044c..a054aed55 100644 --- a/libc/include/strings.h +++ b/libc/include/strings.h @@ -51,17 +51,15 @@ __BEGIN_DECLS -#if defined(__BIONIC_FORTIFY) /** Deprecated. Use memmove() instead. */ -#define bcopy(b1, b2, len) (void)(__builtin___memmove_chk((b2), (b1), (len), __bos0(b2))) -/** Deprecated. Use memset() instead. */ -#define bzero(b, len) (void)(__builtin___memset_chk((b), '\0', (len), __bos0(b))) -#else -/** Deprecated. Use memmove() instead. */ -#define bcopy(b1, b2, len) (void)(__builtin_memmove((b2), (b1), (len))) +static __inline__ __always_inline void bcopy(const void* b1, void* b2, size_t len) { + __builtin_memmove(b2, b1, len); +} + /** Deprecated. Use memset() instead. */ -#define bzero(b, len) (void)(__builtin_memset((b), '\0', (len))) -#endif +static __inline__ __always_inline void bzero(void* b, size_t len) { + __builtin_memset(b, 0, len); +} #if !defined(__i386__) || __ANDROID_API__ >= __ANDROID_API_J_MR2__ /** @@ -72,6 +70,10 @@ __BEGIN_DECLS int ffs(int __i) __INTRODUCED_IN_X86(18); #endif +#if defined(__BIONIC_INCLUDE_FORTIFY_HEADERS) +#include <bits/fortify/strings.h> +#endif + __END_DECLS #include <android/legacy_strings_inlines.h> diff --git a/libc/include/sys/cdefs.h b/libc/include/sys/cdefs.h index dceb1165c..689b65031 100644 --- a/libc/include/sys/cdefs.h +++ b/libc/include/sys/cdefs.h @@ -361,3 +361,6 @@ int __size_mul_overflow(__SIZE_TYPE__ a, __SIZE_TYPE__ b, __SIZE_TYPE__ *result) #include <android/versioning.h> #include <android/api-level.h> +#if __has_include(<android/ndk-version.h>) +#include <android/ndk-version.h> +#endif diff --git a/libc/include/sys/mman.h b/libc/include/sys/mman.h index 89d6d07c3..3b83229d7 100644 --- a/libc/include/sys/mman.h +++ b/libc/include/sys/mman.h @@ -26,34 +26,27 @@ * SUCH DAMAGE. */ -#ifndef _SYS_MMAN_H_ -#define _SYS_MMAN_H_ +#pragma once #include <sys/cdefs.h> #include <sys/types.h> +#include <linux/memfd.h> #include <linux/mman.h> __BEGIN_DECLS -#ifndef MAP_ANON -#define MAP_ANON MAP_ANONYMOUS -#endif +/** Alternative spelling of the `MAP_ANONYMOUS` flag for mmap(). */ +#define MAP_ANON MAP_ANONYMOUS +/** Return value for mmap(). */ #define MAP_FAILED __BIONIC_CAST(reinterpret_cast, void*, -1) -#define MREMAP_MAYMOVE 1 -#define MREMAP_FIXED 2 - -/* - * See https://android.googlesource.com/platform/bionic/+/master/docs/32-bit-abi.md - * - * mmap64 wasn't really around until L, but we added an inline for it since it - * allows a lot more code to compile with _FILE_OFFSET_BITS=64. +/** + * [mmap(2)](http://man7.org/linux/man-pages/man2/mmap.2.html) + * creates a memory mapping for the given range. * - * GCC removes the static inline unless it is explicitly used. We can get around - * this with __attribute__((used)), but that needlessly adds a definition of - * mmap64 to every translation unit that includes this header. Instead, just - * preserve the old behavior for GCC and emit a useful diagnostic. + * Returns the address of the mapping on success, + * and returns `MAP_FAILED` and sets `errno` on failure. */ #if defined(__USE_FILE_OFFSET64) void* mmap(void* __addr, size_t __size, int __prot, int __flags, int __fd, off_t __offset) __RENAME(mmap64); @@ -62,25 +55,126 @@ void* mmap(void* __addr, size_t __size, int __prot, int __flags, int __fd, off_t #endif #if __ANDROID_API__ >= __ANDROID_API_L__ +/** + * mmap64() is a variant of mmap() that takes a 64-bit offset even on LP32. + * + * See https://android.googlesource.com/platform/bionic/+/master/docs/32-bit-abi.md + * + * mmap64 wasn't really around until L, but we added an inline for it since it + * allows a lot more code to compile with _FILE_OFFSET_BITS=64. + */ void* mmap64(void* __addr, size_t __size, int __prot, int __flags, int __fd, off64_t __offset) __INTRODUCED_IN(21); #endif +/** + * [munmap(2)](http://man7.org/linux/man-pages/man2/munmap.2.html) + * deletes a memory mapping for the given range. + * + * Returns 0 on success, and returns -1 and sets `errno` on failure. + */ int munmap(void* __addr, size_t __size); + +/** + * [msync(2)](http://man7.org/linux/man-pages/man2/msync.2.html) + * flushes changes to a memory-mapped file to disk. + * + * Returns 0 on success, and returns -1 and sets `errno` on failure. + */ int msync(void* __addr, size_t __size, int __flags); + +/** + * [mprotect(2)](http://man7.org/linux/man-pages/man2/mprotect.2.html) + * sets the protection on a memory region. + * + * Returns 0 on success, and returns -1 and sets `errno` on failure. + */ int mprotect(void* __addr, size_t __size, int __prot); + +/** Flag for mremap(). */ +#define MREMAP_MAYMOVE 1 + +/** Flag for mremap(). */ +#define MREMAP_FIXED 2 + +/** + * [mremap(2)](http://man7.org/linux/man-pages/man2/mremap.2.html) + * expands or shrinks an existing memory mapping. + * + * Returns the address of the mapping on success, + * and returns `MAP_FAILED` and sets `errno` on failure. + */ void* mremap(void* __old_addr, size_t __old_size, size_t __new_size, int __flags, ...); +/** + * [mlockall(2)](http://man7.org/linux/man-pages/man2/mlockall.2.html) + * locks pages (preventing swapping). + * + * Returns 0 on success, and returns -1 and sets `errno` on failure. + */ int mlockall(int __flags) __INTRODUCED_IN(17); + +/** + * [munlockall(2)](http://man7.org/linux/man-pages/man2/munlockall.2.html) + * unlocks pages (allowing swapping). + * + * Returns 0 on success, and returns -1 and sets `errno` on failure. + */ int munlockall(void) __INTRODUCED_IN(17); +/** + * [mlock(2)](http://man7.org/linux/man-pages/man2/mlock.2.html) + * locks pages (preventing swapping). + * + * Returns 0 on success, and returns -1 and sets `errno` on failure. + */ int mlock(const void* __addr, size_t __size); + +/** + * [mlock2(2)](http://man7.org/linux/man-pages/man2/mlock.2.html) + * locks pages (preventing swapping), with optional flags. + * + * Returns 0 on success, and returns -1 and sets `errno` on failure. + */ +int mlock2(const void* __addr, size_t __size, int __flags) __INTRODUCED_IN(30); + +/** + * [munlock(2)](http://man7.org/linux/man-pages/man2/munlock.2.html) + * unlocks pages (allowing swapping). + * + * Returns 0 on success, and returns -1 and sets `errno` on failure. + */ int munlock(const void* __addr, size_t __size); +/** + * [mincore(2)](http://man7.org/linux/man-pages/man2/mincore.2.html) + * tests whether pages are resident in memory. + * + * Returns 0 on success, and returns -1 and sets `errno` on failure. + */ int mincore(void* __addr, size_t __size, unsigned char* __vector); +/** + * [madvise(2)](http://man7.org/linux/man-pages/man2/madvise.2.html) + * gives the kernel advice about future usage patterns. + * + * Returns 0 on success, and returns -1 and sets `errno` on failure. + */ int madvise(void* __addr, size_t __size, int __advice); +#if defined(__USE_GNU) + +/** + * [memfd_create(2)](http://man7.org/linux/man-pages/man2/memfd_create.2.html) + * creates an anonymous file. + * + * Returns an fd on success, and returns -1 and sets `errno` on failure. + */ +int memfd_create(const char* __name, unsigned __flags) __INTRODUCED_IN(30); + +#endif + #if __ANDROID_API__ >= __ANDROID_API_M__ + /* * Some third-party code uses the existence of POSIX_MADV_NORMAL to detect the * availability of posix_madvise. This is not correct, since having up-to-date @@ -89,16 +183,30 @@ int madvise(void* __addr, size_t __size, int __advice); * * https://github.com/android-ndk/ndk/issues/395 */ + +/** Flag for posix_madvise(). */ #define POSIX_MADV_NORMAL MADV_NORMAL +/** Flag for posix_madvise(). */ #define POSIX_MADV_RANDOM MADV_RANDOM +/** Flag for posix_madvise(). */ #define POSIX_MADV_SEQUENTIAL MADV_SEQUENTIAL +/** Flag for posix_madvise(). */ #define POSIX_MADV_WILLNEED MADV_WILLNEED +/** Flag for posix_madvise(). */ #define POSIX_MADV_DONTNEED MADV_DONTNEED + #endif + +/** + * [posix_madvise(3)](http://man7.org/linux/man-pages/man3/posix_madvise.3.html) + * gives the kernel advice about future usage patterns. + * + * Returns 0 on success, and returns a positive error number on failure. + * + * See also madvise() which has been available much longer. + */ int posix_madvise(void* __addr, size_t __size, int __advice) __INTRODUCED_IN(23); __END_DECLS #include <android/legacy_sys_mman_inlines.h> - -#endif diff --git a/libc/kernel/tools/update_all.py b/libc/kernel/tools/update_all.py index 9d5b02dee..cef24dd4c 100755 --- a/libc/kernel/tools/update_all.py +++ b/libc/kernel/tools/update_all.py @@ -110,7 +110,9 @@ def GenerateGlibcSyscallsHeader(updater): content += ' #define SYS_%s %s\n' % (syscall, nr_name) content += '#endif\n' - updater.editFile('%s/include/bits/glibc-syscalls.h' % libc_root, content) + syscall_file = os.path.join(libc_root, 'include/bits/glibc-syscalls.h') + updater.readFile(syscall_file) + updater.editFile(syscall_file, content) try: diff --git a/libc/kernel/uapi/asm-arm/asm/unistd-common.h b/libc/kernel/uapi/asm-arm/asm/unistd-common.h index e7abfeb33..d9e73dc18 100644 --- a/libc/kernel/uapi/asm-arm/asm/unistd-common.h +++ b/libc/kernel/uapi/asm-arm/asm/unistd-common.h @@ -399,4 +399,10 @@ #define __NR_io_uring_setup (__NR_SYSCALL_BASE + 425) #define __NR_io_uring_enter (__NR_SYSCALL_BASE + 426) #define __NR_io_uring_register (__NR_SYSCALL_BASE + 427) +#define __NR_open_tree (__NR_SYSCALL_BASE + 428) +#define __NR_move_mount (__NR_SYSCALL_BASE + 429) +#define __NR_fsopen (__NR_SYSCALL_BASE + 430) +#define __NR_fsconfig (__NR_SYSCALL_BASE + 431) +#define __NR_fsmount (__NR_SYSCALL_BASE + 432) +#define __NR_fspick (__NR_SYSCALL_BASE + 433) #endif diff --git a/libc/kernel/uapi/asm-arm64/asm/hwcap.h b/libc/kernel/uapi/asm-arm64/asm/hwcap.h index 44853a486..80935fc5d 100644 --- a/libc/kernel/uapi/asm-arm64/asm/hwcap.h +++ b/libc/kernel/uapi/asm-arm64/asm/hwcap.h @@ -50,4 +50,11 @@ #define HWCAP_SB (1 << 29) #define HWCAP_PACA (1 << 30) #define HWCAP_PACG (1UL << 31) +#define HWCAP2_DCPODP (1 << 0) +#define HWCAP2_SVE2 (1 << 1) +#define HWCAP2_SVEAES (1 << 2) +#define HWCAP2_SVEPMULL (1 << 3) +#define HWCAP2_SVEBITPERM (1 << 4) +#define HWCAP2_SVESHA3 (1 << 5) +#define HWCAP2_SVESM4 (1 << 6) #endif diff --git a/libc/kernel/uapi/asm-arm64/asm/kvm.h b/libc/kernel/uapi/asm-arm64/asm/kvm.h index e79562cd2..b62d9efb3 100644 --- a/libc/kernel/uapi/asm-arm64/asm/kvm.h +++ b/libc/kernel/uapi/asm-arm64/asm/kvm.h @@ -29,6 +29,7 @@ #include <linux/psci.h> #include <linux/types.h> #include <asm/ptrace.h> +#include <asm/sve_context.h> #define __KVM_HAVE_GUEST_DEBUG #define __KVM_HAVE_IRQ_LINE #define __KVM_HAVE_READONLY_MEM @@ -69,6 +70,9 @@ struct kvm_regs { #define KVM_ARM_VCPU_EL1_32BIT 1 #define KVM_ARM_VCPU_PSCI_0_2 2 #define KVM_ARM_VCPU_PMU_V3 3 +#define KVM_ARM_VCPU_SVE 4 +#define KVM_ARM_VCPU_PTRAUTH_ADDRESS 5 +#define KVM_ARM_VCPU_PTRAUTH_GENERIC 6 struct kvm_vcpu_init { __u32 target; __u32 features[7]; @@ -137,6 +141,20 @@ struct kvm_vcpu_events { #define KVM_REG_ARM_FW (0x0014 << KVM_REG_ARM_COPROC_SHIFT) #define KVM_REG_ARM_FW_REG(r) (KVM_REG_ARM64 | KVM_REG_SIZE_U64 | KVM_REG_ARM_FW | ((r) & 0xffff)) #define KVM_REG_ARM_PSCI_VERSION KVM_REG_ARM_FW_REG(0) +#define KVM_REG_ARM64_SVE (0x15 << KVM_REG_ARM_COPROC_SHIFT) +#define KVM_REG_ARM64_SVE_ZREG_BASE 0 +#define KVM_REG_ARM64_SVE_PREG_BASE 0x400 +#define KVM_REG_ARM64_SVE_FFR_BASE 0x600 +#define KVM_ARM64_SVE_NUM_ZREGS __SVE_NUM_ZREGS +#define KVM_ARM64_SVE_NUM_PREGS __SVE_NUM_PREGS +#define KVM_ARM64_SVE_MAX_SLICES 32 +#define KVM_REG_ARM64_SVE_ZREG(n,i) (KVM_REG_ARM64 | KVM_REG_ARM64_SVE | KVM_REG_ARM64_SVE_ZREG_BASE | KVM_REG_SIZE_U2048 | (((n) & (KVM_ARM64_SVE_NUM_ZREGS - 1)) << 5) | ((i) & (KVM_ARM64_SVE_MAX_SLICES - 1))) +#define KVM_REG_ARM64_SVE_PREG(n,i) (KVM_REG_ARM64 | KVM_REG_ARM64_SVE | KVM_REG_ARM64_SVE_PREG_BASE | KVM_REG_SIZE_U256 | (((n) & (KVM_ARM64_SVE_NUM_PREGS - 1)) << 5) | ((i) & (KVM_ARM64_SVE_MAX_SLICES - 1))) +#define KVM_REG_ARM64_SVE_FFR(i) (KVM_REG_ARM64 | KVM_REG_ARM64_SVE | KVM_REG_ARM64_SVE_FFR_BASE | KVM_REG_SIZE_U256 | ((i) & (KVM_ARM64_SVE_MAX_SLICES - 1))) +#define KVM_ARM64_SVE_VQ_MIN __SVE_VQ_MIN +#define KVM_ARM64_SVE_VQ_MAX __SVE_VQ_MAX +#define KVM_REG_ARM64_SVE_VLS (KVM_REG_ARM64 | KVM_REG_ARM64_SVE | KVM_REG_SIZE_U512 | 0xffff) +#define KVM_ARM64_SVE_VLS_WORDS ((KVM_ARM64_SVE_VQ_MAX - KVM_ARM64_SVE_VQ_MIN) / 64 + 1) #define KVM_DEV_ARM_VGIC_GRP_ADDR 0 #define KVM_DEV_ARM_VGIC_GRP_DIST_REGS 1 #define KVM_DEV_ARM_VGIC_GRP_CPU_REGS 2 diff --git a/libc/kernel/uapi/asm-arm64/asm/ptrace.h b/libc/kernel/uapi/asm-arm64/asm/ptrace.h index b8c046b12..c4c574829 100644 --- a/libc/kernel/uapi/asm-arm64/asm/ptrace.h +++ b/libc/kernel/uapi/asm-arm64/asm/ptrace.h @@ -46,7 +46,6 @@ #define PSR_x 0x0000ff00 #define PSR_c 0x000000ff #ifndef __ASSEMBLY__ -#include <linux/prctl.h> struct user_pt_regs { __u64 regs[31]; __u64 sp; @@ -79,8 +78,8 @@ struct user_sve_header { #define SVE_PT_REGS_MASK (1 << 0) #define SVE_PT_REGS_FPSIMD 0 #define SVE_PT_REGS_SVE SVE_PT_REGS_MASK -#define SVE_PT_VL_INHERIT (PR_SVE_VL_INHERIT >> 16) -#define SVE_PT_VL_ONEXEC (PR_SVE_SET_VL_ONEXEC >> 16) +#define SVE_PT_VL_INHERIT ((1 << 17) >> 16) +#define SVE_PT_VL_ONEXEC ((1 << 18) >> 16) #define SVE_PT_REGS_OFFSET ((sizeof(struct user_sve_header) + (__SVE_VQ_BYTES - 1)) / __SVE_VQ_BYTES * __SVE_VQ_BYTES) #define SVE_PT_FPSIMD_OFFSET SVE_PT_REGS_OFFSET #define SVE_PT_FPSIMD_SIZE(vq,flags) (sizeof(struct user_fpsimd_state)) diff --git a/libc/kernel/uapi/asm-generic/sockios.h b/libc/kernel/uapi/asm-generic/sockios.h index 0725dcc01..afbc6ad35 100644 --- a/libc/kernel/uapi/asm-generic/sockios.h +++ b/libc/kernel/uapi/asm-generic/sockios.h @@ -23,6 +23,6 @@ #define FIOGETOWN 0x8903 #define SIOCGPGRP 0x8904 #define SIOCATMARK 0x8905 -#define SIOCGSTAMP 0x8906 -#define SIOCGSTAMPNS 0x8907 +#define SIOCGSTAMP_OLD 0x8906 +#define SIOCGSTAMPNS_OLD 0x8907 #endif diff --git a/libc/kernel/uapi/asm-generic/unistd.h b/libc/kernel/uapi/asm-generic/unistd.h index 70d9185c3..73520e16c 100644 --- a/libc/kernel/uapi/asm-generic/unistd.h +++ b/libc/kernel/uapi/asm-generic/unistd.h @@ -386,8 +386,14 @@ #define __NR_io_uring_setup 425 #define __NR_io_uring_enter 426 #define __NR_io_uring_register 427 +#define __NR_open_tree 428 +#define __NR_move_mount 429 +#define __NR_fsopen 430 +#define __NR_fsconfig 431 +#define __NR_fsmount 432 +#define __NR_fspick 433 #undef __NR_syscalls -#define __NR_syscalls 428 +#define __NR_syscalls 434 #if __BITS_PER_LONG == 64 && !defined(__SYSCALL_COMPAT) #define __NR_fcntl __NR3264_fcntl #define __NR_statfs __NR3264_statfs diff --git a/libc/kernel/uapi/asm-mips/asm/inst.h b/libc/kernel/uapi/asm-mips/asm/inst.h index 090a40b00..8489575fc 100644 --- a/libc/kernel/uapi/asm-mips/asm/inst.h +++ b/libc/kernel/uapi/asm-mips/asm/inst.h @@ -146,15 +146,15 @@ enum spec_op { tlt_op, tltu_op, teq_op, - spec5_unused_op, + seleqz_op, tne_op, - spec6_unused_op, + selnez_op, dsll_op, - spec7_unused_op, + spec5_unused_op, dsrl_op, dsra_op, dsll32_op, - spec8_unused_op, + spec6_unused_op, dsrl32_op, dsra32_op }; diff --git a/libc/kernel/uapi/asm-mips/asm/sockios.h b/libc/kernel/uapi/asm-mips/asm/sockios.h index 02261d7fd..42404183a 100644 --- a/libc/kernel/uapi/asm-mips/asm/sockios.h +++ b/libc/kernel/uapi/asm-mips/asm/sockios.h @@ -24,6 +24,6 @@ #define SIOCATMARK _IOR('s', 7, int) #define SIOCSPGRP _IOW('s', 8, pid_t) #define SIOCGPGRP _IOR('s', 9, pid_t) -#define SIOCGSTAMP 0x8906 -#define SIOCGSTAMPNS 0x8907 +#define SIOCGSTAMP_OLD 0x8906 +#define SIOCGSTAMPNS_OLD 0x8907 #endif diff --git a/libc/kernel/uapi/asm-mips/asm/unistd_n32.h b/libc/kernel/uapi/asm-mips/asm/unistd_n32.h index 8bafcf0bc..ad928ac07 100644 --- a/libc/kernel/uapi/asm-mips/asm/unistd_n32.h +++ b/libc/kernel/uapi/asm-mips/asm/unistd_n32.h @@ -374,4 +374,10 @@ #define __NR_io_uring_setup (__NR_Linux + 425) #define __NR_io_uring_enter (__NR_Linux + 426) #define __NR_io_uring_register (__NR_Linux + 427) +#define __NR_open_tree (__NR_Linux + 428) +#define __NR_move_mount (__NR_Linux + 429) +#define __NR_fsopen (__NR_Linux + 430) +#define __NR_fsconfig (__NR_Linux + 431) +#define __NR_fsmount (__NR_Linux + 432) +#define __NR_fspick (__NR_Linux + 433) #endif diff --git a/libc/kernel/uapi/asm-mips/asm/unistd_n64.h b/libc/kernel/uapi/asm-mips/asm/unistd_n64.h index 2191c2139..0ffc069a8 100644 --- a/libc/kernel/uapi/asm-mips/asm/unistd_n64.h +++ b/libc/kernel/uapi/asm-mips/asm/unistd_n64.h @@ -350,4 +350,10 @@ #define __NR_io_uring_setup (__NR_Linux + 425) #define __NR_io_uring_enter (__NR_Linux + 426) #define __NR_io_uring_register (__NR_Linux + 427) +#define __NR_open_tree (__NR_Linux + 428) +#define __NR_move_mount (__NR_Linux + 429) +#define __NR_fsopen (__NR_Linux + 430) +#define __NR_fsconfig (__NR_Linux + 431) +#define __NR_fsmount (__NR_Linux + 432) +#define __NR_fspick (__NR_Linux + 433) #endif diff --git a/libc/kernel/uapi/asm-mips/asm/unistd_nr_n32.h b/libc/kernel/uapi/asm-mips/asm/unistd_nr_n32.h index 3ef3a317b..af3c8502c 100644 --- a/libc/kernel/uapi/asm-mips/asm/unistd_nr_n32.h +++ b/libc/kernel/uapi/asm-mips/asm/unistd_nr_n32.h @@ -19,5 +19,5 @@ #ifndef _UAPI_ASM_MIPS_UNISTD_NR_N32_H #define _UAPI_ASM_MIPS_UNISTD_NR_N32_H #define __NR_N32_Linux 6000 -#define __NR_N32_Linux_syscalls 428 +#define __NR_N32_Linux_syscalls 434 #endif diff --git a/libc/kernel/uapi/asm-mips/asm/unistd_nr_n64.h b/libc/kernel/uapi/asm-mips/asm/unistd_nr_n64.h index ececf3587..c78f3e619 100644 --- a/libc/kernel/uapi/asm-mips/asm/unistd_nr_n64.h +++ b/libc/kernel/uapi/asm-mips/asm/unistd_nr_n64.h @@ -19,5 +19,5 @@ #ifndef _UAPI_ASM_MIPS_UNISTD_NR_N64_H #define _UAPI_ASM_MIPS_UNISTD_NR_N64_H #define __NR_64_Linux 5000 -#define __NR_64_Linux_syscalls 428 +#define __NR_64_Linux_syscalls 434 #endif diff --git a/libc/kernel/uapi/asm-mips/asm/unistd_nr_o32.h b/libc/kernel/uapi/asm-mips/asm/unistd_nr_o32.h index 6fb35396d..444710e63 100644 --- a/libc/kernel/uapi/asm-mips/asm/unistd_nr_o32.h +++ b/libc/kernel/uapi/asm-mips/asm/unistd_nr_o32.h @@ -19,5 +19,5 @@ #ifndef _UAPI_ASM_MIPS_UNISTD_NR_O32_H #define _UAPI_ASM_MIPS_UNISTD_NR_O32_H #define __NR_O32_Linux 4000 -#define __NR_O32_Linux_syscalls 428 +#define __NR_O32_Linux_syscalls 434 #endif diff --git a/libc/kernel/uapi/asm-mips/asm/unistd_o32.h b/libc/kernel/uapi/asm-mips/asm/unistd_o32.h index 8330a8839..5bf392b6a 100644 --- a/libc/kernel/uapi/asm-mips/asm/unistd_o32.h +++ b/libc/kernel/uapi/asm-mips/asm/unistd_o32.h @@ -420,4 +420,10 @@ #define __NR_io_uring_setup (__NR_Linux + 425) #define __NR_io_uring_enter (__NR_Linux + 426) #define __NR_io_uring_register (__NR_Linux + 427) +#define __NR_open_tree (__NR_Linux + 428) +#define __NR_move_mount (__NR_Linux + 429) +#define __NR_fsopen (__NR_Linux + 430) +#define __NR_fsconfig (__NR_Linux + 431) +#define __NR_fsmount (__NR_Linux + 432) +#define __NR_fspick (__NR_Linux + 433) #endif diff --git a/libc/kernel/uapi/asm-x86/asm/kvm.h b/libc/kernel/uapi/asm-x86/asm/kvm.h index 10b129400..4ec3c10bd 100644 --- a/libc/kernel/uapi/asm-x86/asm/kvm.h +++ b/libc/kernel/uapi/asm-x86/asm/kvm.h @@ -318,14 +318,21 @@ struct kvm_sync_regs { #define KVM_X86_QUIRK_CD_NW_CLEARED (1 << 1) #define KVM_X86_QUIRK_LAPIC_MMIO_HOLE (1 << 2) #define KVM_X86_QUIRK_OUT_7E_INC_RIP (1 << 3) +#define KVM_STATE_NESTED_FORMAT_VMX 0 +#define KVM_STATE_NESTED_FORMAT_SVM 1 #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 { +#define KVM_STATE_NESTED_VMX_VMCS_SIZE 0x1000 +struct kvm_vmx_nested_state_data { + __u8 vmcs12[KVM_STATE_NESTED_VMX_VMCS_SIZE]; + __u8 shadow_vmcs12[KVM_STATE_NESTED_VMX_VMCS_SIZE]; +}; +struct kvm_vmx_nested_state_hdr { __u64 vmxon_pa; - __u64 vmcs_pa; + __u64 vmcs12_pa; struct { __u16 flags; } smm; @@ -335,9 +342,11 @@ struct kvm_nested_state { __u16 format; __u32 size; union { - struct kvm_vmx_nested_state vmx; + struct kvm_vmx_nested_state_hdr vmx; __u8 pad[120]; - }; - __u8 data[0]; + } hdr; + union { + struct kvm_vmx_nested_state_data vmx[0]; + } data; }; #endif diff --git a/libc/kernel/uapi/asm-x86/asm/perf_regs.h b/libc/kernel/uapi/asm-x86/asm/perf_regs.h index 6a015ba31..984b7ea9d 100644 --- a/libc/kernel/uapi/asm-x86/asm/perf_regs.h +++ b/libc/kernel/uapi/asm-x86/asm/perf_regs.h @@ -45,5 +45,23 @@ enum perf_event_x86_regs { PERF_REG_X86_R15, PERF_REG_X86_32_MAX = PERF_REG_X86_GS + 1, PERF_REG_X86_64_MAX = PERF_REG_X86_R15 + 1, + PERF_REG_X86_XMM0 = 32, + PERF_REG_X86_XMM1 = 34, + PERF_REG_X86_XMM2 = 36, + PERF_REG_X86_XMM3 = 38, + PERF_REG_X86_XMM4 = 40, + PERF_REG_X86_XMM5 = 42, + PERF_REG_X86_XMM6 = 44, + PERF_REG_X86_XMM7 = 46, + PERF_REG_X86_XMM8 = 48, + PERF_REG_X86_XMM9 = 50, + PERF_REG_X86_XMM10 = 52, + PERF_REG_X86_XMM11 = 54, + PERF_REG_X86_XMM12 = 56, + PERF_REG_X86_XMM13 = 58, + PERF_REG_X86_XMM14 = 60, + PERF_REG_X86_XMM15 = 62, + PERF_REG_X86_XMM_MAX = PERF_REG_X86_XMM15 + 2, }; +#define PERF_REG_EXTENDED_MASK (~((1ULL << PERF_REG_X86_XMM0) - 1)) #endif diff --git a/libc/kernel/uapi/asm-x86/asm/unistd_32.h b/libc/kernel/uapi/asm-x86/asm/unistd_32.h index bccc6f1b9..09f2e7b25 100644 --- a/libc/kernel/uapi/asm-x86/asm/unistd_32.h +++ b/libc/kernel/uapi/asm-x86/asm/unistd_32.h @@ -435,4 +435,10 @@ #define __NR_io_uring_setup 425 #define __NR_io_uring_enter 426 #define __NR_io_uring_register 427 +#define __NR_open_tree 428 +#define __NR_move_mount 429 +#define __NR_fsopen 430 +#define __NR_fsconfig 431 +#define __NR_fsmount 432 +#define __NR_fspick 433 #endif diff --git a/libc/kernel/uapi/asm-x86/asm/unistd_64.h b/libc/kernel/uapi/asm-x86/asm/unistd_64.h index ddac7db98..36859b541 100644 --- a/libc/kernel/uapi/asm-x86/asm/unistd_64.h +++ b/libc/kernel/uapi/asm-x86/asm/unistd_64.h @@ -357,4 +357,10 @@ #define __NR_io_uring_setup 425 #define __NR_io_uring_enter 426 #define __NR_io_uring_register 427 +#define __NR_open_tree 428 +#define __NR_move_mount 429 +#define __NR_fsopen 430 +#define __NR_fsconfig 431 +#define __NR_fsmount 432 +#define __NR_fspick 433 #endif diff --git a/libc/kernel/uapi/asm-x86/asm/unistd_x32.h b/libc/kernel/uapi/asm-x86/asm/unistd_x32.h index 9c4ba12c4..d3e2d3fb1 100644 --- a/libc/kernel/uapi/asm-x86/asm/unistd_x32.h +++ b/libc/kernel/uapi/asm-x86/asm/unistd_x32.h @@ -310,6 +310,12 @@ #define __NR_io_uring_setup (__X32_SYSCALL_BIT + 425) #define __NR_io_uring_enter (__X32_SYSCALL_BIT + 426) #define __NR_io_uring_register (__X32_SYSCALL_BIT + 427) +#define __NR_open_tree (__X32_SYSCALL_BIT + 428) +#define __NR_move_mount (__X32_SYSCALL_BIT + 429) +#define __NR_fsopen (__X32_SYSCALL_BIT + 430) +#define __NR_fsconfig (__X32_SYSCALL_BIT + 431) +#define __NR_fsmount (__X32_SYSCALL_BIT + 432) +#define __NR_fspick (__X32_SYSCALL_BIT + 433) #define __NR_rt_sigaction (__X32_SYSCALL_BIT + 512) #define __NR_rt_sigreturn (__X32_SYSCALL_BIT + 513) #define __NR_ioctl (__X32_SYSCALL_BIT + 514) diff --git a/libc/kernel/uapi/asm-x86/asm/vmx.h b/libc/kernel/uapi/asm-x86/asm/vmx.h index 0f7ede3b5..83365f8df 100644 --- a/libc/kernel/uapi/asm-x86/asm/vmx.h +++ b/libc/kernel/uapi/asm-x86/asm/vmx.h @@ -78,6 +78,5 @@ #define VMX_EXIT_REASONS { EXIT_REASON_EXCEPTION_NMI, "EXCEPTION_NMI" }, { EXIT_REASON_EXTERNAL_INTERRUPT, "EXTERNAL_INTERRUPT" }, { EXIT_REASON_TRIPLE_FAULT, "TRIPLE_FAULT" }, { EXIT_REASON_PENDING_INTERRUPT, "PENDING_INTERRUPT" }, { EXIT_REASON_NMI_WINDOW, "NMI_WINDOW" }, { EXIT_REASON_TASK_SWITCH, "TASK_SWITCH" }, { EXIT_REASON_CPUID, "CPUID" }, { EXIT_REASON_HLT, "HLT" }, { EXIT_REASON_INVD, "INVD" }, { EXIT_REASON_INVLPG, "INVLPG" }, { EXIT_REASON_RDPMC, "RDPMC" }, { EXIT_REASON_RDTSC, "RDTSC" }, { EXIT_REASON_VMCALL, "VMCALL" }, { EXIT_REASON_VMCLEAR, "VMCLEAR" }, { EXIT_REASON_VMLAUNCH, "VMLAUNCH" }, { EXIT_REASON_VMPTRLD, "VMPTRLD" }, { EXIT_REASON_VMPTRST, "VMPTRST" }, { EXIT_REASON_VMREAD, "VMREAD" }, { EXIT_REASON_VMRESUME, "VMRESUME" }, { EXIT_REASON_VMWRITE, "VMWRITE" }, { EXIT_REASON_VMOFF, "VMOFF" }, { EXIT_REASON_VMON, "VMON" }, { EXIT_REASON_CR_ACCESS, "CR_ACCESS" }, { EXIT_REASON_DR_ACCESS, "DR_ACCESS" }, { EXIT_REASON_IO_INSTRUCTION, "IO_INSTRUCTION" }, { EXIT_REASON_MSR_READ, "MSR_READ" }, { EXIT_REASON_MSR_WRITE, "MSR_WRITE" }, { EXIT_REASON_INVALID_STATE, "INVALID_STATE" }, { EXIT_REASON_MSR_LOAD_FAIL, "MSR_LOAD_FAIL" }, { EXIT_REASON_MWAIT_INSTRUCTION, "MWAIT_INSTRUCTION" }, { EXIT_REASON_MONITOR_TRAP_FLAG, "MONITOR_TRAP_FLAG" }, { EXIT_REASON_MONITOR_INSTRUCTION, "MONITOR_INSTRUCTION" }, { EXIT_REASON_PAUSE_INSTRUCTION, "PAUSE_INSTRUCTION" }, { EXIT_REASON_MCE_DURING_VMENTRY, "MCE_DURING_VMENTRY" }, { EXIT_REASON_TPR_BELOW_THRESHOLD, "TPR_BELOW_THRESHOLD" }, { EXIT_REASON_APIC_ACCESS, "APIC_ACCESS" }, { EXIT_REASON_EOI_INDUCED, "EOI_INDUCED" }, { EXIT_REASON_GDTR_IDTR, "GDTR_IDTR" }, { EXIT_REASON_LDTR_TR, "LDTR_TR" }, { EXIT_REASON_EPT_VIOLATION, "EPT_VIOLATION" }, { EXIT_REASON_EPT_MISCONFIG, "EPT_MISCONFIG" }, { EXIT_REASON_INVEPT, "INVEPT" }, { EXIT_REASON_RDTSCP, "RDTSCP" }, { EXIT_REASON_PREEMPTION_TIMER, "PREEMPTION_TIMER" }, { EXIT_REASON_INVVPID, "INVVPID" }, { EXIT_REASON_WBINVD, "WBINVD" }, { EXIT_REASON_XSETBV, "XSETBV" }, { EXIT_REASON_APIC_WRITE, "APIC_WRITE" }, { EXIT_REASON_RDRAND, "RDRAND" }, { EXIT_REASON_INVPCID, "INVPCID" }, { EXIT_REASON_VMFUNC, "VMFUNC" }, { EXIT_REASON_ENCLS, "ENCLS" }, { EXIT_REASON_RDSEED, "RDSEED" }, { EXIT_REASON_PML_FULL, "PML_FULL" }, { EXIT_REASON_XSAVES, "XSAVES" }, { EXIT_REASON_XRSTORS, "XRSTORS" } #define VMX_ABORT_SAVE_GUEST_MSR_FAIL 1 #define VMX_ABORT_LOAD_HOST_PDPTE_FAIL 2 -#define VMX_ABORT_VMCS_CORRUPTED 3 #define VMX_ABORT_LOAD_HOST_MSR_FAIL 4 #endif diff --git a/libc/kernel/uapi/drm/amdgpu_drm.h b/libc/kernel/uapi/drm/amdgpu_drm.h index 53da9dd6c..193881d16 100644 --- a/libc/kernel/uapi/drm/amdgpu_drm.h +++ b/libc/kernel/uapi/drm/amdgpu_drm.h @@ -117,6 +117,8 @@ union drm_amdgpu_bo_list { #define AMDGPU_CTX_QUERY2_FLAGS_RESET (1 << 0) #define AMDGPU_CTX_QUERY2_FLAGS_VRAMLOST (1 << 1) #define AMDGPU_CTX_QUERY2_FLAGS_GUILTY (1 << 2) +#define AMDGPU_CTX_QUERY2_FLAGS_RAS_CE (1 << 3) +#define AMDGPU_CTX_QUERY2_FLAGS_RAS_UE (1 << 4) #define AMDGPU_CTX_PRIORITY_UNSET - 2048 #define AMDGPU_CTX_PRIORITY_VERY_LOW - 1023 #define AMDGPU_CTX_PRIORITY_LOW - 512 @@ -325,6 +327,8 @@ struct drm_amdgpu_gem_va { #define AMDGPU_CHUNK_ID_SYNCOBJ_OUT 0x05 #define AMDGPU_CHUNK_ID_BO_HANDLES 0x06 #define AMDGPU_CHUNK_ID_SCHEDULED_DEPENDENCIES 0x07 +#define AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_WAIT 0x08 +#define AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_SIGNAL 0x09 struct drm_amdgpu_cs_chunk { __u32 chunk_id; __u32 length_dw; @@ -372,6 +376,11 @@ struct drm_amdgpu_cs_chunk_fence { struct drm_amdgpu_cs_chunk_sem { __u32 handle; }; +struct drm_amdgpu_cs_chunk_syncobj { + __u32 handle; + __u32 flags; + __u64 point; +}; #define AMDGPU_FENCE_TO_HANDLE_GET_SYNCOBJ 0 #define AMDGPU_FENCE_TO_HANDLE_GET_SYNCOBJ_FD 1 #define AMDGPU_FENCE_TO_HANDLE_GET_SYNC_FILE_FD 2 @@ -416,6 +425,7 @@ struct drm_amdgpu_cs_chunk_data { #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_FW_TA 0x13 #define AMDGPU_INFO_NUM_BYTES_MOVED 0x0f #define AMDGPU_INFO_VRAM_USAGE 0x10 #define AMDGPU_INFO_GTT_USAGE 0x11 @@ -443,6 +453,21 @@ struct drm_amdgpu_cs_chunk_data { #define AMDGPU_INFO_SENSOR_STABLE_PSTATE_GFX_MCLK 0x9 #define AMDGPU_INFO_NUM_VRAM_CPU_PAGE_FAULTS 0x1E #define AMDGPU_INFO_VRAM_LOST_COUNTER 0x1F +#define AMDGPU_INFO_RAS_ENABLED_FEATURES 0x20 +#define AMDGPU_INFO_RAS_ENABLED_UMC (1 << 0) +#define AMDGPU_INFO_RAS_ENABLED_SDMA (1 << 1) +#define AMDGPU_INFO_RAS_ENABLED_GFX (1 << 2) +#define AMDGPU_INFO_RAS_ENABLED_MMHUB (1 << 3) +#define AMDGPU_INFO_RAS_ENABLED_ATHUB (1 << 4) +#define AMDGPU_INFO_RAS_ENABLED_PCIE (1 << 5) +#define AMDGPU_INFO_RAS_ENABLED_HDP (1 << 6) +#define AMDGPU_INFO_RAS_ENABLED_XGMI (1 << 7) +#define AMDGPU_INFO_RAS_ENABLED_DF (1 << 8) +#define AMDGPU_INFO_RAS_ENABLED_SMN (1 << 9) +#define AMDGPU_INFO_RAS_ENABLED_SEM (1 << 10) +#define AMDGPU_INFO_RAS_ENABLED_MP0 (1 << 11) +#define AMDGPU_INFO_RAS_ENABLED_MP1 (1 << 12) +#define AMDGPU_INFO_RAS_ENABLED_FUSE (1 << 13) #define AMDGPU_INFO_MMR_SE_INDEX_SHIFT 0 #define AMDGPU_INFO_MMR_SE_INDEX_MASK 0xff #define AMDGPU_INFO_MMR_SH_INDEX_SHIFT 8 diff --git a/libc/kernel/uapi/drm/drm.h b/libc/kernel/uapi/drm/drm.h index ef64ed712..66adf9911 100644 --- a/libc/kernel/uapi/drm/drm.h +++ b/libc/kernel/uapi/drm/drm.h @@ -363,6 +363,7 @@ struct drm_gem_open { #define DRM_CAP_PAGE_FLIP_TARGET 0x11 #define DRM_CAP_CRTC_IN_VBLANK_EVENT 0x12 #define DRM_CAP_SYNCOBJ 0x13 +#define DRM_CAP_SYNCOBJ_TIMELINE 0x14 struct drm_get_cap { __u64 capability; __u64 value; @@ -400,8 +401,17 @@ struct drm_syncobj_handle { __s32 fd; __u32 pad; }; +struct drm_syncobj_transfer { + __u32 src_handle; + __u32 dst_handle; + __u64 src_point; + __u64 dst_point; + __u32 flags; + __u32 pad; +}; #define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL (1 << 0) #define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT (1 << 1) +#define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE (1 << 2) struct drm_syncobj_wait { __u64 handles; __s64 timeout_nsec; @@ -410,11 +420,26 @@ struct drm_syncobj_wait { __u32 first_signaled; __u32 pad; }; +struct drm_syncobj_timeline_wait { + __u64 handles; + __u64 points; + __s64 timeout_nsec; + __u32 count_handles; + __u32 flags; + __u32 first_signaled; + __u32 pad; +}; struct drm_syncobj_array { __u64 handles; __u32 count_handles; __u32 pad; }; +struct drm_syncobj_timeline_array { + __u64 handles; + __u64 points; + __u32 count_handles; + __u32 pad; +}; struct drm_crtc_get_sequence { __u32 crtc_id; __u32 active; @@ -542,6 +567,10 @@ extern "C" { #define DRM_IOCTL_MODE_LIST_LESSEES DRM_IOWR(0xC7, struct drm_mode_list_lessees) #define DRM_IOCTL_MODE_GET_LEASE DRM_IOWR(0xC8, struct drm_mode_get_lease) #define DRM_IOCTL_MODE_REVOKE_LEASE DRM_IOWR(0xC9, struct drm_mode_revoke_lease) +#define DRM_IOCTL_SYNCOBJ_TIMELINE_WAIT DRM_IOWR(0xCA, struct drm_syncobj_timeline_wait) +#define DRM_IOCTL_SYNCOBJ_QUERY DRM_IOWR(0xCB, struct drm_syncobj_timeline_array) +#define DRM_IOCTL_SYNCOBJ_TRANSFER DRM_IOWR(0xCC, struct drm_syncobj_transfer) +#define DRM_IOCTL_SYNCOBJ_TIMELINE_SIGNAL DRM_IOWR(0xCD, struct drm_syncobj_timeline_array) #define DRM_COMMAND_BASE 0x40 #define DRM_COMMAND_END 0xA0 struct drm_event { diff --git a/libc/kernel/uapi/drm/drm_fourcc.h b/libc/kernel/uapi/drm/drm_fourcc.h index fd808535e..593d87c6a 100644 --- a/libc/kernel/uapi/drm/drm_fourcc.h +++ b/libc/kernel/uapi/drm/drm_fourcc.h @@ -70,16 +70,33 @@ extern "C" { #define DRM_FORMAT_ABGR2101010 fourcc_code('A', 'B', '3', '0') #define DRM_FORMAT_RGBA1010102 fourcc_code('R', 'A', '3', '0') #define DRM_FORMAT_BGRA1010102 fourcc_code('B', 'A', '3', '0') +#define DRM_FORMAT_XRGB16161616F fourcc_code('X', 'R', '4', 'H') +#define DRM_FORMAT_XBGR16161616F fourcc_code('X', 'B', '4', 'H') +#define DRM_FORMAT_ARGB16161616F fourcc_code('A', 'R', '4', 'H') +#define DRM_FORMAT_ABGR16161616F fourcc_code('A', 'B', '4', 'H') #define DRM_FORMAT_YUYV fourcc_code('Y', 'U', 'Y', 'V') #define DRM_FORMAT_YVYU fourcc_code('Y', 'V', 'Y', 'U') #define DRM_FORMAT_UYVY fourcc_code('U', 'Y', 'V', 'Y') #define DRM_FORMAT_VYUY fourcc_code('V', 'Y', 'U', 'Y') #define DRM_FORMAT_AYUV fourcc_code('A', 'Y', 'U', 'V') #define DRM_FORMAT_XYUV8888 fourcc_code('X', 'Y', 'U', 'V') +#define DRM_FORMAT_VUY888 fourcc_code('V', 'U', '2', '4') +#define DRM_FORMAT_VUY101010 fourcc_code('V', 'U', '3', '0') +#define DRM_FORMAT_Y210 fourcc_code('Y', '2', '1', '0') +#define DRM_FORMAT_Y212 fourcc_code('Y', '2', '1', '2') +#define DRM_FORMAT_Y216 fourcc_code('Y', '2', '1', '6') +#define DRM_FORMAT_Y410 fourcc_code('Y', '4', '1', '0') +#define DRM_FORMAT_Y412 fourcc_code('Y', '4', '1', '2') +#define DRM_FORMAT_Y416 fourcc_code('Y', '4', '1', '6') +#define DRM_FORMAT_XVYU2101010 fourcc_code('X', 'V', '3', '0') +#define DRM_FORMAT_XVYU12_16161616 fourcc_code('X', 'V', '3', '6') +#define DRM_FORMAT_XVYU16161616 fourcc_code('X', 'V', '4', '8') #define DRM_FORMAT_Y0L0 fourcc_code('Y', '0', 'L', '0') #define DRM_FORMAT_X0L0 fourcc_code('X', '0', 'L', '0') #define DRM_FORMAT_Y0L2 fourcc_code('Y', '0', 'L', '2') #define DRM_FORMAT_X0L2 fourcc_code('X', '0', 'L', '2') +#define DRM_FORMAT_YUV420_8BIT fourcc_code('Y', 'U', '0', '8') +#define DRM_FORMAT_YUV420_10BIT fourcc_code('Y', 'U', '1', '0') #define DRM_FORMAT_XRGB8888_A8 fourcc_code('X', 'R', 'A', '8') #define DRM_FORMAT_XBGR8888_A8 fourcc_code('X', 'B', 'A', '8') #define DRM_FORMAT_RGBX8888_A8 fourcc_code('R', 'X', 'A', '8') @@ -94,6 +111,7 @@ extern "C" { #define DRM_FORMAT_NV61 fourcc_code('N', 'V', '6', '1') #define DRM_FORMAT_NV24 fourcc_code('N', 'V', '2', '4') #define DRM_FORMAT_NV42 fourcc_code('N', 'V', '4', '2') +#define DRM_FORMAT_P210 fourcc_code('P', '2', '1', '0') #define DRM_FORMAT_P010 fourcc_code('P', '0', '1', '0') #define DRM_FORMAT_P012 fourcc_code('P', '0', '1', '2') #define DRM_FORMAT_P016 fourcc_code('P', '0', '1', '6') diff --git a/libc/kernel/uapi/drm/drm_mode.h b/libc/kernel/uapi/drm/drm_mode.h index 1944c9cd8..3f321d039 100644 --- a/libc/kernel/uapi/drm/drm_mode.h +++ b/libc/kernel/uapi/drm/drm_mode.h @@ -22,7 +22,6 @@ #ifdef __cplusplus extern "C" { #endif -#define DRM_DISPLAY_INFO_LEN 32 #define DRM_CONNECTOR_NAME_LEN 32 #define DRM_DISPLAY_MODE_LEN 32 #define DRM_PROP_NAME_LEN 32 diff --git a/libc/kernel/uapi/drm/i915_drm.h b/libc/kernel/uapi/drm/i915_drm.h index d48a581a6..d83a4c0d2 100644 --- a/libc/kernel/uapi/drm/i915_drm.h +++ b/libc/kernel/uapi/drm/i915_drm.h @@ -25,6 +25,12 @@ extern "C" { #define I915_L3_PARITY_UEVENT "L3_PARITY_ERROR" #define I915_ERROR_UEVENT "ERROR" #define I915_RESET_UEVENT "RESET" +struct i915_user_extension { + __u64 next_extension; + __u32 name; + __u32 flags; + __u32 rsvd[4]; +}; enum i915_mocs_table_index { I915_MOCS_UNCACHED, I915_MOCS_PTE, @@ -37,6 +43,10 @@ enum drm_i915_gem_engine_class { I915_ENGINE_CLASS_VIDEO_ENHANCE = 3, I915_ENGINE_CLASS_INVALID = - 1 }; +struct i915_engine_class_instance { + __u16 engine_class; + __u16 engine_instance; +}; enum drm_i915_pmu_engine_sample { I915_SAMPLE_BUSY = 0, I915_SAMPLE_WAIT = 1, @@ -249,6 +259,7 @@ typedef struct _drm_i915_sarea { #define DRM_IOCTL_I915_GET_SPRITE_COLORKEY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GET_SPRITE_COLORKEY, struct drm_intel_sprite_colorkey) #define DRM_IOCTL_I915_GEM_WAIT DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_WAIT, struct drm_i915_gem_wait) #define DRM_IOCTL_I915_GEM_CONTEXT_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_CREATE, struct drm_i915_gem_context_create) +#define DRM_IOCTL_I915_GEM_CONTEXT_CREATE_EXT DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_CREATE, struct drm_i915_gem_context_create_ext) #define DRM_IOCTL_I915_GEM_CONTEXT_DESTROY DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_DESTROY, struct drm_i915_gem_context_destroy) #define DRM_IOCTL_I915_REG_READ DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_REG_READ, struct drm_i915_reg_read) #define DRM_IOCTL_I915_GET_RESET_STATS DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GET_RESET_STATS, struct drm_i915_reset_stats) @@ -328,6 +339,7 @@ typedef struct drm_i915_irq_wait { #define I915_SCHEDULER_CAP_ENABLED (1ul << 0) #define I915_SCHEDULER_CAP_PRIORITY (1ul << 1) #define I915_SCHEDULER_CAP_PREEMPTION (1ul << 2) +#define I915_SCHEDULER_CAP_SEMAPHORES (1ul << 3) #define I915_PARAM_HUC_STATUS 42 #define I915_PARAM_HAS_EXEC_ASYNC 43 #define I915_PARAM_HAS_EXEC_FENCE 44 @@ -499,7 +511,7 @@ struct drm_i915_gem_execbuffer2 { __u32 DR4; __u32 num_cliprects; __u64 cliprects_ptr; -#define I915_EXEC_RING_MASK (7 << 0) +#define I915_EXEC_RING_MASK (0x3f) #define I915_EXEC_DEFAULT (0 << 0) #define I915_EXEC_RENDER (1 << 0) #define I915_EXEC_BSD (2 << 0) @@ -665,30 +677,12 @@ struct drm_i915_gem_context_create { __u32 ctx_id; __u32 pad; }; -struct drm_i915_gem_context_destroy { - __u32 ctx_id; - __u32 pad; -}; -struct drm_i915_reg_read { - __u64 offset; -#define I915_REG_READ_8B_WA (1ul << 0) - __u64 val; -}; -struct drm_i915_reset_stats { +struct drm_i915_gem_context_create_ext { __u32 ctx_id; __u32 flags; - __u32 reset_count; - __u32 batch_active; - __u32 batch_pending; - __u32 pad; -}; -struct drm_i915_gem_userptr { - __u64 user_ptr; - __u64 user_size; - __u32 flags; -#define I915_USERPTR_READ_ONLY 0x1 -#define I915_USERPTR_UNSYNCHRONIZED 0x80000000 - __u32 handle; +#define I915_CONTEXT_CREATE_FLAGS_USE_EXTENSIONS (1u << 0) +#define I915_CONTEXT_CREATE_FLAGS_UNKNOWN (- (I915_CONTEXT_CREATE_FLAGS_USE_EXTENSIONS << 1)) + __u64 extensions; }; struct drm_i915_gem_context_param { __u32 ctx_id; @@ -704,11 +698,11 @@ struct drm_i915_gem_context_param { #define I915_CONTEXT_DEFAULT_PRIORITY 0 #define I915_CONTEXT_MIN_USER_PRIORITY - 1023 #define I915_CONTEXT_PARAM_SSEU 0x7 +#define I915_CONTEXT_PARAM_RECOVERABLE 0x8 __u64 value; }; struct drm_i915_gem_context_param_sseu { - __u16 engine_class; - __u16 engine_instance; + struct i915_engine_class_instance engine; __u32 flags; __u64 slice_mask; __u64 subslice_mask; @@ -716,6 +710,41 @@ struct drm_i915_gem_context_param_sseu { __u16 max_eus_per_subslice; __u32 rsvd; }; +struct drm_i915_gem_context_create_ext_setparam { +#define I915_CONTEXT_CREATE_EXT_SETPARAM 0 + struct i915_user_extension base; + struct drm_i915_gem_context_param param; +}; +struct drm_i915_gem_context_destroy { + __u32 ctx_id; + __u32 pad; +}; +struct drm_i915_gem_vm_control { + __u64 extensions; + __u32 flags; + __u32 vm_id; +}; +struct drm_i915_reg_read { + __u64 offset; +#define I915_REG_READ_8B_WA (1ul << 0) + __u64 val; +}; +struct drm_i915_reset_stats { + __u32 ctx_id; + __u32 flags; + __u32 reset_count; + __u32 batch_active; + __u32 batch_pending; + __u32 pad; +}; +struct drm_i915_gem_userptr { + __u64 user_ptr; + __u64 user_size; + __u32 flags; +#define I915_USERPTR_READ_ONLY 0x1 +#define I915_USERPTR_UNSYNCHRONIZED 0x80000000 + __u32 handle; +}; enum drm_i915_oa_format { I915_OA_FORMAT_A13 = 1, I915_OA_FORMAT_A29, diff --git a/libc/kernel/uapi/drm/lima_drm.h b/libc/kernel/uapi/drm/lima_drm.h new file mode 100644 index 000000000..bb70cf79d --- /dev/null +++ b/libc/kernel/uapi/drm/lima_drm.h @@ -0,0 +1,129 @@ +/**************************************************************************** + **************************************************************************** + *** + *** 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 __LIMA_DRM_H__ +#define __LIMA_DRM_H__ +#include "drm.h" +#ifdef __cplusplus +extern "C" { +#endif +enum drm_lima_param_gpu_id { + DRM_LIMA_PARAM_GPU_ID_UNKNOWN, + DRM_LIMA_PARAM_GPU_ID_MALI400, + DRM_LIMA_PARAM_GPU_ID_MALI450, +}; +enum drm_lima_param { + DRM_LIMA_PARAM_GPU_ID, + DRM_LIMA_PARAM_NUM_PP, + DRM_LIMA_PARAM_GP_VERSION, + DRM_LIMA_PARAM_PP_VERSION, +}; +struct drm_lima_get_param { + __u32 param; + __u32 pad; + __u64 value; +}; +struct drm_lima_gem_create { + __u32 size; + __u32 flags; + __u32 handle; + __u32 pad; +}; +struct drm_lima_gem_info { + __u32 handle; + __u32 va; + __u64 offset; +}; +#define LIMA_SUBMIT_BO_READ 0x01 +#define LIMA_SUBMIT_BO_WRITE 0x02 +struct drm_lima_gem_submit_bo { + __u32 handle; + __u32 flags; +}; +#define LIMA_GP_FRAME_REG_NUM 6 +struct drm_lima_gp_frame { + __u32 frame[LIMA_GP_FRAME_REG_NUM]; +}; +#define LIMA_PP_FRAME_REG_NUM 23 +#define LIMA_PP_WB_REG_NUM 12 +struct drm_lima_m400_pp_frame { + __u32 frame[LIMA_PP_FRAME_REG_NUM]; + __u32 num_pp; + __u32 wb[3 * LIMA_PP_WB_REG_NUM]; + __u32 plbu_array_address[4]; + __u32 fragment_stack_address[4]; +}; +struct drm_lima_m450_pp_frame { + __u32 frame[LIMA_PP_FRAME_REG_NUM]; + __u32 num_pp; + __u32 wb[3 * LIMA_PP_WB_REG_NUM]; + __u32 use_dlbu; + __u32 _pad; + union { + __u32 plbu_array_address[8]; + __u32 dlbu_regs[4]; + }; + __u32 fragment_stack_address[8]; +}; +#define LIMA_PIPE_GP 0x00 +#define LIMA_PIPE_PP 0x01 +#define LIMA_SUBMIT_FLAG_EXPLICIT_FENCE (1 << 0) +struct drm_lima_gem_submit { + __u32 ctx; + __u32 pipe; + __u32 nr_bos; + __u32 frame_size; + __u64 bos; + __u64 frame; + __u32 flags; + __u32 out_sync; + __u32 in_sync[2]; +}; +#define LIMA_GEM_WAIT_READ 0x01 +#define LIMA_GEM_WAIT_WRITE 0x02 +struct drm_lima_gem_wait { + __u32 handle; + __u32 op; + __s64 timeout_ns; +}; +struct drm_lima_ctx_create { + __u32 id; + __u32 _pad; +}; +struct drm_lima_ctx_free { + __u32 id; + __u32 _pad; +}; +#define DRM_LIMA_GET_PARAM 0x00 +#define DRM_LIMA_GEM_CREATE 0x01 +#define DRM_LIMA_GEM_INFO 0x02 +#define DRM_LIMA_GEM_SUBMIT 0x03 +#define DRM_LIMA_GEM_WAIT 0x04 +#define DRM_LIMA_CTX_CREATE 0x05 +#define DRM_LIMA_CTX_FREE 0x06 +#define DRM_IOCTL_LIMA_GET_PARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_LIMA_GET_PARAM, struct drm_lima_get_param) +#define DRM_IOCTL_LIMA_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_LIMA_GEM_CREATE, struct drm_lima_gem_create) +#define DRM_IOCTL_LIMA_GEM_INFO DRM_IOWR(DRM_COMMAND_BASE + DRM_LIMA_GEM_INFO, struct drm_lima_gem_info) +#define DRM_IOCTL_LIMA_GEM_SUBMIT DRM_IOW(DRM_COMMAND_BASE + DRM_LIMA_GEM_SUBMIT, struct drm_lima_gem_submit) +#define DRM_IOCTL_LIMA_GEM_WAIT DRM_IOW(DRM_COMMAND_BASE + DRM_LIMA_GEM_WAIT, struct drm_lima_gem_wait) +#define DRM_IOCTL_LIMA_CTX_CREATE DRM_IOR(DRM_COMMAND_BASE + DRM_LIMA_CTX_CREATE, struct drm_lima_ctx_create) +#define DRM_IOCTL_LIMA_CTX_FREE DRM_IOW(DRM_COMMAND_BASE + DRM_LIMA_CTX_FREE, struct drm_lima_ctx_free) +#ifdef __cplusplus +} +#endif +#endif diff --git a/libc/kernel/uapi/drm/msm_drm.h b/libc/kernel/uapi/drm/msm_drm.h index f6bee3e32..3c1b734b2 100644 --- a/libc/kernel/uapi/drm/msm_drm.h +++ b/libc/kernel/uapi/drm/msm_drm.h @@ -40,6 +40,8 @@ struct drm_msm_timespec { #define MSM_PARAM_TIMESTAMP 0x05 #define MSM_PARAM_GMEM_BASE 0x06 #define MSM_PARAM_NR_RINGS 0x07 +#define MSM_PARAM_PP_PGTABLE 0x08 +#define MSM_PARAM_FAULTS 0x09 struct drm_msm_param { __u32 pipe; __u32 param; @@ -143,6 +145,14 @@ struct drm_msm_submitqueue { __u32 prio; __u32 id; }; +#define MSM_SUBMITQUEUE_PARAM_FAULTS 0 +struct drm_msm_submitqueue_query { + __u64 data; + __u32 id; + __u32 param; + __u32 len; + __u32 pad; +}; #define DRM_MSM_GET_PARAM 0x00 #define DRM_MSM_GEM_NEW 0x02 #define DRM_MSM_GEM_INFO 0x03 @@ -153,6 +163,7 @@ struct drm_msm_submitqueue { #define DRM_MSM_GEM_MADVISE 0x08 #define DRM_MSM_SUBMITQUEUE_NEW 0x0A #define DRM_MSM_SUBMITQUEUE_CLOSE 0x0B +#define DRM_MSM_SUBMITQUEUE_QUERY 0x0C #define DRM_IOCTL_MSM_GET_PARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GET_PARAM, struct drm_msm_param) #define DRM_IOCTL_MSM_GEM_NEW DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GEM_NEW, struct drm_msm_gem_new) #define DRM_IOCTL_MSM_GEM_INFO DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GEM_INFO, struct drm_msm_gem_info) @@ -163,6 +174,7 @@ struct drm_msm_submitqueue { #define DRM_IOCTL_MSM_GEM_MADVISE DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GEM_MADVISE, struct drm_msm_gem_madvise) #define DRM_IOCTL_MSM_SUBMITQUEUE_NEW DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_SUBMITQUEUE_NEW, struct drm_msm_submitqueue) #define DRM_IOCTL_MSM_SUBMITQUEUE_CLOSE DRM_IOW(DRM_COMMAND_BASE + DRM_MSM_SUBMITQUEUE_CLOSE, __u32) +#define DRM_IOCTL_MSM_SUBMITQUEUE_QUERY DRM_IOW(DRM_COMMAND_BASE + DRM_MSM_SUBMITQUEUE_QUERY, struct drm_msm_submitqueue_query) #ifdef __cplusplus } #endif diff --git a/libc/kernel/uapi/drm/panfrost_drm.h b/libc/kernel/uapi/drm/panfrost_drm.h new file mode 100644 index 000000000..17f093ba4 --- /dev/null +++ b/libc/kernel/uapi/drm/panfrost_drm.h @@ -0,0 +1,80 @@ +/**************************************************************************** + **************************************************************************** + *** + *** 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 _PANFROST_DRM_H_ +#define _PANFROST_DRM_H_ +#include "drm.h" +#ifdef __cplusplus +extern "C" { +#endif +#define DRM_PANFROST_SUBMIT 0x00 +#define DRM_PANFROST_WAIT_BO 0x01 +#define DRM_PANFROST_CREATE_BO 0x02 +#define DRM_PANFROST_MMAP_BO 0x03 +#define DRM_PANFROST_GET_PARAM 0x04 +#define DRM_PANFROST_GET_BO_OFFSET 0x05 +#define DRM_IOCTL_PANFROST_SUBMIT DRM_IOW(DRM_COMMAND_BASE + DRM_PANFROST_SUBMIT, struct drm_panfrost_submit) +#define DRM_IOCTL_PANFROST_WAIT_BO DRM_IOW(DRM_COMMAND_BASE + DRM_PANFROST_WAIT_BO, struct drm_panfrost_wait_bo) +#define DRM_IOCTL_PANFROST_CREATE_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_PANFROST_CREATE_BO, struct drm_panfrost_create_bo) +#define DRM_IOCTL_PANFROST_MMAP_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_PANFROST_MMAP_BO, struct drm_panfrost_mmap_bo) +#define DRM_IOCTL_PANFROST_GET_PARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_PANFROST_GET_PARAM, struct drm_panfrost_get_param) +#define DRM_IOCTL_PANFROST_GET_BO_OFFSET DRM_IOWR(DRM_COMMAND_BASE + DRM_PANFROST_GET_BO_OFFSET, struct drm_panfrost_get_bo_offset) +#define PANFROST_JD_REQ_FS (1 << 0) +struct drm_panfrost_submit { + __u64 jc; + __u64 in_syncs; + __u32 in_sync_count; + __u32 out_sync; + __u64 bo_handles; + __u32 bo_handle_count; + __u32 requirements; +}; +struct drm_panfrost_wait_bo { + __u32 handle; + __u32 pad; + __s64 timeout_ns; +}; +struct drm_panfrost_create_bo { + __u32 size; + __u32 flags; + __u32 handle; + __u32 pad; + __u64 offset; +}; +struct drm_panfrost_mmap_bo { + __u32 handle; + __u32 flags; + __u64 offset; +}; +enum drm_panfrost_param { + DRM_PANFROST_PARAM_GPU_PROD_ID, +}; +struct drm_panfrost_get_param { + __u32 param; + __u32 pad; + __u64 value; +}; +struct drm_panfrost_get_bo_offset { + __u32 handle; + __u32 pad; + __u64 offset; +}; +#ifdef __cplusplus +} +#endif +#endif diff --git a/libc/kernel/uapi/linux/aspeed-p2a-ctrl.h b/libc/kernel/uapi/linux/aspeed-p2a-ctrl.h new file mode 100644 index 000000000..94e51326f --- /dev/null +++ b/libc/kernel/uapi/linux/aspeed-p2a-ctrl.h @@ -0,0 +1,33 @@ +/**************************************************************************** + **************************************************************************** + *** + *** 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_ASPEED_P2A_CTRL_H +#define _UAPI_LINUX_ASPEED_P2A_CTRL_H +#include <linux/ioctl.h> +#include <linux/types.h> +#define ASPEED_P2A_CTRL_READ_ONLY 0 +#define ASPEED_P2A_CTRL_READWRITE 1 +struct aspeed_p2a_ctrl_mapping { + __u64 addr; + __u32 length; + __u32 flags; +}; +#define __ASPEED_P2A_CTRL_IOCTL_MAGIC 0xb3 +#define ASPEED_P2A_CTRL_IOCTL_SET_WINDOW _IOW(__ASPEED_P2A_CTRL_IOCTL_MAGIC, 0x00, struct aspeed_p2a_ctrl_mapping) +#define ASPEED_P2A_CTRL_IOCTL_GET_MEMORY_CONFIG _IOWR(__ASPEED_P2A_CTRL_IOCTL_MAGIC, 0x01, struct aspeed_p2a_ctrl_mapping) +#endif diff --git a/libc/kernel/uapi/linux/audit.h b/libc/kernel/uapi/linux/audit.h index 0698fc84c..509d734c8 100644 --- a/libc/kernel/uapi/linux/audit.h +++ b/libc/kernel/uapi/linux/audit.h @@ -79,6 +79,8 @@ #define AUDIT_REPLACE 1329 #define AUDIT_KERN_MODULE 1330 #define AUDIT_FANOTIFY 1331 +#define AUDIT_TIME_INJOFFSET 1332 +#define AUDIT_TIME_ADJNTPVAL 1333 #define AUDIT_AVC 1400 #define AUDIT_SELINUX_ERR 1401 #define AUDIT_AVC_PATH 1402 @@ -262,11 +264,19 @@ enum { #define __AUDIT_ARCH_LE 0x40000000 #define AUDIT_ARCH_AARCH64 (EM_AARCH64 | __AUDIT_ARCH_64BIT | __AUDIT_ARCH_LE) #define AUDIT_ARCH_ALPHA (EM_ALPHA | __AUDIT_ARCH_64BIT | __AUDIT_ARCH_LE) +#define AUDIT_ARCH_ARCOMPACT (EM_ARCOMPACT | __AUDIT_ARCH_LE) +#define AUDIT_ARCH_ARCOMPACTBE (EM_ARCOMPACT) +#define AUDIT_ARCH_ARCV2 (EM_ARCV2 | __AUDIT_ARCH_LE) +#define AUDIT_ARCH_ARCV2BE (EM_ARCV2) #define AUDIT_ARCH_ARM (EM_ARM | __AUDIT_ARCH_LE) #define AUDIT_ARCH_ARMEB (EM_ARM) +#define AUDIT_ARCH_C6X (EM_TI_C6000 | __AUDIT_ARCH_LE) +#define AUDIT_ARCH_C6XBE (EM_TI_C6000) #define AUDIT_ARCH_CRIS (EM_CRIS | __AUDIT_ARCH_LE) #define AUDIT_ARCH_CSKY (EM_CSKY | __AUDIT_ARCH_LE) #define AUDIT_ARCH_FRV (EM_FRV) +#define AUDIT_ARCH_H8300 (EM_H8_300) +#define AUDIT_ARCH_HEXAGON (EM_HEXAGON) #define AUDIT_ARCH_I386 (EM_386 | __AUDIT_ARCH_LE) #define AUDIT_ARCH_IA64 (EM_IA_64 | __AUDIT_ARCH_64BIT | __AUDIT_ARCH_LE) #define AUDIT_ARCH_M32R (EM_M32R) @@ -278,6 +288,9 @@ enum { #define AUDIT_ARCH_MIPS64N32 (EM_MIPS | __AUDIT_ARCH_64BIT | __AUDIT_ARCH_CONVENTION_MIPS64_N32) #define AUDIT_ARCH_MIPSEL64 (EM_MIPS | __AUDIT_ARCH_64BIT | __AUDIT_ARCH_LE) #define AUDIT_ARCH_MIPSEL64N32 (EM_MIPS | __AUDIT_ARCH_64BIT | __AUDIT_ARCH_LE | __AUDIT_ARCH_CONVENTION_MIPS64_N32) +#define AUDIT_ARCH_NDS32 (EM_NDS32 | __AUDIT_ARCH_LE) +#define AUDIT_ARCH_NDS32BE (EM_NDS32) +#define AUDIT_ARCH_NIOS2 (EM_ALTERA_NIOS2 | __AUDIT_ARCH_LE) #define AUDIT_ARCH_OPENRISC (EM_OPENRISC) #define AUDIT_ARCH_PARISC (EM_PARISC) #define AUDIT_ARCH_PARISC64 (EM_PARISC | __AUDIT_ARCH_64BIT) @@ -297,6 +310,7 @@ enum { #define AUDIT_ARCH_TILEGX (EM_TILEGX | __AUDIT_ARCH_64BIT | __AUDIT_ARCH_LE) #define AUDIT_ARCH_TILEGX32 (EM_TILEGX | __AUDIT_ARCH_LE) #define AUDIT_ARCH_TILEPRO (EM_TILEPRO | __AUDIT_ARCH_LE) +#define AUDIT_ARCH_UNICORE (EM_UNICORE | __AUDIT_ARCH_LE) #define AUDIT_ARCH_X86_64 (EM_X86_64 | __AUDIT_ARCH_64BIT | __AUDIT_ARCH_LE) #define AUDIT_ARCH_XTENSA (EM_XTENSA) #define AUDIT_PERM_EXEC 1 diff --git a/libc/kernel/uapi/linux/batman_adv.h b/libc/kernel/uapi/linux/batman_adv.h index 9cad20a15..96b259b23 100644 --- a/libc/kernel/uapi/linux/batman_adv.h +++ b/libc/kernel/uapi/linux/batman_adv.h @@ -104,6 +104,7 @@ enum batadv_nl_attrs { BATADV_ATTR_ORIG_INTERVAL, BATADV_ATTR_ELP_INTERVAL, BATADV_ATTR_THROUGHPUT_OVERRIDE, + BATADV_ATTR_MULTICAST_FANOUT, __BATADV_ATTR_AFTER_LAST, NUM_BATADV_ATTR = __BATADV_ATTR_AFTER_LAST, BATADV_ATTR_MAX = __BATADV_ATTR_AFTER_LAST - 1 diff --git a/libc/kernel/uapi/linux/bpf.h b/libc/kernel/uapi/linux/bpf.h index edae89389..3f0942167 100644 --- a/libc/kernel/uapi/linux/bpf.h +++ b/libc/kernel/uapi/linux/bpf.h @@ -93,6 +93,7 @@ enum bpf_cmd { BPF_BTF_GET_FD_BY_ID, BPF_TASK_FD_QUERY, BPF_MAP_LOOKUP_AND_DELETE_ELEM, + BPF_MAP_FREEZE, }; enum bpf_map_type { BPF_MAP_TYPE_UNSPEC, @@ -119,6 +120,7 @@ enum bpf_map_type { BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE, BPF_MAP_TYPE_QUEUE, BPF_MAP_TYPE_STACK, + BPF_MAP_TYPE_SK_STORAGE, }; enum bpf_prog_type { BPF_PROG_TYPE_UNSPEC, @@ -144,6 +146,8 @@ enum bpf_prog_type { BPF_PROG_TYPE_LIRC_MODE2, BPF_PROG_TYPE_SK_REUSEPORT, BPF_PROG_TYPE_FLOW_DISSECTOR, + BPF_PROG_TYPE_CGROUP_SYSCTL, + BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE, }; enum bpf_attach_type { BPF_CGROUP_INET_INGRESS, @@ -164,6 +168,9 @@ enum bpf_attach_type { BPF_CGROUP_UDP6_SENDMSG, BPF_LIRC_MODE2, BPF_FLOW_DISSECTOR, + BPF_CGROUP_SYSCTL, + BPF_CGROUP_UDP4_RECVMSG, + BPF_CGROUP_UDP6_RECVMSG, __MAX_BPF_ATTACH_TYPE }; #define MAX_BPF_ATTACH_TYPE __MAX_BPF_ATTACH_TYPE @@ -172,6 +179,7 @@ enum bpf_attach_type { #define BPF_F_STRICT_ALIGNMENT (1U << 0) #define BPF_F_ANY_ALIGNMENT (1U << 1) #define BPF_PSEUDO_MAP_FD 1 +#define BPF_PSEUDO_MAP_VALUE 2 #define BPF_PSEUDO_CALL 1 #define BPF_ANY 0 #define BPF_NOEXIST 1 @@ -185,6 +193,8 @@ enum bpf_attach_type { #define BPF_F_WRONLY (1U << 4) #define BPF_F_STACK_BUILD_ID (1U << 5) #define BPF_F_ZERO_SEED (1U << 6) +#define BPF_F_RDONLY_PROG (1U << 7) +#define BPF_F_WRONLY_PROG (1U << 8) #define BPF_F_QUERY_EFFECTIVE (1U << 0) enum bpf_stack_build_id_status { BPF_STACK_BUILD_ID_EMPTY = 0, @@ -265,6 +275,10 @@ union bpf_attr { __aligned_u64 data_out; __u32 repeat; __u32 duration; + __u32 ctx_size_in; + __u32 ctx_size_out; + __aligned_u64 ctx_in; + __aligned_u64 ctx_out; } test; struct { union { @@ -312,7 +326,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), 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), FN(msg_pop_data), FN(rc_pointer_rel), FN(spin_lock), FN(spin_unlock), FN(sk_fullsock), FN(tcp_sock), FN(skb_ecn_set_ce), FN(get_listener_sock), +#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), FN(msg_pop_data), FN(rc_pointer_rel), FN(spin_lock), FN(spin_unlock), FN(sk_fullsock), FN(tcp_sock), FN(skb_ecn_set_ce), FN(get_listener_sock), FN(skc_lookup_tcp), FN(tcp_check_syncookie), FN(sysctl_get_name), FN(sysctl_get_current_value), FN(sysctl_get_new_value), FN(sysctl_set_new_value), FN(strtol), FN(strtoul), FN(sk_storage_get), FN(sk_storage_delete), #define __BPF_ENUM_FN(x) BPF_FUNC_ ##x enum bpf_func_id { __BPF_FUNC_MAPPER(__BPF_ENUM_FN) __BPF_FUNC_MAX_ID, @@ -338,8 +352,19 @@ enum bpf_func_id { #define BPF_F_CURRENT_CPU BPF_F_INDEX_MASK #define BPF_F_CTXLEN_MASK (0xfffffULL << 32) #define BPF_F_CURRENT_NETNS (- 1L) +#define BPF_F_ADJ_ROOM_FIXED_GSO (1ULL << 0) +#define BPF_ADJ_ROOM_ENCAP_L2_MASK 0xff +#define BPF_ADJ_ROOM_ENCAP_L2_SHIFT 56 +#define BPF_F_ADJ_ROOM_ENCAP_L3_IPV4 (1ULL << 1) +#define BPF_F_ADJ_ROOM_ENCAP_L3_IPV6 (1ULL << 2) +#define BPF_F_ADJ_ROOM_ENCAP_L4_GRE (1ULL << 3) +#define BPF_F_ADJ_ROOM_ENCAP_L4_UDP (1ULL << 4) +#define BPF_F_ADJ_ROOM_ENCAP_L2(len) (((__u64) len & BPF_ADJ_ROOM_ENCAP_L2_MASK) << BPF_ADJ_ROOM_ENCAP_L2_SHIFT) +#define BPF_F_SYSCTL_BASE_NAME (1ULL << 0) +#define BPF_SK_STORAGE_GET_F_CREATE (1ULL << 0) enum bpf_adj_room_mode { BPF_ADJ_ROOM_NET, + BPF_ADJ_ROOM_MAC, }; enum bpf_hdr_start_off { BPF_HDR_START_MAC, @@ -523,6 +548,7 @@ struct bpf_prog_info { char name[BPF_OBJ_NAME_LEN]; __u32 ifindex; __u32 gpl_compatible : 1; + __u32 : 31; __u64 netns_dev; __u64 netns_ino; __u32 nr_jited_ksyms; @@ -670,8 +696,8 @@ struct bpf_cgroup_dev_ctx { struct bpf_raw_tracepoint_args { __u64 args[0]; }; -#define BPF_FIB_LOOKUP_DIRECT BIT(0) -#define BPF_FIB_LOOKUP_OUTPUT BIT(1) +#define BPF_FIB_LOOKUP_DIRECT (1U << 0) +#define BPF_FIB_LOOKUP_OUTPUT (1U << 1) enum { BPF_FIB_LKUP_RET_SUCCESS, BPF_FIB_LKUP_RET_BLACKHOLE, @@ -753,4 +779,8 @@ struct bpf_line_info { struct bpf_spin_lock { __u32 val; }; +struct bpf_sysctl { + __u32 write; + __u32 file_pos; +}; #endif diff --git a/libc/kernel/uapi/linux/btf.h b/libc/kernel/uapi/linux/btf.h index 6e1363151..475e2eb71 100644 --- a/libc/kernel/uapi/linux/btf.h +++ b/libc/kernel/uapi/linux/btf.h @@ -59,10 +59,12 @@ struct btf_type { #define BTF_KIND_RESTRICT 11 #define BTF_KIND_FUNC 12 #define BTF_KIND_FUNC_PROTO 13 -#define BTF_KIND_MAX 13 -#define NR_BTF_KINDS 14 +#define BTF_KIND_VAR 14 +#define BTF_KIND_DATASEC 15 +#define BTF_KIND_MAX BTF_KIND_DATASEC +#define NR_BTF_KINDS (BTF_KIND_MAX + 1) #define BTF_INT_ENCODING(VAL) (((VAL) & 0x0f000000) >> 24) -#define BTF_INT_OFFSET(VAL) (((VAL & 0x00ff0000)) >> 16) +#define BTF_INT_OFFSET(VAL) (((VAL) & 0x00ff0000) >> 16) #define BTF_INT_BITS(VAL) ((VAL) & 0x000000ff) #define BTF_INT_SIGNED (1 << 0) #define BTF_INT_CHAR (1 << 1) @@ -87,4 +89,16 @@ struct btf_param { __u32 name_off; __u32 type; }; +enum { + BTF_VAR_STATIC = 0, + BTF_VAR_GLOBAL_ALLOCATED, +}; +struct btf_var { + __u32 linkage; +}; +struct btf_var_secinfo { + __u32 type; + __u32 offset; + __u32 size; +}; #endif diff --git a/libc/kernel/uapi/linux/elf-em.h b/libc/kernel/uapi/linux/elf-em.h index 99835aeca..d1ed1f6ce 100644 --- a/libc/kernel/uapi/linux/elf-em.h +++ b/libc/kernel/uapi/linux/elf-em.h @@ -45,14 +45,19 @@ #define EM_M32R 88 #define EM_MN10300 89 #define EM_OPENRISC 92 +#define EM_ARCOMPACT 93 #define EM_XTENSA 94 #define EM_BLACKFIN 106 +#define EM_UNICORE 110 #define EM_ALTERA_NIOS2 113 #define EM_TI_C6000 140 +#define EM_HEXAGON 164 +#define EM_NDS32 167 #define EM_AARCH64 183 #define EM_TILEPRO 188 #define EM_MICROBLAZE 189 #define EM_TILEGX 191 +#define EM_ARCV2 195 #define EM_RISCV 243 #define EM_BPF 247 #define EM_CSKY 252 diff --git a/libc/kernel/uapi/linux/ethtool.h b/libc/kernel/uapi/linux/ethtool.h index 642af99f3..67a7efde0 100644 --- a/libc/kernel/uapi/linux/ethtool.h +++ b/libc/kernel/uapi/linux/ethtool.h @@ -101,9 +101,12 @@ struct ethtool_tunable { }; #define DOWNSHIFT_DEV_DEFAULT_COUNT 0xff #define DOWNSHIFT_DEV_DISABLE 0 +#define ETHTOOL_PHY_FAST_LINK_DOWN_ON 0 +#define ETHTOOL_PHY_FAST_LINK_DOWN_OFF 0xff enum phy_tunable_id { ETHTOOL_PHY_ID_UNSPEC, ETHTOOL_PHY_DOWNSHIFT, + ETHTOOL_PHY_FAST_LINK_DOWN, __ETHTOOL_PHY_TUNABLE_COUNT, }; struct ethtool_regs { @@ -754,6 +757,8 @@ enum ethtool_link_mode_bit_indices { #define ETH_MODULE_SFF_8636_LEN 256 #define ETH_MODULE_SFF_8436 0x4 #define ETH_MODULE_SFF_8436_LEN 256 +#define ETH_MODULE_SFF_8636_MAX_LEN 640 +#define ETH_MODULE_SFF_8436_MAX_LEN 640 enum ethtool_reset_flags { ETH_RESET_MGMT = 1 << 0, ETH_RESET_IRQ = 1 << 1, diff --git a/libc/kernel/uapi/linux/fcntl.h b/libc/kernel/uapi/linux/fcntl.h index 66f27b659..e2045c8cf 100644 --- a/libc/kernel/uapi/linux/fcntl.h +++ b/libc/kernel/uapi/linux/fcntl.h @@ -60,4 +60,5 @@ #define AT_STATX_SYNC_AS_STAT 0x0000 #define AT_STATX_FORCE_SYNC 0x2000 #define AT_STATX_DONT_SYNC 0x4000 +#define AT_RECURSIVE 0x8000 #endif diff --git a/libc/kernel/uapi/linux/fou.h b/libc/kernel/uapi/linux/fou.h index 7e59bd026..a16b8c672 100644 --- a/libc/kernel/uapi/linux/fou.h +++ b/libc/kernel/uapi/linux/fou.h @@ -27,6 +27,12 @@ enum { FOU_ATTR_IPPROTO, FOU_ATTR_TYPE, FOU_ATTR_REMCSUM_NOPARTIAL, + FOU_ATTR_LOCAL_V4, + FOU_ATTR_LOCAL_V6, + FOU_ATTR_PEER_V4, + FOU_ATTR_PEER_V6, + FOU_ATTR_PEER_PORT, + FOU_ATTR_IFINDEX, __FOU_ATTR_MAX, }; #define FOU_ATTR_MAX (__FOU_ATTR_MAX - 1) diff --git a/libc/kernel/uapi/linux/fs.h b/libc/kernel/uapi/linux/fs.h index 84dc010ea..5edd66b78 100644 --- a/libc/kernel/uapi/linux/fs.h +++ b/libc/kernel/uapi/linux/fs.h @@ -219,6 +219,7 @@ struct fscrypt_key { #define SYNC_FILE_RANGE_WAIT_BEFORE 1 #define SYNC_FILE_RANGE_WRITE 2 #define SYNC_FILE_RANGE_WAIT_AFTER 4 +#define SYNC_FILE_RANGE_WRITE_AND_WAIT (SYNC_FILE_RANGE_WRITE | SYNC_FILE_RANGE_WAIT_BEFORE | SYNC_FILE_RANGE_WAIT_AFTER) typedef int __bitwise __kernel_rwf_t; #define RWF_HIPRI ((__force __kernel_rwf_t) 0x00000001) #define RWF_DSYNC ((__force __kernel_rwf_t) 0x00000002) diff --git a/libc/kernel/uapi/linux/fuse.h b/libc/kernel/uapi/linux/fuse.h index 4a76ae317..86b01f05a 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 29 +#define FUSE_KERNEL_MINOR_VERSION 31 #define FUSE_ROOT_ID 1 struct fuse_attr { uint64_t ino; @@ -73,6 +73,7 @@ struct fuse_file_lock { #define FOPEN_KEEP_CACHE (1 << 1) #define FOPEN_NONSEEKABLE (1 << 2) #define FOPEN_CACHE_DIR (1 << 3) +#define FOPEN_STREAM (1 << 4) #define FUSE_ASYNC_READ (1 << 0) #define FUSE_POSIX_LOCKS (1 << 1) #define FUSE_FILE_OPS (1 << 2) @@ -98,6 +99,7 @@ struct fuse_file_lock { #define FUSE_MAX_PAGES (1 << 22) #define FUSE_CACHE_SYMLINKS (1 << 23) #define FUSE_NO_OPENDIR_SUPPORT (1 << 24) +#define FUSE_EXPLICIT_INVAL_DATA (1 << 25) #define CUSE_UNRESTRICTED_IOCTL (1 << 0) #define FUSE_RELEASE_FLUSH (1 << 0) #define FUSE_RELEASE_FLOCK_UNLOCK (1 << 1) @@ -105,14 +107,17 @@ struct fuse_file_lock { #define FUSE_LK_FLOCK (1 << 0) #define FUSE_WRITE_CACHE (1 << 0) #define FUSE_WRITE_LOCKOWNER (1 << 1) +#define FUSE_WRITE_KILL_PRIV (1 << 2) #define FUSE_READ_LOCKOWNER (1 << 1) #define FUSE_IOCTL_COMPAT (1 << 0) #define FUSE_IOCTL_UNRESTRICTED (1 << 1) #define FUSE_IOCTL_RETRY (1 << 2) #define FUSE_IOCTL_32BIT (1 << 3) #define FUSE_IOCTL_DIR (1 << 4) +#define FUSE_IOCTL_COMPAT_X32 (1 << 5) #define FUSE_IOCTL_MAX_IOV 256 #define FUSE_POLL_SCHEDULE_NOTIFY (1 << 0) +#define FUSE_FSYNC_FDATASYNC (1 << 0) enum fuse_opcode { FUSE_LOOKUP = 1, FUSE_FORGET = 2, diff --git a/libc/kernel/uapi/linux/icmpv6.h b/libc/kernel/uapi/linux/icmpv6.h index ef73a7c18..798a94599 100644 --- a/libc/kernel/uapi/linux/icmpv6.h +++ b/libc/kernel/uapi/linux/icmpv6.h @@ -77,6 +77,7 @@ struct icmp6hdr { #define ICMPV6_PKT_TOOBIG 2 #define ICMPV6_TIME_EXCEED 3 #define ICMPV6_PARAMPROB 4 +#define ICMPV6_ERRMSG_MAX 127 #define ICMPV6_INFOMSG_MASK 0x80 #define ICMPV6_ECHO_REQUEST 128 #define ICMPV6_ECHO_REPLY 129 @@ -91,6 +92,7 @@ struct icmp6hdr { #define ICMPV6_MOBILE_PREFIX_SOL 146 #define ICMPV6_MOBILE_PREFIX_ADV 147 #define ICMPV6_MRDISC_ADV 151 +#define ICMPV6_MSG_MAX 255 #define ICMPV6_NOROUTE 0 #define ICMPV6_ADM_PROHIBITED 1 #define ICMPV6_NOT_NEIGHBOUR 2 diff --git a/libc/kernel/uapi/linux/if_ether.h b/libc/kernel/uapi/linux/if_ether.h index 4fb58f193..9e0b15c54 100644 --- a/libc/kernel/uapi/linux/if_ether.h +++ b/libc/kernel/uapi/linux/if_ether.h @@ -90,6 +90,7 @@ #define ETH_P_QINQ2 0x9200 #define ETH_P_QINQ3 0x9300 #define ETH_P_EDSA 0xDADA +#define ETH_P_DSA_8021Q 0xDADB #define ETH_P_IFE 0xED3E #define ETH_P_AF_IUCV 0xFBFB #define ETH_P_802_3_MIN 0x0600 diff --git a/libc/kernel/uapi/linux/if_tun.h b/libc/kernel/uapi/linux/if_tun.h index cb2d2d234..d1a8f9ecf 100644 --- a/libc/kernel/uapi/linux/if_tun.h +++ b/libc/kernel/uapi/linux/if_tun.h @@ -52,6 +52,7 @@ #define TUNSETSTEERINGEBPF _IOR('T', 224, int) #define TUNSETFILTEREBPF _IOR('T', 225, int) #define TUNSETCARRIER _IOW('T', 226, int) +#define TUNGETDEVNETNS _IO('T', 227) #define IFF_TUN 0x0001 #define IFF_TAP 0x0002 #define IFF_NAPI 0x0010 diff --git a/libc/kernel/uapi/linux/if_vlan.h b/libc/kernel/uapi/linux/if_vlan.h index 27403b639..8ca8900db 100644 --- a/libc/kernel/uapi/linux/if_vlan.h +++ b/libc/kernel/uapi/linux/if_vlan.h @@ -35,6 +35,7 @@ enum vlan_flags { VLAN_FLAG_GVRP = 0x2, VLAN_FLAG_LOOSE_BINDING = 0x4, VLAN_FLAG_MVRP = 0x8, + VLAN_FLAG_BRIDGE_BINDING = 0x10, }; enum vlan_name_types { VLAN_NAME_TYPE_PLUS_VID, diff --git a/libc/kernel/uapi/linux/input-event-codes.h b/libc/kernel/uapi/linux/input-event-codes.h index 7bbb2340e..5d20c2481 100644 --- a/libc/kernel/uapi/linux/input-event-codes.h +++ b/libc/kernel/uapi/linux/input-event-codes.h @@ -543,6 +543,7 @@ #define KEY_SCREENSAVER 0x245 #define KEY_VOICECOMMAND 0x246 #define KEY_ASSISTANT 0x247 +#define KEY_KBD_LAYOUT_NEXT 0x248 #define KEY_BRIGHTNESS_MIN 0x250 #define KEY_BRIGHTNESS_MAX 0x251 #define KEY_KBDINPUTASSIST_PREV 0x260 diff --git a/libc/kernel/uapi/linux/io_uring.h b/libc/kernel/uapi/linux/io_uring.h index fe2d0eb28..434b24bfa 100644 --- a/libc/kernel/uapi/linux/io_uring.h +++ b/libc/kernel/uapi/linux/io_uring.h @@ -32,6 +32,7 @@ struct io_uring_sqe { __kernel_rwf_t rw_flags; __u32 fsync_flags; __u16 poll_events; + __u32 sync_range_flags; }; __u64 user_data; union { @@ -40,6 +41,7 @@ struct io_uring_sqe { }; }; #define IOSQE_FIXED_FILE (1U << 0) +#define IOSQE_IO_DRAIN (1U << 1) #define IORING_SETUP_IOPOLL (1U << 0) #define IORING_SETUP_SQPOLL (1U << 1) #define IORING_SETUP_SQ_AFF (1U << 2) @@ -51,6 +53,7 @@ struct io_uring_sqe { #define IORING_OP_WRITE_FIXED 5 #define IORING_OP_POLL_ADD 6 #define IORING_OP_POLL_REMOVE 7 +#define IORING_OP_SYNC_FILE_RANGE 8 #define IORING_FSYNC_DATASYNC (1U << 0) struct io_uring_cqe { __u64 user_data; @@ -97,4 +100,6 @@ struct io_uring_params { #define IORING_UNREGISTER_BUFFERS 1 #define IORING_REGISTER_FILES 2 #define IORING_UNREGISTER_FILES 3 +#define IORING_REGISTER_EVENTFD 4 +#define IORING_UNREGISTER_EVENTFD 5 #endif diff --git a/libc/kernel/uapi/linux/ip_vs.h b/libc/kernel/uapi/linux/ip_vs.h index d89598d25..0230aae7a 100644 --- a/libc/kernel/uapi/linux/ip_vs.h +++ b/libc/kernel/uapi/linux/ip_vs.h @@ -85,6 +85,11 @@ #define IP_VS_PENAME_MAXLEN 16 #define IP_VS_IFNAME_MAXLEN 16 #define IP_VS_PEDATA_MAXLEN 255 +enum { + IP_VS_CONN_F_TUNNEL_TYPE_IPIP = 0, + IP_VS_CONN_F_TUNNEL_TYPE_GUE, + IP_VS_CONN_F_TUNNEL_TYPE_MAX, +}; struct ip_vs_service_user { __u16 protocol; __be32 addr; @@ -236,6 +241,8 @@ enum { IPVS_DEST_ATTR_STATS, IPVS_DEST_ATTR_ADDR_FAMILY, IPVS_DEST_ATTR_STATS64, + IPVS_DEST_ATTR_TUN_TYPE, + IPVS_DEST_ATTR_TUN_PORT, __IPVS_DEST_ATTR_MAX, }; #define IPVS_DEST_ATTR_MAX (__IPVS_DEST_ATTR_MAX - 1) diff --git a/libc/kernel/uapi/linux/kfd_ioctl.h b/libc/kernel/uapi/linux/kfd_ioctl.h index 5e2060617..400c4239d 100644 --- a/libc/kernel/uapi/linux/kfd_ioctl.h +++ b/libc/kernel/uapi/linux/kfd_ioctl.h @@ -148,6 +148,10 @@ struct kfd_ioctl_dbg_wave_control_args { #define KFD_HW_EXCEPTION_PER_ENGINE_RESET 1 #define KFD_HW_EXCEPTION_GPU_HANG 0 #define KFD_HW_EXCEPTION_ECC 1 +#define KFD_MEM_ERR_NO_RAS 0 +#define KFD_MEM_ERR_SRAM_ECC 1 +#define KFD_MEM_ERR_POISON_CONSUMED 2 +#define KFD_MEM_ERR_GPU_HANG 3 struct kfd_ioctl_create_event_args { __u64 event_page_offset; __u32 event_trigger_data; @@ -179,7 +183,7 @@ struct kfd_hsa_memory_exception_data { struct kfd_memory_exception_failure failure; __u64 va; __u32 gpu_id; - __u32 pad; + __u32 ErrorType; }; struct kfd_hsa_hw_exception_data { __u32 reset_type; diff --git a/libc/kernel/uapi/linux/kvm.h b/libc/kernel/uapi/linux/kvm.h index 8cfa34d76..374b0d15e 100644 --- a/libc/kernel/uapi/linux/kvm.h +++ b/libc/kernel/uapi/linux/kvm.h @@ -770,6 +770,11 @@ struct kvm_ppc_resize_hpt { #define KVM_CAP_ARM_VM_IPA_SIZE 165 #define KVM_CAP_MANUAL_DIRTY_LOG_PROTECT 166 #define KVM_CAP_HYPERV_CPUID 167 +#define KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2 168 +#define KVM_CAP_PPC_IRQ_XIVE 169 +#define KVM_CAP_ARM_SVE 170 +#define KVM_CAP_ARM_PTRAUTH_ADDRESS 171 +#define KVM_CAP_ARM_PTRAUTH_GENERIC 172 #ifdef KVM_CAP_IRQ_ROUTING struct kvm_irq_routing_irqchip { __u32 irqchip; @@ -886,6 +891,7 @@ struct kvm_dirty_tlb { #define KVM_REG_SIZE_U256 0x0050000000000000ULL #define KVM_REG_SIZE_U512 0x0060000000000000ULL #define KVM_REG_SIZE_U1024 0x0070000000000000ULL +#define KVM_REG_SIZE_U2048 0x0080000000000000ULL struct kvm_reg_list { __u64 n; __u64 reg[0]; @@ -940,6 +946,8 @@ enum kvm_device_type { #define KVM_DEV_TYPE_ARM_VGIC_V3 KVM_DEV_TYPE_ARM_VGIC_V3 KVM_DEV_TYPE_ARM_VGIC_ITS, #define KVM_DEV_TYPE_ARM_VGIC_ITS KVM_DEV_TYPE_ARM_VGIC_ITS + KVM_DEV_TYPE_XIVE, +#define KVM_DEV_TYPE_XIVE KVM_DEV_TYPE_XIVE KVM_DEV_TYPE_MAX, }; struct kvm_vfio_spapr_tce { @@ -1083,6 +1091,7 @@ struct kvm_enc_region { #define KVM_SET_NESTED_STATE _IOW(KVMIO, 0xbf, struct kvm_nested_state) #define KVM_CLEAR_DIRTY_LOG _IOWR(KVMIO, 0xc0, struct kvm_clear_dirty_log) #define KVM_GET_SUPPORTED_HV_CPUID _IOWR(KVMIO, 0xc1, struct kvm_cpuid2) +#define KVM_ARM_VCPU_FINALIZE _IOW(KVMIO, 0xc2, int) enum sev_cmd_id { KVM_SEV_INIT = 0, KVM_SEV_ES_INIT, diff --git a/libc/kernel/uapi/linux/lirc.h b/libc/kernel/uapi/linux/lirc.h index 515d8ce90..20b08e9ed 100644 --- a/libc/kernel/uapi/linux/lirc.h +++ b/libc/kernel/uapi/linux/lirc.h @@ -130,5 +130,6 @@ enum rc_proto { RC_PROTO_RCMM12 = 24, RC_PROTO_RCMM24 = 25, RC_PROTO_RCMM32 = 26, + RC_PROTO_XBOX_DVD = 27, }; #endif diff --git a/libc/kernel/uapi/linux/media-bus-format.h b/libc/kernel/uapi/linux/media-bus-format.h index 7c701b1ca..1b1300215 100644 --- a/libc/kernel/uapi/linux/media-bus-format.h +++ b/libc/kernel/uapi/linux/media-bus-format.h @@ -34,6 +34,7 @@ #define MEDIA_BUS_FMT_RGB666_1X24_CPADHI 0x1015 #define MEDIA_BUS_FMT_RGB666_1X7X3_SPWG 0x1010 #define MEDIA_BUS_FMT_BGR888_1X24 0x1013 +#define MEDIA_BUS_FMT_BGR888_3X8 0x101b #define MEDIA_BUS_FMT_GBR888_1X24 0x1014 #define MEDIA_BUS_FMT_RGB888_1X24 0x100a #define MEDIA_BUS_FMT_RGB888_2X12_BE 0x100b diff --git a/libc/kernel/uapi/linux/media.h b/libc/kernel/uapi/linux/media.h index 4ba0ef669..68821e70c 100644 --- a/libc/kernel/uapi/linux/media.h +++ b/libc/kernel/uapi/linux/media.h @@ -141,6 +141,10 @@ struct media_links_enum { #define MEDIA_INTF_T_V4L_SUBDEV (MEDIA_INTF_T_V4L_BASE + 3) #define MEDIA_INTF_T_V4L_SWRADIO (MEDIA_INTF_T_V4L_BASE + 4) #define MEDIA_INTF_T_V4L_TOUCH (MEDIA_INTF_T_V4L_BASE + 5) +#define MEDIA_INTF_T_ALSA_BASE 0x00000300 +#define MEDIA_INTF_T_ALSA_PCM_CAPTURE (MEDIA_INTF_T_ALSA_BASE) +#define MEDIA_INTF_T_ALSA_PCM_PLAYBACK (MEDIA_INTF_T_ALSA_BASE + 1) +#define MEDIA_INTF_T_ALSA_CONTROL (MEDIA_INTF_T_ALSA_BASE + 2) #define MEDIA_V2_ENTITY_HAS_FLAGS(media_version) ((media_version) >= ((4 << 16) | (19 << 8) | 0)) struct media_v2_entity { __u32 id; @@ -219,10 +223,6 @@ struct media_v2_topology { #define MEDIA_ENT_T_V4L2_SUBDEV_DECODER MEDIA_ENT_F_ATV_DECODER #define MEDIA_ENT_T_V4L2_SUBDEV_TUNER MEDIA_ENT_F_TUNER #define MEDIA_ENT_F_DTV_DECODER MEDIA_ENT_F_DV_DECODER -#define MEDIA_INTF_T_ALSA_BASE 0x00000300 -#define MEDIA_INTF_T_ALSA_PCM_CAPTURE (MEDIA_INTF_T_ALSA_BASE) -#define MEDIA_INTF_T_ALSA_PCM_PLAYBACK (MEDIA_INTF_T_ALSA_BASE + 1) -#define MEDIA_INTF_T_ALSA_CONTROL (MEDIA_INTF_T_ALSA_BASE + 2) #define MEDIA_INTF_T_ALSA_COMPRESS (MEDIA_INTF_T_ALSA_BASE + 3) #define MEDIA_INTF_T_ALSA_RAWMIDI (MEDIA_INTF_T_ALSA_BASE + 4) #define MEDIA_INTF_T_ALSA_HWDEP (MEDIA_INTF_T_ALSA_BASE + 5) diff --git a/libc/kernel/uapi/linux/mount.h b/libc/kernel/uapi/linux/mount.h index 54a471968..10c53a506 100644 --- a/libc/kernel/uapi/linux/mount.h +++ b/libc/kernel/uapi/linux/mount.h @@ -52,4 +52,38 @@ #define MS_RMT_MASK (MS_RDONLY | MS_SYNCHRONOUS | MS_MANDLOCK | MS_I_VERSION | MS_LAZYTIME) #define MS_MGC_VAL 0xC0ED0000 #define MS_MGC_MSK 0xffff0000 +#define OPEN_TREE_CLONE 1 +#define OPEN_TREE_CLOEXEC O_CLOEXEC +#define MOVE_MOUNT_F_SYMLINKS 0x00000001 +#define MOVE_MOUNT_F_AUTOMOUNTS 0x00000002 +#define MOVE_MOUNT_F_EMPTY_PATH 0x00000004 +#define MOVE_MOUNT_T_SYMLINKS 0x00000010 +#define MOVE_MOUNT_T_AUTOMOUNTS 0x00000020 +#define MOVE_MOUNT_T_EMPTY_PATH 0x00000040 +#define MOVE_MOUNT__MASK 0x00000077 +#define FSOPEN_CLOEXEC 0x00000001 +#define FSPICK_CLOEXEC 0x00000001 +#define FSPICK_SYMLINK_NOFOLLOW 0x00000002 +#define FSPICK_NO_AUTOMOUNT 0x00000004 +#define FSPICK_EMPTY_PATH 0x00000008 +enum fsconfig_command { + FSCONFIG_SET_FLAG = 0, + FSCONFIG_SET_STRING = 1, + FSCONFIG_SET_BINARY = 2, + FSCONFIG_SET_PATH = 3, + FSCONFIG_SET_PATH_EMPTY = 4, + FSCONFIG_SET_FD = 5, + FSCONFIG_CMD_CREATE = 6, + FSCONFIG_CMD_RECONFIGURE = 7, +}; +#define FSMOUNT_CLOEXEC 0x00000001 +#define MOUNT_ATTR_RDONLY 0x00000001 +#define MOUNT_ATTR_NOSUID 0x00000002 +#define MOUNT_ATTR_NODEV 0x00000004 +#define MOUNT_ATTR_NOEXEC 0x00000008 +#define MOUNT_ATTR__ATIME 0x00000070 +#define MOUNT_ATTR_RELATIME 0x00000000 +#define MOUNT_ATTR_NOATIME 0x00000010 +#define MOUNT_ATTR_STRICTATIME 0x00000020 +#define MOUNT_ATTR_NODIRATIME 0x00000080 #endif diff --git a/libc/kernel/uapi/linux/netfilter/nf_tables.h b/libc/kernel/uapi/linux/netfilter/nf_tables.h index 1043799a0..6869f58f8 100644 --- a/libc/kernel/uapi/linux/netfilter/nf_tables.h +++ b/libc/kernel/uapi/linux/netfilter/nf_tables.h @@ -496,7 +496,7 @@ enum nft_ct_keys { NFT_CT_DST_IP, NFT_CT_SRC_IP6, NFT_CT_DST_IP6, - NFT_CT_TIMEOUT, + NFT_CT_ID, __NFT_CT_MAX }; #define NFT_CT_MAX (__NFT_CT_MAX - 1) @@ -574,7 +574,7 @@ enum nft_log_level { NFT_LOGLEVEL_AUDIT, __NFT_LOGLEVEL_MAX }; -#define NFT_LOGLEVEL_MAX (__NFT_LOGLEVEL_MAX + 1) +#define NFT_LOGLEVEL_MAX (__NFT_LOGLEVEL_MAX - 1) enum nft_queue_attributes { NFTA_QUEUE_UNSPEC, NFTA_QUEUE_NUM, @@ -786,9 +786,13 @@ enum nft_osf_attributes { NFTA_OSF_UNSPEC, NFTA_OSF_DREG, NFTA_OSF_TTL, + NFTA_OSF_FLAGS, __NFTA_OSF_MAX, }; #define NFTA_OSF_MAX (__NFTA_OSF_MAX - 1) +enum nft_osf_flags { + NFT_OSF_F_VERSION = (1 << 0), +}; enum nft_devices_attributes { NFTA_DEVICE_UNSPEC, NFTA_DEVICE_NAME, diff --git a/libc/kernel/uapi/linux/nfs_mount.h b/libc/kernel/uapi/linux/nfs_mount.h index ddd318abd..5b0022238 100644 --- a/libc/kernel/uapi/linux/nfs_mount.h +++ b/libc/kernel/uapi/linux/nfs_mount.h @@ -62,10 +62,4 @@ struct nfs_mount_data { #define NFS_MOUNT_NORDIRPLUS 0x4000 #define NFS_MOUNT_UNSHARED 0x8000 #define NFS_MOUNT_FLAGMASK 0xFFFF -#define NFS_MOUNT_LOOKUP_CACHE_NONEG 0x10000 -#define NFS_MOUNT_LOOKUP_CACHE_NONE 0x20000 -#define NFS_MOUNT_NORESVPORT 0x40000 -#define NFS_MOUNT_LEGACY_INTERFACE 0x80000 -#define NFS_MOUNT_LOCAL_FLOCK 0x100000 -#define NFS_MOUNT_LOCAL_FCNTL 0x200000 #endif diff --git a/libc/kernel/uapi/linux/nfsd/cld.h b/libc/kernel/uapi/linux/nfsd/cld.h index 82651d13c..ed99e73bf 100644 --- a/libc/kernel/uapi/linux/nfsd/cld.h +++ b/libc/kernel/uapi/linux/nfsd/cld.h @@ -26,6 +26,7 @@ enum cld_command { Cld_Remove, Cld_Check, Cld_GraceDone, + Cld_GraceStart, }; struct cld_name { __u16 cn_len; diff --git a/libc/kernel/uapi/linux/nilfs2_ondisk.h b/libc/kernel/uapi/linux/nilfs2_ondisk.h index e9995a11a..a05e7b732 100644 --- a/libc/kernel/uapi/linux/nilfs2_ondisk.h +++ b/libc/kernel/uapi/linux/nilfs2_ondisk.h @@ -20,6 +20,7 @@ #define _LINUX_NILFS2_ONDISK_H #include <linux/types.h> #include <linux/magic.h> +#include <asm/byteorder.h> #define NILFS_INODE_BMAP_SIZE 7 struct nilfs_inode { __le64 i_blocks; @@ -248,11 +249,11 @@ enum { NILFS_CHECKPOINT_MINOR, }; #define NILFS_CHECKPOINT_FNS(flag,name) static inline void nilfs_checkpoint_set_ ##name(struct nilfs_checkpoint * cp) \ -{ cp->cp_flags = cpu_to_le32(le32_to_cpu(cp->cp_flags) | (1UL << NILFS_CHECKPOINT_ ##flag)); \ +{ cp->cp_flags = __cpu_to_le32(__le32_to_cpu(cp->cp_flags) | (1UL << NILFS_CHECKPOINT_ ##flag)); \ } static inline void nilfs_checkpoint_clear_ ##name(struct nilfs_checkpoint * cp) \ -{ cp->cp_flags = cpu_to_le32(le32_to_cpu(cp->cp_flags) & ~(1UL << NILFS_CHECKPOINT_ ##flag)); \ +{ cp->cp_flags = __cpu_to_le32(__le32_to_cpu(cp->cp_flags) & ~(1UL << NILFS_CHECKPOINT_ ##flag)); \ } static inline int nilfs_checkpoint_ ##name(const struct nilfs_checkpoint * cp) \ -{ return ! ! (le32_to_cpu(cp->cp_flags) & (1UL << NILFS_CHECKPOINT_ ##flag)); \ +{ return ! ! (__le32_to_cpu(cp->cp_flags) & (1UL << NILFS_CHECKPOINT_ ##flag)); \ } struct nilfs_cpfile_header { __le64 ch_ncheckpoints; @@ -272,11 +273,11 @@ enum { NILFS_SEGMENT_USAGE_ERROR, }; #define NILFS_SEGMENT_USAGE_FNS(flag,name) static inline void nilfs_segment_usage_set_ ##name(struct nilfs_segment_usage * su) \ -{ su->su_flags = cpu_to_le32(le32_to_cpu(su->su_flags) | (1UL << NILFS_SEGMENT_USAGE_ ##flag)); \ +{ su->su_flags = __cpu_to_le32(__le32_to_cpu(su->su_flags) | (1UL << NILFS_SEGMENT_USAGE_ ##flag)); \ } static inline void nilfs_segment_usage_clear_ ##name(struct nilfs_segment_usage * su) \ -{ su->su_flags = cpu_to_le32(le32_to_cpu(su->su_flags) & ~(1UL << NILFS_SEGMENT_USAGE_ ##flag)); \ +{ su->su_flags = __cpu_to_le32(__le32_to_cpu(su->su_flags) & ~(1UL << NILFS_SEGMENT_USAGE_ ##flag)); \ } static inline int nilfs_segment_usage_ ##name(const struct nilfs_segment_usage * su) \ -{ return ! ! (le32_to_cpu(su->su_flags) & (1UL << NILFS_SEGMENT_USAGE_ ##flag)); \ +{ return ! ! (__le32_to_cpu(su->su_flags) & (1UL << NILFS_SEGMENT_USAGE_ ##flag)); \ } struct nilfs_sufile_header { __le64 sh_ncleansegs; diff --git a/libc/kernel/uapi/linux/nl80211.h b/libc/kernel/uapi/linux/nl80211.h index a7f63096e..93b219690 100644 --- a/libc/kernel/uapi/linux/nl80211.h +++ b/libc/kernel/uapi/linux/nl80211.h @@ -168,6 +168,8 @@ enum nl80211_commands { NL80211_CMD_PEER_MEASUREMENT_RESULT, NL80211_CMD_PEER_MEASUREMENT_COMPLETE, NL80211_CMD_NOTIFY_RADAR, + NL80211_CMD_UPDATE_OWE_INFO, + NL80211_CMD_PROBE_MESH_LINK, __NL80211_CMD_AFTER_LAST, NL80211_CMD_MAX = __NL80211_CMD_AFTER_LAST - 1 }; @@ -459,6 +461,8 @@ enum nl80211_attrs { NL80211_ATTR_TIMEOUT, NL80211_ATTR_PEER_MEASUREMENTS, NL80211_ATTR_AIRTIME_WEIGHT, + NL80211_ATTR_STA_TX_POWER_SETTING, + NL80211_ATTR_STA_TX_POWER, __NL80211_ATTR_AFTER_LAST, NUM_NL80211_ATTR = __NL80211_ATTR_AFTER_LAST, NL80211_ATTR_MAX = __NL80211_ATTR_AFTER_LAST - 1 @@ -491,7 +495,7 @@ enum nl80211_attrs { #define NL80211_WIPHY_NAME_MAXLEN 64 #define NL80211_MAX_SUPP_RATES 32 #define NL80211_MAX_SUPP_HT_RATES 77 -#define NL80211_MAX_SUPP_REG_RULES 64 +#define NL80211_MAX_SUPP_REG_RULES 128 #define NL80211_TKIP_DATA_OFFSET_ENCR_KEY 0 #define NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY 16 #define NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY 24 @@ -631,6 +635,7 @@ enum nl80211_sta_info { NL80211_STA_INFO_CONNECTED_TO_GATE, NL80211_STA_INFO_TX_DURATION, NL80211_STA_INFO_AIRTIME_WEIGHT, + NL80211_STA_INFO_AIRTIME_LINK_METRIC, __NL80211_STA_INFO_AFTER_LAST, NL80211_STA_INFO_MAX = __NL80211_STA_INFO_AFTER_LAST - 1 }; @@ -783,6 +788,7 @@ enum nl80211_sched_scan_match_attr { NL80211_SCHED_SCAN_MATCH_ATTR_RELATIVE_RSSI, NL80211_SCHED_SCAN_MATCH_ATTR_RSSI_ADJUST, NL80211_SCHED_SCAN_MATCH_ATTR_BSSID, + NL80211_SCHED_SCAN_MATCH_PER_BAND_RSSI, __NL80211_SCHED_SCAN_MATCH_ATTR_AFTER_LAST, NL80211_SCHED_SCAN_MATCH_ATTR_MAX = __NL80211_SCHED_SCAN_MATCH_ATTR_AFTER_LAST - 1 }; @@ -935,6 +941,11 @@ enum nl80211_channel_type { NL80211_CHAN_HT40MINUS, NL80211_CHAN_HT40PLUS }; +enum nl80211_key_mode { + NL80211_KEY_RX_TX, + NL80211_KEY_NO_TX, + NL80211_KEY_SET_TX +}; enum nl80211_chan_width { NL80211_CHAN_WIDTH_20_NOHT, NL80211_CHAN_WIDTH_20, @@ -1023,6 +1034,7 @@ enum nl80211_key_attributes { NL80211_KEY_DEFAULT_MGMT, NL80211_KEY_TYPE, NL80211_KEY_DEFAULT_TYPES, + NL80211_KEY_MODE, __NL80211_KEY_AFTER_LAST, NL80211_KEY_MAX = __NL80211_KEY_AFTER_LAST - 1 }; @@ -1311,6 +1323,9 @@ enum nl80211_ext_feature_index { NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER, NL80211_EXT_FEATURE_AIRTIME_FAIRNESS, NL80211_EXT_FEATURE_AP_PMKSA_CACHING, + NL80211_EXT_FEATURE_SCHED_SCAN_BAND_SPECIFIC_RSSI_THOLD, + NL80211_EXT_FEATURE_EXT_KEY_ID, + NL80211_EXT_FEATURE_STA_TX_PWR, NUM_NL80211_EXT_FEATURES, MAX_NL80211_EXT_FEATURES = NUM_NL80211_EXT_FEATURES - 1 }; diff --git a/libc/kernel/uapi/linux/openvswitch.h b/libc/kernel/uapi/linux/openvswitch.h index 7e75ac6f6..2344ab19e 100644 --- a/libc/kernel/uapi/linux/openvswitch.h +++ b/libc/kernel/uapi/linux/openvswitch.h @@ -205,6 +205,7 @@ enum ovs_tunnel_key_attr { OVS_TUNNEL_KEY_ATTR_IPV6_DST, OVS_TUNNEL_KEY_ATTR_PAD, OVS_TUNNEL_KEY_ATTR_ERSPAN_OPTS, + OVS_TUNNEL_KEY_ATTR_IPV4_INFO_BRIDGE, __OVS_TUNNEL_KEY_ATTR_MAX }; #define OVS_TUNNEL_KEY_ATTR_MAX (__OVS_TUNNEL_KEY_ATTR_MAX - 1) @@ -384,6 +385,7 @@ enum ovs_ct_attr { OVS_CT_ATTR_NAT, OVS_CT_ATTR_FORCE_COMMIT, OVS_CT_ATTR_EVENTMASK, + OVS_CT_ATTR_TIMEOUT, __OVS_CT_ATTR_MAX }; #define OVS_CT_ATTR_MAX (__OVS_CT_ATTR_MAX - 1) @@ -404,6 +406,14 @@ enum ovs_nat_attr { struct ovs_action_push_eth { struct ovs_key_ethernet addresses; }; +enum ovs_check_pkt_len_attr { + OVS_CHECK_PKT_LEN_ATTR_UNSPEC, + OVS_CHECK_PKT_LEN_ATTR_PKT_LEN, + OVS_CHECK_PKT_LEN_ATTR_ACTIONS_IF_GREATER, + OVS_CHECK_PKT_LEN_ATTR_ACTIONS_IF_LESS_EQUAL, + __OVS_CHECK_PKT_LEN_ATTR_MAX, +}; +#define OVS_CHECK_PKT_LEN_ATTR_MAX (__OVS_CHECK_PKT_LEN_ATTR_MAX - 1) enum ovs_action_attr { OVS_ACTION_ATTR_UNSPEC, OVS_ACTION_ATTR_OUTPUT, @@ -426,6 +436,7 @@ enum ovs_action_attr { OVS_ACTION_ATTR_POP_NSH, OVS_ACTION_ATTR_METER, OVS_ACTION_ATTR_CLONE, + OVS_ACTION_ATTR_CHECK_PKT_LEN, __OVS_ACTION_ATTR_MAX, }; #define OVS_ACTION_ATTR_MAX (__OVS_ACTION_ATTR_MAX - 1) diff --git a/libc/kernel/uapi/linux/pci_regs.h b/libc/kernel/uapi/linux/pci_regs.h index d75d200e9..4c8cc9583 100644 --- a/libc/kernel/uapi/linux/pci_regs.h +++ b/libc/kernel/uapi/linux/pci_regs.h @@ -275,7 +275,7 @@ #define PCI_MSIX_ENTRY_UPPER_ADDR 4 #define PCI_MSIX_ENTRY_DATA 8 #define PCI_MSIX_ENTRY_VECTOR_CTRL 12 -#define PCI_MSIX_ENTRY_CTRL_MASKBIT 1 +#define PCI_MSIX_ENTRY_CTRL_MASKBIT 0x00000001 #define PCI_CHSWP_CSR 2 #define PCI_CHSWP_DHA 0x01 #define PCI_CHSWP_EIM 0x02 @@ -299,6 +299,9 @@ #define PCI_EA_FIRST_ENT_BRIDGE 8 #define PCI_EA_ES 0x00000007 #define PCI_EA_BEI 0x000000f0 +#define PCI_EA_SEC_BUS_MASK 0xff +#define PCI_EA_SUB_BUS_MASK 0xff00 +#define PCI_EA_SUB_BUS_SHIFT 8 #define PCI_EA_BEI_BAR0 0 #define PCI_EA_BEI_BAR5 5 #define PCI_EA_BEI_BRIDGE 6 @@ -746,12 +749,12 @@ #define PCI_ATS_MIN_STU 12 #define PCI_EXT_CAP_ATS_SIZEOF 8 #define PCI_PRI_CTRL 0x04 -#define PCI_PRI_CTRL_ENABLE 0x01 -#define PCI_PRI_CTRL_RESET 0x02 +#define PCI_PRI_CTRL_ENABLE 0x0001 +#define PCI_PRI_CTRL_RESET 0x0002 #define PCI_PRI_STATUS 0x06 -#define PCI_PRI_STATUS_RF 0x001 -#define PCI_PRI_STATUS_UPRGI 0x002 -#define PCI_PRI_STATUS_STOPPED 0x100 +#define PCI_PRI_STATUS_RF 0x0001 +#define PCI_PRI_STATUS_UPRGI 0x0002 +#define PCI_PRI_STATUS_STOPPED 0x0100 #define PCI_PRI_STATUS_PASID 0x8000 #define PCI_PRI_MAX_REQ 0x08 #define PCI_PRI_ALLOC_REQ 0x0c @@ -765,16 +768,16 @@ #define PCI_PASID_CTRL_PRIV 0x04 #define PCI_EXT_CAP_PASID_SIZEOF 8 #define PCI_SRIOV_CAP 0x04 -#define PCI_SRIOV_CAP_VFM 0x01 +#define PCI_SRIOV_CAP_VFM 0x00000001 #define PCI_SRIOV_CAP_INTR(x) ((x) >> 21) #define PCI_SRIOV_CTRL 0x08 -#define PCI_SRIOV_CTRL_VFE 0x01 -#define PCI_SRIOV_CTRL_VFM 0x02 -#define PCI_SRIOV_CTRL_INTR 0x04 -#define PCI_SRIOV_CTRL_MSE 0x08 -#define PCI_SRIOV_CTRL_ARI 0x10 +#define PCI_SRIOV_CTRL_VFE 0x0001 +#define PCI_SRIOV_CTRL_VFM 0x0002 +#define PCI_SRIOV_CTRL_INTR 0x0004 +#define PCI_SRIOV_CTRL_MSE 0x0008 +#define PCI_SRIOV_CTRL_ARI 0x0010 #define PCI_SRIOV_STATUS 0x0a -#define PCI_SRIOV_STATUS_VFM 0x01 +#define PCI_SRIOV_STATUS_VFM 0x0001 #define PCI_SRIOV_INITIAL_VF 0x0c #define PCI_SRIOV_TOTAL_VF 0x0e #define PCI_SRIOV_NUM_VF 0x10 @@ -801,13 +804,13 @@ #define PCI_LTR_SCALE_SHIFT 10 #define PCI_EXT_CAP_LTR_SIZEOF 8 #define PCI_ACS_CAP 0x04 -#define PCI_ACS_SV 0x01 -#define PCI_ACS_TB 0x02 -#define PCI_ACS_RR 0x04 -#define PCI_ACS_CR 0x08 -#define PCI_ACS_UF 0x10 -#define PCI_ACS_EC 0x20 -#define PCI_ACS_DT 0x40 +#define PCI_ACS_SV 0x0001 +#define PCI_ACS_TB 0x0002 +#define PCI_ACS_RR 0x0004 +#define PCI_ACS_CR 0x0008 +#define PCI_ACS_UF 0x0010 +#define PCI_ACS_EC 0x0020 +#define PCI_ACS_DT 0x0040 #define PCI_ACS_EGRESS_BITS 0x05 #define PCI_ACS_CTRL 0x06 #define PCI_ACS_EGRESS_CTL_V 0x08 diff --git a/libc/kernel/uapi/linux/pkt_sched.h b/libc/kernel/uapi/linux/pkt_sched.h index 6adc01307..2e1f24b7d 100644 --- a/libc/kernel/uapi/linux/pkt_sched.h +++ b/libc/kernel/uapi/linux/pkt_sched.h @@ -883,6 +883,9 @@ enum { TCA_TAPRIO_ATTR_SCHED_SINGLE_ENTRY, TCA_TAPRIO_ATTR_SCHED_CLOCKID, TCA_TAPRIO_PAD, + TCA_TAPRIO_ATTR_ADMIN_SCHED, + TCA_TAPRIO_ATTR_SCHED_CYCLE_TIME, + TCA_TAPRIO_ATTR_SCHED_CYCLE_TIME_EXTENSION, __TCA_TAPRIO_ATTR_MAX, }; #define TCA_TAPRIO_ATTR_MAX (__TCA_TAPRIO_ATTR_MAX - 1) diff --git a/libc/kernel/uapi/linux/psci.h b/libc/kernel/uapi/linux/psci.h index 658552a6f..bc522e78f 100644 --- a/libc/kernel/uapi/linux/psci.h +++ b/libc/kernel/uapi/linux/psci.h @@ -40,7 +40,10 @@ #define PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU PSCI_0_2_FN64(7) #define PSCI_1_0_FN_PSCI_FEATURES PSCI_0_2_FN(10) #define PSCI_1_0_FN_SYSTEM_SUSPEND PSCI_0_2_FN(14) +#define PSCI_1_0_FN_SET_SUSPEND_MODE PSCI_0_2_FN(15) +#define PSCI_1_1_FN_SYSTEM_RESET2 PSCI_0_2_FN(18) #define PSCI_1_0_FN64_SYSTEM_SUSPEND PSCI_0_2_FN64(14) +#define PSCI_1_1_FN64_SYSTEM_RESET2 PSCI_0_2_FN64(18) #define PSCI_0_2_POWER_STATE_ID_MASK 0xffff #define PSCI_0_2_POWER_STATE_ID_SHIFT 0 #define PSCI_0_2_POWER_STATE_TYPE_SHIFT 16 @@ -65,6 +68,9 @@ #define PSCI_VERSION(maj,min) ((((maj) << PSCI_VERSION_MAJOR_SHIFT) & PSCI_VERSION_MAJOR_MASK) | ((min) & PSCI_VERSION_MINOR_MASK)) #define PSCI_1_0_FEATURES_CPU_SUSPEND_PF_SHIFT 1 #define PSCI_1_0_FEATURES_CPU_SUSPEND_PF_MASK (0x1 << PSCI_1_0_FEATURES_CPU_SUSPEND_PF_SHIFT) +#define PSCI_1_0_OS_INITIATED BIT(0) +#define PSCI_1_0_SUSPEND_MODE_PC 0 +#define PSCI_1_0_SUSPEND_MODE_OSI 1 #define PSCI_RET_SUCCESS 0 #define PSCI_RET_NOT_SUPPORTED - 1 #define PSCI_RET_INVALID_PARAMS - 2 diff --git a/libc/kernel/uapi/linux/psp-sev.h b/libc/kernel/uapi/linux/psp-sev.h index 10582d48a..b3f88dc2f 100644 --- a/libc/kernel/uapi/linux/psp-sev.h +++ b/libc/kernel/uapi/linux/psp-sev.h @@ -28,6 +28,7 @@ enum { SEV_PDH_CERT_EXPORT, SEV_PEK_CERT_IMPORT, SEV_GET_ID, + SEV_GET_ID2, SEV_MAX, }; typedef enum { @@ -83,6 +84,10 @@ struct sev_user_data_get_id { __u8 socket1[64]; __u8 socket2[64]; } __packed; +struct sev_user_data_get_id2 { + __u64 address; + __u32 length; +} __packed; struct sev_issue_cmd { __u32 cmd; __u64 data; diff --git a/libc/kernel/uapi/linux/sched.h b/libc/kernel/uapi/linux/sched.h index 20d4956a7..046008391 100644 --- a/libc/kernel/uapi/linux/sched.h +++ b/libc/kernel/uapi/linux/sched.h @@ -23,6 +23,7 @@ #define CLONE_FS 0x00000200 #define CLONE_FILES 0x00000400 #define CLONE_SIGHAND 0x00000800 +#define CLONE_PIDFD 0x00001000 #define CLONE_PTRACE 0x00002000 #define CLONE_VFORK 0x00004000 #define CLONE_PARENT 0x00008000 diff --git a/libc/kernel/uapi/linux/serial_core.h b/libc/kernel/uapi/linux/serial_core.h index 791f5d7f6..c5ce9fe02 100644 --- a/libc/kernel/uapi/linux/serial_core.h +++ b/libc/kernel/uapi/linux/serial_core.h @@ -136,4 +136,6 @@ #define PORT_MPS2UART 116 #define PORT_MTK_BTIF 117 #define PORT_RDA 118 +#define PORT_MLB_USIO 119 +#define PORT_SIFIVE_V0 120 #endif diff --git a/libc/kernel/uapi/linux/snmp.h b/libc/kernel/uapi/linux/snmp.h index 75dea5495..2a48541fc 100644 --- a/libc/kernel/uapi/linux/snmp.h +++ b/libc/kernel/uapi/linux/snmp.h @@ -250,6 +250,7 @@ enum { LINUX_MIB_TCPACKCOMPRESSED, LINUX_MIB_TCPZEROWINDOWDROP, LINUX_MIB_TCPRCVQDROP, + LINUX_MIB_TCPWQUEUETOOBIG, __LINUX_MIB_MAX }; enum { diff --git a/libc/kernel/uapi/linux/sockios.h b/libc/kernel/uapi/linux/sockios.h index c68a5b137..2d13d9380 100644 --- a/libc/kernel/uapi/linux/sockios.h +++ b/libc/kernel/uapi/linux/sockios.h @@ -18,10 +18,20 @@ ****************************************************************************/ #ifndef _LINUX_SOCKIOS_H #define _LINUX_SOCKIOS_H +#include <asm/bitsperlong.h> #include <asm/sockios.h> #define SIOCINQ FIONREAD #define SIOCOUTQ TIOCOUTQ #define SOCK_IOC_TYPE 0x89 +#define SIOCGSTAMP_NEW _IOR(SOCK_IOC_TYPE, 0x06, long long[2]) +#define SIOCGSTAMPNS_NEW _IOR(SOCK_IOC_TYPE, 0x07, long long[2]) +#if __BITS_PER_LONG == 64 || defined(__x86_64__) && defined(__ILP32__) +#define SIOCGSTAMP SIOCGSTAMP_OLD +#define SIOCGSTAMPNS SIOCGSTAMPNS_OLD +#else +#define SIOCGSTAMP ((sizeof(struct timeval)) == 8 ? SIOCGSTAMP_OLD : SIOCGSTAMP_NEW) +#define SIOCGSTAMPNS ((sizeof(struct timespec)) == 8 ? SIOCGSTAMPNS_OLD : SIOCGSTAMPNS_NEW) +#endif #define SIOCADDRT 0x890B #define SIOCDELRT 0x890C #define SIOCRTMSG 0x890D diff --git a/libc/kernel/uapi/linux/spi/spidev.h b/libc/kernel/uapi/linux/spi/spidev.h index 2fe826445..343285b20 100644 --- a/libc/kernel/uapi/linux/spi/spidev.h +++ b/libc/kernel/uapi/linux/spi/spidev.h @@ -47,7 +47,8 @@ struct spi_ioc_transfer { __u8 cs_change; __u8 tx_nbits; __u8 rx_nbits; - __u16 pad; + __u8 word_delay_usecs; + __u8 pad; }; #define SPI_MSGSIZE(N) ((((N) * (sizeof(struct spi_ioc_transfer))) < (1 << _IOC_SIZEBITS)) ? ((N) * (sizeof(struct spi_ioc_transfer))) : 0) #define SPI_IOC_MESSAGE(N) _IOW(SPI_IOC_MAGIC, 0, char[SPI_MSGSIZE(N)]) diff --git a/libc/kernel/uapi/linux/switchtec_ioctl.h b/libc/kernel/uapi/linux/switchtec_ioctl.h index 09cf9cdba..2143148e6 100644 --- a/libc/kernel/uapi/linux/switchtec_ioctl.h +++ b/libc/kernel/uapi/linux/switchtec_ioctl.h @@ -46,7 +46,7 @@ struct switchtec_ioctl_flash_part_info { __u32 length; __u32 active; }; -struct switchtec_ioctl_event_summary { +struct switchtec_ioctl_event_summary_legacy { __u64 global; __u64 part_bitmap; __u32 local_part; @@ -54,6 +54,14 @@ struct switchtec_ioctl_event_summary { __u32 part[48]; __u32 pff[48]; }; +struct switchtec_ioctl_event_summary { + __u64 global; + __u64 part_bitmap; + __u32 local_part; + __u32 padding; + __u32 part[48]; + __u32 pff[255]; +}; #define SWITCHTEC_IOCTL_EVENT_STACK_ERROR 0 #define SWITCHTEC_IOCTL_EVENT_PPU_ERROR 1 #define SWITCHTEC_IOCTL_EVENT_ISP_ERROR 2 @@ -114,6 +122,7 @@ struct switchtec_ioctl_pff_port { #define SWITCHTEC_IOCTL_FLASH_INFO _IOR('W', 0x40, struct switchtec_ioctl_flash_info) #define SWITCHTEC_IOCTL_FLASH_PART_INFO _IOWR('W', 0x41, struct switchtec_ioctl_flash_part_info) #define SWITCHTEC_IOCTL_EVENT_SUMMARY _IOR('W', 0x42, struct switchtec_ioctl_event_summary) +#define SWITCHTEC_IOCTL_EVENT_SUMMARY_LEGACY _IOR('W', 0x42, struct switchtec_ioctl_event_summary_legacy) #define SWITCHTEC_IOCTL_EVENT_CTL _IOWR('W', 0x43, struct switchtec_ioctl_event_ctl) #define SWITCHTEC_IOCTL_PFF_TO_PORT _IOWR('W', 0x44, struct switchtec_ioctl_pff_port) #define SWITCHTEC_IOCTL_PORT_TO_PFF _IOWR('W', 0x45, struct switchtec_ioctl_pff_port) diff --git a/libc/kernel/uapi/linux/tipc.h b/libc/kernel/uapi/linux/tipc.h index 72bcad97d..b66b3400d 100644 --- a/libc/kernel/uapi/linux/tipc.h +++ b/libc/kernel/uapi/linux/tipc.h @@ -111,6 +111,7 @@ struct sockaddr_tipc { #define TIPC_MCAST_REPLICAST 134 #define TIPC_GROUP_JOIN 135 #define TIPC_GROUP_LEAVE 136 +#define TIPC_SOCK_RECVQ_USED 137 #define TIPC_GROUP_LOOPBACK 0x1 #define TIPC_GROUP_MEMBER_EVTS 0x2 struct tipc_group_req { diff --git a/libc/kernel/uapi/linux/tipc_netlink.h b/libc/kernel/uapi/linux/tipc_netlink.h index 911bbdea1..372111819 100644 --- a/libc/kernel/uapi/linux/tipc_netlink.h +++ b/libc/kernel/uapi/linux/tipc_netlink.h @@ -212,6 +212,8 @@ enum { TIPC_NLA_PROP_TOL, TIPC_NLA_PROP_WIN, TIPC_NLA_PROP_MTU, + TIPC_NLA_PROP_BROADCAST, + TIPC_NLA_PROP_BROADCAST_RATIO, __TIPC_NLA_PROP_MAX, TIPC_NLA_PROP_MAX = __TIPC_NLA_PROP_MAX - 1 }; diff --git a/libc/kernel/uapi/linux/tls.h b/libc/kernel/uapi/linux/tls.h index 96bb3a56e..e18882634 100644 --- a/libc/kernel/uapi/linux/tls.h +++ b/libc/kernel/uapi/linux/tls.h @@ -42,6 +42,12 @@ #define TLS_CIPHER_AES_GCM_256_SALT_SIZE 4 #define TLS_CIPHER_AES_GCM_256_TAG_SIZE 16 #define TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE 8 +#define TLS_CIPHER_AES_CCM_128 53 +#define TLS_CIPHER_AES_CCM_128_IV_SIZE 8 +#define TLS_CIPHER_AES_CCM_128_KEY_SIZE 16 +#define TLS_CIPHER_AES_CCM_128_SALT_SIZE 4 +#define TLS_CIPHER_AES_CCM_128_TAG_SIZE 16 +#define TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE 8 #define TLS_SET_RECORD_TYPE 1 #define TLS_GET_RECORD_TYPE 2 struct tls_crypto_info { @@ -62,4 +68,11 @@ struct tls12_crypto_info_aes_gcm_256 { unsigned char salt[TLS_CIPHER_AES_GCM_256_SALT_SIZE]; unsigned char rec_seq[TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE]; }; +struct tls12_crypto_info_aes_ccm_128 { + struct tls_crypto_info info; + unsigned char iv[TLS_CIPHER_AES_CCM_128_IV_SIZE]; + unsigned char key[TLS_CIPHER_AES_CCM_128_KEY_SIZE]; + unsigned char salt[TLS_CIPHER_AES_CCM_128_SALT_SIZE]; + unsigned char rec_seq[TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE]; +}; #endif diff --git a/libc/kernel/uapi/linux/v4l2-controls.h b/libc/kernel/uapi/linux/v4l2-controls.h index e8108dd10..7a133f538 100644 --- a/libc/kernel/uapi/linux/v4l2-controls.h +++ b/libc/kernel/uapi/linux/v4l2-controls.h @@ -310,6 +310,8 @@ enum v4l2_mpeg_video_multi_slice_mode { #define V4L2_CID_MPEG_VIDEO_MV_H_SEARCH_RANGE (V4L2_CID_MPEG_BASE + 227) #define V4L2_CID_MPEG_VIDEO_MV_V_SEARCH_RANGE (V4L2_CID_MPEG_BASE + 228) #define V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME (V4L2_CID_MPEG_BASE + 229) +#define V4L2_CID_FWHT_I_FRAME_QP (V4L2_CID_MPEG_BASE + 290) +#define V4L2_CID_FWHT_P_FRAME_QP (V4L2_CID_MPEG_BASE + 291) #define V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP (V4L2_CID_MPEG_BASE + 300) #define V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP (V4L2_CID_MPEG_BASE + 301) #define V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP (V4L2_CID_MPEG_BASE + 302) @@ -441,6 +443,10 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type { #define V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_QP (V4L2_CID_MPEG_BASE + 382) #define V4L2_CID_MPEG_VIDEO_H264_CONSTRAINED_INTRA_PREDICTION (V4L2_CID_MPEG_BASE + 383) #define V4L2_CID_MPEG_VIDEO_H264_CHROMA_QP_INDEX_OFFSET (V4L2_CID_MPEG_BASE + 384) +#define V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MIN_QP (V4L2_CID_MPEG_BASE + 385) +#define V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MAX_QP (V4L2_CID_MPEG_BASE + 386) +#define V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MIN_QP (V4L2_CID_MPEG_BASE + 387) +#define V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MAX_QP (V4L2_CID_MPEG_BASE + 388) #define V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP (V4L2_CID_MPEG_BASE + 400) #define V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP (V4L2_CID_MPEG_BASE + 401) #define V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP (V4L2_CID_MPEG_BASE + 402) diff --git a/libc/kernel/uapi/linux/version.h b/libc/kernel/uapi/linux/version.h index 5905e81de..94bf4ba5e 100644 --- a/libc/kernel/uapi/linux/version.h +++ b/libc/kernel/uapi/linux/version.h @@ -16,5 +16,5 @@ *** **************************************************************************** ****************************************************************************/ -#define LINUX_VERSION_CODE 327939 +#define LINUX_VERSION_CODE 328198 #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 b947abce2..62cd970ab 100644 --- a/libc/kernel/uapi/linux/vfio.h +++ b/libc/kernel/uapi/linux/vfio.h @@ -114,6 +114,8 @@ struct vfio_region_gfx_edid { #define VFIO_DEVICE_GFX_LINK_STATE_UP 1 #define VFIO_DEVICE_GFX_LINK_STATE_DOWN 2 }; +#define VFIO_REGION_TYPE_CCW (2) +#define VFIO_REGION_SUBTYPE_CCW_ASYNC_CMD (1) #define VFIO_REGION_SUBTYPE_NVIDIA_NVLINK2_RAM (1) #define VFIO_REGION_SUBTYPE_IBM_NVLINK2_ATSD (1) #define VFIO_REGION_INFO_CAP_MSIX_MAPPABLE 3 diff --git a/libc/kernel/uapi/linux/vfio_ccw.h b/libc/kernel/uapi/linux/vfio_ccw.h index 047862fd9..6ed6830e4 100644 --- a/libc/kernel/uapi/linux/vfio_ccw.h +++ b/libc/kernel/uapi/linux/vfio_ccw.h @@ -28,4 +28,10 @@ struct ccw_io_region { __u8 irb_area[IRB_AREA_SIZE]; __u32 ret_code; } __packed; +#define VFIO_CCW_ASYNC_CMD_HSCH (1 << 0) +#define VFIO_CCW_ASYNC_CMD_CSCH (1 << 1) +struct ccw_cmd_region { + __u32 command; + __u32 ret_code; +} __packed; #endif diff --git a/libc/kernel/uapi/linux/videodev2.h b/libc/kernel/uapi/linux/videodev2.h index 3bd71381f..f77c6bda5 100644 --- a/libc/kernel/uapi/linux/videodev2.h +++ b/libc/kernel/uapi/linux/videodev2.h @@ -206,9 +206,21 @@ struct v4l2_pix_format { #define V4L2_PIX_FMT_RGB444 v4l2_fourcc('R', '4', '4', '4') #define V4L2_PIX_FMT_ARGB444 v4l2_fourcc('A', 'R', '1', '2') #define V4L2_PIX_FMT_XRGB444 v4l2_fourcc('X', 'R', '1', '2') +#define V4L2_PIX_FMT_RGBA444 v4l2_fourcc('R', 'A', '1', '2') +#define V4L2_PIX_FMT_RGBX444 v4l2_fourcc('R', 'X', '1', '2') +#define V4L2_PIX_FMT_ABGR444 v4l2_fourcc('A', 'B', '1', '2') +#define V4L2_PIX_FMT_XBGR444 v4l2_fourcc('X', 'B', '1', '2') +#define V4L2_PIX_FMT_BGRA444 v4l2_fourcc('G', 'A', '1', '2') +#define V4L2_PIX_FMT_BGRX444 v4l2_fourcc('B', 'X', '1', '2') #define V4L2_PIX_FMT_RGB555 v4l2_fourcc('R', 'G', 'B', 'O') #define V4L2_PIX_FMT_ARGB555 v4l2_fourcc('A', 'R', '1', '5') #define V4L2_PIX_FMT_XRGB555 v4l2_fourcc('X', 'R', '1', '5') +#define V4L2_PIX_FMT_RGBA555 v4l2_fourcc('R', 'A', '1', '5') +#define V4L2_PIX_FMT_RGBX555 v4l2_fourcc('R', 'X', '1', '5') +#define V4L2_PIX_FMT_ABGR555 v4l2_fourcc('A', 'B', '1', '5') +#define V4L2_PIX_FMT_XBGR555 v4l2_fourcc('X', 'B', '1', '5') +#define V4L2_PIX_FMT_BGRA555 v4l2_fourcc('B', 'A', '1', '5') +#define V4L2_PIX_FMT_BGRX555 v4l2_fourcc('B', 'X', '1', '5') #define V4L2_PIX_FMT_RGB565 v4l2_fourcc('R', 'G', 'B', 'P') #define V4L2_PIX_FMT_RGB555X v4l2_fourcc('R', 'G', 'B', 'Q') #define V4L2_PIX_FMT_ARGB555X v4l2_fourcc_be('A', 'R', '1', '5') @@ -220,7 +232,11 @@ struct v4l2_pix_format { #define V4L2_PIX_FMT_BGR32 v4l2_fourcc('B', 'G', 'R', '4') #define V4L2_PIX_FMT_ABGR32 v4l2_fourcc('A', 'R', '2', '4') #define V4L2_PIX_FMT_XBGR32 v4l2_fourcc('X', 'R', '2', '4') +#define V4L2_PIX_FMT_BGRA32 v4l2_fourcc('R', 'A', '2', '4') +#define V4L2_PIX_FMT_BGRX32 v4l2_fourcc('R', 'X', '2', '4') #define V4L2_PIX_FMT_RGB32 v4l2_fourcc('R', 'G', 'B', '4') +#define V4L2_PIX_FMT_RGBA32 v4l2_fourcc('A', 'B', '2', '4') +#define V4L2_PIX_FMT_RGBX32 v4l2_fourcc('X', 'B', '2', '4') #define V4L2_PIX_FMT_ARGB32 v4l2_fourcc('B', 'A', '2', '4') #define V4L2_PIX_FMT_XRGB32 v4l2_fourcc('B', 'X', '2', '4') #define V4L2_PIX_FMT_GREY v4l2_fourcc('G', 'R', 'E', 'Y') @@ -332,6 +348,7 @@ struct v4l2_pix_format { #define V4L2_PIX_FMT_VP9 v4l2_fourcc('V', 'P', '9', '0') #define V4L2_PIX_FMT_HEVC v4l2_fourcc('H', 'E', 'V', 'C') #define V4L2_PIX_FMT_FWHT v4l2_fourcc('F', 'W', 'H', 'T') +#define V4L2_PIX_FMT_FWHT_STATELESS v4l2_fourcc('S', 'F', 'W', 'H') #define V4L2_PIX_FMT_CPIA1 v4l2_fourcc('C', 'P', 'I', 'A') #define V4L2_PIX_FMT_WNVA v4l2_fourcc('W', 'N', 'V', 'A') #define V4L2_PIX_FMT_SN9C10X v4l2_fourcc('S', '9', '1', '0') diff --git a/libc/kernel/uapi/misc/habanalabs.h b/libc/kernel/uapi/misc/habanalabs.h index c2e25de6d..1029a672d 100644 --- a/libc/kernel/uapi/misc/habanalabs.h +++ b/libc/kernel/uapi/misc/habanalabs.h @@ -39,10 +39,16 @@ enum goya_queue_id { GOYA_QUEUE_ID_TPC7, GOYA_QUEUE_ID_SIZE }; +enum hl_device_status { + HL_DEVICE_STATUS_OPERATIONAL, + HL_DEVICE_STATUS_IN_RESET, + HL_DEVICE_STATUS_MALFUNCTION +}; #define HL_INFO_HW_IP_INFO 0 #define HL_INFO_HW_EVENTS 1 #define HL_INFO_DRAM_USAGE 2 #define HL_INFO_HW_IDLE 3 +#define HL_INFO_DEVICE_STATUS 4 #define HL_INFO_VERSION_MAX_LEN 128 struct hl_info_hw_ip_info { __u64 sram_base_address; @@ -70,6 +76,10 @@ struct hl_info_hw_idle { __u32 is_idle; __u32 pad; }; +struct hl_info_device_status { + __u32 status; + __u32 pad; +}; struct hl_info_args { __u64 return_pointer; __u32 return_size; @@ -183,11 +193,64 @@ union hl_mem_args { struct hl_mem_in in; struct hl_mem_out out; }; +#define HL_DEBUG_MAX_AUX_VALUES 10 +struct hl_debug_params_etr { + __u64 buffer_address; + __u64 buffer_size; + __u32 sink_mode; + __u32 pad; +}; +struct hl_debug_params_etf { + __u64 buffer_address; + __u64 buffer_size; + __u32 sink_mode; + __u32 pad; +}; +struct hl_debug_params_stm { + __u64 he_mask; + __u64 sp_mask; + __u32 id; + __u32 frequency; +}; +struct hl_debug_params_bmon { + __u64 start_addr0; + __u64 addr_mask0; + __u64 start_addr1; + __u64 addr_mask1; + __u32 bw_win; + __u32 win_capture; + __u32 id; + __u32 pad; +}; +struct hl_debug_params_spmu { + __u64 event_types[HL_DEBUG_MAX_AUX_VALUES]; + __u32 event_types_num; + __u32 pad; +}; +#define HL_DEBUG_OP_ETR 0 +#define HL_DEBUG_OP_ETF 1 +#define HL_DEBUG_OP_STM 2 +#define HL_DEBUG_OP_FUNNEL 3 +#define HL_DEBUG_OP_BMON 4 +#define HL_DEBUG_OP_SPMU 5 +#define HL_DEBUG_OP_TIMESTAMP 6 +#define HL_DEBUG_OP_SET_MODE 7 +struct hl_debug_args { + __u64 input_ptr; + __u64 output_ptr; + __u32 input_size; + __u32 output_size; + __u32 op; + __u32 reg_idx; + __u32 enable; + __u32 ctx_id; +}; #define HL_IOCTL_INFO _IOWR('H', 0x01, struct hl_info_args) #define HL_IOCTL_CB _IOWR('H', 0x02, union hl_cb_args) #define HL_IOCTL_CS _IOWR('H', 0x03, union hl_cs_args) #define HL_IOCTL_WAIT_CS _IOWR('H', 0x04, union hl_wait_cs_args) #define HL_IOCTL_MEMORY _IOWR('H', 0x05, union hl_mem_args) +#define HL_IOCTL_DEBUG _IOWR('H', 0x06, struct hl_debug_args) #define HL_COMMAND_START 0x01 -#define HL_COMMAND_END 0x06 +#define HL_COMMAND_END 0x07 #endif diff --git a/libc/kernel/uapi/rdma/efa-abi.h b/libc/kernel/uapi/rdma/efa-abi.h new file mode 100644 index 000000000..1445c9c2a --- /dev/null +++ b/libc/kernel/uapi/rdma/efa-abi.h @@ -0,0 +1,88 @@ +/**************************************************************************** + **************************************************************************** + *** + *** 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 EFA_ABI_USER_H +#define EFA_ABI_USER_H +#include <linux/types.h> +#define EFA_UVERBS_ABI_VERSION 1 +enum efa_ibv_user_cmds_supp_udata { + EFA_USER_CMDS_SUPP_UDATA_QUERY_DEVICE = 1 << 0, + EFA_USER_CMDS_SUPP_UDATA_CREATE_AH = 1 << 1, +}; +struct efa_ibv_alloc_ucontext_resp { + __u32 comp_mask; + __u32 cmds_supp_udata_mask; + __u16 sub_cqs_per_cq; + __u16 inline_buf_size; + __u32 max_llq_size; +}; +struct efa_ibv_alloc_pd_resp { + __u32 comp_mask; + __u16 pdn; + __u8 reserved_30[2]; +}; +struct efa_ibv_create_cq { + __u32 comp_mask; + __u32 cq_entry_size; + __u16 num_sub_cqs; + __u8 reserved_50[6]; +}; +struct efa_ibv_create_cq_resp { + __u32 comp_mask; + __u8 reserved_20[4]; + __aligned_u64 q_mmap_key; + __aligned_u64 q_mmap_size; + __u16 cq_idx; + __u8 reserved_d0[6]; +}; +enum { + EFA_QP_DRIVER_TYPE_SRD = 0, +}; +struct efa_ibv_create_qp { + __u32 comp_mask; + __u32 rq_ring_size; + __u32 sq_ring_size; + __u32 driver_qp_type; +}; +struct efa_ibv_create_qp_resp { + __u32 comp_mask; + __u32 rq_db_offset; + __u32 sq_db_offset; + __u32 llq_desc_offset; + __aligned_u64 rq_mmap_key; + __aligned_u64 rq_mmap_size; + __aligned_u64 rq_db_mmap_key; + __aligned_u64 sq_db_mmap_key; + __aligned_u64 llq_desc_mmap_key; + __u16 send_sub_cq_idx; + __u16 recv_sub_cq_idx; + __u8 reserved_1e0[4]; +}; +struct efa_ibv_create_ah_resp { + __u32 comp_mask; + __u16 efa_address_handle; + __u8 reserved_30[2]; +}; +struct efa_ibv_ex_query_device_resp { + __u32 comp_mask; + __u32 max_sq_wr; + __u32 max_rq_wr; + __u16 max_sq_sge; + __u16 max_rq_sge; +}; +#endif diff --git a/libc/kernel/uapi/rdma/mlx5-abi.h b/libc/kernel/uapi/rdma/mlx5-abi.h index f1ab1474e..e01b6d377 100644 --- a/libc/kernel/uapi/rdma/mlx5-abi.h +++ b/libc/kernel/uapi/rdma/mlx5-abi.h @@ -263,6 +263,7 @@ enum mlx5_ib_create_qp_resp_mask { 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, + MLX5_IB_CREATE_QP_RESP_MASK_TIR_ICM_ADDR = 1UL << 4, }; struct mlx5_ib_create_qp_resp { __u32 bfreg_index; @@ -273,6 +274,7 @@ struct mlx5_ib_create_qp_resp { __u32 rqn; __u32 sqn; __u32 reserved1; + __u64 tir_icm_addr; }; 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 88b84c29c..66bd6663f 100644 --- a/libc/kernel/uapi/rdma/mlx5_user_ioctl_cmds.h +++ b/libc/kernel/uapi/rdma/mlx5_user_ioctl_cmds.h @@ -26,6 +26,7 @@ enum mlx5_ib_create_flow_action_attrs { enum mlx5_ib_alloc_dm_attrs { MLX5_IB_ATTR_ALLOC_DM_RESP_START_OFFSET = (1U << UVERBS_ID_NS_SHIFT), MLX5_IB_ATTR_ALLOC_DM_RESP_PAGE_INDEX, + MLX5_IB_ATTR_ALLOC_DM_REQ_TYPE, }; enum mlx5_ib_devx_methods { MLX5_IB_METHOD_DEVX_OTHER = (1U << UVERBS_ID_NS_SHIFT), @@ -109,6 +110,7 @@ enum mlx5_ib_flow_matcher_create_attrs { MLX5_IB_ATTR_FLOW_MATCHER_FLOW_TYPE, MLX5_IB_ATTR_FLOW_MATCHER_MATCH_CRITERIA, MLX5_IB_ATTR_FLOW_MATCHER_FLOW_FLAGS, + MLX5_IB_ATTR_FLOW_MATCHER_FT_TYPE, }; enum mlx5_ib_flow_matcher_destroy_attrs { MLX5_IB_ATTR_FLOW_MATCHER_DESTROY_HANDLE = (1U << UVERBS_ID_NS_SHIFT), diff --git a/libc/kernel/uapi/rdma/mlx5_user_ioctl_verbs.h b/libc/kernel/uapi/rdma/mlx5_user_ioctl_verbs.h index e83b9e2dd..a75368d49 100644 --- a/libc/kernel/uapi/rdma/mlx5_user_ioctl_verbs.h +++ b/libc/kernel/uapi/rdma/mlx5_user_ioctl_verbs.h @@ -25,6 +25,7 @@ enum mlx5_ib_uapi_flow_action_flags { 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, + MLX5_IB_UAPI_FLOW_TABLE_TYPE_FDB = 0x2, }; enum mlx5_ib_uapi_flow_action_packet_reformat_type { MLX5_IB_UAPI_FLOW_ACTION_PACKET_REFORMAT_TYPE_L2_TUNNEL_TO_L2 = 0x0, @@ -36,4 +37,9 @@ struct mlx5_ib_uapi_devx_async_cmd_hdr { __aligned_u64 wr_id; __u8 out_data[]; }; +enum mlx5_ib_uapi_dm_type { + MLX5_IB_UAPI_DM_TYPE_MEMIC, + MLX5_IB_UAPI_DM_TYPE_STEERING_SW_ICM, + MLX5_IB_UAPI_DM_TYPE_HEADER_MODIFY_SW_ICM, +}; #endif diff --git a/libc/kernel/uapi/rdma/rdma_netlink.h b/libc/kernel/uapi/rdma/rdma_netlink.h index 7730edfc7..bbb18227d 100644 --- a/libc/kernel/uapi/rdma/rdma_netlink.h +++ b/libc/kernel/uapi/rdma/rdma_netlink.h @@ -51,16 +51,6 @@ enum { RDMA_NL_IWPM_HELLO, RDMA_NL_IWPM_NUM_OPS }; -struct rdma_cm_id_stats { - __u32 qp_num; - __u32 bound_dev_if; - __u32 port_space; - __s32 pid; - __u8 cm_state; - __u8 node_type; - __u8 port_num; - __u8 qp_type; -}; enum { IWPM_NLA_REG_PID_UNSPEC = 0, IWPM_NLA_REG_PID_SEQ, @@ -193,6 +183,8 @@ enum rdma_nldev_command { RDMA_NLDEV_CMD_NEWLINK, RDMA_NLDEV_CMD_DELLINK, RDMA_NLDEV_CMD_PORT_GET, + RDMA_NLDEV_CMD_SYS_GET, + RDMA_NLDEV_CMD_SYS_SET, RDMA_NLDEV_CMD_RES_GET = 9, RDMA_NLDEV_CMD_RES_QP_GET, RDMA_NLDEV_CMD_RES_CM_ID_GET, @@ -276,6 +268,9 @@ enum rdma_nldev_attr { RDMA_NLDEV_ATTR_RES_CM_IDN, RDMA_NLDEV_ATTR_RES_CTXN, RDMA_NLDEV_ATTR_LINK_TYPE, + RDMA_NLDEV_SYS_ATTR_NETNS_MODE, + RDMA_NLDEV_ATTR_DEV_PROTOCOL, + RDMA_NLDEV_NET_NS_FD, RDMA_NLDEV_ATTR_MAX }; #endif diff --git a/libc/kernel/uapi/rdma/rdma_user_ioctl_cmds.h b/libc/kernel/uapi/rdma/rdma_user_ioctl_cmds.h index 7cd6cd0c1..2692e3ae5 100644 --- a/libc/kernel/uapi/rdma/rdma_user_ioctl_cmds.h +++ b/libc/kernel/uapi/rdma/rdma_user_ioctl_cmds.h @@ -70,5 +70,6 @@ enum rdma_driver_id { RDMA_DRIVER_RXE, RDMA_DRIVER_HFI1, RDMA_DRIVER_QIB, + RDMA_DRIVER_EFA, }; #endif diff --git a/libc/kernel/uapi/scsi/fc/fc_els.h b/libc/kernel/uapi/scsi/fc/fc_els.h index 7e9409ad0..1cabaddfa 100644 --- a/libc/kernel/uapi/scsi/fc/fc_els.h +++ b/libc/kernel/uapi/scsi/fc/fc_els.h @@ -40,6 +40,7 @@ enum fc_els_cmd { ELS_RRQ = 0x12, ELS_REC = 0x13, ELS_SRR = 0x14, + ELS_FPIN = 0x16, ELS_PRLI = 0x20, ELS_PRLO = 0x21, ELS_SCN = 0x22, @@ -81,7 +82,7 @@ enum fc_els_cmd { ELS_LKA = 0x80, ELS_AUTH_ELS = 0x90, }; -#define FC_ELS_CMDS_INIT {[ELS_LS_RJT] = "LS_RJT",[ELS_LS_ACC] = "LS_ACC",[ELS_PLOGI] = "PLOGI",[ELS_FLOGI] = "FLOGI",[ELS_LOGO] = "LOGO",[ELS_ABTX] = "ABTX",[ELS_RCS] = "RCS",[ELS_RES] = "RES",[ELS_RSS] = "RSS",[ELS_RSI] = "RSI",[ELS_ESTS] = "ESTS",[ELS_ESTC] = "ESTC",[ELS_ADVC] = "ADVC",[ELS_RTV] = "RTV",[ELS_RLS] = "RLS",[ELS_ECHO] = "ECHO",[ELS_TEST] = "TEST",[ELS_RRQ] = "RRQ",[ELS_REC] = "REC",[ELS_SRR] = "SRR",[ELS_PRLI] = "PRLI",[ELS_PRLO] = "PRLO",[ELS_SCN] = "SCN",[ELS_TPLS] = "TPLS",[ELS_TPRLO] = "TPRLO",[ELS_LCLM] = "LCLM",[ELS_GAID] = "GAID",[ELS_FACT] = "FACT",[ELS_FDACDT] = "FDACDT",[ELS_NACT] = "NACT",[ELS_NDACT] = "NDACT",[ELS_QOSR] = "QOSR",[ELS_RVCS] = "RVCS",[ELS_PDISC] = "PDISC",[ELS_FDISC] = "FDISC",[ELS_ADISC] = "ADISC",[ELS_RNC] = "RNC",[ELS_FARP_REQ] = "FARP_REQ",[ELS_FARP_REPL] = "FARP_REPL",[ELS_RPS] = "RPS",[ELS_RPL] = "RPL",[ELS_RPBC] = "RPBC",[ELS_FAN] = "FAN",[ELS_RSCN] = "RSCN",[ELS_SCR] = "SCR",[ELS_RNFT] = "RNFT",[ELS_CSR] = "CSR",[ELS_CSU] = "CSU",[ELS_LINIT] = "LINIT",[ELS_LSTS] = "LSTS",[ELS_RNID] = "RNID",[ELS_RLIR] = "RLIR",[ELS_LIRR] = "LIRR",[ELS_SRL] = "SRL",[ELS_SBRP] = "SBRP",[ELS_RPSC] = "RPSC",[ELS_QSA] = "QSA",[ELS_EVFP] = "EVFP",[ELS_LKA] = "LKA",[ELS_AUTH_ELS] = "AUTH_ELS", \ +#define FC_ELS_CMDS_INIT {[ELS_LS_RJT] = "LS_RJT",[ELS_LS_ACC] = "LS_ACC",[ELS_PLOGI] = "PLOGI",[ELS_FLOGI] = "FLOGI",[ELS_LOGO] = "LOGO",[ELS_ABTX] = "ABTX",[ELS_RCS] = "RCS",[ELS_RES] = "RES",[ELS_RSS] = "RSS",[ELS_RSI] = "RSI",[ELS_ESTS] = "ESTS",[ELS_ESTC] = "ESTC",[ELS_ADVC] = "ADVC",[ELS_RTV] = "RTV",[ELS_RLS] = "RLS",[ELS_ECHO] = "ECHO",[ELS_TEST] = "TEST",[ELS_RRQ] = "RRQ",[ELS_REC] = "REC",[ELS_SRR] = "SRR",[ELS_FPIN] = "FPIN",[ELS_PRLI] = "PRLI",[ELS_PRLO] = "PRLO",[ELS_SCN] = "SCN",[ELS_TPLS] = "TPLS",[ELS_TPRLO] = "TPRLO",[ELS_LCLM] = "LCLM",[ELS_GAID] = "GAID",[ELS_FACT] = "FACT",[ELS_FDACDT] = "FDACDT",[ELS_NACT] = "NACT",[ELS_NDACT] = "NDACT",[ELS_QOSR] = "QOSR",[ELS_RVCS] = "RVCS",[ELS_PDISC] = "PDISC",[ELS_FDISC] = "FDISC",[ELS_ADISC] = "ADISC",[ELS_RNC] = "RNC",[ELS_FARP_REQ] = "FARP_REQ",[ELS_FARP_REPL] = "FARP_REPL",[ELS_RPS] = "RPS",[ELS_RPL] = "RPL",[ELS_RPBC] = "RPBC",[ELS_FAN] = "FAN",[ELS_RSCN] = "RSCN",[ELS_SCR] = "SCR",[ELS_RNFT] = "RNFT",[ELS_CSR] = "CSR",[ELS_CSU] = "CSU",[ELS_LINIT] = "LINIT",[ELS_LSTS] = "LSTS",[ELS_RNID] = "RNID",[ELS_RLIR] = "RLIR",[ELS_LIRR] = "LIRR",[ELS_SRL] = "SRL",[ELS_SBRP] = "SBRP",[ELS_RPSC] = "RPSC",[ELS_QSA] = "QSA",[ELS_EVFP] = "EVFP",[ELS_LKA] = "LKA",[ELS_AUTH_ELS] = "AUTH_ELS", \ } struct fc_els_ls_acc { __u8 la_cmd; @@ -542,4 +543,20 @@ enum fc_els_clid_ic { ELS_CLID_IC_LOOP_TO = 7, ELS_CLID_IC_LIP = 8, }; +enum fc_fn_dtag { + ELS_FN_DTAG_LNK_INTEGRITY = 0x00020001, + ELS_FN_DTAG_PEER_CONGEST = 0x00020003, + ELS_FN_DTAG_CONGESTION = 0x00020004, +}; +struct fc_fn_desc { + __be32 fn_desc_tag; + __be32 fn_desc_value_len; + __u8 fn_desc_value[0]; +}; +struct fc_els_fpin { + __u8 fpin_cmd; + __u8 fpin_zero[3]; + __be32 fpin_desc_cnt; + struct fc_fn_desc fpin_desc[0]; +}; #endif diff --git a/libc/kernel/uapi/sound/sof/abi.h b/libc/kernel/uapi/sound/sof/abi.h new file mode 100644 index 000000000..2111f5c37 --- /dev/null +++ b/libc/kernel/uapi/sound/sof/abi.h @@ -0,0 +1,37 @@ +/**************************************************************************** + **************************************************************************** + *** + *** 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 __INCLUDE_UAPI_SOUND_SOF_ABI_H__ +#define __INCLUDE_UAPI_SOUND_SOF_ABI_H__ +#define SOF_ABI_MAJOR 3 +#define SOF_ABI_MINOR 6 +#define SOF_ABI_PATCH 0 +#define SOF_ABI_MAJOR_SHIFT 24 +#define SOF_ABI_MAJOR_MASK 0xff +#define SOF_ABI_MINOR_SHIFT 12 +#define SOF_ABI_MINOR_MASK 0xfff +#define SOF_ABI_PATCH_SHIFT 0 +#define SOF_ABI_PATCH_MASK 0xfff +#define SOF_ABI_VER(major,minor,patch) (((major) << SOF_ABI_MAJOR_SHIFT) | ((minor) << SOF_ABI_MINOR_SHIFT) | ((patch) << SOF_ABI_PATCH_SHIFT)) +#define SOF_ABI_VERSION_MAJOR(version) (((version) >> SOF_ABI_MAJOR_SHIFT) & SOF_ABI_MAJOR_MASK) +#define SOF_ABI_VERSION_MINOR(version) (((version) >> SOF_ABI_MINOR_SHIFT) & SOF_ABI_MINOR_MASK) +#define SOF_ABI_VERSION_PATCH(version) (((version) >> SOF_ABI_PATCH_SHIFT) & SOF_ABI_PATCH_MASK) +#define SOF_ABI_VERSION_INCOMPATIBLE(sof_ver,client_ver) (SOF_ABI_VERSION_MAJOR((sof_ver)) != SOF_ABI_VERSION_MAJOR((client_ver))) +#define SOF_ABI_VERSION SOF_ABI_VER(SOF_ABI_MAJOR, SOF_ABI_MINOR, SOF_ABI_PATCH) +#define SOF_ABI_MAGIC 0x00464F53 +#endif diff --git a/libc/kernel/uapi/sound/sof/eq.h b/libc/kernel/uapi/sound/sof/eq.h new file mode 100644 index 000000000..c45ba3554 --- /dev/null +++ b/libc/kernel/uapi/sound/sof/eq.h @@ -0,0 +1,67 @@ +/**************************************************************************** + **************************************************************************** + *** + *** 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 __INCLUDE_UAPI_SOUND_SOF_USER_EQ_H__ +#define __INCLUDE_UAPI_SOUND_SOF_USER_EQ_H__ +#define SOF_EQ_FIR_IDX_SWITCH 0 +#define SOF_EQ_FIR_MAX_SIZE 4096 +#define SOF_EQ_FIR_MAX_LENGTH 192 +#define SOF_EQ_FIR_MAX_RESPONSES 8 +struct sof_eq_fir_config { + uint32_t size; + uint16_t channels_in_config; + uint16_t number_of_responses; + uint32_t reserved[4]; + int16_t data[]; +} __packed; +struct sof_eq_fir_coef_data { + int16_t length; + int16_t out_shift; + uint32_t reserved[4]; + int16_t coef[]; +} __packed; +#define SOF_EQ_FIR_COEF_NHEADER (sizeof(struct sof_eq_fir_coef_data) / sizeof(int16_t)) +#define SOF_EQ_IIR_IDX_SWITCH 0 +#define SOF_EQ_IIR_MAX_SIZE 1024 +#define SOF_EQ_IIR_MAX_RESPONSES 8 +struct sof_eq_iir_config { + uint32_t size; + uint32_t channels_in_config; + uint32_t number_of_responses; + uint32_t reserved[4]; + int32_t data[]; +} __packed; +struct sof_eq_iir_header_df2t { + uint32_t num_sections; + uint32_t num_sections_in_series; + uint32_t reserved[4]; + int32_t biquads[]; +} __packed; +struct sof_eq_iir_biquad_df2t { + int32_t a2; + int32_t a1; + int32_t b2; + int32_t b1; + int32_t b0; + int32_t output_shift; + int32_t output_gain; +} __packed; +#define SOF_EQ_IIR_DF2T_BIQUADS_MAX 11 +#define SOF_EQ_IIR_NHEADER_DF2T (sizeof(struct sof_eq_iir_header_df2t) / sizeof(int32_t)) +#define SOF_EQ_IIR_NBIQUAD_DF2T (sizeof(struct sof_eq_iir_biquad_df2t) / sizeof(int32_t)) +#endif diff --git a/libc/kernel/uapi/sound/sof/fw.h b/libc/kernel/uapi/sound/sof/fw.h new file mode 100644 index 000000000..72bb31c21 --- /dev/null +++ b/libc/kernel/uapi/sound/sof/fw.h @@ -0,0 +1,64 @@ +/**************************************************************************** + **************************************************************************** + *** + *** 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 __INCLUDE_UAPI_SOF_FW_H__ +#define __INCLUDE_UAPI_SOF_FW_H__ +#define SND_SOF_FW_SIG_SIZE 4 +#define SND_SOF_FW_ABI 1 +#define SND_SOF_FW_SIG "Reef" +enum snd_sof_fw_blk_type { + SOF_FW_BLK_TYPE_INVALID = - 1, + SOF_FW_BLK_TYPE_START = 0, + SOF_FW_BLK_TYPE_RSRVD0 = SOF_FW_BLK_TYPE_START, + SOF_FW_BLK_TYPE_IRAM = 1, + SOF_FW_BLK_TYPE_DRAM = 2, + SOF_FW_BLK_TYPE_SRAM = 3, + SOF_FW_BLK_TYPE_ROM = 4, + SOF_FW_BLK_TYPE_IMR = 5, + SOF_FW_BLK_TYPE_RSRVD6 = 6, + SOF_FW_BLK_TYPE_RSRVD7 = 7, + SOF_FW_BLK_TYPE_RSRVD8 = 8, + SOF_FW_BLK_TYPE_RSRVD9 = 9, + SOF_FW_BLK_TYPE_RSRVD10 = 10, + SOF_FW_BLK_TYPE_RSRVD11 = 11, + SOF_FW_BLK_TYPE_RSRVD12 = 12, + SOF_FW_BLK_TYPE_RSRVD13 = 13, + SOF_FW_BLK_TYPE_RSRVD14 = 14, + SOF_FW_BLK_TYPE_NUM +}; +struct snd_sof_blk_hdr { + enum snd_sof_fw_blk_type type; + uint32_t size; + uint32_t offset; +} __packed; +enum snd_sof_fw_mod_type { + SOF_FW_BASE = 0, + SOF_FW_MODULE = 1, +}; +struct snd_sof_mod_hdr { + enum snd_sof_fw_mod_type type; + uint32_t size; + uint32_t num_blocks; +} __packed; +struct snd_sof_fw_header { + unsigned char sig[SND_SOF_FW_SIG_SIZE]; + uint32_t file_size; + uint32_t num_modules; + uint32_t abi; +} __packed; +#endif diff --git a/libc/kernel/uapi/sound/sof/header.h b/libc/kernel/uapi/sound/sof/header.h new file mode 100644 index 000000000..cf90e9bcc --- /dev/null +++ b/libc/kernel/uapi/sound/sof/header.h @@ -0,0 +1,29 @@ +/**************************************************************************** + **************************************************************************** + *** + *** 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 __INCLUDE_UAPI_SOUND_SOF_USER_HEADER_H__ +#define __INCLUDE_UAPI_SOUND_SOF_USER_HEADER_H__ +struct sof_abi_hdr { + uint32_t magic; + uint32_t type; + uint32_t size; + uint32_t abi; + uint32_t reserved[4]; + uint32_t data[0]; +} __packed; +#endif diff --git a/libc/kernel/uapi/sound/sof/manifest.h b/libc/kernel/uapi/sound/sof/manifest.h new file mode 100644 index 000000000..b8bd3e5dd --- /dev/null +++ b/libc/kernel/uapi/sound/sof/manifest.h @@ -0,0 +1,128 @@ +/**************************************************************************** + **************************************************************************** + *** + *** 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 __INCLUDE_UAPI_SOUND_SOF_USER_MANIFEST_H__ +#define __INCLUDE_UAPI_SOUND_SOF_USER_MANIFEST_H__ +#define SOF_MAN_ELF_TEXT_OFFSET 0x2000 +#define SOF_MAN_EXT_HEADER_MAGIC 0x31454124 +#define SOF_MAN_MOD_TYPE_BUILTIN 0 +#define SOF_MAN_MOD_TYPE_MODULE 1 +struct sof_man_module_type { + uint32_t load_type : 4; + uint32_t auto_start : 1; + uint32_t domain_ll : 1; + uint32_t domain_dp : 1; + uint32_t rsvd_ : 25; +}; +#define SOF_MAN_SEGMENT_TEXT 0 +#define SOF_MAN_SEGMENT_RODATA 1 +#define SOF_MAN_SEGMENT_DATA 1 +#define SOF_MAN_SEGMENT_BSS 2 +#define SOF_MAN_SEGMENT_EMPTY 15 +union sof_man_segment_flags { + uint32_t ul; + struct { + uint32_t contents : 1; + uint32_t alloc : 1; + uint32_t load : 1; + uint32_t readonly : 1; + uint32_t code : 1; + uint32_t data : 1; + uint32_t _rsvd0 : 2; + uint32_t type : 4; + uint32_t _rsvd1 : 4; + uint32_t length : 16; + } r; +} __packed; +struct sof_man_segment_desc { + union sof_man_segment_flags flags; + uint32_t v_base_addr; + uint32_t file_offset; +} __packed; +#define SOF_MAN_MOD_ID_LEN 4 +#define SOF_MAN_MOD_NAME_LEN 8 +#define SOF_MAN_MOD_SHA256_LEN 32 +#define SOF_MAN_MOD_ID { '$', 'A', 'M', 'E' } +struct sof_man_module { + uint8_t struct_id[SOF_MAN_MOD_ID_LEN]; + uint8_t name[SOF_MAN_MOD_NAME_LEN]; + uint8_t uuid[16]; + struct sof_man_module_type type; + uint8_t hash[SOF_MAN_MOD_SHA256_LEN]; + uint32_t entry_point; + uint16_t cfg_offset; + uint16_t cfg_count; + uint32_t affinity_mask; + uint16_t instance_max_count; + uint16_t instance_bss_size; + struct sof_man_segment_desc segment[3]; +} __packed; +struct sof_man_mod_config { + uint32_t par[4]; + uint32_t is_pages; + uint32_t cps; + uint32_t ibs; + uint32_t obs; + uint32_t module_flags; + uint32_t cpc; + uint32_t obls; +} __packed; +#define SOF_MAN_FW_HDR_FW_NAME_LEN 8 +#define SOF_MAN_FW_HDR_ID { '$', 'A', 'M', '1' } +#define SOF_MAN_FW_HDR_NAME "ADSPFW" +#define SOF_MAN_FW_HDR_FLAGS 0x0 +#define SOF_MAN_FW_HDR_FEATURES 0xff +struct sof_man_fw_header { + uint8_t header_id[4]; + uint32_t header_len; + uint8_t name[SOF_MAN_FW_HDR_FW_NAME_LEN]; + uint32_t preload_page_count; + uint32_t fw_image_flags; + uint32_t feature_mask; + uint16_t major_version; + uint16_t minor_version; + uint16_t hotfix_version; + uint16_t build_version; + uint32_t num_module_entries; + uint32_t hw_buf_base_addr; + uint32_t hw_buf_length; + uint32_t load_offset; +} __packed; +struct sof_man_fw_desc { + struct sof_man_fw_header header; +} __packed; +struct sof_man_component_desc { + uint32_t reserved[2]; + uint32_t version; + uint8_t hash[SOF_MAN_MOD_SHA256_LEN]; + uint32_t base_offset; + uint32_t limit_offset; + uint32_t attributes[4]; +} __packed; +struct sof_man_adsp_meta_file_ext { + uint32_t ext_type; + uint32_t ext_len; + uint32_t imr_type; + uint8_t reserved[16]; + struct sof_man_component_desc comp_desc[1]; +} __packed; +struct sof_man_module_manifest { + struct sof_man_module module; + uint32_t text_size; +} __packed; +#endif diff --git a/libc/kernel/uapi/sound/sof/tokens.h b/libc/kernel/uapi/sound/sof/tokens.h new file mode 100644 index 000000000..748c5fecb --- /dev/null +++ b/libc/kernel/uapi/sound/sof/tokens.h @@ -0,0 +1,68 @@ +/**************************************************************************** + **************************************************************************** + *** + *** 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 __INCLUDE_UAPI_SOF_TOPOLOGY_H__ +#define __INCLUDE_UAPI_SOF_TOPOLOGY_H__ +#define SOF_TPLG_KCTL_VOL_ID 256 +#define SOF_TPLG_KCTL_ENUM_ID 257 +#define SOF_TPLG_KCTL_BYTES_ID 258 +#define SOF_TPLG_KCTL_SWITCH_ID 259 +#define SOF_TKN_BUF_SIZE 100 +#define SOF_TKN_BUF_CAPS 101 +#define SOF_TKN_DAI_TYPE 154 +#define SOF_TKN_DAI_INDEX 155 +#define SOF_TKN_DAI_DIRECTION 156 +#define SOF_TKN_SCHED_PERIOD 200 +#define SOF_TKN_SCHED_PRIORITY 201 +#define SOF_TKN_SCHED_MIPS 202 +#define SOF_TKN_SCHED_CORE 203 +#define SOF_TKN_SCHED_FRAMES 204 +#define SOF_TKN_SCHED_TIME_DOMAIN 205 +#define SOF_TKN_VOLUME_RAMP_STEP_TYPE 250 +#define SOF_TKN_VOLUME_RAMP_STEP_MS 251 +#define SOF_TKN_SRC_RATE_IN 300 +#define SOF_TKN_SRC_RATE_OUT 301 +#define SOF_TKN_PCM_DMAC_CONFIG 353 +#define SOF_TKN_COMP_PERIOD_SINK_COUNT 400 +#define SOF_TKN_COMP_PERIOD_SOURCE_COUNT 401 +#define SOF_TKN_COMP_FORMAT 402 +#define SOF_TKN_INTEL_SSP_CLKS_CONTROL 500 +#define SOF_TKN_INTEL_SSP_MCLK_ID 501 +#define SOF_TKN_INTEL_SSP_SAMPLE_BITS 502 +#define SOF_TKN_INTEL_SSP_FRAME_PULSE_WIDTH 503 +#define SOF_TKN_INTEL_SSP_QUIRKS 504 +#define SOF_TKN_INTEL_SSP_TDM_PADDING_PER_SLOT 505 +#define SOF_TKN_INTEL_DMIC_DRIVER_VERSION 600 +#define SOF_TKN_INTEL_DMIC_CLK_MIN 601 +#define SOF_TKN_INTEL_DMIC_CLK_MAX 602 +#define SOF_TKN_INTEL_DMIC_DUTY_MIN 603 +#define SOF_TKN_INTEL_DMIC_DUTY_MAX 604 +#define SOF_TKN_INTEL_DMIC_NUM_PDM_ACTIVE 605 +#define SOF_TKN_INTEL_DMIC_SAMPLE_RATE 608 +#define SOF_TKN_INTEL_DMIC_FIFO_WORD_LENGTH 609 +#define SOF_TKN_INTEL_DMIC_PDM_CTRL_ID 700 +#define SOF_TKN_INTEL_DMIC_PDM_MIC_A_Enable 701 +#define SOF_TKN_INTEL_DMIC_PDM_MIC_B_Enable 702 +#define SOF_TKN_INTEL_DMIC_PDM_POLARITY_A 703 +#define SOF_TKN_INTEL_DMIC_PDM_POLARITY_B 704 +#define SOF_TKN_INTEL_DMIC_PDM_CLK_EDGE 705 +#define SOF_TKN_INTEL_DMIC_PDM_SKEW 706 +#define SOF_TKN_TONE_SAMPLE_RATE 800 +#define SOF_TKN_PROCESS_TYPE 900 +#define SOF_TKN_EFFECT_TYPE SOF_TKN_PROCESS_TYPE +#endif diff --git a/libc/kernel/uapi/sound/sof/tone.h b/libc/kernel/uapi/sound/sof/tone.h new file mode 100644 index 000000000..a4b745ef7 --- /dev/null +++ b/libc/kernel/uapi/sound/sof/tone.h @@ -0,0 +1,29 @@ +/**************************************************************************** + **************************************************************************** + *** + *** 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 __INCLUDE_UAPI_SOUND_SOF_USER_TONE_H__ +#define __INCLUDE_UAPI_SOUND_SOF_USER_TONE_H__ +#define SOF_TONE_IDX_FREQUENCY 0 +#define SOF_TONE_IDX_AMPLITUDE 1 +#define SOF_TONE_IDX_FREQ_MULT 2 +#define SOF_TONE_IDX_AMPL_MULT 3 +#define SOF_TONE_IDX_LENGTH 4 +#define SOF_TONE_IDX_PERIOD 5 +#define SOF_TONE_IDX_REPEATS 6 +#define SOF_TONE_IDX_LIN_RAMP_STEP 7 +#endif diff --git a/libc/kernel/uapi/sound/sof/trace.h b/libc/kernel/uapi/sound/sof/trace.h new file mode 100644 index 000000000..a5eed43e0 --- /dev/null +++ b/libc/kernel/uapi/sound/sof/trace.h @@ -0,0 +1,45 @@ +/**************************************************************************** + **************************************************************************** + *** + *** 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 __INCLUDE_UAPI_SOUND_SOF_USER_TRACE_H__ +#define __INCLUDE_UAPI_SOUND_SOF_USER_TRACE_H__ +struct system_time { + uint32_t val_l; + uint32_t val_u; +} __packed; +#define LOG_ENABLE 1 +#define LOG_DISABLE 0 +#define LOG_LEVEL_CRITICAL 1 +#define LOG_LEVEL_VERBOSE 2 +struct log_buffer_layout { + uint32_t read_ptr; + uint32_t write_ptr; + uint32_t buffer[0]; +} __packed; +struct log_buffer_status { + uint32_t core_id; +} __packed; +#define TRACE_ID_LENGTH 12 +struct log_entry_header { + uint32_t id_0 : TRACE_ID_LENGTH; + uint32_t id_1 : TRACE_ID_LENGTH; + uint32_t core_id : 8; + uint64_t timestamp; + uint32_t log_entry_address; +} __packed; +#endif diff --git a/libc/libc.map.txt b/libc/libc.map.txt index b36ee4c5d..9b39bb842 100644 --- a/libc/libc.map.txt +++ b/libc/libc.map.txt @@ -690,7 +690,7 @@ LIBC { ns_name_ntol; # arm64 x86_64 mips64 introduced=22 ns_name_ntop; # arm64 x86_64 mips64 introduced=22 ns_name_pack; # arm64 x86_64 mips64 introduced=22 - ns_name_pton; # arm64 x86_64 mips64 introduced=23 + ns_name_pton; # arm64 x86_64 mips64 introduced=22 ns_name_rollback; # arm64 x86_64 mips64 introduced=22 ns_name_skip; # arm64 x86_64 mips64 introduced=22 ns_name_uncompress; # arm64 x86_64 mips64 introduced=22 @@ -1482,6 +1482,10 @@ LIBC_Q { # introduced=Q LIBC_R { # introduced=R global: + __mempcpy_chk; + __open64_2; + __openat64_2; + __tls_get_addr; # arm64 call_once; cnd_broadcast; cnd_destroy; @@ -1489,12 +1493,20 @@ LIBC_R { # introduced=R cnd_signal; cnd_timedwait; cnd_wait; + memfd_create; + mlock2; mtx_destroy; mtx_init; mtx_lock; mtx_timedlock; mtx_trylock; mtx_unlock; + pthread_cond_clockwait; + pthread_mutex_clocklock; + pthread_rwlock_clockrdlock; + pthread_rwlock_clockwrlock; + renameat2; + sem_clockwait; thrd_create; thrd_current; thrd_detach; diff --git a/libc/malloc_debug/Android.bp b/libc/malloc_debug/Android.bp index aae16f14d..d6b85319e 100644 --- a/libc/malloc_debug/Android.bp +++ b/libc/malloc_debug/Android.bp @@ -16,7 +16,6 @@ cc_library_static { whole_static_libs: [ "libbase", "libasync_safe", - "libdemangle", ], include_dirs: ["bionic/libc"], @@ -66,7 +65,6 @@ cc_library { static_libs: [ "libasync_safe", "libbase", - "libdemangle", "libc_malloc_debug_backtrace", ], @@ -122,7 +120,6 @@ cc_test { static_libs: [ "libc_malloc_debug", - "libdemangle", "libtinyxml2", ], diff --git a/libc/malloc_debug/PointerData.cpp b/libc/malloc_debug/PointerData.cpp index 8cc1a2891..b5219a172 100644 --- a/libc/malloc_debug/PointerData.cpp +++ b/libc/malloc_debug/PointerData.cpp @@ -43,7 +43,6 @@ #include <android-base/stringprintf.h> #include <android-base/thread_annotations.h> -#include <demangle.h> #include <private/bionic_macros.h> #include "Config.h" @@ -54,6 +53,8 @@ #include "malloc_debug.h" #include "UnwindBacktrace.h" +extern "C" char* __cxa_demangle(const char*, char*, size_t*, int*); + std::atomic_uint8_t PointerData::backtrace_enabled_; std::atomic_bool PointerData::backtrace_dump_; @@ -599,7 +600,16 @@ void PointerData::DumpLiveToFile(FILE* fp) { if (frame.function_name.empty()) { fprintf(fp, " \"\" 0}"); } else { - fprintf(fp, " \"%s\" %" PRIx64 "}", demangle(frame.function_name.c_str()).c_str(), frame.function_offset); + char* demangled_name = __cxa_demangle(frame.function_name.c_str(), nullptr, nullptr, + nullptr); + const char* name; + if (demangled_name != nullptr) { + name = demangled_name; + } else { + name = frame.function_name.c_str(); + } + fprintf(fp, " \"%s\" %" PRIx64 "}", name, frame.function_offset); + free(demangled_name); } } fprintf(fp, "\n"); diff --git a/libc/malloc_debug/UnwindBacktrace.cpp b/libc/malloc_debug/UnwindBacktrace.cpp index ddafc731f..92fb3fa96 100644 --- a/libc/malloc_debug/UnwindBacktrace.cpp +++ b/libc/malloc_debug/UnwindBacktrace.cpp @@ -36,7 +36,6 @@ #include <vector> #include <android-base/stringprintf.h> -#include <demangle.h> #include <unwindstack/LocalUnwinder.h> #include <unwindstack/MapInfo.h> @@ -49,6 +48,8 @@ #define PAD_PTR "08" PRIx64 #endif +extern "C" char* __cxa_demangle(const char*, char*, size_t*, int*); + static pthread_once_t g_setup_once = PTHREAD_ONCE_INIT; static unwindstack::LocalUnwinder* g_unwinder; @@ -100,7 +101,14 @@ void UnwindLog(const std::vector<unwindstack::LocalFrameData>& frame_info) { } if (!info->function_name.empty()) { - line += " (" + demangle(info->function_name.c_str()); + line += " ("; + char* demangled_name = __cxa_demangle(info->function_name.c_str(), nullptr, nullptr, nullptr); + if (demangled_name != nullptr) { + line += demangled_name; + free(demangled_name); + } else { + line += info->function_name; + } if (info->function_offset != 0) { line += "+" + std::to_string(info->function_offset); } diff --git a/libc/malloc_debug/backtrace.cpp b/libc/malloc_debug/backtrace.cpp index 0e3a53f92..ab5c50523 100644 --- a/libc/malloc_debug/backtrace.cpp +++ b/libc/malloc_debug/backtrace.cpp @@ -36,8 +36,6 @@ #include <unistd.h> #include <unwind.h> -#include <demangle.h> - #include "MapData.h" #include "backtrace.h" #include "debug_log.h" @@ -164,10 +162,18 @@ std::string backtrace_string(const uintptr_t* frames, size_t frame_count) { char buf[1024]; if (symbol != nullptr) { + char* demangled_name = __cxa_demangle(symbol, nullptr, nullptr, nullptr); + const char* name; + if (demangled_name != nullptr) { + name = demangled_name; + } else { + name = symbol; + } async_safe_format_buffer(buf, sizeof(buf), " #%02zd pc %" PAD_PTR " %s%s (%s+%" PRIuPTR ")\n", - frame_num, rel_pc, soname, offset_buf, demangle(symbol).c_str(), + frame_num, rel_pc, soname, offset_buf, name, frames[frame_num] - offset); + free(demangled_name); } else { async_safe_format_buffer(buf, sizeof(buf), " #%02zd pc %" PAD_PTR " %s%s\n", frame_num, rel_pc, soname, offset_buf); diff --git a/libc/private/NetdClientDispatch.h b/libc/private/NetdClientDispatch.h index 20e7f25b7..7ebbe0c02 100644 --- a/libc/private/NetdClientDispatch.h +++ b/libc/private/NetdClientDispatch.h @@ -14,8 +14,7 @@ * limitations under the License. */ -#ifndef PRIVATE_NETD_CLIENT_DISPATCH_H -#define PRIVATE_NETD_CLIENT_DISPATCH_H +#pragma once #include <sys/cdefs.h> #include <sys/socket.h> @@ -25,6 +24,9 @@ __BEGIN_DECLS struct NetdClientDispatch { int (*accept4)(int, struct sockaddr*, socklen_t*, int); int (*connect)(int, const struct sockaddr*, socklen_t); + int (*sendmmsg)(int, const struct mmsghdr*, unsigned int, int); + ssize_t (*sendmsg)(int, const struct msghdr*, unsigned int); + int (*sendto)(int, const void*, size_t, int, const struct sockaddr*, socklen_t); int (*socket)(int, int, int); unsigned (*netIdForResolv)(unsigned); int (*dnsOpenProxy)(); @@ -33,5 +35,3 @@ struct NetdClientDispatch { extern __LIBC_HIDDEN__ struct NetdClientDispatch __netdClientDispatch; __END_DECLS - -#endif // PRIVATE_NETD_CLIENT_DISPATCH_H diff --git a/libc/private/WriteProtected.h b/libc/private/WriteProtected.h index 69a68229b..26c239ca1 100644 --- a/libc/private/WriteProtected.h +++ b/libc/private/WriteProtected.h @@ -46,6 +46,16 @@ class WriteProtected { WriteProtectedContents<T> contents; + int set_protection(int prot) { + auto addr = &contents; +#if __has_feature(hwaddress_sanitizer) + // The mprotect system call does not currently untag pointers, so do it + // ourselves. + addr = untag_address(addr); +#endif + return mprotect(reinterpret_cast<void*>(addr), PAGE_SIZE, prot); + } + public: WriteProtected() = default; BIONIC_DISALLOW_COPY_AND_ASSIGN(WriteProtected); @@ -55,7 +65,7 @@ class WriteProtected { // multiple times by accident. memset(&contents, 0, sizeof(contents)); - if (mprotect(&contents, PAGE_SIZE, PROT_READ)) { + if (set_protection(PROT_READ)) { async_safe_fatal("failed to make WriteProtected nonwritable in initialize"); } } @@ -70,12 +80,12 @@ class WriteProtected { template <typename Mutator> void mutate(Mutator mutator) { - if (mprotect(&contents, PAGE_SIZE, PROT_READ | PROT_WRITE) != 0) { + if (set_protection(PROT_READ | PROT_WRITE) != 0) { async_safe_fatal("failed to make WriteProtected writable in mutate: %s", strerror(errno)); } mutator(&contents.value); - if (mprotect(&contents, PAGE_SIZE, PROT_READ) != 0) { + if (set_protection(PROT_READ) != 0) { async_safe_fatal("failed to make WriteProtected nonwritable in mutate: %s", strerror(errno)); } diff --git a/libc/private/bionic_globals.h b/libc/private/bionic_globals.h index d73079e33..ef735bab0 100644 --- a/libc/private/bionic_globals.h +++ b/libc/private/bionic_globals.h @@ -88,6 +88,10 @@ struct libc_shared_globals { TlsModules tls_modules; BionicAllocator tls_allocator; + // Values passed from the HWASan runtime (via libc.so) to the loader. + void (*load_hook)(ElfW(Addr) base, const ElfW(Phdr)* phdr, ElfW(Half) phnum) = nullptr; + void (*unload_hook)(ElfW(Addr) base, const ElfW(Phdr)* phdr, ElfW(Half) phnum) = nullptr; + // Values passed from the linker to libc.so. const char* init_progname = nullptr; char** init_environ = nullptr; diff --git a/libc/private/bionic_macros.h b/libc/private/bionic_macros.h index 4800e3af9..13934e5f6 100644 --- a/libc/private/bionic_macros.h +++ b/libc/private/bionic_macros.h @@ -87,3 +87,12 @@ char (&ArraySizeHelper(T (&array)[N]))[N]; // NOLINT(readability/casting) #else #define __BIONIC_FALLTHROUGH #endif + +template <typename T> +static inline T* untag_address(T* p) { +#if defined(__aarch64__) + return reinterpret_cast<T*>(reinterpret_cast<uintptr_t>(p) & ((1ULL << 56) - 1)); +#else + return p; +#endif +} diff --git a/libc/private/sigrtmin.h b/libc/private/sigrtmin.h index d78d98058..5de1a32ae 100644 --- a/libc/private/sigrtmin.h +++ b/libc/private/sigrtmin.h @@ -39,13 +39,14 @@ // 33 (__SIGRTMIN + 1) libbacktrace // 34 (__SIGRTMIN + 2) libcore // 35 (__SIGRTMIN + 3) debuggerd -b -// 36 (__SIGRTMIN + 4) heapprofd +// 36 (__SIGRTMIN + 4) heapprofd native dumps // 37 (__SIGRTMIN + 5) coverage (libprofile-extras) +// 38 (__SIGRTMIN + 6) heapprofd ART managed heap dumps // // If you change this, also change __ndk_legacy___libc_current_sigrtmin // in <android/legacy_signal_inlines.h> to match. -#define __SIGRT_RESERVED 6 +#define __SIGRT_RESERVED 7 static inline __always_inline sigset64_t filter_reserved_signals(sigset64_t sigset, int how) { int (*block)(sigset64_t*, int); int (*unblock)(sigset64_t*, int); @@ -72,5 +73,6 @@ static inline __always_inline sigset64_t filter_reserved_signals(sigset64_t sigs unblock(&sigset, __SIGRTMIN + 3); unblock(&sigset, __SIGRTMIN + 4); unblock(&sigset, __SIGRTMIN + 5); + unblock(&sigset, __SIGRTMIN + 6); return sigset; } diff --git a/libc/stdio/stdio.cpp b/libc/stdio/stdio.cpp index 91c7689f8..a0b421923 100644 --- a/libc/stdio/stdio.cpp +++ b/libc/stdio/stdio.cpp @@ -57,8 +57,6 @@ #include "private/ErrnoRestorer.h" #include "private/thread_private.h" -extern "C" int ___close(int fd); - #define ALIGNBYTES (sizeof(uintptr_t) - 1) #define ALIGN(p) (((uintptr_t)(p) + ALIGNBYTES) &~ ALIGNBYTES) diff --git a/libc/symbol_ordering b/libc/symbol_ordering deleted file mode 100644 index c04692bca..000000000 --- a/libc/symbol_ordering +++ /dev/null @@ -1,210 +0,0 @@ -# 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. - -ctl_initialized -gGlobalsMutating -global_hashtable_initialized -gmtcheck.gmt_is_set -had_conf_error -je_background_thread_enabled_state -je_log_init_done -je_opt_abort -je_opt_abort_conf -je_opt_background_thread -je_opt_junk_alloc -je_opt_junk_free -je_opt_stats_print -je_opt_utrace -je_opt_xmalloc -je_opt_zero -je_tsd_booted -malloc_disabled_tcache -malloc_slow_flags -mmap_flags -os_overcommits -restartloop -_ZL24gHeapprofdInitInProgress -_ZL27gHeapprofdInitHookInstalled -_ZL23gZygoteChildProfileable -_ZZ17__find_icu_symbolPKcE9found_icu -ru_a -ru_b -ru_counter -ru_g -ru_msb -ru_seed -ru_seed2 -ru_x -_ZZ12bindresvportE4port -a0 -__atexit -atexit_mutex -b0 -ctl_arenas -ctl_stats -__cxa_finalize.call_depth -daylight -dirty_decay_ms_default.0 -environ -error_message_count -error_one_per_line -error_print_progname -__free_hook -g_atexit_lock -gGlobalsMutateLock -global_hashtable -gmtptr -handlers -je_background_thread_info -je_hooks_arena_new_hook -je_init_system_thp_mode -je_malloc_conf -je_malloc_disable.once_control -je_malloc_message -je_narenas_auto -je_ncpus -je_nhbins -je_opt_dirty_decay_ms -je_opt_metadata_thp -je_opt_muzzy_decay_ms -je_opt_narenas -je_opt_thp -je_tcache_bin_info -je_tcache_maxclass -je_tcaches -je_tsd_tsd -lastenv -lcl_is_set -lclptr -locallock -malloc_disabled_lock -__malloc_hook -malloc_initializer -mbrlen.mbs -mbtowc.mbs -__memalign_hook -muzzy_decay_ms_default.0 -narenas_total -ncleanups -optarg -optreset -os_page -p5s -__progname -random_mutex -__realloc_hook -_res_cache_list_lock -_res_cache_once -_res_key -__res_randomid.__libc_mutex_random -rs -_rs_forkdetect._rs_pid -_rs_forked -rsx -ru_pid -ru_prf -ru_reseed -__stack_chk_guard -stack_nelms -strtok.last -suboptarg -__system_property_area__ -tcaches_avail -tcaches_past -timezone -tmpnam.tmpcount -ut -wctomb.mbs -_ZL11g_arc4_lock -_ZL13g_locale_once -_ZL13g_thread_list -_ZL14syslog_log_tag -_ZL16gHeapprofdHandle -_ZL17g_libicuuc_handle -_ZL18netdClientInitOnce -_ZL30g_propservice_protocol_version -_ZN9prop_area13pa_data_size_E -_ZN9prop_area8pa_size_E -_ZZ10mbsnrtowcsE15__private_state -_ZZ10wcsnrtombsE15__private_state -_ZZ13error_at_lineE9last_file -_ZZ13error_at_lineE9last_line -_ZZ14__icu_charTypejE10u_charType -_ZZ23__bionic_get_shell_pathE7sh_path -_ZZ23__icu_hasBinaryPropertyj9UPropertyPFiiEE19u_hasBinaryProperty -_ZZ25__icu_getIntPropertyValuej9UPropertyE21u_getIntPropertyValue -_ZZ7mbrtowcE15__private_state -_ZZ7wcrtombE15__private_state -_ZZ8c16rtombE15__private_state -_ZZ8c32rtombE15__private_state -_ZZ8iswcntrlE10u_charType -_ZZ8iswdigitE9u_isdigit -_ZZ8iswpunctE9u_ispunct -_ZZ8mbrtoc16E15__private_state -_ZZ8mbrtoc32E15__private_state -_ZZ8towlowerE9u_tolower -_ZZ8towupperE9u_toupper -ether_aton.addr -seed48.sseed -__dtoa_locks -_ZGVZ14__icu_charTypejE10u_charType -_ZGVZ14tzset_unlockedE20persist_sys_timezone -_ZGVZ17__find_icu_symbolPKcE9found_icu -_ZGVZ23__bionic_get_shell_pathE7sh_path -_ZGVZ23__icu_hasBinaryPropertyj9UPropertyPFiiEE19u_hasBinaryProperty -_ZGVZ25__icu_getIntPropertyValuej9UPropertyE21u_getIntPropertyValue -_ZGVZ8iswcntrlE10u_charType -_ZGVZ8iswdigitE9u_isdigit -_ZGVZ8iswpunctE9u_ispunct -_ZGVZ8towlowerE9u_tolower -_ZGVZ8towupperE9u_toupper -_ZL10gAllocated -_ZL11gAllocLimit -_ZL13g_atfork_list -_ZL6g_lock -_ZL6g_tags -je_opt_stats_print_opts -nuls -precsize_ntoa.retbuf -__p_secstodate.output -ether_ntoa.buf -inet_ntoa.b -__p_class.classbuf -__p_type.typebuf -__sym_ntop.unname -__sym_ntos.unname -_ZL10gFunctions -_ZL12vendor_group -_ZL13vendor_passwd -freelist -__p_option.nbuf -__p_time.nbuf -_ZL18g_thread_list_lock -tm -_ZL8g_locale -ctl_mtx -init_lock -je_arenas_lock -je_background_thread_lock -tcaches_mtx -je_tsd_init_head -buf_asctime -__loc_ntoa.tmpbuf -utmp -_ZZ14tzset_unlockedE20persist_sys_timezone -arena_binind_div_info -__hexdig_D2A -lcl_TZname -inet_nsap_ntoa_tmpbuf -_ZL7key_map -_ZL17system_properties -private_mem -_res_cache_list -__libc_globals -tmpnam.buf -je_extents_rtree -_nres -je_arenas -je_extent_mutex_pool diff --git a/libc/tools/gensyscalls.py b/libc/tools/gensyscalls.py index b307486d5..0f3f1dc15 100755 --- a/libc/tools/gensyscalls.py +++ b/libc/tools/gensyscalls.py @@ -265,8 +265,7 @@ def add_footer(pointer_length, stub, syscall): stub += "\nALIAS_SYMBOL(%s, %s)\n" % (alias, syscall["func"]) # Use hidden visibility on LP64 for any functions beginning with underscores. - # Force hidden visibility for any functions which begin with 3 underscores - if (pointer_length == 64 and syscall["func"].startswith("__")) or syscall["func"].startswith("___"): + if pointer_length == 64 and syscall["func"].startswith("__"): stub += '.hidden ' + syscall["func"] + '\n' return stub diff --git a/libc/tzcode/bionic.cpp b/libc/tzcode/bionic.cpp index 1742d7941..6d84303a4 100644 --- a/libc/tzcode/bionic.cpp +++ b/libc/tzcode/bionic.cpp @@ -199,37 +199,36 @@ static int __bionic_open_tzdata_path(const char* path, int __bionic_open_tzdata(const char* olson_id, int32_t* entry_length) { int fd; -#if defined(__ANDROID__) - // On Android devices, try the four hard-coded locations in order. - // + // Try the three locations for the tzdata file in a strict order: // 1: The O-MR1 time zone updates via APK update mechanism. This is - // tried first because it allows us to test that the time zone updates - // via APK mechanism still works even on devices with the time zone - // module. + // tried first because it allows us to test that the time zone updates + // via APK mechanism still works even on devices with the time zone + // module. + // 2: The time zone data module which contains the main copy. This is the + // common case. + // 3: The ultimate fallback: the non-updatable copy in /system. + +#if defined(__ANDROID__) + // On Android devices, bionic has to work even if exec takes place without + // environment variables set. So, all paths are hardcoded here. + fd = __bionic_open_tzdata_path("/data/misc/zoneinfo/current/tzdata", olson_id, entry_length); if (fd >= 0) return fd; - // 2: The time zone data module which may contain newer data on - // devices that support module updates. fd = __bionic_open_tzdata_path("/apex/com.android.tzdata/etc/tz/tzdata", olson_id, entry_length); if (fd >= 0) return fd; - // 3: The runtime module, which should exist even on devices that - // do not support APEX file updates. - fd = __bionic_open_tzdata_path("/apex/com.android.runtime/etc/tz/tzdata", - olson_id, entry_length); - if (fd >= 0) return fd; - - // 4: The ultimate fallback: the non-updatable copy in /system. fd = __bionic_open_tzdata_path("/system/usr/share/zoneinfo/tzdata", olson_id, entry_length); if (fd >= 0) return fd; #else - // On the host, we don't expect those locations to exist, and we're not - // worried about security so we trust $ANDROID_DATA, $ANDROID_RUNTIME_ROOT, - // $ANDROID_TZDATA_ROOT, and $ANDROID_ROOT to point us in the right direction. + // On the host, we don't expect the hard-coded locations above to exist, and + // we're not worried about security so we trust $ANDROID_DATA, + // $ANDROID_TZDATA_ROOT, and $ANDROID_ROOT to point us in the right direction + // instead. + char* path = make_path("ANDROID_DATA", "/misc/zoneinfo/current/tzdata"); fd = __bionic_open_tzdata_path(path, olson_id, entry_length); free(path); @@ -240,11 +239,6 @@ int __bionic_open_tzdata(const char* olson_id, int32_t* entry_length) { free(path); if (fd >= 0) return fd; - path = make_path("ANDROID_RUNTIME_ROOT", "/etc/tz/tzdata"); - fd = __bionic_open_tzdata_path(path, olson_id, entry_length); - free(path); - if (fd >= 0) return fd; - path = make_path("ANDROID_ROOT", "/usr/share/zoneinfo/tzdata"); fd = __bionic_open_tzdata_path(path, olson_id, entry_length); free(path); diff --git a/libc/versioner-dependencies/common/clang-builtins b/libc/versioner-dependencies/common/clang-builtins index 7bd481c94..148dd2b63 120000 --- a/libc/versioner-dependencies/common/clang-builtins +++ b/libc/versioner-dependencies/common/clang-builtins @@ -1 +1 @@ -../../../../external/clang/lib/Headers/
\ No newline at end of file +../../../../prebuilts/clang-tools/linux-x86/clang-headers
\ No newline at end of file diff --git a/libdl/libdl_cfi.cpp b/libdl/libdl_cfi.cpp index 1dd5b21cd..3b68fc7d3 100644 --- a/libdl/libdl_cfi.cpp +++ b/libdl/libdl_cfi.cpp @@ -44,7 +44,8 @@ extern "C" size_t __cfi_shadow_size() { } static uint16_t shadow_load(void* p) { - uintptr_t addr = reinterpret_cast<uintptr_t>(p); + // Untag the pointer to move it into the address space covered by the shadow. + uintptr_t addr = reinterpret_cast<uintptr_t>(untag_address(p)); uintptr_t ofs = CFIShadow::MemToShadowOffset(addr); if (ofs > CFIShadow::kShadowSize) return CFIShadow::kInvalidShadow; return *reinterpret_cast<uint16_t*>(shadow_base_storage.v + ofs); diff --git a/libm/Android.bp b/libm/Android.bp index 48b9a5f06..59466e490 100644 --- a/libm/Android.bp +++ b/libm/Android.bp @@ -324,8 +324,16 @@ cc_library { x86: { srcs: [ "i387/fenv.c", + "x86/ceil.S", + "x86/ceilf.S", + "x86/floor.S", + "x86/floorf.S", + "x86/rint.S", + "x86/rintf.S", "x86/sqrt.S", "x86/sqrtf.S", + "x86/trunc.S", + "x86/truncf.S", "x86/e_acos.S", "x86/e_asin.S", "x86/e_atan2.S", @@ -359,37 +367,23 @@ cc_library { "upstream-freebsd/lib/msun/src/e_sqrtf.c", "upstream-freebsd/lib/msun/src/s_atan.c", "upstream-freebsd/lib/msun/src/s_cbrt.c", + "upstream-freebsd/lib/msun/src/s_ceil.c", + "upstream-freebsd/lib/msun/src/s_ceilf.c", "upstream-freebsd/lib/msun/src/s_cos.c", "upstream-freebsd/lib/msun/src/s_expm1.c", + "upstream-freebsd/lib/msun/src/s_floor.c", + "upstream-freebsd/lib/msun/src/s_floorf.c", "upstream-freebsd/lib/msun/src/s_log1p.c", "upstream-freebsd/lib/msun/src/s_lrint.c", "upstream-freebsd/lib/msun/src/s_lrintf.c", + "upstream-freebsd/lib/msun/src/s_rint.c", + "upstream-freebsd/lib/msun/src/s_rintf.c", "upstream-freebsd/lib/msun/src/s_sin.c", "upstream-freebsd/lib/msun/src/s_tan.c", "upstream-freebsd/lib/msun/src/s_tanh.c", + "upstream-freebsd/lib/msun/src/s_trunc.c", + "upstream-freebsd/lib/msun/src/s_truncf.c", ], - sse4_1: { - srcs: [ - "x86/ceil.S", - "x86/ceilf.S", - "x86/floor.S", - "x86/floorf.S", - "x86/rint.S", - "x86/rintf.S", - "x86/trunc.S", - "x86/truncf.S", - ], - exclude_srcs: [ - "upstream-freebsd/lib/msun/src/s_ceil.c", - "upstream-freebsd/lib/msun/src/s_ceilf.c", - "upstream-freebsd/lib/msun/src/s_floor.c", - "upstream-freebsd/lib/msun/src/s_floorf.c", - "upstream-freebsd/lib/msun/src/s_rint.c", - "upstream-freebsd/lib/msun/src/s_rintf.c", - "upstream-freebsd/lib/msun/src/s_trunc.c", - "upstream-freebsd/lib/msun/src/s_truncf.c", - ], - }, local_include_dirs: ["i387"], pack_relocations: false, ldflags: ["-Wl,--hash-style=both"], @@ -399,8 +393,16 @@ cc_library { x86_64: { srcs: [ "amd64/fenv.c", + "x86_64/ceil.S", + "x86_64/ceilf.S", + "x86_64/floor.S", + "x86_64/floorf.S", + "x86_64/rint.S", + "x86_64/rintf.S", "x86_64/sqrt.S", "x86_64/sqrtf.S", + "x86_64/trunc.S", + "x86_64/truncf.S", "x86_64/e_acos.S", "x86_64/e_asin.S", "x86_64/e_atan2.S", @@ -431,39 +433,25 @@ cc_library { "upstream-freebsd/lib/msun/src/e_sqrtf.c", "upstream-freebsd/lib/msun/src/s_atan.c", "upstream-freebsd/lib/msun/src/s_cbrt.c", + "upstream-freebsd/lib/msun/src/s_ceil.c", + "upstream-freebsd/lib/msun/src/s_ceilf.c", "upstream-freebsd/lib/msun/src/s_cos.c", "upstream-freebsd/lib/msun/src/s_expm1.c", + "upstream-freebsd/lib/msun/src/s_floor.c", + "upstream-freebsd/lib/msun/src/s_floorf.c", "upstream-freebsd/lib/msun/src/s_log1p.c", "upstream-freebsd/lib/msun/src/s_llrint.c", "upstream-freebsd/lib/msun/src/s_llrintf.c", "upstream-freebsd/lib/msun/src/s_lrint.c", "upstream-freebsd/lib/msun/src/s_lrintf.c", + "upstream-freebsd/lib/msun/src/s_rint.c", + "upstream-freebsd/lib/msun/src/s_rintf.c", "upstream-freebsd/lib/msun/src/s_sin.c", "upstream-freebsd/lib/msun/src/s_tan.c", "upstream-freebsd/lib/msun/src/s_tanh.c", + "upstream-freebsd/lib/msun/src/s_trunc.c", + "upstream-freebsd/lib/msun/src/s_truncf.c", ], - sse4_1: { - srcs: [ - "x86_64/ceil.S", - "x86_64/ceilf.S", - "x86_64/floor.S", - "x86_64/floorf.S", - "x86_64/rint.S", - "x86_64/rintf.S", - "x86_64/trunc.S", - "x86_64/truncf.S", - ], - exclude_srcs: [ - "upstream-freebsd/lib/msun/src/s_ceil.c", - "upstream-freebsd/lib/msun/src/s_ceilf.c", - "upstream-freebsd/lib/msun/src/s_floor.c", - "upstream-freebsd/lib/msun/src/s_floorf.c", - "upstream-freebsd/lib/msun/src/s_rint.c", - "upstream-freebsd/lib/msun/src/s_rintf.c", - "upstream-freebsd/lib/msun/src/s_trunc.c", - "upstream-freebsd/lib/msun/src/s_truncf.c", - ], - }, version_script: ":libm.x86_64.map", }, }, @@ -503,7 +491,7 @@ cc_library { native_coverage: bionic_coverage, sanitize: { address: false, - coverage: false, + fuzzer: false, integer_overflow: false, }, stl: "none", diff --git a/linker/Android.bp b/linker/Android.bp index 5e7a921a4..bdb7c178a 100644 --- a/linker/Android.bp +++ b/linker/Android.bp @@ -177,11 +177,6 @@ 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/dlfcn.cpp b/linker/dlfcn.cpp index 5a47272c1..18301e0e2 100644 --- a/linker/dlfcn.cpp +++ b/linker/dlfcn.cpp @@ -308,11 +308,11 @@ static uint8_t __libdl_info_buf[sizeof(soinfo)] __attribute__((aligned(8))); static soinfo* __libdl_info = nullptr; // This is used by the dynamic linker. Every process gets these symbols for free. -soinfo* get_libdl_info(const char* linker_path, const soinfo& linker_si) { +soinfo* get_libdl_info(const soinfo& linker_si) { CHECK((linker_si.flags_ & FLAG_GNU_HASH) != 0); if (__libdl_info == nullptr) { - __libdl_info = new (__libdl_info_buf) soinfo(&g_default_namespace, linker_path, nullptr, 0, 0); + __libdl_info = new (__libdl_info_buf) soinfo(&g_default_namespace, nullptr, nullptr, 0, 0); __libdl_info->flags_ |= (FLAG_LINKED | FLAG_GNU_HASH); __libdl_info->strtab_ = linker_si.strtab_; __libdl_info->symtab_ = linker_si.symtab_; diff --git a/linker/ld.config.format.md b/linker/ld.config.format.md index faf5cc8a6..f9fbcde3f 100644 --- a/linker/ld.config.format.md +++ b/linker/ld.config.format.md @@ -25,7 +25,7 @@ configuration using set of properties described in example below. ## Example ``` -# The following line maps section to a dir. Binraies ran from this location will use namespaces +# The following line maps section to a dir. Binaries ran from this location will use namespaces # configuration specified in [example_section] below dir.example_section=/system/bin/example @@ -38,7 +38,7 @@ dir.example_section=/system/bin/example # default value is false enable.target.sdk.version = true -# This property can be used to declare additional namespaces.Note that there is always the default +# This property can be used to declare additional namespaces. Note that there is always the default # namespace. The default namespace is the namespace for the main executable. This list is # comma-separated. additional.namespaces = ns1 @@ -65,7 +65,7 @@ namespace.default.asan.permitted.paths = /data/${LIB} # This declares linked namespaces - comma separated list. namespace.default.links = ns1 -# For every link define list of shared libraries. This is list of the libraries accessilbe from +# For every link define list of shared libraries. This is list of the libraries accessible from # default namespace but loaded in the linked namespace. namespace.default.link.ns1.shared_libs = libexternal.so:libother.so diff --git a/linker/ldd b/linker/ldd index 3a0aff91a..6bc49b4b1 100644 --- a/linker/ldd +++ b/linker/ldd @@ -10,7 +10,8 @@ function error() { [ $# -eq 1 ] || error "usage: ldd FILE" -case `file -L "$1"` in +what=$(file -L "$1") +case "$what" in *32-bit*) linker --list "$1" ;; @@ -18,6 +19,6 @@ case `file -L "$1"` in linker64 --list "$1" ;; *) - error "$1: not an ELF file" + error "$what" ;; esac diff --git a/linker/linker.cpp b/linker/linker.cpp index 32dce3805..d581dd8ce 100644 --- a/linker/linker.cpp +++ b/linker/linker.cpp @@ -76,6 +76,7 @@ static std::unordered_map<void*, size_t> g_dso_handle_counters; +static bool g_anonymous_namespace_set = false; static android_namespace_t* g_anonymous_namespace = &g_default_namespace; static std::unordered_map<std::string, android_namespace_t*> g_exported_namespaces; @@ -90,6 +91,8 @@ static const char* const kLdConfigArchFilePath = "/system/etc/ld.config." ABI_ST static const char* const kLdConfigFilePath = "/system/etc/ld.config.txt"; static const char* const kLdConfigVndkLiteFilePath = "/system/etc/ld.config.vndk_lite.txt"; +static const char* const kLdGeneratedConfigFilePath = "/dev/linkerconfig/ld.config.txt"; + #if defined(__LP64__) static const char* const kSystemLibDir = "/system/lib64"; static const char* const kOdmLibDir = "/odm/lib64"; @@ -270,8 +273,6 @@ static bool translateSystemPathToApexPath(const char* name, std::string* out_nam static std::vector<std::string> g_ld_preload_names; -static bool g_anonymous_namespace_initialized; - #if STATS struct linker_stats_t { int count[kRelocMax]; @@ -282,6 +283,16 @@ static linker_stats_t linker_stats; void count_relocation(RelocationKind kind) { ++linker_stats.count[kind]; } + +void print_linker_stats() { + PRINT("RELO STATS: %s: %d abs, %d rel, %d copy, %d symbol (%d cached)", + g_argv[0], + linker_stats.count[kRelocAbsolute], + linker_stats.count[kRelocRelative], + linker_stats.count[kRelocCopy], + linker_stats.count[kRelocSymbol], + linker_stats.count[kRelocSymbolCached]); +} #else void count_relocation(RelocationKind) { } @@ -393,16 +404,23 @@ static void parse_LD_LIBRARY_PATH(const char* path) { } static bool realpath_fd(int fd, std::string* realpath) { - std::vector<char> buf(PATH_MAX), proc_self_fd(PATH_MAX); - async_safe_format_buffer(&proc_self_fd[0], proc_self_fd.size(), "/proc/self/fd/%d", fd); - if (readlink(&proc_self_fd[0], &buf[0], buf.size()) == -1) { + // proc_self_fd needs to be large enough to hold "/proc/self/fd/" plus an + // integer, plus the NULL terminator. + char proc_self_fd[32]; + // We want to statically allocate this large buffer so that we don't grow + // the stack by too much. + static char buf[PATH_MAX]; + + async_safe_format_buffer(proc_self_fd, sizeof(proc_self_fd), "/proc/self/fd/%d", fd); + auto length = readlink(proc_self_fd, buf, sizeof(buf)); + if (length == -1) { if (!is_first_stage_init()) { - PRINT("readlink(\"%s\") failed: %s [fd=%d]", &proc_self_fd[0], strerror(errno), fd); + PRINT("readlink(\"%s\") failed: %s [fd=%d]", proc_self_fd, strerror(errno), fd); } return false; } - *realpath = &buf[0]; + realpath->assign(buf, length); return true; } @@ -934,7 +952,9 @@ static const ElfW(Sym)* dlsym_linear_lookup(android_namespace_t* ns, } soinfo* find_containing_library(const void* p) { - ElfW(Addr) address = reinterpret_cast<ElfW(Addr)>(p); + // Addresses within a library may be tagged if they point to globals. Untag + // them so that the bounds check succeeds. + ElfW(Addr) address = reinterpret_cast<ElfW(Addr)>(untag_address(p)); for (soinfo* si = solist_get_head(); si != nullptr; si = si->next) { if (address < si->base || address - si->base >= si->size) { continue; @@ -1215,12 +1235,14 @@ static bool find_loaded_library_by_inode(android_namespace_t* ns, off64_t file_offset, bool search_linked_namespaces, soinfo** candidate) { + if (file_stat.st_dev == 0 || file_stat.st_ino == 0) { + *candidate = nullptr; + return false; + } auto predicate = [&](soinfo* si) { - return si->get_st_dev() != 0 && - si->get_st_ino() != 0 && + return si->get_st_ino() == file_stat.st_ino && si->get_st_dev() == file_stat.st_dev && - si->get_st_ino() == file_stat.st_ino && si->get_file_offset() == file_offset; }; @@ -1882,6 +1904,9 @@ bool find_libraries(android_namespace_t* ns, // flag is set. link_extinfo = extinfo; } + if (__libc_shared_globals()->load_hook) { + __libc_shared_globals()->load_hook(si->load_bias, si->phdr, si->phnum); + } if (!si->link_image(global_group, local_group, link_extinfo, &relro_fd_offset) || !get_cfi_shadow()->AfterLoad(si, solist_get_head())) { return false; @@ -2020,6 +2045,9 @@ static void soinfo_unload_impl(soinfo* root) { si); notify_gdb_of_unload(si); unregister_soinfo_tls(si); + if (__libc_shared_globals()->unload_hook) { + __libc_shared_globals()->unload_hook(si->load_bias, si->phdr, si->phnum); + } get_cfi_shadow()->BeforeUnload(si); soinfo_free(si); } @@ -2452,14 +2480,29 @@ int do_dlclose(void* handle) { return 0; } -bool init_anonymous_namespace(const char* shared_lib_sonames, const char* library_search_path) { - if (g_anonymous_namespace_initialized) { - DL_ERR("anonymous namespace has already been initialized."); - return false; +// Make ns as the anonymous namespace that is a namespace used when +// we fail to determine the caller address (e.g., call from mono-jited code) +// Since there can be multiple anonymous namespace in a process, subsequent +// call to this function causes an error. +static bool set_anonymous_namespace(android_namespace_t* ns) { + if (!g_anonymous_namespace_set && ns != nullptr) { + CHECK(ns->is_also_used_as_anonymous()); + g_anonymous_namespace = ns; + g_anonymous_namespace_set = true; + return true; } + return false; +} +// TODO(b/130388701) remove this. Currently, this is used only for testing +// where we don't have classloader namespace. +bool init_anonymous_namespace(const char* shared_lib_sonames, const char* library_search_path) { ProtectedDataGuard guard; + // Test-only feature: we need to change the anonymous namespace multiple times + // while the test is running. + g_anonymous_namespace_set = false; + // create anonymous namespace // When the caller is nullptr - create_namespace will take global group // from the anonymous namespace, which is fine because anonymous namespace @@ -2469,21 +2512,18 @@ bool init_anonymous_namespace(const char* shared_lib_sonames, const char* librar "(anonymous)", nullptr, library_search_path, - ANDROID_NAMESPACE_TYPE_ISOLATED, + ANDROID_NAMESPACE_TYPE_ISOLATED | + ANDROID_NAMESPACE_TYPE_ALSO_USED_AS_ANONYMOUS, nullptr, &g_default_namespace); - if (anon_ns == nullptr) { - return false; - } + CHECK(anon_ns != nullptr); if (!link_namespaces(anon_ns, &g_default_namespace, shared_lib_sonames)) { + // TODO: delete anon_ns return false; } - g_anonymous_namespace = anon_ns; - g_anonymous_namespace_initialized = true; - return true; } @@ -2523,6 +2563,7 @@ android_namespace_t* create_namespace(const void* caller_addr, ns->set_name(name); ns->set_isolated((type & ANDROID_NAMESPACE_TYPE_ISOLATED) != 0); ns->set_greylist_enabled((type & ANDROID_NAMESPACE_TYPE_GREYLIST_ENABLED) != 0); + ns->set_also_used_as_anonymous((type & ANDROID_NAMESPACE_TYPE_ALSO_USED_AS_ANONYMOUS) != 0); if ((type & ANDROID_NAMESPACE_TYPE_SHARED) != 0) { // append parent namespace paths. @@ -2554,6 +2595,16 @@ android_namespace_t* create_namespace(const void* caller_addr, ns->set_default_library_paths(std::move(default_library_paths)); ns->set_permitted_paths(std::move(permitted_paths)); + if (ns->is_also_used_as_anonymous() && !set_anonymous_namespace(ns)) { + DL_ERR("failed to set namespace: [name=\"%s\", ld_library_path=\"%s\", default_library_paths=\"%s\"" + " permitted_paths=\"%s\"] as the anonymous namespace", + ns->get_name(), + android::base::Join(ns->get_ld_library_paths(), ':').c_str(), + android::base::Join(ns->get_default_library_paths(), ':').c_str(), + android::base::Join(ns->get_permitted_paths(), ':').c_str()); + return nullptr; + } + return ns; } @@ -2874,6 +2925,17 @@ bool soinfo::relocate(const VersionTracker& version_tracker, ElfRelIteratorT&& r const size_t tls_tp_base = __libc_shared_globals()->static_tls_layout.offset_thread_pointer(); std::vector<std::pair<TlsDescriptor*, size_t>> deferred_tlsdesc_relocs; + struct { + // Cache key + ElfW(Word) sym; + + // Cache value + const ElfW(Sym)* s; + soinfo* lsi; + } symbol_lookup_cache; + + symbol_lookup_cache.sym = 0; + for (size_t idx = 0; rel_iterator.has_next(); ++idx) { const auto rel = rel_iterator.next(); if (rel == nullptr) { @@ -2917,14 +2979,25 @@ bool soinfo::relocate(const VersionTracker& version_tracker, ElfRelIteratorT&& r return false; } else { sym_name = get_string(symtab_[sym].st_name); - const version_info* vi = nullptr; - if (!lookup_version_info(version_tracker, sym, sym_name, &vi)) { - return false; - } + if (sym == symbol_lookup_cache.sym) { + s = symbol_lookup_cache.s; + lsi = symbol_lookup_cache.lsi; + count_relocation(kRelocSymbolCached); + } else { + const version_info* vi = nullptr; - if (!soinfo_do_lookup(this, sym_name, vi, &lsi, global_group, local_group, &s)) { - return false; + if (!lookup_version_info(version_tracker, sym, sym_name, &vi)) { + return false; + } + + if (!soinfo_do_lookup(this, sym_name, vi, &lsi, global_group, local_group, &s)) { + return false; + } + + symbol_lookup_cache.sym = sym; + symbol_lookup_cache.s = s; + symbol_lookup_cache.lsi = lsi; } if (s == nullptr) { @@ -3121,10 +3194,6 @@ bool soinfo::relocate(const VersionTracker& version_tracker, ElfRelIteratorT&& r *reinterpret_cast<ElfW(Addr)*>(reloc) = tpoff; } break; - -#if !defined(__aarch64__) - // Omit support for DTPMOD/DTPREL on arm64, at least until - // http://b/123385182 is fixed. arm64 uses TLSDESC instead. case R_GENERIC_TLS_DTPMOD: count_relocation(kRelocRelative); MARK(rel->r_offset); @@ -3149,7 +3218,6 @@ bool soinfo::relocate(const VersionTracker& version_tracker, ElfRelIteratorT&& r reinterpret_cast<void*>(sym_addr + addend), sym_name); *reinterpret_cast<ElfW(Addr)*>(reloc) = sym_addr + addend; break; -#endif // !defined(__aarch64__) #if defined(__aarch64__) // Bionic currently only implements TLSDESC for arm64. This implementation should work with @@ -4073,10 +4141,10 @@ static std::vector<android_namespace_t*> init_default_namespace_no_config(bool i return namespaces; } -// return /apex/<name>/etc/ld.config.txt from /apex/<name>/bin/<exec> +// return /apex/<name>/etc/ld.config.txt from /apex/<name>/bin/* static std::string get_ld_config_file_apex_path(const char* executable_path) { std::vector<std::string> paths = android::base::Split(executable_path, "/"); - if (paths.size() == 5 && paths[1] == "apex" && paths[3] == "bin") { + if (paths.size() >= 5 && paths[1] == "apex" && paths[3] == "bin") { return std::string("/apex/") + paths[2] + "/etc/ld.config.txt"; } return ""; @@ -4106,6 +4174,13 @@ static std::string get_ld_config_file_path(const char* executable_path) { } #endif + // Use generated linker config if flag is set + // TODO(b/138920271) Do not check property once it is confirmed as stable + if (android::base::GetBoolProperty("sys.linker.use_generated_config", false) && + file_exists(kLdGeneratedConfigFilePath)) { + return kLdGeneratedConfigFilePath; + } + std::string path = get_ld_config_file_apex_path(executable_path); if (!path.empty()) { if (file_exists(path.c_str())) { diff --git a/linker/linker.h b/linker/linker.h index 4c89cebcd..89390b384 100644 --- a/linker/linker.h +++ b/linker/linker.h @@ -94,12 +94,15 @@ enum RelocationKind { kRelocRelative, kRelocCopy, kRelocSymbol, + kRelocSymbolCached, kRelocMax }; void count_relocation(RelocationKind kind); -soinfo* get_libdl_info(const char* linker_path, const soinfo& linker_si); +void print_linker_stats(); + +soinfo* get_libdl_info(const soinfo& linker_si); soinfo* find_containing_library(const void* p); @@ -162,6 +165,13 @@ enum { */ ANDROID_NAMESPACE_TYPE_GREYLIST_ENABLED = 0x08000000, + /* This flag instructs linker to use this namespace as the anonymous + * namespace. There can be only one anonymous namespace in a process. If there + * already an anonymous namespace in the process, using this flag when + * creating a new namespace causes an error + */ + ANDROID_NAMESPACE_TYPE_ALSO_USED_AS_ANONYMOUS = 0x10000000, + ANDROID_NAMESPACE_TYPE_SHARED_ISOLATED = ANDROID_NAMESPACE_TYPE_SHARED | ANDROID_NAMESPACE_TYPE_ISOLATED, }; diff --git a/linker/linker_main.cpp b/linker/linker_main.cpp index f5760231a..fd1592d33 100644 --- a/linker/linker_main.cpp +++ b/linker/linker_main.cpp @@ -63,6 +63,8 @@ static ElfW(Addr) get_elf_exec_load_bias(const ElfW(Ehdr)* elf); static void get_elf_base_from_phdr(const ElfW(Phdr)* phdr_table, size_t phdr_count, ElfW(Addr)* base, ElfW(Addr)* load_bias); +static void set_bss_vma_name(soinfo* si); + // These should be preserved static to avoid emitting // RELATIVE relocations for the part of the code running // before linker links itself. @@ -176,11 +178,12 @@ static void add_vdso() { } // Initializes an soinfo's link_map_head field using other fields from the -// soinfo (phdr, phnum, load_bias). -static void init_link_map_head(soinfo& info, const char* linker_path) { +// soinfo (phdr, phnum, load_bias). The soinfo's realpath must not change after +// this function is called. +static void init_link_map_head(soinfo& info) { auto& map = info.link_map_head; map.l_addr = info.load_bias; - map.l_name = const_cast<char*>(linker_path); + map.l_name = const_cast<char*>(info.get_realpath()); phdr_table_get_dynamic_section(info.phdr, info.phnum, info.load_bias, &map.l_ld, nullptr); } @@ -232,9 +235,9 @@ static ExecutableInfo get_executable_info() { } #if defined(__LP64__) -static char kLinkerPath[] = "/system/bin/linker64"; +static char kFallbackLinkerPath[] = "/system/bin/linker64"; #else -static char kLinkerPath[] = "/system/bin/linker"; +static char kFallbackLinkerPath[] = "/system/bin/linker"; #endif __printflike(1, 2) @@ -350,15 +353,11 @@ static ElfW(Addr) linker_main(KernelArgumentBlock& args, const char* exe_to_load const ExecutableInfo exe_info = exe_to_load ? load_executable(exe_to_load) : get_executable_info(); - // Assign to a static variable for the sake of the debug map, which needs - // a C-style string to last until the program exits. - static std::string exe_path = exe_info.path; - - INFO("[ Linking executable \"%s\" ]", exe_path.c_str()); + INFO("[ Linking executable \"%s\" ]", exe_info.path.c_str()); // Initialize the main exe's soinfo. soinfo* si = soinfo_alloc(&g_default_namespace, - exe_path.c_str(), &exe_info.file_stat, + exe_info.path.c_str(), &exe_info.file_stat, 0, RTLD_GLOBAL); somain = si; si->phdr = exe_info.phdr; @@ -367,7 +366,27 @@ static ElfW(Addr) linker_main(KernelArgumentBlock& args, const char* exe_to_load si->size = phdr_table_get_load_size(si->phdr, si->phnum); si->dynamic = nullptr; si->set_main_executable(); - init_link_map_head(*si, exe_path.c_str()); + init_link_map_head(*si); + + set_bss_vma_name(si); + + // Use the executable's PT_INTERP string as the solinker filename in the + // dynamic linker's module list. gdb reads both PT_INTERP and the module list, + // and if the paths for the linker are different, gdb will report that the + // PT_INTERP linker path was unloaded once the module list is initialized. + // There are three situations to handle: + // - the APEX linker (/system/bin/linker[64] -> /apex/.../linker[64]) + // - the ASAN linker (/system/bin/linker_asan[64] -> /apex/.../linker[64]) + // - the bootstrap linker (/system/bin/bootstrap/linker[64]) + const char *interp = phdr_table_get_interpreter_name(somain->phdr, somain->phnum, + somain->load_bias); + if (interp == nullptr) { + // This case can happen if the linker attempts to execute itself + // (e.g. "linker64 /system/bin/linker64"). + interp = kFallbackLinkerPath; + } + solinker->set_realpath(interp); + init_link_map_head(*solinker); // Register the main executable and the linker upfront to have // gdb aware of them before loading the rest of the dependency @@ -405,7 +424,7 @@ static ElfW(Addr) linker_main(KernelArgumentBlock& args, const char* exe_to_load parse_LD_LIBRARY_PATH(ldpath_env); parse_LD_PRELOAD(ldpreload_env); - std::vector<android_namespace_t*> namespaces = init_default_namespaces(exe_path.c_str()); + std::vector<android_namespace_t*> namespaces = init_default_namespaces(exe_info.path.c_str()); if (!si->prelink_image()) __linker_cannot_link(g_argv[0]); @@ -475,11 +494,7 @@ static ElfW(Addr) linker_main(KernelArgumentBlock& args, const char* exe_to_load static_cast<long long>(t0.tv_usec)))); #endif #if STATS - PRINT("RELO STATS: %s: %d abs, %d rel, %d copy, %d symbol", g_argv[0], - linker_stats.count[kRelocAbsolute], - linker_stats.count[kRelocRelative], - linker_stats.count[kRelocCopy], - linker_stats.count[kRelocSymbol]); + print_linker_stats(); #endif #if COUNT_PAGES { @@ -559,6 +574,31 @@ static void get_elf_base_from_phdr(const ElfW(Phdr)* phdr_table, size_t phdr_cou async_safe_fatal("Could not find a PHDR: broken executable?"); } +/* + * Set anonymous VMA name for .bss section. For DSOs loaded by the linker, this + * is done by ElfReader. This function is here for DSOs loaded by the kernel, + * namely the linker itself and the main executable. + */ +static void set_bss_vma_name(soinfo* si) { + for (size_t i = 0; i < si->phnum; ++i) { + auto phdr = &si->phdr[i]; + + if (phdr->p_type != PT_LOAD) { + continue; + } + + ElfW(Addr) seg_start = phdr->p_vaddr + si->load_bias; + ElfW(Addr) seg_page_end = PAGE_END(seg_start + phdr->p_memsz); + ElfW(Addr) seg_file_end = PAGE_END(seg_start + phdr->p_filesz); + + if (seg_page_end > seg_file_end) { + prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, + reinterpret_cast<void*>(seg_file_end), seg_page_end - seg_file_end, + ".bss"); + } + } +} + // Detect an attempt to run the linker on itself. e.g.: // /system/bin/linker64 /system/bin/linker64 // Use priority-1 to run this constructor before other constructors. @@ -649,6 +689,9 @@ __linker_init_post_relocation(KernelArgumentBlock& args, soinfo& tmp_linker_so) // couldn't make system calls on x86 at that point, but we can now... if (!tmp_linker_so.protect_relro()) __linker_cannot_link(args.argv[0]); + // And we can set VMA name for the bss section now + set_bss_vma_name(&tmp_linker_so); + // Initialize the linker's static libc's globals __libc_init_globals(); @@ -695,9 +738,8 @@ __linker_init_post_relocation(KernelArgumentBlock& args, soinfo& tmp_linker_so) // Initialize static variables. Note that in order to // get correct libdl_info we need to call constructors // before get_libdl_info(). - sonext = solist = solinker = get_libdl_info(kLinkerPath, tmp_linker_so); + sonext = solist = solinker = get_libdl_info(tmp_linker_so); g_default_namespace.add_soinfo(solinker); - init_link_map_head(*solinker, kLinkerPath); ElfW(Addr) start_address = linker_main(args, exe_to_load); diff --git a/linker/linker_namespaces.h b/linker/linker_namespaces.h index 215ad05c3..9561bb444 100644 --- a/linker/linker_namespaces.h +++ b/linker/linker_namespaces.h @@ -72,7 +72,10 @@ struct android_namespace_link_t { struct android_namespace_t { public: - android_namespace_t() : is_isolated_(false), is_greylist_enabled_(false) {} + android_namespace_t() : + is_isolated_(false), + is_greylist_enabled_(false), + is_also_used_as_anonymous_(false) {} const char* get_name() const { return name_.c_str(); } void set_name(const char* name) { name_ = name; } @@ -83,6 +86,9 @@ struct android_namespace_t { bool is_greylist_enabled() const { return is_greylist_enabled_; } void set_greylist_enabled(bool enabled) { is_greylist_enabled_ = enabled; } + bool is_also_used_as_anonymous() const { return is_also_used_as_anonymous_; } + void set_also_used_as_anonymous(bool yes) { is_also_used_as_anonymous_ = yes; } + const std::vector<std::string>& get_ld_library_paths() const { return ld_library_paths_; } @@ -164,6 +170,7 @@ struct android_namespace_t { std::string name_; bool is_isolated_; bool is_greylist_enabled_; + bool is_also_used_as_anonymous_; std::vector<std::string> ld_library_paths_; std::vector<std::string> default_library_paths_; std::vector<std::string> permitted_paths_; diff --git a/linker/linker_relocs.h b/linker/linker_relocs.h index 68191f911..1da5ebe34 100644 --- a/linker/linker_relocs.h +++ b/linker/linker_relocs.h @@ -38,9 +38,9 @@ #define R_GENERIC_GLOB_DAT R_AARCH64_GLOB_DAT #define R_GENERIC_RELATIVE R_AARCH64_RELATIVE #define R_GENERIC_IRELATIVE R_AARCH64_IRELATIVE -#define R_GENERIC_TLS_DTPMOD R_AARCH64_TLS_DTPMOD64 -#define R_GENERIC_TLS_DTPREL R_AARCH64_TLS_DTPREL64 -#define R_GENERIC_TLS_TPREL R_AARCH64_TLS_TPREL64 +#define R_GENERIC_TLS_DTPMOD R_AARCH64_TLS_DTPMOD +#define R_GENERIC_TLS_DTPREL R_AARCH64_TLS_DTPREL +#define R_GENERIC_TLS_TPREL R_AARCH64_TLS_TPREL #define R_GENERIC_TLSDESC R_AARCH64_TLSDESC #elif defined (__arm__) diff --git a/linker/linker_sdk_versions.cpp b/linker/linker_sdk_versions.cpp index b06f3e63f..29c0f4af2 100644 --- a/linker/linker_sdk_versions.cpp +++ b/linker/linker_sdk_versions.cpp @@ -26,10 +26,13 @@ * SUCH DAMAGE. */ -#include "linker.h" -#include <android/api-level.h> #include <atomic> +#include <android/api-level.h> +#include <android/fdsan.h> + +#include "linker.h" + static std::atomic<int> g_target_sdk_version(__ANDROID_API__); void set_application_target_sdk_version(int target) { @@ -38,6 +41,10 @@ void set_application_target_sdk_version(int target) { target = __ANDROID_API__; } g_target_sdk_version = target; + + if (target < 30) { + android_fdsan_set_error_level_from_property(ANDROID_FDSAN_ERROR_LEVEL_WARN_ONCE); + } } int get_application_target_sdk_version() { diff --git a/linker/linker_soinfo.cpp b/linker/linker_soinfo.cpp index 5f40528e9..d4b25414e 100644 --- a/linker/linker_soinfo.cpp +++ b/linker/linker_soinfo.cpp @@ -550,6 +550,16 @@ void soinfo::set_nodelete() { rtld_flags_ |= RTLD_NODELETE; } +void soinfo::set_realpath(const char* path) { +#if defined(__work_around_b_24465209__) + if (has_min_version(2)) { + realpath_ = path; + } +#else + realpath_ = path; +#endif +} + const char* soinfo::get_realpath() const { #if defined(__work_around_b_24465209__) if (has_min_version(2)) { diff --git a/linker/linker_soinfo.h b/linker/linker_soinfo.h index 80c51af9a..27032c2da 100644 --- a/linker/linker_soinfo.h +++ b/linker/linker_soinfo.h @@ -278,6 +278,7 @@ struct soinfo { void set_soname(const char* soname); const char* get_soname() const; + void set_realpath(const char* path); const char* get_realpath() const; const ElfW(Versym)* get_versym(size_t n) const; ElfW(Addr) get_verneed_ptr() const; @@ -372,7 +373,7 @@ struct soinfo { android_namespace_list_t secondary_namespaces_; uintptr_t handle_; - friend soinfo* get_libdl_info(const char* linker_path, const soinfo& linker_si); + friend soinfo* get_libdl_info(const soinfo& linker_si); // version >= 4 ElfW(Relr)* relr_; diff --git a/tests/Android.bp b/tests/Android.bp index db02d751a..aac419c23 100644 --- a/tests/Android.bp +++ b/tests/Android.bp @@ -241,6 +241,15 @@ cc_test_library { cflags: [ "-fno-emulated-tls", ], + // With fuzzer builds, compiler instrumentation generates a reference to the + // __sancov_lowest_stack variable, which (for now) is defined by the fuzzer + // library as an emutls symbol. The -fno-emulated-tls flag above configures + // the compiler to reference an ordinary ELF TLS __sancov_lowest_stack + // symbol instead, which isn't defined. Disable the fuzzer for this test + // until the platform is switched to ELF TLS. + sanitize: { + fuzzer: false, + }, } cc_test_library { @@ -262,6 +271,15 @@ cc_test_library { cflags: [ "-fno-emulated-tls", ], + // With fuzzer builds, compiler instrumentation generates a reference to the + // __sancov_lowest_stack variable, which (for now) is defined by the fuzzer + // library as an emutls symbol. The -fno-emulated-tls flag above configures + // the compiler to reference an ordinary ELF TLS __sancov_lowest_stack + // symbol instead, which isn't defined. Disable the fuzzer for this test + // until the platform is switched to ELF TLS. + sanitize: { + fuzzer: false, + }, } // ----------------------------------------------------------------------------- @@ -269,6 +287,18 @@ cc_test_library { // ----------------------------------------------------------------------------- cc_defaults { + name: "bionic_clang_fortify_tests_w_flags", + cflags: [ + "-Wno-builtin-memcpy-chk-size", + "-Wno-format-security", + "-Wno-format-zero-length", + "-Wno-memset-transposed-args", + "-Wno-strlcpy-strlcat-size", + "-Wno-strncat-size", + ], +} + +cc_defaults { name: "bionic_fortify_tests_defaults", cflags: [ "-U_FORTIFY_SOURCE", @@ -287,6 +317,9 @@ cc_defaults { // unused. cc_test_library { name: "fortify_disabled_for_asan", + defaults: [ + "bionic_clang_fortify_tests_w_flags", + ], cflags: [ "-Werror", "-D_FORTIFY_SOURCE=2", @@ -294,11 +327,10 @@ cc_test_library { // enabled. Since the intent is just to build this, we can get away with // passing this flag on its own. "-fsanitize=address", - "-Wno-memset-transposed-args", ], // Ignore that we don't have ASAN symbols linked in. allow_undefined_symbols: true, - srcs: ["fortify_filecheck_diagnostics_test.cpp"], + srcs: ["clang_fortify_tests.cpp"], } // Ensure we don't use FORTIFY'ed functions with the static analyzer/clang-tidy: @@ -307,13 +339,15 @@ cc_test_library { // enabled. The library that results from building this is meant to be unused. cc_test_library { name: "fortify_disabled_for_tidy", + defaults: [ + "bionic_clang_fortify_tests_w_flags", + ], cflags: [ "-Werror", "-D_FORTIFY_SOURCE=2", "-D__clang_analyzer__", - "-Wno-memset-transposed-args", ], - srcs: ["fortify_filecheck_diagnostics_test.cpp"], + srcs: ["clang_fortify_tests.cpp"], } cc_test_library { @@ -346,6 +380,53 @@ cc_test_library { }, } +cc_defaults { + name: "bionic_new_fortify_tests_defaults", + defaults: [ + "bionic_clang_fortify_tests_w_flags", + ], + cflags: [ + "-U_FORTIFY_SOURCE", + ], + srcs: ["clang_fortify_tests.cpp"], + target: { + host: { + clang_cflags: ["-D__clang__"], + }, + }, +} + +cc_test_library { + name: "libfortify1-new-tests-clang", + defaults: [ + "bionic_new_fortify_tests_defaults", + "bionic_tests_defaults", + ], + cflags: [ + "-D_FORTIFY_SOURCE=1", + "-DTEST_NAME=Fortify1_clang_new", + ], + shared: { + enabled: false, + }, +} + +cc_test_library { + name: "libfortify2-new-tests-clang", + defaults: [ + "bionic_new_fortify_tests_defaults", + "bionic_tests_defaults", + ], + cflags: [ + "-D_FORTIFY_SOURCE=2", + "-DTEST_NAME=Fortify2_clang_new", + ], + shared: { + enabled: false, + }, +} + + // ----------------------------------------------------------------------------- // Library of all tests (excluding the dynamic linker tests). // ----------------------------------------------------------------------------- @@ -356,7 +437,9 @@ cc_test_library { "libBionicStandardTests", "libBionicElfTlsTests", "libfortify1-tests-clang", + "libfortify1-new-tests-clang", "libfortify2-tests-clang", + "libfortify2-new-tests-clang", ], shared: { enabled: false, @@ -477,7 +560,6 @@ cc_defaults { android: { shared_libs: [ "ld-android", - "libandroidicu", "libdl", "libdl_android", "libdl_preempt_test_1", diff --git a/tests/Android.mk b/tests/Android.mk index 848d2917e..b5571e3f6 100644 --- a/tests/Android.mk +++ b/tests/Android.mk @@ -59,23 +59,11 @@ ifeq ($(HOST_OS)-$(HOST_ARCH),$(filter $(HOST_OS)-$(HOST_ARCH),linux-x86 linux-x # Compile time tests. # ----------------------------------------------------------------------------- -# Some of these are intentionally using = instead of := since we need access to -# some variables not initialtized until we're in the build system. - -include $(CLEAR_VARS) -LOCAL_ADDITIONAL_DEPENDENCIES := \ - $(LOCAL_PATH)/Android.mk \ - $(LOCAL_PATH)/touch-obj-on-success - -LOCAL_CXX := $(LOCAL_PATH)/touch-obj-on-success \ - $(LLVM_PREBUILTS_PATH)/clang++ \ - -LOCAL_CLANG := true -LOCAL_MODULE := bionic-compile-time-tests-clang++ -LOCAL_CPPFLAGS := -Wall -Wno-error -LOCAL_CPPFLAGS += -fno-color-diagnostics -ferror-limit=10000 -Xclang -verify -LOCAL_SRC_FILES := fortify_filecheck_diagnostics_test.cpp -include $(BUILD_STATIC_LIBRARY) +FORTIFY_LEVEL := 1 +include $(LOCAL_PATH)/make_fortify_compile_test.mk + +FORTIFY_LEVEL := 2 +include $(LOCAL_PATH)/make_fortify_compile_test.mk endif # linux-x86 diff --git a/tests/clang_fortify_tests.cpp b/tests/clang_fortify_tests.cpp new file mode 100644 index 000000000..1b6b898d5 --- /dev/null +++ b/tests/clang_fortify_tests.cpp @@ -0,0 +1,607 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __clang__ +#error "Non-clang isn't supported" +#endif + +// Clang compile-time and run-time tests for Bionic's FORTIFY. +// +// This file is compiled in two configurations ways to give us a sane set of tests for clang's +// FORTIFY implementation. +// +// One configuration uses clang's diagnostic consumer +// (https://clang.llvm.org/doxygen/classclang_1_1VerifyDiagnosticConsumer.html#details) +// to check diagnostics (e.g. the expected-* comments everywhere). +// +// Please note that this test does things like leaking memory. That's WAI. + +// Silence all "from 'diagnose_if'" `note`s from anywhere, including headers; they're uninteresting +// for this test case, and their line numbers may change over time. +// expected-note@* 0+{{from 'diagnose_if'}} +// +// Similarly, there are a few overload tricks we have to emit errors. Ignore any notes from those. +// expected-note@* 0+{{candidate function}} + +#ifndef _FORTIFY_SOURCE +#error "_FORTIFY_SOURCE must be defined" +#endif + +#include <sys/cdefs.h> + +// This is a test specifically of bionic's FORTIFY machinery. Other stdlibs need not apply. +#ifndef __BIONIC__ +// expected-no-diagnostics +#else + +// As alluded to above, we're going to be doing some obviously very broken things in this file. +// FORTIFY helpfully flags a lot of it at compile-time, but we want it to *actually* crash, too. So +// let's wipe out any build-time errors. +#ifndef COMPILATION_TESTS +#undef __clang_error_if +#define __clang_error_if(...) +#undef __clang_warning_if +#define __clang_warning_if(...) + +// SOMETIMES_CONST allows clang to emit eager diagnostics when we're doing compilation tests, but +// blocks them otherwise. This is needed for diagnostics emitted with __enable_if. +#define SOMETIMES_CONST volatile +#else +#define SOMETIMES_CONST const +#endif + +#include <err.h> +#include <fcntl.h> +#include <limits.h> +#include <poll.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/socket.h> +#include <sys/stat.h> +#include <sys/wait.h> +#include <syslog.h> +#include <unistd.h> +#include <wchar.h> + +#ifndef COMPILATION_TESTS +#include <gtest/gtest.h> +#include "BionicDeathTest.h" + +#define CONCAT2(x, y) x##y +#define CONCAT(x, y) CONCAT2(x, y) +#define FORTIFY_TEST_NAME CONCAT(clang_fortify_test_, _FORTIFY_SOURCE) + +namespace { +struct FORTIFY_TEST_NAME : BionicDeathTest { + protected: + void SetUp() override { + stdin_saved = dup(STDIN_FILENO); + if (stdin_saved < 0) err(1, "failed to dup stdin"); + + int devnull = open("/dev/null", O_RDONLY); + if (devnull < 0) err(1, "failed to open /dev/null"); + + if (!dup2(devnull, STDIN_FILENO)) err(1, "failed to overwrite stdin"); + static_cast<void>(close(devnull)); + + BionicDeathTest::SetUp(); + } + + void TearDown() override { + if (stdin_saved == -1) return; + if (!dup2(stdin_saved, STDIN_FILENO)) warn("failed to restore stdin"); + + static_cast<void>(close(stdin_saved)); + + BionicDeathTest::TearDown(); + } + + private: + int stdin_saved = -1; +}; +} // namespace + +template <typename Fn> +__attribute__((noreturn)) static void ExitAfter(Fn&& f) { + f(); + // No need to tear things down; our parent process should handle that. + _exit(0); +} + +// In any case (including failing tests), we always want to die after this. +#define DIE_WITH(expr, cond, regex) EXPECT_EXIT(ExitAfter([&] { (expr); }), cond, regex) + +// EXPECT_NO_DEATH forks so that the test remains alive on a bug, and so that the environment +// doesn't get modified on no bug. (Environment modification is especially tricky to deal with given +// the *_STRUCT variants below.) +#define EXPECT_NO_DEATH(expr) DIE_WITH(expr, testing::ExitedWithCode(0), "") +#define EXPECT_FORTIFY_DEATH(expr) DIE_WITH(expr, testing::KilledBySignal(SIGABRT), "FORTIFY") +// Expecting death, but only if we're doing a "strict" struct-checking mode. +#if _FORTIFY_SOURCE > 1 +#define EXPECT_FORTIFY_DEATH_STRUCT EXPECT_FORTIFY_DEATH +#else +#define EXPECT_FORTIFY_DEATH_STRUCT EXPECT_NO_DEATH +#endif + +#define FORTIFY_TEST(test_name) TEST(FORTIFY_TEST_NAME, test_name) + +#else // defined(COMPILATION_TESTS) + +#define EXPECT_NO_DEATH(expr) expr +#define EXPECT_FORTIFY_DEATH(expr) expr +#define EXPECT_FORTIFY_DEATH_STRUCT EXPECT_FORTIFY_DEATH +#define FORTIFY_TEST(test_name) void test_name() +#endif + +const static int kBogusFD = -1; + +FORTIFY_TEST(string) { + char small_buffer[8] = {}; + + { + char large_buffer[sizeof(small_buffer) + 1] = {}; + // expected-error@+1{{size bigger than buffer}} + EXPECT_FORTIFY_DEATH(memcpy(small_buffer, large_buffer, sizeof(large_buffer))); + // expected-error@+1{{size bigger than buffer}} + EXPECT_FORTIFY_DEATH(memmove(small_buffer, large_buffer, sizeof(large_buffer))); + // expected-error@+1{{size bigger than buffer}} + EXPECT_FORTIFY_DEATH(mempcpy(small_buffer, large_buffer, sizeof(large_buffer))); + // expected-error@+1{{size bigger than buffer}} + EXPECT_FORTIFY_DEATH(memset(small_buffer, 0, sizeof(large_buffer))); + // expected-warning@+1{{arguments got flipped?}} + EXPECT_NO_DEATH(memset(small_buffer, sizeof(small_buffer), 0)); + // expected-error@+1{{size bigger than buffer}} + EXPECT_FORTIFY_DEATH(bcopy(large_buffer, small_buffer, sizeof(large_buffer))); + // expected-error@+1{{size bigger than buffer}} + EXPECT_FORTIFY_DEATH(bzero(small_buffer, sizeof(large_buffer))); + } + + { + const char large_string[] = "Hello!!!"; + static_assert(sizeof(large_string) > sizeof(small_buffer), ""); + + // expected-error@+1{{string bigger than buffer}} + EXPECT_FORTIFY_DEATH(strcpy(small_buffer, large_string)); + // expected-error@+1{{string bigger than buffer}} + EXPECT_FORTIFY_DEATH(stpcpy(small_buffer, large_string)); + // expected-error@+1{{size bigger than buffer}} + EXPECT_FORTIFY_DEATH(strncpy(small_buffer, large_string, sizeof(large_string))); + // expected-error@+1{{size bigger than buffer}} + EXPECT_FORTIFY_DEATH(stpncpy(small_buffer, large_string, sizeof(large_string))); + // expected-error@+1{{string bigger than buffer}} + EXPECT_FORTIFY_DEATH(strcat(small_buffer, large_string)); + // expected-error@+1{{size bigger than buffer}} + EXPECT_FORTIFY_DEATH(strncat(small_buffer, large_string, sizeof(large_string))); + // expected-error@+1{{size bigger than buffer}} + EXPECT_FORTIFY_DEATH(strlcpy(small_buffer, large_string, sizeof(large_string))); + // expected-error@+1{{size bigger than buffer}} + EXPECT_FORTIFY_DEATH(strlcat(small_buffer, large_string, sizeof(large_string))); + } + + { + struct { + char tiny_buffer[4]; + char tiny_buffer2[4]; + } split = {}; + + EXPECT_NO_DEATH(memcpy(split.tiny_buffer, &split, sizeof(split))); + EXPECT_NO_DEATH(memcpy(split.tiny_buffer, &split, sizeof(split))); + EXPECT_NO_DEATH(memmove(split.tiny_buffer, &split, sizeof(split))); + EXPECT_NO_DEATH(mempcpy(split.tiny_buffer, &split, sizeof(split))); + EXPECT_NO_DEATH(memset(split.tiny_buffer, 0, sizeof(split))); + + EXPECT_NO_DEATH(bcopy(&split, split.tiny_buffer, sizeof(split))); + EXPECT_NO_DEATH(bzero(split.tiny_buffer, sizeof(split))); + + const char small_string[] = "Hi!!"; + static_assert(sizeof(small_string) > sizeof(split.tiny_buffer), ""); + +#if _FORTIFY_SOURCE > 1 + // expected-error@+2{{string bigger than buffer}} +#endif + EXPECT_FORTIFY_DEATH_STRUCT(strcpy(split.tiny_buffer, small_string)); + +#if _FORTIFY_SOURCE > 1 + // expected-error@+2{{string bigger than buffer}} +#endif + EXPECT_FORTIFY_DEATH_STRUCT(stpcpy(split.tiny_buffer, small_string)); + +#if _FORTIFY_SOURCE > 1 + // expected-error@+2{{size bigger than buffer}} +#endif + EXPECT_FORTIFY_DEATH_STRUCT(strncpy(split.tiny_buffer, small_string, sizeof(small_string))); + +#if _FORTIFY_SOURCE > 1 + // expected-error@+2{{size bigger than buffer}} +#endif + EXPECT_FORTIFY_DEATH_STRUCT(stpncpy(split.tiny_buffer, small_string, sizeof(small_string))); + +#if _FORTIFY_SOURCE > 1 + // expected-error@+2{{string bigger than buffer}} +#endif + EXPECT_FORTIFY_DEATH_STRUCT(strcat(split.tiny_buffer, small_string)); + +#if _FORTIFY_SOURCE > 1 + // expected-error@+2{{size bigger than buffer}} +#endif + EXPECT_FORTIFY_DEATH_STRUCT(strncat(split.tiny_buffer, small_string, sizeof(small_string))); + +#if _FORTIFY_SOURCE > 1 + // expected-error@+2{{size bigger than buffer}} +#endif + EXPECT_FORTIFY_DEATH_STRUCT(strlcat(split.tiny_buffer, small_string, sizeof(small_string))); + +#if _FORTIFY_SOURCE > 1 + // expected-error@+2{{size bigger than buffer}} +#endif + EXPECT_FORTIFY_DEATH_STRUCT(strlcpy(split.tiny_buffer, small_string, sizeof(small_string))); + } +} + +FORTIFY_TEST(fcntl) { + const char target[] = "/dev/null"; + int dirfd = 0; + + // These all emit hard errors without diagnose_if, so running them is a bit + // more involved. +#ifdef COMPILATION_TESTS + // expected-error@+1{{too many arguments}} + open("/", 0, 0, 0); + // expected-error@+1{{too many arguments}} + open64("/", 0, 0, 0); + // expected-error@+1{{too many arguments}} + openat(0, "/", 0, 0, 0); + // expected-error@+1{{too many arguments}} + openat64(0, "/", 0, 0, 0); +#endif + + // expected-error@+1{{missing mode}} + EXPECT_FORTIFY_DEATH(open(target, O_CREAT)); + // expected-error@+1{{missing mode}} + EXPECT_FORTIFY_DEATH(open(target, O_TMPFILE)); + // expected-error@+1{{missing mode}} + EXPECT_FORTIFY_DEATH(open64(target, O_CREAT)); + // expected-error@+1{{missing mode}} + EXPECT_FORTIFY_DEATH(open64(target, O_TMPFILE)); + // expected-error@+1{{missing mode}} + EXPECT_FORTIFY_DEATH(openat(dirfd, target, O_CREAT)); + // expected-error@+1{{missing mode}} + EXPECT_FORTIFY_DEATH(openat(dirfd, target, O_TMPFILE)); + // expected-error@+1{{missing mode}} + EXPECT_FORTIFY_DEATH(openat64(dirfd, target, O_CREAT)); + // expected-error@+1{{missing mode}} + EXPECT_FORTIFY_DEATH(openat64(dirfd, target, O_TMPFILE)); + + // expected-warning@+1{{superfluous mode bits}} + EXPECT_NO_DEATH(open(target, O_RDONLY, 0777)); + // expected-warning@+1{{superfluous mode bits}} + EXPECT_NO_DEATH(open64(target, O_RDONLY, 0777)); + // expected-warning@+1{{superfluous mode bits}} + EXPECT_NO_DEATH(openat(dirfd, target, O_RDONLY, 0777)); + // expected-warning@+1{{superfluous mode bits}} + EXPECT_NO_DEATH(openat64(dirfd, target, O_RDONLY, 0777)); +} + +// Since these emit hard errors, it's sort of hard to run them... +#ifdef COMPILATION_TESTS +namespace compilation_tests { +template <typename T> +static T declval() { + __builtin_unreachable(); +} + +static void testFormatStrings() { + const auto unsigned_value = declval<unsigned long long>(); + const auto* unknown_string = declval<const char*>(); + const auto va = *declval<va_list*>(); + + { + auto some_fd = declval<int>(); + // expected-warning@+1{{format specifies type 'int'}} + dprintf(some_fd, "%d", unsigned_value); + // expected-warning@+1{{format string is not a string literal}} + dprintf(some_fd, unknown_string, unsigned_value); + // expected-warning@+1{{format string is not a string literal}} + vdprintf(1, unknown_string, va); + } + + { + auto* retval = declval<char*>(); +#if 0 + // expected-error@+2{{ignoring return value}} +#endif + // expected-warning@+1{{format specifies type 'int'}} + asprintf(&retval, "%d", unsigned_value); +#if 0 + // expected-error@+2{{ignoring return value}} +#endif + // expected-warning@+1{{format string is not a string literal}} + asprintf(&retval, unknown_string, unsigned_value); +#if 0 + // expected-error@+2{{ignoring return value}} +#endif + // expected-warning@+1{{format string is not a string literal}} + vasprintf(&retval, unknown_string, va); + } + + // expected-warning@+1{{format specifies type 'int'}} + syslog(0, "%d", unsigned_value); + // expected-warning@+1{{format string is not a string literal}} + syslog(0, unknown_string, unsigned_value); + // expected-warning@+1{{format string is not a string literal}} + vsyslog(0, unknown_string, va); + + { + auto* file = declval<FILE*>(); + // expected-warning@+1{{format specifies type 'int'}} + fprintf(file, "%d", unsigned_value); + // expected-warning@+1{{format string is not a string literal}} + fprintf(file, unknown_string, unsigned_value); + // expected-warning@+1{{format string is not a string literal}} + vfprintf(file, unknown_string, va); + } + + // expected-warning@+1{{format specifies type 'int'}} + printf("%d", unsigned_value); + // expected-warning@+1{{format string is not a string literal}} + printf(unknown_string, unsigned_value); + // expected-warning@+1{{format string is not a string literal}} + vprintf(unknown_string, va); + + { + char buf[128]; + // expected-warning@+1{{format specifies type 'int'}} + sprintf(buf, "%d", unsigned_value); + // expected-warning@+1{{format string is not a string literal}} + sprintf(buf, unknown_string, unsigned_value); + // expected-warning@+1{{format string is not a string literal}} + sprintf(buf, unknown_string, va); + + // expected-warning@+1{{format specifies type 'int'}} + snprintf(buf, sizeof(buf), "%d", unsigned_value); + // expected-warning@+1{{format string is not a string literal}} + snprintf(buf, sizeof(buf), unknown_string, unsigned_value); + // expected-warning@+1{{format string is not a string literal}} + vsnprintf(buf, sizeof(buf), unknown_string, va); + } + + // FIXME: below are general format string cases where clang should probably try to warn. + { + char buf[4]; + sprintf(buf, "%s", "1234"); + sprintf(buf, "1%s4", "23"); + sprintf(buf, "%d", 1234); + + // Similar thoughts for strncpy, etc. + } +} + +static void testStdlib() { + char path_buffer[PATH_MAX - 1]; + // expected-warning@+2{{ignoring return value of function}} + // expected-error@+1{{must be NULL or a pointer to a buffer with >= PATH_MAX bytes}} + realpath("/", path_buffer); + // expected-warning@+1{{ignoring return value of function}} + realpath("/", nullptr); + + // expected-warning@+2{{ignoring return value of function}} + // expected-error@+1{{flipped arguments?}} + realpath(nullptr, path_buffer); + + // expected-warning@+2{{ignoring return value of function}} + // expected-error@+1{{flipped arguments?}} + realpath(nullptr, nullptr); +} +} // namespace compilation_tests +#endif + +FORTIFY_TEST(poll) { + int pipe_fds[2]; + if (pipe(pipe_fds)) err(1, "pipe failed"); + + // after this, pipe_fds[0] should always report RDHUP + if (close(pipe_fds[1])) err(1, "close failed"); + + struct pollfd poll_fd = { pipe_fds[0], POLLRDHUP, 0 }; + { + struct pollfd few_fds[] = { poll_fd, poll_fd }; + // expected-error@+1{{fd_count is larger than the given buffer}} + EXPECT_FORTIFY_DEATH(poll(few_fds, 3, 0)); + // expected-error@+1{{fd_count is larger than the given buffer}} + EXPECT_FORTIFY_DEATH(ppoll(few_fds, 3, 0, 0)); + // expected-error@+1{{fd_count is larger than the given buffer}} + EXPECT_FORTIFY_DEATH(ppoll64(few_fds, 3, 0, nullptr)); + } + + { + struct { + struct pollfd few[2]; + struct pollfd extra[1]; + } fds = { { poll_fd, poll_fd }, { poll_fd } }; + static_assert(sizeof(fds) >= sizeof(struct pollfd) * 3, ""); + +#if _FORTIFY_SOURCE > 1 + // expected-error@+2{{fd_count is larger than the given buffer}} +#endif + EXPECT_FORTIFY_DEATH_STRUCT(poll(fds.few, 3, 0)); + + struct timespec timeout = {}; +#if _FORTIFY_SOURCE > 1 + // expected-error@+2{{fd_count is larger than the given buffer}} +#endif + EXPECT_FORTIFY_DEATH_STRUCT(ppoll(fds.few, 3, &timeout, 0)); + +#if _FORTIFY_SOURCE > 1 + // expected-error@+2{{fd_count is larger than the given buffer}} +#endif + EXPECT_FORTIFY_DEATH_STRUCT(ppoll64(fds.few, 3, 0, nullptr)); + } +} + +FORTIFY_TEST(socket) { + { + char small_buffer[8]; + // expected-error@+1{{size bigger than buffer}} + EXPECT_FORTIFY_DEATH(recv(kBogusFD, small_buffer, sizeof(small_buffer) + 1, 0)); + // expected-error@+1{{size bigger than buffer}} + EXPECT_FORTIFY_DEATH(recvfrom(kBogusFD, small_buffer, sizeof(small_buffer) + 1, 0, 0, 0)); + + // expected-error@+1{{size bigger than buffer}} + EXPECT_FORTIFY_DEATH(send(kBogusFD, small_buffer, sizeof(small_buffer) + 1, 0)); + // expected-error@+1{{size bigger than buffer}} + EXPECT_FORTIFY_DEATH(sendto(kBogusFD, small_buffer, sizeof(small_buffer) + 1, 0, 0, 0)); + } + + { + struct { + char tiny_buffer[4]; + char tiny_buffer2; + } split = {}; + + EXPECT_NO_DEATH(recv(kBogusFD, split.tiny_buffer, sizeof(split), 0)); + EXPECT_NO_DEATH(recvfrom(kBogusFD, split.tiny_buffer, sizeof(split), 0, 0, 0)); + } +} + +FORTIFY_TEST(sys_stat) { + // expected-error@+1{{'umask' called with invalid mode}} + EXPECT_FORTIFY_DEATH(umask(01777)); +} + +FORTIFY_TEST(stdio) { + char small_buffer[8] = {}; + { + // expected-error@+1{{size is larger than the destination buffer}} + EXPECT_FORTIFY_DEATH(snprintf(small_buffer, sizeof(small_buffer) + 1, "")); + + va_list va; + // expected-error@+2{{size is larger than the destination buffer}} + // expected-warning@+1{{format string is empty}} + EXPECT_FORTIFY_DEATH(vsnprintf(small_buffer, sizeof(small_buffer) + 1, "", va)); + + const char *SOMETIMES_CONST format_string = "aaaaaaaaa"; + + // expected-error@+1{{format string will always overflow}} + EXPECT_FORTIFY_DEATH(sprintf(small_buffer, format_string)); + } + + // expected-error@+1{{size should not be negative}} + EXPECT_FORTIFY_DEATH(fgets(small_buffer, -1, stdin)); + // expected-error@+1{{size is larger than the destination buffer}} + EXPECT_FORTIFY_DEATH(fgets(small_buffer, sizeof(small_buffer) + 1, stdin)); + + // expected-error@+1{{size * count overflows}} + EXPECT_NO_DEATH(fread(small_buffer, 2, (size_t)-1, stdin)); + // expected-error@+1{{size * count is too large for the given buffer}} + EXPECT_FORTIFY_DEATH(fread(small_buffer, 1, sizeof(small_buffer) + 1, stdin)); + + // expected-error@+1{{size * count overflows}} + EXPECT_NO_DEATH(fwrite(small_buffer, 2, (size_t)-1, stdout)); + // expected-error@+1{{size * count is too large for the given buffer}} + EXPECT_FORTIFY_DEATH(fwrite(small_buffer, 1, sizeof(small_buffer) + 1, stdout)); +} + +FORTIFY_TEST(unistd) { + char small_buffer[8]; + + // Return value warnings are (sort of) a part of FORTIFY, so we don't ignore them. +#if 0 + // expected-error@+2{{ignoring return value of function}} +#endif + // expected-error@+1{{bytes overflows the given object}} + EXPECT_FORTIFY_DEATH(read(kBogusFD, small_buffer, sizeof(small_buffer) + 1)); +#if 0 + // expected-error@+2{{ignoring return value of function}} +#endif + // expected-error@+1{{bytes overflows the given object}} + EXPECT_FORTIFY_DEATH(pread(kBogusFD, small_buffer, sizeof(small_buffer) + 1, 0)); +#if 0 + // expected-error@+2{{ignoring return value of function}} +#endif + // expected-error@+1{{bytes overflows the given object}} + EXPECT_FORTIFY_DEATH(pread64(kBogusFD, small_buffer, sizeof(small_buffer) + 1, 0)); +#if 0 + // expected-error@+2{{ignoring return value of function}} +#endif + // expected-error@+1{{bytes overflows the given object}} + EXPECT_FORTIFY_DEATH(write(kBogusFD, small_buffer, sizeof(small_buffer) + 1)); +#if 0 + // expected-error@+2{{ignoring return value of function}} +#endif + // expected-error@+1{{bytes overflows the given object}} + EXPECT_FORTIFY_DEATH(pwrite(kBogusFD, small_buffer, sizeof(small_buffer) + 1, 0)); +#if 0 + // expected-error@+2{{ignoring return value of function}} +#endif + // expected-error@+1{{bytes overflows the given object}} + EXPECT_FORTIFY_DEATH(pwrite64(kBogusFD, small_buffer, sizeof(small_buffer) + 1, 0)); +#if 0 + // expected-error@+2{{ignoring return value of function}} +#endif + // expected-error@+1{{bytes overflows the given object}} + EXPECT_FORTIFY_DEATH(readlink("/", small_buffer, sizeof(small_buffer) + 1)); +#if 0 + // expected-error@+2{{ignoring return value of function}} +#endif + // expected-error@+1{{bytes overflows the given object}} + EXPECT_FORTIFY_DEATH(getcwd(small_buffer, sizeof(small_buffer) + 1)); + + // getcwd allocates and returns a buffer if you pass null to getcwd + EXPECT_NO_DEATH(getcwd(nullptr, 0)); + EXPECT_NO_DEATH(getcwd(nullptr, 4096)); + + struct { + char tiny_buffer[4]; + char tiny_buffer2[4]; + } split; + + EXPECT_NO_DEATH(read(kBogusFD, split.tiny_buffer, sizeof(split))); + EXPECT_NO_DEATH(pread(kBogusFD, split.tiny_buffer, sizeof(split), 0)); + EXPECT_NO_DEATH(pread64(kBogusFD, split.tiny_buffer, sizeof(split), 0)); + EXPECT_NO_DEATH(write(kBogusFD, split.tiny_buffer, sizeof(split))); + EXPECT_NO_DEATH(pwrite(kBogusFD, split.tiny_buffer, sizeof(split), 0)); + EXPECT_NO_DEATH(pwrite64(kBogusFD, split.tiny_buffer, sizeof(split), 0)); + +#if _FORTIFY_SOURCE > 1 + // expected-error@+2{{bytes overflows the given object}} +#endif + EXPECT_FORTIFY_DEATH_STRUCT(readlink("/", split.tiny_buffer, sizeof(split))); +#if _FORTIFY_SOURCE > 1 + // expected-error@+2{{bytes overflows the given object}} +#endif + EXPECT_FORTIFY_DEATH_STRUCT(getcwd(split.tiny_buffer, sizeof(split))); + + { + char* volatile unknown = small_buffer; + const size_t count = static_cast<size_t>(SSIZE_MAX) + 1; + // expected-error@+1{{'count' must be <= SSIZE_MAX}} + EXPECT_FORTIFY_DEATH(read(kBogusFD, unknown, count)); + // expected-error@+1{{'count' must be <= SSIZE_MAX}} + EXPECT_FORTIFY_DEATH(pread(kBogusFD, unknown, count, 0)); + // expected-error@+1{{'count' must be <= SSIZE_MAX}} + EXPECT_FORTIFY_DEATH(pread64(kBogusFD, unknown, count, 0)); + // expected-error@+1{{'count' must be <= SSIZE_MAX}} + EXPECT_FORTIFY_DEATH(write(kBogusFD, unknown, count)); + // expected-error@+1{{'count' must be <= SSIZE_MAX}} + EXPECT_FORTIFY_DEATH(pwrite(kBogusFD, unknown, count, 0)); + // expected-error@+1{{'count' must be <= SSIZE_MAX}} + EXPECT_FORTIFY_DEATH(pwrite64(kBogusFD, unknown, count, 0)); + } +} + +#endif // defined(__BIONIC__) diff --git a/tests/dlext_test.cpp b/tests/dlext_test.cpp index 67ebf37df..e7274f704 100644 --- a/tests/dlext_test.cpp +++ b/tests/dlext_test.cpp @@ -29,9 +29,7 @@ #include <android-base/file.h> #include <android-base/strings.h> -#include <linux/memfd.h> #include <sys/mman.h> -#include <sys/syscall.h> #include <sys/types.h> #include <sys/vfs.h> #include <sys/wait.h> @@ -363,8 +361,10 @@ TEST_F(DlExtTest, ReservedRecursive) { uint32_t* taxicab_number = reinterpret_cast<uint32_t*>(dlsym(handle_, "dlopen_testlib_taxicab_number")); ASSERT_DL_NOTNULL(taxicab_number); - EXPECT_GE(reinterpret_cast<void*>(taxicab_number), start); - EXPECT_LT(reinterpret_cast<void*>(taxicab_number), reinterpret_cast<char*>(start) + kLibSize); + // Untag the pointer so that it can be compared with start, which will be untagged. + void* addr = reinterpret_cast<void*>(untag_address(taxicab_number)); + EXPECT_GE(addr, start); + EXPECT_LT(addr, reinterpret_cast<char*>(start) + kLibSize); EXPECT_EQ(1729U, *taxicab_number); } @@ -942,7 +942,7 @@ TEST(dlext, dlopen_ext_use_memfd) { const std::string lib_path = GetTestlibRoot() + "/libtest_simple.so"; // create memfd - int memfd = syscall(__NR_memfd_create, "foobar", MFD_CLOEXEC); + int memfd = memfd_create("foobar", MFD_CLOEXEC); if (memfd == -1 && errno == ENOSYS) { return; } diff --git a/tests/fortify_filecheck_diagnostics_test.cpp b/tests/fortify_filecheck_diagnostics_test.cpp deleted file mode 100644 index ac9853c7f..000000000 --- a/tests/fortify_filecheck_diagnostics_test.cpp +++ /dev/null @@ -1,323 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * Silence all notes about enable_if-related 'candidates'; they're nice to know - * about for users, but this test doesn't care. - */ -// expected-note@* 0+{{candidate function}} - -/* Similarly, ignore all "from 'diagnose_if'"s. */ -// expected-note@* 0+{{from 'diagnose_if'}} - - -#undef _FORTIFY_SOURCE -#define _FORTIFY_SOURCE 2 -#include <fcntl.h> -#include <netinet/in.h> -#include <poll.h> -#include <stdarg.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/socket.h> -#include <sys/stat.h> -#include <time.h> -#include <unistd.h> - -#if !defined(__BIONIC__) -# error "This only works with Bionic." -#endif - -void test_sprintf() { - char buf[4]; - - // NOLINTNEXTLINE(whitespace/line_length) - // expected-error@+1{{call to unavailable function 'sprintf': format string will always overflow destination buffer}} - sprintf(buf, "foobar"); // NOLINT(runtime/printf) - - // TODO: clang should emit a warning, but doesn't - sprintf(buf, "%s", "foobar"); // NOLINT(runtime/printf) -} - -void test_snprintf() { - char buf[4]; - - // NOLINTNEXTLINE(whitespace/line_length) - // expected-error@+1{{call to unavailable function 'snprintf': format string will always overflow destination buffer}} - snprintf(buf, 5, "foobar"); // NOLINT(runtime/printf) - - // TODO: clang should emit a warning, but doesn't - snprintf(buf, 5, "%s", "foobar"); // NOLINT(runtime/printf) - - // TODO: clang should emit a warning, but doesn't - snprintf(buf, 5, " %s ", "foobar"); // NOLINT(runtime/printf) - - // TODO: clang should emit a warning, but doesn't - snprintf(buf, 5, "%d", 100000); // NOLINT(runtime/printf) -} - -void test_memcpy() { - char buf[4]; - - // expected-error@+1{{'memcpy' called with size bigger than buffer}} - memcpy(buf, "foobar", sizeof("foobar") + 100); -} - -void test_memmove() { - char buf[4]; - - // expected-error@+1{{'memmove' called with size bigger than buffer}} - memmove(buf, "foobar", sizeof("foobar")); -} - -void test_memset() { - char buf[4]; - - // expected-error@+1{{'memset' called with size bigger than buffer}} - memset(buf, 0, 6); -} - -void test_strcpy() { - char buf[4]; - - // expected-error@+1{{'strcpy' called with string bigger than buffer}} - strcpy(buf, "foobar"); // NOLINT(runtime/printf) - - // expected-error@+1{{'strcpy' called with string bigger than buffer}} - strcpy(buf, "quux"); -} - -void test_stpcpy() { - char buf[4]; - - // expected-error@+1{{'stpcpy' called with string bigger than buffer}} - stpcpy(buf, "foobar"); - - // expected-error@+1{{'stpcpy' called with string bigger than buffer}} - stpcpy(buf, "quux"); -} - -void test_strncpy() { - char buf[4]; - - // TODO: clang should emit a warning, but doesn't - strncpy(buf, "foobar", sizeof("foobar")); -} - -void test_strcat() { - char buf[4] = ""; - - // TODO: clang should emit a warning, but doesn't - strcat(buf, "foobar"); // NOLINT(runtime/printf) -} - -void test_strncat() { - char buf[4] = ""; - - // TODO: clang should emit a warning, but doesn't - strncat(buf, "foobar", sizeof("foobar")); -} - -void test_vsprintf(const char* fmt, ...) { - va_list va; - char buf[4]; - va_start(va, fmt); - - // clang should emit a warning, but doesn't - vsprintf(buf, "foobar", va); - va_end(va); -} - -void test_vsnprintf(const char* fmt, ...) { - va_list va; - char buf[4]; - va_start(va, fmt); - - // clang should emit a warning, but doesn't - vsnprintf(buf, 5, "foobar", va); // NOLINT(runtime/printf) - - va_end(va); -} - -void test_fgets() { - char buf[4]; - - // expected-error@+1{{in call to 'fgets', size should not be negative}} - fgets(buf, -1, stdin); - - // expected-error@+1{{in call to 'fgets', size is larger than the destination buffer}} - fgets(buf, 6, stdin); -} - -void test_recvfrom() { - char buf[4]; - sockaddr_in addr; - - // expected-error@+1{{'recvfrom' called with size bigger than buffer}} - recvfrom(0, buf, 6, 0, reinterpret_cast<sockaddr*>(&addr), nullptr); -} - -void test_recv() { - char buf[4] = {0}; - - // expected-error@+1{{'recv' called with size bigger than buffer}} - recv(0, buf, 6, 0); -} - -void test_umask() { - // expected-error@+1{{'umask' called with invalid mode}} - umask(01777); -} - -void test_read() { - char buf[4]; - // expected-error@+1{{in call to 'read', 'count' bytes overflows the given object}} - read(0, buf, 6); -} - -void test_open() { - // expected-error@+1{{'open' called with O_CREAT or O_TMPFILE, but missing mode}} - open("/dev/null", O_CREAT); - - // expected-error@+1{{'open' called with O_CREAT or O_TMPFILE, but missing mode}} - open("/dev/null", O_TMPFILE); - - // expected-error@+1{{call to unavailable function 'open': too many arguments}} - open("/dev/null", O_CREAT, 0, 0); - - // expected-error@+1{{call to unavailable function 'open': too many arguments}} - open("/dev/null", O_TMPFILE, 0, 0); - - // expected-warning@+1{{'open' has superfluous mode bits; missing O_CREAT?}} - open("/dev/null", O_RDONLY, 0644); - - // expected-warning@+1{{'open' has superfluous mode bits; missing O_CREAT?}} - open("/dev/null", O_DIRECTORY, 0644); -} - -void test_poll() { - pollfd fds[1]; - // expected-error@+1{{in call to 'poll', fd_count is larger than the given buffer}} - poll(fds, 2, 0); -} - -void test_ppoll() { - pollfd fds[1]; - timespec timeout; - // expected-error@+1{{in call to 'ppoll', fd_count is larger than the given buffer}} - ppoll(fds, 2, &timeout, nullptr); -} - -void test_ppoll64() { - pollfd fds[1]; - timespec timeout; - // NOLINTNEXTLINE(whitespace/line_length) - // expected-error@+1{{in call to 'ppoll64', fd_count is larger than the given buffer}} - ppoll64(fds, 2, &timeout, nullptr); -} - -void test_fread_overflow() { - char buf[4]; - // expected-error@+1{{in call to 'fread', size * count overflows}} - fread(buf, 2, (size_t)-1, stdin); -} - -void test_fread_too_big() { - char buf[4]; - // NOLINTNEXTLINE(whitespace/line_length) - // expected-error@+1{{in call to 'fread', size * count is too large for the given buffer}} - fread(buf, 1, 5, stdin); -} - -void test_fwrite_overflow() { - char buf[4] = {0}; - // expected-error@+1{{in call to 'fwrite', size * count overflows}} - fwrite(buf, 2, (size_t)-1, stdout); -} - -void test_fwrite_too_big() { - char buf[4] = {0}; - // NOLINTNEXTLINE(whitespace/line_length) - // expected-error@+1{{in call to 'fwrite', size * count is too large for the given buffer}} - fwrite(buf, 1, 5, stdout); -} - -void test_getcwd() { - char buf[4]; - // expected-error@+1{{in call to 'getcwd', 'size' bytes overflows the given object}} - getcwd(buf, 5); -} - -void test_pwrite64_size() { - char buf[4] = {0}; - // expected-error@+1{{in call to 'pwrite64', 'count' bytes overflows the given object}} - pwrite64(STDOUT_FILENO, buf, 5, 0); -} - -void test_pwrite64_too_big_malloc() { - void *buf = calloc(atoi("5"), 1); - // expected-error@+1{{in call to 'pwrite64', 'count' must be <= SSIZE_MAX}} - pwrite64(STDOUT_FILENO, buf, SIZE_MAX, 0); -} - -void test_pwrite64_too_big() { - char buf[4] = {0}; - // expected-error@+1{{in call to 'pwrite64', 'count' must be <= SSIZE_MAX}} - pwrite64(STDOUT_FILENO, buf, SIZE_MAX, 0); -} - -void test_write_size() { - char buf[4] = {0}; - // expected-error@+1{{in call to 'write', 'count' bytes overflows the given object}} - write(STDOUT_FILENO, buf, 5); -} - -void test_memset_args_flipped() { - char from[4] = {0}; - // NOLINTNEXTLINE(whitespace/line_length) - // expected-warning@+1{{'memset' will set 0 bytes; maybe the arguments got flipped?}} - memset(from, sizeof(from), 0); -} - -void test_sendto() { - char buf[4] = {0}; - sockaddr_in addr; - - // expected-error@+1{{'sendto' called with size bigger than buffer}} - sendto(0, buf, 6, 0, reinterpret_cast<sockaddr*>(&addr), sizeof(sockaddr_in)); -} - -void test_send() { - char buf[4] = {0}; - - // expected-error@+1{{'send' called with size bigger than buffer}} - send(0, buf, 6, 0); -} - -void test_realpath() { - char buf[4] = {0}; - // NOLINTNEXTLINE(whitespace/line_length) - // expected-error@+1{{'realpath' output parameter must be NULL or a pointer to a buffer with >= PATH_MAX bytes}} - realpath(".", buf); - - // This is fine. - realpath(".", nullptr); - - char bigbuf[PATH_MAX]; - // expected-error@+1{{'realpath': NULL path is never correct; flipped arguments?}} - realpath(nullptr, bigbuf); -} diff --git a/tests/fortify_test.cpp b/tests/fortify_test.cpp index 489b7018d..9a4b781fc 100644 --- a/tests/fortify_test.cpp +++ b/tests/fortify_test.cpp @@ -926,6 +926,24 @@ TEST(TEST_NAME, strcat_chk_max_int_size) { ASSERT_EQ('\0', buf[9]); } +TEST(TEST_NAME, mempcpy_chk) { + const char input_str[] = "abcdefg"; + size_t input_str_size = strlen(input_str) + 1; + + char buf1[10] = {}; + char buf2[10] = {}; + + __builtin_mempcpy(buf1, input_str, input_str_size); + __builtin___mempcpy_chk(buf2, input_str, input_str_size, __bos0(buf2)); + + ASSERT_EQ(memcmp(buf1, buf2, sizeof(buf2)), 0); + + void *builtin_ptr = __builtin_mempcpy(buf1, input_str, input_str_size); + void *fortify_ptr = __builtin___mempcpy_chk(buf1, input_str, input_str_size, __bos0(buf2)); + + ASSERT_EQ(builtin_ptr, fortify_ptr); +} + extern "C" char* __stpcpy_chk(char*, const char*, size_t); TEST(TEST_NAME, stpcpy_chk_max_int_size) { diff --git a/tests/grp_pwd_test.cpp b/tests/grp_pwd_test.cpp index ebc357c4b..6b49e298e 100644 --- a/tests/grp_pwd_test.cpp +++ b/tests/grp_pwd_test.cpp @@ -46,6 +46,8 @@ using android::base::ReadFileToString; using android::base::Split; using android::base::StartsWith; +using namespace std::literals; + enum uid_type_t { TYPE_APP, TYPE_SYSTEM, @@ -73,11 +75,7 @@ static void check_passwd(const passwd* pwd, const char* username, uid_t uid, uid EXPECT_STREQ("/", pwd->pw_dir); } - if (uid_type == TYPE_VENDOR) { - EXPECT_STREQ("/vendor/bin/sh", pwd->pw_shell); - } else { - EXPECT_STREQ("/system/bin/sh", pwd->pw_shell); - } + EXPECT_STREQ("/bin/sh", pwd->pw_shell); } static void check_getpwuid(const char* username, uid_t uid, uid_type_t uid_type, @@ -130,12 +128,41 @@ static void check_getpwnam_r(const char* username, uid_t uid, uid_type_t uid_typ static void check_get_passwd(const char* username, uid_t uid, uid_type_t uid_type, bool check_username = true) { + SCOPED_TRACE("username '"s + username + "'"); check_getpwuid(username, uid, uid_type, check_username); check_getpwnam(username, uid, uid_type, check_username); check_getpwuid_r(username, uid, uid_type, check_username); check_getpwnam_r(username, uid, uid_type, check_username); } +static void expect_no_passwd_id(uid_t uid) { + SCOPED_TRACE("uid '" + std::to_string(uid) + "'"); + errno = 0; + passwd* passwd = nullptr; + passwd = getpwuid(uid); + EXPECT_EQ(nullptr, passwd) << "name = '" << passwd->pw_name << "'"; + EXPECT_EQ(ENOENT, errno); + + struct passwd passwd_storage; + char buf[512]; + EXPECT_EQ(ENOENT, getpwuid_r(uid, &passwd_storage, buf, sizeof(buf), &passwd)); + EXPECT_EQ(nullptr, passwd) << "name = '" << passwd->pw_name << "'"; +} + +static void expect_no_passwd_name(const char* username) { + SCOPED_TRACE("username '"s + username + "'"); + errno = 0; + passwd* passwd = nullptr; + passwd = getpwnam(username); + EXPECT_EQ(nullptr, passwd) << "name = '" << passwd->pw_name << "'"; + EXPECT_EQ(ENOENT, errno); + + struct passwd passwd_storage; + char buf[512]; + EXPECT_EQ(ENOENT, getpwnam_r(username, &passwd_storage, buf, sizeof(buf), &passwd)); + EXPECT_EQ(nullptr, passwd) << "name = '" << passwd->pw_name << "'"; +} + #else // !defined(__BIONIC__) static void check_get_passwd(const char* /* username */, uid_t /* uid */, uid_type_t /* uid_type */, @@ -147,75 +174,124 @@ static void check_get_passwd(const char* /* username */, uid_t /* uid */, uid_ty GTEST_SKIP() << "bionic-only test"; } +static void expect_no_passwd_id(uid_t /* uid */) { + GTEST_SKIP() << "bionic-only test"; +} + +static void expect_no_passwd_name(const char* /* username */) { + GTEST_SKIP() << "bionic-only test"; +} + #endif -TEST(pwd, getpwnam_system_id_root) { +TEST(pwd, getpwnam_platform_ids) { check_get_passwd("root", 0, TYPE_SYSTEM); -} + check_get_passwd("daemon", 1, TYPE_SYSTEM); + check_get_passwd("bin", 2, TYPE_SYSTEM); -TEST(pwd, getpwnam_system_id_system) { check_get_passwd("system", 1000, TYPE_SYSTEM); -} - -TEST(pwd, getpwnam_app_id_radio) { check_get_passwd("radio", 1001, TYPE_SYSTEM); -} -TEST(pwd, getpwnam_oem_id_5000) { - check_get_passwd("oem_5000", 5000, TYPE_VENDOR, false); -} + check_get_passwd("shell", 2000, TYPE_SYSTEM); -TEST(pwd, getpwnam_oem_id_5999) { - check_get_passwd("oem_5999", 5999, TYPE_VENDOR, false); + check_get_passwd("nobody", 9999, TYPE_SYSTEM); } -TEST(pwd, getpwnam_oem_id_2900) { +TEST(pwd, getpwnam_oem_ids) { check_get_passwd("oem_2900", 2900, TYPE_VENDOR, false); -} - -TEST(pwd, getpwnam_oem_id_2999) { + check_get_passwd("oem_2945", 2945, TYPE_VENDOR, false); check_get_passwd("oem_2999", 2999, TYPE_VENDOR, false); + check_get_passwd("oem_5000", 5000, TYPE_VENDOR, false); + check_get_passwd("oem_5454", 5454, TYPE_VENDOR, false); + check_get_passwd("oem_5999", 5999, TYPE_VENDOR, false); } -TEST(pwd, getpwnam_app_id_nobody) { - check_get_passwd("nobody", 9999, TYPE_SYSTEM); -} +TEST(pwd, getpwnam_non_exist) { + expect_no_passwd_id(999); // End of the system reserved range, unallocated. + expect_no_passwd_id(1999); // End of the system reserved range, unallocated. + expect_no_passwd_id(2899); // End of the system reserved range, unallocated. -TEST(pwd, getpwnam_app_id_u0_a0) { - check_get_passwd("u0_a0", 10000, TYPE_APP); -} + // These ranges are for GIDs only. + expect_no_passwd_id(20000); + expect_no_passwd_id(30000); + expect_no_passwd_id(40000); + expect_no_passwd_id(50000); -TEST(pwd, getpwnam_app_id_u0_a1234) { - check_get_passwd("u0_a1234", 11234, TYPE_APP); + // These should not be parsed as users, only as groups. + expect_no_passwd_name("u0_a9999_cache"); + expect_no_passwd_name("u0_a9999_ext"); + expect_no_passwd_name("u0_a9999_ext_cache"); + expect_no_passwd_name("all_a9999"); } -// Test the difference between uid and shared gid. -TEST(pwd, getpwnam_app_id_u0_a49999) { - check_get_passwd("u0_a49999", 59999, TYPE_APP); -} +TEST(pwd, getpwnam_u0_app_ids) { + check_get_passwd("u0_a0", 10000, TYPE_APP); + check_get_passwd("u0_a1234", 11234, TYPE_APP); + check_get_passwd("u0_a9999", 19999, TYPE_APP); -TEST(pwd, getpwnam_app_id_u0_i1) { check_get_passwd("u0_i1", 90001, TYPE_APP); + check_get_passwd("u0_i4545", 94545, TYPE_APP); + check_get_passwd("u0_i9999", 99999, TYPE_APP); } -TEST(pwd, getpwnam_app_id_u1_root) { - check_get_passwd("u1_root", 100000, TYPE_SYSTEM); +TEST(pwd, getpwnam_app_id_u1_ids) { + check_get_passwd("u1_system", 101000, TYPE_SYSTEM); + check_get_passwd("u1_radio", 101001, TYPE_SYSTEM); + + check_get_passwd("u1_a0", 110000, TYPE_APP); + check_get_passwd("u1_a1234", 111234, TYPE_APP); + check_get_passwd("u1_a9999", 119999, TYPE_APP); + + check_get_passwd("u1_i1", 190001, TYPE_APP); + check_get_passwd("u1_i4545", 194545, TYPE_APP); + check_get_passwd("u1_i9999", 199999, TYPE_APP); } -TEST(pwd, getpwnam_app_id_u1_radio) { - check_get_passwd("u1_radio", 101001, TYPE_SYSTEM); +TEST(pwd, getpwnam_app_id_u31_ids) { + check_get_passwd("u31_system", 3101000, TYPE_SYSTEM); + check_get_passwd("u31_radio", 3101001, TYPE_SYSTEM); + + check_get_passwd("u31_a0", 3110000, TYPE_APP); + check_get_passwd("u31_a1234", 3111234, TYPE_APP); + check_get_passwd("u31_a9999", 3119999, TYPE_APP); + + check_get_passwd("u31_i1", 3190001, TYPE_APP); + check_get_passwd("u31_i4545", 3194545, TYPE_APP); + check_get_passwd("u31_i9999", 3199999, TYPE_APP); } -TEST(pwd, getpwnam_app_id_u1_a0) { - check_get_passwd("u1_a0", 110000, TYPE_APP); +TEST(pwd, getpwnam_app_id_not_allowed_platform) { + expect_no_passwd_name("u1_root"); + expect_no_passwd_name("u1_debuggerd"); + + expect_no_passwd_name("u31_root"); + expect_no_passwd_name("u31_debuggerd"); } -TEST(pwd, getpwnam_app_id_u1_a40000) { - check_get_passwd("u1_a40000", 150000, TYPE_APP); +TEST(pwd, getpwuid_app_id_u1_non_exist) { + expect_no_passwd_id(100000); // There is no 'root' for secondary users. + expect_no_passwd_id(101999); // End of the system reserved range, unallocated. + expect_no_passwd_id(102900); // The OEM ranges were never allocated to secondary users. + expect_no_passwd_id(105000); // The OEM ranges were never allocated to secondary users. + + // These ranges are for GIDs only. + expect_no_passwd_id(120000); + expect_no_passwd_id(130000); + expect_no_passwd_id(140000); + expect_no_passwd_id(150000); } -TEST(pwd, getpwnam_app_id_u1_i0) { - check_get_passwd("u1_i0", 190000, TYPE_APP); +TEST(pwd, getpwuid_app_id_u31_non_exist) { + expect_no_passwd_id(3100000); // There is no 'root' for secondary users. + expect_no_passwd_id(3101999); // End of the system reserved range, unallocated. + expect_no_passwd_id(3102900); // The OEM ranges were never allocated to secondary users. + expect_no_passwd_id(3105000); // The OEM ranges were never allocated to secondary users. + + // These ranges are for GIDs only. + expect_no_passwd_id(3120000); + expect_no_passwd_id(3130000); + expect_no_passwd_id(3140000); + expect_no_passwd_id(3150000); } TEST(pwd, getpwnam_r_alignment) { @@ -302,7 +378,7 @@ TEST(pwd, getpwnam_r_large_enough_suggested_buffer_size) { #if defined(__BIONIC__) template <typename T> -static void expect_ids(const T& ids) { +static void expect_ids(T ids, bool is_group) { std::set<typename T::key_type> expected_ids; // Ensure that all android_ids are iterated through. for (size_t n = 0; n < android_id_count; ++n) { @@ -321,10 +397,12 @@ static void expect_ids(const T& ids) { expect_range(AID_OEM_RESERVED_START, AID_OEM_RESERVED_END); expect_range(AID_OEM_RESERVED_2_START, AID_OEM_RESERVED_2_END); expect_range(AID_APP_START, AID_APP_END); - expect_range(AID_CACHE_GID_START, AID_CACHE_GID_END); - expect_range(AID_EXT_GID_START, AID_EXT_GID_END); - expect_range(AID_EXT_CACHE_GID_START, AID_EXT_CACHE_GID_END); - expect_range(AID_SHARED_GID_START, AID_SHARED_GID_END); + if (is_group) { + expect_range(AID_CACHE_GID_START, AID_CACHE_GID_END); + expect_range(AID_EXT_GID_START, AID_EXT_GID_END); + expect_range(AID_EXT_CACHE_GID_START, AID_EXT_CACHE_GID_END); + expect_range(AID_SHARED_GID_START, AID_SHARED_GID_END); + } expect_range(AID_ISOLATED_START, AID_ISOLATED_END); // TODO(73062966): We still don't have a good way to create vendor AIDs in the system or other @@ -333,6 +411,14 @@ static void expect_ids(const T& ids) { return; } + auto allow_range = [&ids](uid_t start, uid_t end) { + for (size_t n = start; n <= end; ++n) { + ids.erase(n); + } + }; + + allow_range(AID_SYSTEM_RESERVED_START, AID_SYSTEM_EXT_RESERVED_END); + // Ensure that no other ids were returned. auto return_differences = [&ids, &expected_ids] { std::vector<typename T::key_type> missing_from_ids; @@ -388,7 +474,7 @@ TEST(pwd, getpwent_iterate) { } endpwent(); - expect_ids(uids); + expect_ids(uids, false); #else GTEST_SKIP() << "bionic-only test"; #endif @@ -453,12 +539,41 @@ static void check_getgrnam_r(const char* group_name, gid_t gid, bool check_group } static void check_get_group(const char* group_name, gid_t gid, bool check_groupname = true) { + SCOPED_TRACE("groupname '"s + group_name + "'"); check_getgrgid(group_name, gid, check_groupname); check_getgrnam(group_name, gid, check_groupname); check_getgrgid_r(group_name, gid, check_groupname); check_getgrnam_r(group_name, gid, check_groupname); } +static void expect_no_group_id(gid_t gid) { + SCOPED_TRACE("gid '" + std::to_string(gid) + "'"); + errno = 0; + group* group = nullptr; + group = getgrgid(gid); + EXPECT_EQ(nullptr, group) << "name = '" << group->gr_name << "'"; + EXPECT_EQ(ENOENT, errno); + + struct group group_storage; + char buf[512]; + EXPECT_EQ(ENOENT, getgrgid_r(gid, &group_storage, buf, sizeof(buf), &group)); + EXPECT_EQ(nullptr, group) << "name = '" << group->gr_name << "'"; +} + +static void expect_no_group_name(const char* groupname) { + SCOPED_TRACE("groupname '"s + groupname + "'"); + errno = 0; + group* group = nullptr; + group = getgrnam(groupname); + EXPECT_EQ(nullptr, group) << "name = '" << group->gr_name << "'"; + EXPECT_EQ(ENOENT, errno); + + struct group group_storage; + char buf[512]; + EXPECT_EQ(ENOENT, getgrnam_r(groupname, &group_storage, buf, sizeof(buf), &group)); + EXPECT_EQ(nullptr, group) << "name = '" << group->gr_name << "'"; +} + #else // !defined(__BIONIC__) static void check_get_group(const char*, gid_t, bool) { @@ -469,95 +584,144 @@ static void check_get_group(const char*, gid_t) { GTEST_SKIP() << "bionic-only test"; } +static void expect_no_group_id(gid_t /* gid */) { + GTEST_SKIP() << "bionic-only test"; +} + +static void expect_no_group_name(const char* /* groupname */) { + GTEST_SKIP() << "bionic-only test"; +} + #endif -TEST(grp, getgrnam_system_id_root) { +TEST(grp, getgrnam_platform_ids) { check_get_group("root", 0); -} + check_get_group("daemon", 1); + check_get_group("bin", 2); -TEST(grp, getgrnam_system_id_system) { check_get_group("system", 1000); -} - -TEST(grp, getgrnam_app_id_radio) { check_get_group("radio", 1001); -} -TEST(grp, getgrnam_oem_id_5000) { - check_get_group("oem_5000", 5000, false); -} + check_get_group("shell", 2000); -TEST(grp, getgrnam_oem_id_5999) { - check_get_group("oem_5999", 5999, false); + check_get_group("nobody", 9999); } -TEST(grp, getgrnam_oem_id_2900) { +TEST(grp, getgrnam_oem_ids) { check_get_group("oem_2900", 2900, false); -} - -TEST(grp, getgrnam_oem_id_2999) { + check_get_group("oem_2945", 2945, false); check_get_group("oem_2999", 2999, false); + check_get_group("oem_5000", 5000, false); + check_get_group("oem_5454", 5454, false); + check_get_group("oem_5999", 5999, false); } -TEST(grp, getgrnam_app_id_nobody) { - check_get_group("nobody", 9999); +TEST(grp, getgrnam_non_exist) { + expect_no_passwd_id(999); // End of the system reserved range, unallocated. + expect_no_passwd_id(1999); // End of the system reserved range, unallocated. + expect_no_passwd_id(2899); // End of the system reserved range, unallocated. } -TEST(grp, getgrnam_app_id_u0_a0) { +TEST(grp, getgrnam_u0_app_ids) { check_get_group("u0_a0", 10000); -} - -TEST(grp, getgrnam_app_id_u0_a1234) { check_get_group("u0_a1234", 11234); -} - -TEST(grp, getgrnam_app_id_u0_a9999) { check_get_group("u0_a9999", 19999); -} -TEST(getgrnam, app_id_u0_a0_cache) { check_get_group("u0_a0_cache", 20000); -} - -TEST(getgrnam, app_id_u0_a1234_cache) { check_get_group("u0_a1234_cache", 21234); -} - -TEST(getgrnam, app_id_u0_a9999_cache) { check_get_group("u0_a9999_cache", 29999); -} -TEST(getgrnam, app_id_u10_a1234_cache) { - check_get_group("u10_a1234_cache", 1021234); -} + check_get_group("u0_a0_ext", 30000); + check_get_group("u0_a4545_ext", 34545); + check_get_group("u0_a9999_ext", 39999); + + check_get_group("u0_a0_ext_cache", 40000); + check_get_group("u0_a4545_ext_cache", 44545); + check_get_group("u0_a9999_ext_cache", 49999); -// Test the difference between uid and shared gid. -TEST(grp, getgrnam_app_id_all_a9999) { + check_get_group("all_a0", 50000); + check_get_group("all_a4545", 54545); check_get_group("all_a9999", 59999); -} -TEST(grp, getgrnam_app_id_u0_i1) { check_get_group("u0_i1", 90001); } -TEST(grp, getgrnam_app_id_u1_root) { - check_get_group("u1_root", 100000); +TEST(grp, getgrnam_u1_app_ids) { + check_get_group("u1_system", 101000); + check_get_group("u1_radio", 101001); + + check_get_group("u1_a0", 110000); + check_get_group("u1_a1234", 111234); + check_get_group("u1_a9999", 119999); + + check_get_group("u1_a0_cache", 120000); + check_get_group("u1_a1234_cache", 121234); + check_get_group("u1_a9999_cache", 129999); + + check_get_group("u1_a0_ext", 130000); + check_get_group("u1_a4545_ext", 134545); + check_get_group("u1_a9999_ext", 139999); + + check_get_group("u1_a0_ext_cache", 140000); + check_get_group("u1_a4545_ext_cache", 144545); + check_get_group("u1_a9999_ext_cache", 149999); + + check_get_group("u1_i1", 190001); } -TEST(grp, getgrnam_app_id_u1_radio) { - check_get_group("u1_radio", 101001); +TEST(grp, getgrnam_u31_app_ids) { + check_get_group("u31_system", 3101000); + check_get_group("u31_radio", 3101001); + + check_get_group("u31_a0", 3110000); + check_get_group("u31_a1234", 3111234); + check_get_group("u31_a9999", 3119999); + + check_get_group("u31_a0_cache", 3120000); + check_get_group("u31_a1234_cache", 3121234); + check_get_group("u31_a9999_cache", 3129999); + + check_get_group("u31_a0_cache", 3120000); + check_get_group("u31_a1234_cache", 3121234); + check_get_group("u31_a9999_cache", 3129999); + + check_get_group("u31_a0_ext", 3130000); + check_get_group("u31_a4545_ext", 3134545); + check_get_group("u31_a9999_ext", 3139999); + + check_get_group("u31_a0_ext_cache", 3140000); + check_get_group("u31_a4545_ext_cache", 3144545); + check_get_group("u31_a9999_ext_cache", 3149999); + + check_get_group("u31_i1", 3190001); } -TEST(grp, getgrnam_app_id_u1_a0) { - check_get_group("u1_a0", 110000); +TEST(grp, getpgram_app_id_not_allowed_platform) { + expect_no_group_name("u1_root"); + expect_no_group_name("u1_debuggerd"); + + expect_no_group_name("u31_root"); + expect_no_group_name("u31_debuggerd"); } -TEST(grp, getgrnam_app_id_u1_a40000) { - check_get_group("u1_a40000", 150000); +TEST(grp, getgrgid_app_id_u1_non_exist) { + expect_no_group_id(100000); // There is no 'root' for secondary users. + expect_no_group_id(101999); // End of the system reserved range, unallocated. + expect_no_group_id(102900); // The OEM ranges were never allocated to secondary users. + expect_no_group_id(105000); // The OEM ranges were never allocated to secondary users. + + // The shared range is shared among users, and therefore doesn't exist for secondary users. + expect_no_group_id(150000); } -TEST(grp, getgrnam_app_id_u1_i0) { - check_get_group("u1_i0", 190000); +TEST(grp, getgrgid_app_id_u31_non_exist) { + expect_no_group_id(3100000); // There is no 'root' for secondary users. + expect_no_group_id(3101999); // End of the system reserved range, unallocated. + expect_no_group_id(3102900); // The OEM ranges were never allocated to secondary users. + expect_no_group_id(3105000); // The OEM ranges were never allocated to secondary users. + + // The shared range is shared among users, and therefore doesn't exist for secondary users. + expect_no_group_id(3150000); } TEST(grp, getgrnam_r_alignment) { @@ -660,7 +824,7 @@ TEST(grp, getgrent_iterate) { } endgrent(); - expect_ids(gids); + expect_ids(gids, true); #else GTEST_SKIP() << "bionic-only test"; #endif diff --git a/tests/leak_test.cpp b/tests/leak_test.cpp index 600520959..3cc1a0a91 100644 --- a/tests/leak_test.cpp +++ b/tests/leak_test.cpp @@ -17,6 +17,7 @@ #include <err.h> #include <inttypes.h> #include <pthread.h> +#include <sched.h> #include <stdio.h> #include <string.h> #include <sys/mman.h> @@ -30,26 +31,28 @@ #include <vector> #include <android-base/macros.h> +#include <android-base/threads.h> #include "utils.h" using namespace std::chrono_literals; -static void WaitUntilAllExited(pid_t* pids, size_t pid_count) { +static void WaitUntilAllThreadsExited(pid_t* tids, size_t tid_count) { // Wait until all children have exited. bool alive = true; while (alive) { alive = false; - for (size_t i = 0; i < pid_count; ++i) { - if (pids[i] != 0) { - if (kill(pids[i], 0) == 0) { + for (size_t i = 0; i < tid_count; ++i) { + if (tids[i] != 0) { + if (tgkill(getpid(), tids[i], 0) == 0) { alive = true; } else { EXPECT_EQ(errno, ESRCH); - pids[i] = 0; // Skip in next loop. + tids[i] = 0; // Skip in next loop. } } } + sched_yield(); } } @@ -155,7 +158,7 @@ TEST(pthread_leak, detach) { pthread_barrier_wait(&barrier); ASSERT_EQ(pthread_barrier_destroy(&barrier), 0); - WaitUntilAllExited(tids, arraysize(tids)); + WaitUntilAllThreadsExited(tids, threads_count); // A native bridge implementation might need a warm up pass to reach a steady state. // http://b/37920774. diff --git a/tests/libs/Android.bp b/tests/libs/Android.bp index 422cd75c0..98d4f25e7 100644 --- a/tests/libs/Android.bp +++ b/tests/libs/Android.bp @@ -29,7 +29,7 @@ cc_defaults { gtest: false, sanitize: { address: false, - coverage: false, + fuzzer: false, }, stl: "libc++_static", target: { diff --git a/tests/libs/segment_gap_outer.lds b/tests/libs/segment_gap_outer.lds index f326aab26..c2961b2c6 100644 --- a/tests/libs/segment_gap_outer.lds +++ b/tests/libs/segment_gap_outer.lds @@ -22,6 +22,6 @@ SECTIONS { # Place end_of_gap at the end of the gap. . = 0x1000000; .bss.end_of_gap : { - *(.bss.end_of_gap); + *(.bss.*end_of_gap*); } } diff --git a/tests/make_fortify_compile_test.mk b/tests/make_fortify_compile_test.mk new file mode 100644 index 000000000..8270f29d7 --- /dev/null +++ b/tests/make_fortify_compile_test.mk @@ -0,0 +1,20 @@ +include $(CLEAR_VARS) + +LOCAL_ADDITIONAL_DEPENDENCIES := \ + $(LOCAL_PATH)/Android.mk \ + $(LOCAL_PATH)/touch-obj-on-success + +LOCAL_CXX := $(LOCAL_PATH)/touch-obj-on-success \ + $(LLVM_PREBUILTS_PATH)/clang++ \ + +LOCAL_CLANG := true +LOCAL_MODULE := bionic-compile-time-tests$(FORTIFY_LEVEL)-clang++ +LOCAL_CPPFLAGS := -Wall -Wno-error +LOCAL_CPPFLAGS += -fno-color-diagnostics -ferror-limit=10000 -Xclang -verify +LOCAL_CPPFLAGS += -DCOMPILATION_TESTS=1 -Wformat-nonliteral +LOCAL_CPPFLAGS += -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=$(FORTIFY_LEVEL) +LOCAL_SRC_FILES := clang_fortify_tests.cpp + +include $(BUILD_STATIC_LIBRARY) + +FORTIFY_LEVEL := diff --git a/tests/malloc_test.cpp b/tests/malloc_test.cpp index 983592f0a..edcc179ed 100644 --- a/tests/malloc_test.cpp +++ b/tests/malloc_test.cpp @@ -312,32 +312,48 @@ TEST(malloc, realloc_overflow) { #if defined(HAVE_DEPRECATED_MALLOC_FUNCS) extern "C" void* pvalloc(size_t); extern "C" void* valloc(size_t); +#endif TEST(malloc, pvalloc_std) { +#if defined(HAVE_DEPRECATED_MALLOC_FUNCS) size_t pagesize = sysconf(_SC_PAGESIZE); void* ptr = pvalloc(100); ASSERT_TRUE(ptr != nullptr); ASSERT_TRUE((reinterpret_cast<uintptr_t>(ptr) & (pagesize-1)) == 0); ASSERT_LE(pagesize, malloc_usable_size(ptr)); free(ptr); +#else + GTEST_SKIP() << "pvalloc not supported."; +#endif } TEST(malloc, pvalloc_overflow) { +#if defined(HAVE_DEPRECATED_MALLOC_FUNCS) ASSERT_EQ(nullptr, pvalloc(SIZE_MAX)); +#else + GTEST_SKIP() << "pvalloc not supported."; +#endif } TEST(malloc, valloc_std) { +#if defined(HAVE_DEPRECATED_MALLOC_FUNCS) size_t pagesize = sysconf(_SC_PAGESIZE); - void* ptr = pvalloc(100); + void* ptr = valloc(100); ASSERT_TRUE(ptr != nullptr); ASSERT_TRUE((reinterpret_cast<uintptr_t>(ptr) & (pagesize-1)) == 0); free(ptr); +#else + GTEST_SKIP() << "valloc not supported."; +#endif } TEST(malloc, valloc_overflow) { +#if defined(HAVE_DEPRECATED_MALLOC_FUNCS) ASSERT_EQ(nullptr, valloc(SIZE_MAX)); -} +#else + GTEST_SKIP() << "valloc not supported."; #endif +} TEST(malloc, malloc_info) { #ifdef __BIONIC__ diff --git a/tests/pthread_test.cpp b/tests/pthread_test.cpp index 0bf8e294b..d8257381c 100644 --- a/tests/pthread_test.cpp +++ b/tests/pthread_test.cpp @@ -990,6 +990,25 @@ TEST(pthread, pthread_rwlock_reader_wakeup_writer_timedwait_monotonic_np) { #endif // __BIONIC__ } +TEST(pthread, pthread_rwlock_reader_wakeup_writer_clockwait) { +#if defined(__BIONIC__) + timespec ts; + ASSERT_EQ(0, clock_gettime(CLOCK_MONOTONIC, &ts)); + ts.tv_sec += 1; + test_pthread_rwlock_reader_wakeup_writer([&](pthread_rwlock_t* lock) { + return pthread_rwlock_clockwrlock(lock, CLOCK_MONOTONIC, &ts); + }); + + ASSERT_EQ(0, clock_gettime(CLOCK_REALTIME, &ts)); + ts.tv_sec += 1; + test_pthread_rwlock_reader_wakeup_writer([&](pthread_rwlock_t* lock) { + return pthread_rwlock_clockwrlock(lock, CLOCK_REALTIME, &ts); + }); +#else // __BIONIC__ + GTEST_SKIP() << "pthread_rwlock_clockwrlock not available"; +#endif // __BIONIC__ +} + static void test_pthread_rwlock_writer_wakeup_reader(std::function<int (pthread_rwlock_t*)> lock_function) { RwlockWakeupHelperArg wakeup_arg; ASSERT_EQ(0, pthread_rwlock_init(&wakeup_arg.lock, nullptr)); @@ -1038,6 +1057,25 @@ TEST(pthread, pthread_rwlock_writer_wakeup_reader_timedwait_monotonic_np) { #endif // __BIONIC__ } +TEST(pthread, pthread_rwlock_writer_wakeup_reader_clockwait) { +#if defined(__BIONIC__) + timespec ts; + ASSERT_EQ(0, clock_gettime(CLOCK_MONOTONIC, &ts)); + ts.tv_sec += 1; + test_pthread_rwlock_writer_wakeup_reader([&](pthread_rwlock_t* lock) { + return pthread_rwlock_clockrdlock(lock, CLOCK_MONOTONIC, &ts); + }); + + ASSERT_EQ(0, clock_gettime(CLOCK_REALTIME, &ts)); + ts.tv_sec += 1; + test_pthread_rwlock_writer_wakeup_reader([&](pthread_rwlock_t* lock) { + return pthread_rwlock_clockrdlock(lock, CLOCK_REALTIME, &ts); + }); +#else // __BIONIC__ + GTEST_SKIP() << "pthread_rwlock_clockrdlock not available"; +#endif // __BIONIC__ +} + static void pthread_rwlock_wakeup_timeout_helper(RwlockWakeupHelperArg* arg) { arg->tid = gettid(); ASSERT_EQ(RwlockWakeupHelperArg::LOCK_INITIALIZED, arg->progress); @@ -1098,6 +1136,38 @@ TEST(pthread, pthread_rwlock_timedrdlock_monotonic_np_timeout) { #endif // __BIONIC__ } +TEST(pthread, pthread_rwlock_clockrdlock_monotonic_timeout) { +#if defined(__BIONIC__) + pthread_rwlock_timedrdlock_timeout_helper( + CLOCK_MONOTONIC, [](pthread_rwlock_t* __rwlock, const timespec* __timeout) { + return pthread_rwlock_clockrdlock(__rwlock, CLOCK_MONOTONIC, __timeout); + }); +#else // __BIONIC__ + GTEST_SKIP() << "pthread_rwlock_clockrdlock not available"; +#endif // __BIONIC__ +} + +TEST(pthread, pthread_rwlock_clockrdlock_realtime_timeout) { +#if defined(__BIONIC__) + pthread_rwlock_timedrdlock_timeout_helper( + CLOCK_REALTIME, [](pthread_rwlock_t* __rwlock, const timespec* __timeout) { + return pthread_rwlock_clockrdlock(__rwlock, CLOCK_REALTIME, __timeout); + }); +#else // __BIONIC__ + GTEST_SKIP() << "pthread_rwlock_clockrdlock not available"; +#endif // __BIONIC__ +} + +TEST(pthread, pthread_rwlock_clockrdlock_invalid) { +#if defined(__BIONIC__) + pthread_rwlock_t lock = PTHREAD_RWLOCK_INITIALIZER; + timespec ts; + EXPECT_EQ(EINVAL, pthread_rwlock_clockrdlock(&lock, CLOCK_PROCESS_CPUTIME_ID, &ts)); +#else // __BIONIC__ + GTEST_SKIP() << "pthread_rwlock_clockrdlock not available"; +#endif // __BIONIC__ +} + static void pthread_rwlock_timedwrlock_timeout_helper( clockid_t clock, int (*lock_function)(pthread_rwlock_t* __rwlock, const timespec* __timeout)) { RwlockWakeupHelperArg wakeup_arg; @@ -1134,6 +1204,38 @@ TEST(pthread, pthread_rwlock_timedwrlock_monotonic_np_timeout) { #endif // __BIONIC__ } +TEST(pthread, pthread_rwlock_clockwrlock_monotonic_timeout) { +#if defined(__BIONIC__) + pthread_rwlock_timedwrlock_timeout_helper( + CLOCK_MONOTONIC, [](pthread_rwlock_t* __rwlock, const timespec* __timeout) { + return pthread_rwlock_clockwrlock(__rwlock, CLOCK_MONOTONIC, __timeout); + }); +#else // __BIONIC__ + GTEST_SKIP() << "pthread_rwlock_clockwrlock not available"; +#endif // __BIONIC__ +} + +TEST(pthread, pthread_rwlock_clockwrlock_realtime_timeout) { +#if defined(__BIONIC__) + pthread_rwlock_timedwrlock_timeout_helper( + CLOCK_REALTIME, [](pthread_rwlock_t* __rwlock, const timespec* __timeout) { + return pthread_rwlock_clockwrlock(__rwlock, CLOCK_REALTIME, __timeout); + }); +#else // __BIONIC__ + GTEST_SKIP() << "pthread_rwlock_clockwrlock not available"; +#endif // __BIONIC__ +} + +TEST(pthread, pthread_rwlock_clockwrlock_invalid) { +#if defined(__BIONIC__) + pthread_rwlock_t lock = PTHREAD_RWLOCK_INITIALIZER; + timespec ts; + EXPECT_EQ(EINVAL, pthread_rwlock_clockwrlock(&lock, CLOCK_PROCESS_CPUTIME_ID, &ts)); +#else // __BIONIC__ + GTEST_SKIP() << "pthread_rwlock_clockrwlock not available"; +#endif // __BIONIC__ +} + class RwlockKindTestHelper { private: struct ThreadArg { @@ -1392,16 +1494,43 @@ class pthread_CondWakeupTest : public ::testing::Test { ASSERT_EQ(0, pthread_condattr_destroy(&attr)); } - void StartWaitingThread(std::function<int (pthread_cond_t* cond, pthread_mutex_t* mutex)> wait_function) { + void StartWaitingThread( + std::function<int(pthread_cond_t* cond, pthread_mutex_t* mutex)> wait_function) { progress = INITIALIZED; this->wait_function = wait_function; - ASSERT_EQ(0, pthread_create(&thread, nullptr, reinterpret_cast<void* (*)(void*)>(WaitThreadFn), this)); + ASSERT_EQ(0, pthread_create(&thread, nullptr, reinterpret_cast<void* (*)(void*)>(WaitThreadFn), + this)); while (progress != WAITING) { usleep(5000); } usleep(5000); } + void RunTimedTest( + clockid_t clock, + std::function<int(pthread_cond_t* cond, pthread_mutex_t* mutex, const timespec* timeout)> + wait_function) { + timespec ts; + ASSERT_EQ(0, clock_gettime(clock, &ts)); + ts.tv_sec += 1; + + StartWaitingThread([&wait_function, &ts](pthread_cond_t* cond, pthread_mutex_t* mutex) { + return wait_function(cond, mutex, &ts); + }); + + progress = SIGNALED; + ASSERT_EQ(0, pthread_cond_signal(&cond)); + } + + void RunTimedTest(clockid_t clock, std::function<int(pthread_cond_t* cond, pthread_mutex_t* mutex, + clockid_t clock, const timespec* timeout)> + wait_function) { + RunTimedTest(clock, [clock, &wait_function](pthread_cond_t* cond, pthread_mutex_t* mutex, + const timespec* timeout) { + return wait_function(cond, mutex, clock, timeout); + }); + } + void TearDown() override { ASSERT_EQ(0, pthread_join(thread, nullptr)); ASSERT_EQ(FINISHED, progress); @@ -1442,52 +1571,80 @@ TEST_F(pthread_CondWakeupTest, broadcast_wait) { TEST_F(pthread_CondWakeupTest, signal_timedwait_CLOCK_REALTIME) { InitCond(CLOCK_REALTIME); - timespec ts; - ASSERT_EQ(0, clock_gettime(CLOCK_REALTIME, &ts)); - ts.tv_sec += 1; - StartWaitingThread([&](pthread_cond_t* cond, pthread_mutex_t* mutex) { - return pthread_cond_timedwait(cond, mutex, &ts); - }); - progress = SIGNALED; - ASSERT_EQ(0, pthread_cond_signal(&cond)); + RunTimedTest(CLOCK_REALTIME, pthread_cond_timedwait); } TEST_F(pthread_CondWakeupTest, signal_timedwait_CLOCK_MONOTONIC) { InitCond(CLOCK_MONOTONIC); - timespec ts; - ASSERT_EQ(0, clock_gettime(CLOCK_MONOTONIC, &ts)); - ts.tv_sec += 1; - StartWaitingThread([&](pthread_cond_t* cond, pthread_mutex_t* mutex) { - return pthread_cond_timedwait(cond, mutex, &ts); - }); - progress = SIGNALED; - ASSERT_EQ(0, pthread_cond_signal(&cond)); + RunTimedTest(CLOCK_MONOTONIC, pthread_cond_timedwait); } TEST_F(pthread_CondWakeupTest, signal_timedwait_CLOCK_MONOTONIC_np) { #if defined(__BIONIC__) InitCond(CLOCK_REALTIME); - timespec ts; - ASSERT_EQ(0, clock_gettime(CLOCK_MONOTONIC, &ts)); - ts.tv_sec += 1; - StartWaitingThread([&](pthread_cond_t* cond, pthread_mutex_t* mutex) { - return pthread_cond_timedwait_monotonic_np(cond, mutex, &ts); - }); - progress = SIGNALED; - ASSERT_EQ(0, pthread_cond_signal(&cond)); + RunTimedTest(CLOCK_MONOTONIC, pthread_cond_timedwait_monotonic_np); #else // __BIONIC__ GTEST_SKIP() << "pthread_cond_timedwait_monotonic_np not available"; #endif // __BIONIC__ } -static void pthread_cond_timedwait_timeout_helper(clockid_t clock, +TEST_F(pthread_CondWakeupTest, signal_clockwait_monotonic_monotonic) { +#if defined(__BIONIC__) + InitCond(CLOCK_MONOTONIC); + RunTimedTest(CLOCK_MONOTONIC, pthread_cond_clockwait); +#else // __BIONIC__ + GTEST_SKIP() << "pthread_cond_clockwait not available"; +#endif // __BIONIC__ +} + +TEST_F(pthread_CondWakeupTest, signal_clockwait_monotonic_realtime) { +#if defined(__BIONIC__) + InitCond(CLOCK_MONOTONIC); + RunTimedTest(CLOCK_REALTIME, pthread_cond_clockwait); +#else // __BIONIC__ + GTEST_SKIP() << "pthread_cond_clockwait not available"; +#endif // __BIONIC__ +} + +TEST_F(pthread_CondWakeupTest, signal_clockwait_realtime_monotonic) { +#if defined(__BIONIC__) + InitCond(CLOCK_REALTIME); + RunTimedTest(CLOCK_MONOTONIC, pthread_cond_clockwait); +#else // __BIONIC__ + GTEST_SKIP() << "pthread_cond_clockwait not available"; +#endif // __BIONIC__ +} + +TEST_F(pthread_CondWakeupTest, signal_clockwait_realtime_realtime) { +#if defined(__BIONIC__) + InitCond(CLOCK_REALTIME); + RunTimedTest(CLOCK_REALTIME, pthread_cond_clockwait); +#else // __BIONIC__ + GTEST_SKIP() << "pthread_cond_clockwait not available"; +#endif // __BIONIC__ +} + +static void pthread_cond_timedwait_timeout_helper(bool init_monotonic, clockid_t clock, int (*wait_function)(pthread_cond_t* __cond, pthread_mutex_t* __mutex, const timespec* __timeout)) { pthread_mutex_t mutex; ASSERT_EQ(0, pthread_mutex_init(&mutex, nullptr)); pthread_cond_t cond; - ASSERT_EQ(0, pthread_cond_init(&cond, nullptr)); + + if (init_monotonic) { + pthread_condattr_t attr; + pthread_condattr_init(&attr); + + ASSERT_EQ(0, pthread_condattr_setclock(&attr, CLOCK_MONOTONIC)); + clockid_t clock; + ASSERT_EQ(0, pthread_condattr_getclock(&attr, &clock)); + ASSERT_EQ(CLOCK_MONOTONIC, clock); + + ASSERT_EQ(0, pthread_cond_init(&cond, &attr)); + } else { + ASSERT_EQ(0, pthread_cond_init(&cond, nullptr)); + } ASSERT_EQ(0, pthread_mutex_lock(&mutex)); timespec ts; @@ -1504,17 +1661,57 @@ static void pthread_cond_timedwait_timeout_helper(clockid_t clock, } TEST(pthread, pthread_cond_timedwait_timeout) { - pthread_cond_timedwait_timeout_helper(CLOCK_REALTIME, pthread_cond_timedwait); + pthread_cond_timedwait_timeout_helper(false, CLOCK_REALTIME, pthread_cond_timedwait); } TEST(pthread, pthread_cond_timedwait_monotonic_np_timeout) { #if defined(__BIONIC__) - pthread_cond_timedwait_timeout_helper(CLOCK_MONOTONIC, pthread_cond_timedwait_monotonic_np); + pthread_cond_timedwait_timeout_helper(false, CLOCK_MONOTONIC, pthread_cond_timedwait_monotonic_np); + pthread_cond_timedwait_timeout_helper(true, CLOCK_MONOTONIC, pthread_cond_timedwait_monotonic_np); #else // __BIONIC__ GTEST_SKIP() << "pthread_cond_timedwait_monotonic_np not available"; #endif // __BIONIC__ } +TEST(pthread, pthread_cond_clockwait_timeout) { +#if defined(__BIONIC__) + pthread_cond_timedwait_timeout_helper( + false, CLOCK_MONOTONIC, + [](pthread_cond_t* __cond, pthread_mutex_t* __mutex, const timespec* __timeout) { + return pthread_cond_clockwait(__cond, __mutex, CLOCK_MONOTONIC, __timeout); + }); + pthread_cond_timedwait_timeout_helper( + true, CLOCK_MONOTONIC, + [](pthread_cond_t* __cond, pthread_mutex_t* __mutex, const timespec* __timeout) { + return pthread_cond_clockwait(__cond, __mutex, CLOCK_MONOTONIC, __timeout); + }); + pthread_cond_timedwait_timeout_helper( + false, CLOCK_REALTIME, + [](pthread_cond_t* __cond, pthread_mutex_t* __mutex, const timespec* __timeout) { + return pthread_cond_clockwait(__cond, __mutex, CLOCK_REALTIME, __timeout); + }); + pthread_cond_timedwait_timeout_helper( + true, CLOCK_REALTIME, + [](pthread_cond_t* __cond, pthread_mutex_t* __mutex, const timespec* __timeout) { + return pthread_cond_clockwait(__cond, __mutex, CLOCK_REALTIME, __timeout); + }); +#else // __BIONIC__ + GTEST_SKIP() << "pthread_cond_clockwait not available"; +#endif // __BIONIC__ +} + +TEST(pthread, pthread_cond_clockwait_invalid) { +#if defined(__BIONIC__) + pthread_cond_t cond = PTHREAD_COND_INITIALIZER; + pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + timespec ts; + EXPECT_EQ(EINVAL, pthread_cond_clockwait(&cond, &mutex, CLOCK_PROCESS_CPUTIME_ID, &ts)); + +#else // __BIONIC__ + GTEST_SKIP() << "pthread_cond_clockwait not available"; +#endif // __BIONIC__ +} + TEST(pthread, pthread_attr_getstack__main_thread) { // This test is only meaningful for the main thread, so make sure we're running on it! ASSERT_EQ(getpid(), syscall(__NR_gettid)); @@ -2180,6 +2377,21 @@ TEST(pthread, pthread_mutex_timedlock_monotonic_np) { #endif // __BIONIC__ } +TEST(pthread, pthread_mutex_clocklock) { +#if defined(__BIONIC__) + pthread_mutex_timedlock_helper( + CLOCK_MONOTONIC, [](pthread_mutex_t* __mutex, const timespec* __timeout) { + return pthread_mutex_clocklock(__mutex, CLOCK_MONOTONIC, __timeout); + }); + pthread_mutex_timedlock_helper( + CLOCK_REALTIME, [](pthread_mutex_t* __mutex, const timespec* __timeout) { + return pthread_mutex_clocklock(__mutex, CLOCK_REALTIME, __timeout); + }); +#else // __BIONIC__ + GTEST_SKIP() << "pthread_mutex_clocklock not available"; +#endif // __BIONIC__ +} + static void pthread_mutex_timedlock_pi_helper(clockid_t clock, int (*lock_function)(pthread_mutex_t* __mutex, const timespec* __timeout)) { @@ -2231,6 +2443,31 @@ TEST(pthread, pthread_mutex_timedlock_monotonic_np_pi) { #endif // __BIONIC__ } +TEST(pthread, pthread_mutex_clocklock_pi) { +#if defined(__BIONIC__) + pthread_mutex_timedlock_pi_helper( + CLOCK_MONOTONIC, [](pthread_mutex_t* __mutex, const timespec* __timeout) { + return pthread_mutex_clocklock(__mutex, CLOCK_MONOTONIC, __timeout); + }); + pthread_mutex_timedlock_pi_helper( + CLOCK_REALTIME, [](pthread_mutex_t* __mutex, const timespec* __timeout) { + return pthread_mutex_clocklock(__mutex, CLOCK_REALTIME, __timeout); + }); +#else // __BIONIC__ + GTEST_SKIP() << "pthread_mutex_clocklock not available"; +#endif // __BIONIC__ +} + +TEST(pthread, pthread_mutex_clocklock_invalid) { +#if defined(__BIONIC__) + pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + timespec ts; + EXPECT_EQ(EINVAL, pthread_mutex_clocklock(&mutex, CLOCK_PROCESS_CPUTIME_ID, &ts)); +#else // __BIONIC__ + GTEST_SKIP() << "pthread_mutex_clocklock not available"; +#endif // __BIONIC__ +} + TEST(pthread, pthread_mutex_using_destroyed_mutex) { #if defined(__BIONIC__) pthread_mutex_t m; @@ -2247,6 +2484,13 @@ TEST(pthread, pthread_mutex_using_destroyed_mutex) { "pthread_mutex_timedlock called on a destroyed mutex"); ASSERT_EXIT(pthread_mutex_timedlock_monotonic_np(&m, &ts), ::testing::KilledBySignal(SIGABRT), "pthread_mutex_timedlock_monotonic_np called on a destroyed mutex"); + ASSERT_EXIT(pthread_mutex_clocklock(&m, CLOCK_MONOTONIC, &ts), ::testing::KilledBySignal(SIGABRT), + "pthread_mutex_clocklock called on a destroyed mutex"); + ASSERT_EXIT(pthread_mutex_clocklock(&m, CLOCK_REALTIME, &ts), ::testing::KilledBySignal(SIGABRT), + "pthread_mutex_clocklock called on a destroyed mutex"); + ASSERT_EXIT(pthread_mutex_clocklock(&m, CLOCK_PROCESS_CPUTIME_ID, &ts), + ::testing::KilledBySignal(SIGABRT), + "pthread_mutex_clocklock called on a destroyed mutex"); ASSERT_EXIT(pthread_mutex_destroy(&m), ::testing::KilledBySignal(SIGABRT), "pthread_mutex_destroy called on a destroyed mutex"); #else diff --git a/tests/semaphore_test.cpp b/tests/semaphore_test.cpp index 7addf6dda..5a23b96bf 100644 --- a/tests/semaphore_test.cpp +++ b/tests/semaphore_test.cpp @@ -145,6 +145,19 @@ TEST(semaphore, sem_timedwait_monotonic_np) { #endif // __BIONIC__ } +TEST(semaphore, sem_clockwait) { +#if defined(__BIONIC__) + sem_timedwait_helper(CLOCK_MONOTONIC, [](sem_t* __sem, const timespec* __ts) { + return sem_clockwait(__sem, CLOCK_MONOTONIC, __ts); + }); + sem_timedwait_helper(CLOCK_REALTIME, [](sem_t* __sem, const timespec* __ts) { + return sem_clockwait(__sem, CLOCK_REALTIME, __ts); + }); +#else // __BIONIC__ + GTEST_SKIP() << "sem_clockwait is only supported on bionic"; +#endif // __BIONIC__ +} + TEST(semaphore_DeathTest, sem_timedwait_null_timeout) { sem_t s; ASSERT_EQ(0, sem_init(&s, 0, 0)); diff --git a/tests/stdatomic_test.cpp b/tests/stdatomic_test.cpp index d122d2f39..a9665d18e 100644 --- a/tests/stdatomic_test.cpp +++ b/tests/stdatomic_test.cpp @@ -15,9 +15,14 @@ */ #include <gtest/gtest.h> -// Fool stdatomic.h into not using <atomic>. -#undef _USING_LIBCXX + +#if defined(__ANDROID__) +#include <bits/stdatomic.h> +#else +#undef _USING_LIBCXX //TODO(b/137876753): Remove this #include <stdatomic.h> +#endif + #include <pthread.h> #include <stdint.h> diff --git a/tests/stdio_test.cpp b/tests/stdio_test.cpp index 01b4dbab7..a0cda1be0 100644 --- a/tests/stdio_test.cpp +++ b/tests/stdio_test.cpp @@ -19,7 +19,6 @@ #include <errno.h> #include <fcntl.h> #include <limits.h> -#include <linux/fs.h> #include <math.h> #include <stdio.h> #include <sys/types.h> @@ -34,10 +33,18 @@ #include <vector> #include <android-base/file.h> +#include <android-base/unique_fd.h> #include "BionicDeathTest.h" #include "utils.h" +// This #include is actually a test too. We have to duplicate the +// definitions of the RENAME_ constants because <linux/fs.h> also contains +// pollution such as BLOCK_SIZE which conflicts with lots of user code. +// Important to check that we have matching definitions. +// There's no _MAX to test that we have all the constants, sadly. +#include <linux/fs.h> + #if defined(NOFORTIFY) #define STDIO_TEST stdio_nofortify #define STDIO_DEATHTEST stdio_nofortify_DeathTest @@ -2610,3 +2617,77 @@ TEST(STDIO_TEST, SEEK_macros) { // So we'll notice if Linux grows another constant in <linux/fs.h>... ASSERT_EQ(SEEK_MAX, SEEK_HOLE); } + +TEST(STDIO_TEST, rename) { + TemporaryDir td; + std::string old_path = td.path + "/old"s; + std::string new_path = td.path + "/new"s; + + // Create the file, check it exists. + ASSERT_EQ(0, close(creat(old_path.c_str(), 0666))); + struct stat sb; + ASSERT_EQ(0, stat(old_path.c_str(), &sb)); + ASSERT_EQ(-1, stat(new_path.c_str(), &sb)); + + // Rename and check it moved. + ASSERT_EQ(0, rename(old_path.c_str(), new_path.c_str())); + ASSERT_EQ(-1, stat(old_path.c_str(), &sb)); + ASSERT_EQ(0, stat(new_path.c_str(), &sb)); +} + +TEST(STDIO_TEST, renameat) { + TemporaryDir td; + android::base::unique_fd dirfd{open(td.path, O_PATH)}; + std::string old_path = td.path + "/old"s; + std::string new_path = td.path + "/new"s; + + // Create the file, check it exists. + ASSERT_EQ(0, close(creat(old_path.c_str(), 0666))); + struct stat sb; + ASSERT_EQ(0, stat(old_path.c_str(), &sb)); + ASSERT_EQ(-1, stat(new_path.c_str(), &sb)); + + // Rename and check it moved. + ASSERT_EQ(0, renameat(dirfd, "old", dirfd, "new")); + ASSERT_EQ(-1, stat(old_path.c_str(), &sb)); + ASSERT_EQ(0, stat(new_path.c_str(), &sb)); +} + +TEST(STDIO_TEST, renameat2) { +#if defined(__GLIBC__) + GTEST_SKIP() << "glibc doesn't have renameat2 until 2.28"; +#else + TemporaryDir td; + android::base::unique_fd dirfd{open(td.path, O_PATH)}; + std::string old_path = td.path + "/old"s; + std::string new_path = td.path + "/new"s; + + // Create the file, check it exists. + ASSERT_EQ(0, close(creat(old_path.c_str(), 0666))); + struct stat sb; + ASSERT_EQ(0, stat(old_path.c_str(), &sb)); + ASSERT_EQ(-1, stat(new_path.c_str(), &sb)); + + // Rename and check it moved. + ASSERT_EQ(0, renameat2(dirfd, "old", dirfd, "new", 0)); + ASSERT_EQ(-1, stat(old_path.c_str(), &sb)); + ASSERT_EQ(0, stat(new_path.c_str(), &sb)); + + // After this, both "old" and "new" exist. + ASSERT_EQ(0, close(creat(old_path.c_str(), 0666))); + + // Rename and check it moved. + ASSERT_EQ(-1, renameat2(dirfd, "old", dirfd, "new", RENAME_NOREPLACE)); + ASSERT_EQ(EEXIST, errno); +#endif +} + +TEST(STDIO_TEST, renameat2_flags) { +#if defined(__GLIBC__) + GTEST_SKIP() << "glibc doesn't have renameat2 until 2.28"; +#else + ASSERT_NE(0, RENAME_EXCHANGE); + ASSERT_NE(0, RENAME_NOREPLACE); + ASSERT_NE(0, RENAME_WHITEOUT); +#endif +} diff --git a/tests/sys_mman_test.cpp b/tests/sys_mman_test.cpp index 0b981981c..e403ea5b5 100644 --- a/tests/sys_mman_test.cpp +++ b/tests/sys_mman_test.cpp @@ -230,7 +230,10 @@ TEST(sys_mman, mmap_PTRDIFF_MAX) { TEST(sys_mman, mremap_PTRDIFF_MAX) { void* map = mmap(nullptr, PAGE_SIZE, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); ASSERT_NE(MAP_FAILED, map); + ASSERT_EQ(MAP_FAILED, mremap(map, PAGE_SIZE, kHuge, MREMAP_MAYMOVE)); + + ASSERT_EQ(0, munmap(map, PAGE_SIZE)); } TEST(sys_mman, mmap_bug_27265969) { @@ -239,3 +242,61 @@ TEST(sys_mman, mmap_bug_27265969) { // Some kernels had bugs that would cause segfaults here... __builtin___clear_cache(base, base + (PAGE_SIZE * 2)); } + +TEST(sys_mman, mlock) { + void* map = mmap(nullptr, PAGE_SIZE, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + ASSERT_NE(MAP_FAILED, map); + + // Not really anything we can assert about this. + mlock(map, PAGE_SIZE); + + ASSERT_EQ(0, munmap(map, PAGE_SIZE)); +} + +TEST(sys_mman, mlock2) { +#if defined(__GLIBC__) + GTEST_SKIP() << "needs glibc 2.27"; +#else + void* map = mmap(nullptr, PAGE_SIZE, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + ASSERT_NE(MAP_FAILED, map); + + // Not really anything we can assert about this. + mlock2(map, PAGE_SIZE, MLOCK_ONFAULT); + + ASSERT_EQ(0, munmap(map, PAGE_SIZE)); +#endif +} + +TEST(sys_mman, memfd_create) { +#if defined(__GLIBC__) + GTEST_SKIP() << "needs glibc 2.27"; +#else + // Is the MFD_CLOEXEC flag obeyed? + errno = 0; + int fd = memfd_create("doesn't matter", 0); + if (fd == -1) { + ASSERT_EQ(ENOSYS, errno); + GTEST_SKIP() << "no memfd_create available"; + } + int f = fcntl(fd, F_GETFD); + ASSERT_NE(-1, f); + ASSERT_FALSE(f & FD_CLOEXEC); + close(fd); + + errno = 0; + fd = memfd_create("doesn't matter", MFD_CLOEXEC); + f = fcntl(fd, F_GETFD); + ASSERT_NE(-1, f); + ASSERT_TRUE(f & FD_CLOEXEC); + + // Can we read and write? + std::string expected("hello, world!"); + ASSERT_TRUE(android::base::WriteStringToFd(expected, fd)); + ASSERT_EQ(0, lseek(fd, 0, SEEK_SET)); + std::string actual; + ASSERT_TRUE(android::base::ReadFdToString(fd, &actual)); + ASSERT_EQ(expected, actual); + + close(fd); +#endif +} diff --git a/tests/time_test.cpp b/tests/time_test.cpp index c890358fa..4e1724211 100644 --- a/tests/time_test.cpp +++ b/tests/time_test.cpp @@ -748,11 +748,11 @@ TEST(time, clock_getres_unknown) { } TEST(time, clock) { - // clock(3) is hard to test, but a 1s sleep should cost less than 1ms. + // clock(3) is hard to test, but a 1s sleep should cost less than 5ms. clock_t t0 = clock(); sleep(1); clock_t t1 = clock(); - ASSERT_LT(t1 - t0, CLOCKS_PER_SEC / 1000); + ASSERT_LT(t1 - t0, 5 * (CLOCKS_PER_SEC / 1000)); } static pid_t GetInvalidPid() { diff --git a/tests/touch-obj-on-success b/tests/touch-obj-on-success index df08a4968..d8a71ba24 100755 --- a/tests/touch-obj-on-success +++ b/tests/touch-obj-on-success @@ -4,5 +4,8 @@ # from that command line and touches it. "$@" -obj="$(echo "$@" | grep -oP '\S+\.o\b')" -touch "${obj}" +for arg in "$@"; do + if [[ "$arg" == *.o ]]; then + touch "$arg" + fi +done |