Noticed by "NRK": https://www.openwall.com/lists/musl/2022/07/29/5
We don't have this problem elsewhere in bionic because it's so rare to
call getline() without a loop, and the free() is always outside the loop
because that's a handy optimization.
Test: treehugger
Change-Id: Iff8845aa226d87357b38cf4a285fc1be3cac5659
It came up on the musl mailing list that there's not actually any need
to iterate over the directory entries:
https://www.openwall.com/lists/musl/2022/07/27/1
This lets us reuse the code for "online" processors in the
implementation of "configured" processors. The question of whether
"configured" should correspond to Linux's "possible" or "present" isn't
obvious to me, but the distinction seems unlikely to matter on mobile
devices anyway, and that's a trivial change should it ever be needed.
Plus the motivating argument from the person who brought this up was
that callers asking for "configured" processors are probably asking for
an upper bound, which sounds convincing to me.
Test: treehugger
Change-Id: I0d4e13538dc6b09a6dba520d9ac24f436906f7c0
Adds persistent sysprops for test infra usage, and adds the tests for
the sysprops.
The test does some fancy flocking in order to restore any existing
GWP-ASan sysprop usage in the test cleanup.
Bug: 236738714
Test: atest bionic-unit-tests
Change-Id: I8956296d39c98ce8c7dd0a703b240530d8ad48db
This file is included in libandroid_support.a, where using new/delete
breaks libc++ tests that assume that libc++ makes no extraneous
new/delete calls.
This CL changes newlocale/duplocale to return NULL on out-of-memory.
Previously, the behavior varied:
- libc.so: aborted using async_safe_fatal
- libandroid_support.a: throws std::bad_alloc
Bug: none
Test: std/input.output/filesystems/class.path/path.member/path.assign/move.pass.cpp
Test: libcxx/localization/locales/locale/locale.types/locale.facet/no_allocation.pass.cpp
Test: std/input.output/filesystems/class.path/path.member/path.construct/move.pass.cpp
Change-Id: I38c772f249f32322afb9402ebeeb4bb65a908b59
Upstream has renamed tzsetlcl to tzset_unlocked. As bionic's
implementation of tzset_unlock differs from upstream, these changes were
skipped.
Also, upstream has removed constants (SECSPERMIN, etc) from tzfile.h. As
they are used in strptime.c, I've decided to leave them in tzfile.h and
to not bring them into strptime.c.
HAVE_TZNAME and USG_COMPAT flags semantics were updated, thus setting
their values to 2 in Android.bp file. See
1a27ec76bc
* 4742526b7e
and 0e8f0b06ac
were picked up, which are not part of 2022a.
Changes were applied using following commands:
1) Checkout tzcode repo
2) Prepare patches for all tzcode file using
git diff 2016g 2021e -- <file-name> > <file-name-patch>
3) Apply these patches to files in bionic using
patch -p1 <file-name> <file-name-patch>
Bug: 25413083
Test: CtsLibcoreTestCases
Test: CtsLibcoreOjTestCases
Test: CtsBionicTestCases
Change-Id: I9aba4cbeab30171a32f94d20c8e4057804a4c01f
With memtag_stack, each function is responsible for cleaning up
allocation tags for its stack frame. Allocation tags for anything below
SP must match the address tag in SP.
Both vfork and longjmp implement non-local control transfer which
abandons part of the stack without proper cleanup. Update allocation
tags:
* For longjmp, we know both source and destination values of SP.
* For vfork, save the value of SP before exit() or exec*() - the only
valid ways of ending the child process according to POSIX - and reset
tags from there to SP-in-parent.
This is not 100% solid and can be confused by a number of hopefully
uncommon conditions:
* Segmented stacks.
* Longjmp from sigaltstack into the main stack.
* Some kind of userspace thread implementation using longjmp (that's UB,
longjmp can only return to the caller on the current stack).
* and other strange things.
This change adds a sanity limit on the size of the tag cleanup. Also,
this logic is only activated in the binaries that carry the
NT_MEMTAG_STACK note (set by -fsanitize=memtag-stack) which is meant as
a debugging configuration, is not compatible with pre-armv9 CPUs, and
should not be set on production code.
Bug: b/174878242
Test: fvp_mini with ToT LLVM (more test in a separate change)
Change-Id: Ibef8b2fc5a6ce85c8e562dead1019964d9f6b80b
Map all stacks (primary, thread, and sigaltstack) as PROT_MTE when the
binary requests it through the ELF note.
For the reference, the note is produced by the following toolchain changes:
https://reviews.llvm.org/D118948https://reviews.llvm.org/D119384https://reviews.llvm.org/D119381
Bug: b/174878242
Test: fvp_mini with ToT LLVM (more tests in a separate change)
Change-Id: I04a4e21c966e7309b47b1f549a2919958d93a872
See:
https://man7.org/linux/man-pages/man2/close_range.2.html
Note: 'man close_range' documents 'flags' as unsigned int,
while glibc unistd.h as just 'int'. Picking 'int' to match glibc,
though it probably doesn't matter.
BYPASS_INCLUSIVE_LANGUAGE_REASON=man is a cli command
Test: TreeHugger
Bug: 229913920
Signed-off-by: Maciej Żenczykowski <maze@google.com>
Change-Id: I1e2d1c8edc2ea28922d60f3ce3e534a784622cd1
Linux kernel's close_range() system call (currently) allows:
close() unshare() fcntl(F_SETFD, FD_CLOEXEC)
to be performed on ranges of fds.
All 3 of these are already allowed by seccomp bpf:
as such this doesn't allow you to do anything you can't already do.
We can't add close_range() properly to bionic because we'd need to
fiddle about with ltp and it's too late to add new T API anyway,
so let's just make the direct syscall() call.
We'll add proper support in U.
See also:
https://man7.org/linux/man-pages/man2/close_range.2.html
Test: TreeHugger
Bug: 229913920
Signed-off-by: Maciej Żenczykowski <maze@google.com>
Change-Id: I85586d544fc23bed6aee59f00bdb79ee7a8150d1
This new posix_spawn attribute flag marks all file descriptors
(except stdin/out/err) as close-on-exec before executing any user
registered file actions (posix_spawn_file_actions_addopen/adddup2).
Test: TreeHugger
Bug: 229913920
Signed-off-by: Maciej Żenczykowski <maze@google.com>
Change-Id: If458100d6a253a9b0348d4e93a9a610225f89615
This patch introduces GWP-ASan system properties and environment
variables to control the internal sampling rates of GWP-ASan. This can
be used for:
1. "Torture testing" the system, i.e. running it under an extremely
high sampling rate under GWP-ASan.
2. Increasing sampling remotely to allow further crash report
collection of rare issues.
There are three sets of system properites:
1. libc.debug.gwp_asan.*.system_default: Default values for native
executables and system apps.
2. libc.debug.gwp_asan.*.app_default: Default values for non-system
apps, and
3. libc.debug.gwp_asan.*.<basename/app_name>: Default values for an
individual app or native process.
There are three variables that can be changed:
1. The allocation sampling rate (default: 2500) - using the environment
variable GWP_ASAN_SAMPLE_RATE or the libc.debug.gwp_asan.sample_rate.*
system property.
2. The process sampling rate (default: 128 for system apps/processes, 1
for opted-in apps) - using the environment variable
GWP_ASAN_PROCESS_SAMPLING or the libc.debug.gwp_asan.process_sampling.*
system property,
3. The number of slots available (default: 32) - using the environment
variable GWP_ASAN_MAX_ALLOCS or the libc.debug.gwp_asan.max_allocs.*
system property.
If not specified, #3 will be calculated as a ratio of the default
|2500 SampleRate : 32 slots|. So, a sample rate of "1250" (i.e. twice as
frequent sampling) will result in a doubling of the max_allocs to "64".
Bug: 219651032
Test: atest bionic-unit-tests
Change-Id: Idb40a2a4d074e01ce3c4e635ad639a91a32d570f
If a process is failing due to out of memory, some code calls
android_set_abort_message with a nullptr. Specifically, the libc++
library std::terminate can call do this. In this case, put a
null in the abort message.
Test: Call with nullptr and verify the code does not crash.
Test: Modified crasher to set an abort message and set a null abort
Test: message. Ran both, verified the abort message displays in
Test: first case, and doesn't display in the second case.
Change-Id: Ia9250f47e4537853ce93bbb20b35915a78caa502
Two edge cases were found in aosp/2038947:
1. realloc(p, 0) == free() and returns nullptr. Previously, we just
returned a new pointer.
2. If the malloc() part of realloc() fails (e.g. when the size of the
allocation is 1 << 56), then the old memory shouldn't be destroyed.
Bug: N/A
Test: Covered using atest bionic-unit-tests using aosp/2038947.
Change-Id: Ibafc752787129922a1e0323ffa14221d6a14f108
Revert submission 1954983-master-I3030c47be9d02a27505bd4775c1982a20755758c
Reason for revert: PAC has shipped with S, and we're going with app compat outreach rather than regressing security.
Reverted Changes:
I3030c47be:Disable pointer authentication in app processes.
I3030c47be:Disable pointer authentication in app processes.
Change-Id: I8761f08ddbd9077ff98b1a9a0c323de968792778
dup2(2) is a no-op if the new and old fds are equal, but it's pretty
clear that any useful caller in the posix_spawn(3) context wants us to
clear O_CLOEXEC even if we don't actually "move" the fd.
Bug: https://www.austingroupbugs.net/view.php?id=411
Test: treehugger
Change-Id: I5ce1a1f9216df5afd295cc9e35b84527873e9541
For the perf profiling signal handler to succeed in opening
/proc/self/mem, the process needs to be marked as dumpable in posix
terms. This patch addresses a scenario since Android S where the process
is considered profileable, but is not dumpable on "user" builds. The
solution is to mark the process as dumpable while opening the procfs
descriptors, restoring the original value afterwards. This is the same
approach as the heapprofd heap profiler, which performs the override
within the loaded client library [1].
The particular scenario being addressed is:
* user build
* app does not explicitly opt into being profiled by shell
* app does not explicitly opt out of all profiling
In this case, the app is considered profileable by the platform (but NOT
shell). Therefore ActivityThread marks the process as profileable [2],
but the zygote keeps the process as undumpable as it considers the
profileability from the shell domain [3]. We could change the logic in
the zygote to leave such processes in the dumpable state, but the
override within the signal handler is considered to be more contained as
the dumpability is only needed temporarily.
This override would also apply for any non-dumpable native services that
are signalled for profiling, which is also desireable for profiling
coverage.
This change does not elide any of the existing profileability
checks by the signal handler's preamble and the profiler itself.
[1]
https://cs.android.com/android/platform/superproject/+/master:external/perfetto/src/profiling/memory/client.cc;l=184;drc=78cd82ba31233ce810618e07d349fd34efdb861d
[2]
https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/app/ActivityThread.java;l=6610;drc=de9cf3392d7872c2bee69b65a614e77bb166b26e
[3]
https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/jni/com_android_internal_os_Zygote.cpp;l=1680;drc=master
Tested: clock app on barbet-user succeeds in opening the procfs
descriptors within the signal handler.
Tested: systemwide profiling on sargo-userdebug works as before.
Bug: 196810669
BYPASS_INCLUSIVE_LANGUAGE_REASON=referencing the name of a cmdline utility
Change-Id: Id621d4312418ff0736c97065e9ee577ff67f40da
Currently, the ELF note parsing in the loader is not permissive. This
patch relaxes the restrictions on the bits of the ELF note that could be
extended in the future.
This may allow more MTE options in apexes. If we add some extra metadata
bit (say, in bit 5) in the future, and then build MTE into every apex,
we don't want it to crash on Android 13 devices (we'd much rather it
just be a no-op).
Remove the (unused anywhere) NT_MEMTAG_DEFAULT and call it
NT_MEMTAG_NONE.
And finally, make the tests work on bionic-unit-tests-static. We
previously didn't deploy the test binaries, so add them as a data
dependency.
Bug: N/A
Test: atest bionic-unit-tests-static
Change-Id: I13530faad55c719c6eb848297f8ce378e18afbfc
Normally, platform-specific note types in the toolchain are prefixed
with the platform name. Because we're exposing the NT_TYPE_MEMTAG and
synthesizing the note in the toolchain in an upcoming patch
(https://reviews.llvm.org/D118948), it's been requested that we change
the name to include the platform prefix.
While NT_TYPE_IDENT and NT_TYPE_KUSER aren't known about or synthesized
by the toolchain, update those references as well for consistency.
Bug: N/A
Test: Build Android
Change-Id: I7742e4917ae275d59d7984991664ea48028053a1
The first time should_trace() returns true, bionic_trace_begin() calls
open() on trace_marker.
The problem is that open() can call bionic_trace_begin(). We've observed
this happening, for example when:
* fdtrack is enabled. dlopen("libfdtrack.so") can be used to enable
fdtrack on a process.
* ThreadA is busy unwinding inside fdtrack and is holding an fdtrack
internal mutex.
* ThreadB calls bionic_trace_begin() for the first time since the
property "debug.atrace.tags.enableflags" contains ATRACE_TAG_BIONIC.
* ThreadB calls open("/sys/kernel/tracing/trace_marker"). Since fdtrack
is enabled, ThreadB tries to do unwinding as well.
* ThreadB, inside fdtrack's unwinding tries to grab the same mutex that
ThreadA is holding.
* Mutex contention is reported using bionic_systrace, therefore
bionic_trace_begin() is called again on ThreadB.
* ThreadB tries to grab g_lock in bionin_systrace.cpp, but that's
already held by ThreadB itself, earlier on the stack. Therefore
ThreadB is stuck.
I managed to reproduce the above scenario by manually pausing ThreadA
inside unwinding with a debugger and letting ThreadB hitting
bionic_trace_begin() for the first time.
We could avoid using g_lock while calling open() (either by releasing
g_lock and reacquiring it later, or by using atomics), but
bionic_trace_begin() would try to call open() again. In my tests, open()
does not call bionic_trace_begin() a third time, because fdtrack has
reentrancy protection, but there might be another code path inside open
that calls bionic_trace_begin again (it could be racy or only happen in
certain configurations).
This commit fixes the problem by implementing reentrancy protection in
bionic_systrace.
Sample callstack from ThreadA deadlocked before the fix:
```
* frame #0: 0x0000007436db077c libc.so`syscall at syscall.S:41
frame #1: 0x0000007436db0ba0 libc.so`bionic_trace_begin(char const*) [inlined] __futex(ftx=0x000000743737a548, op=<unavailable>, value=2, timeout=0x0000000000000000, bitset=-1) at bionic_futex.h:45:16
frame #2: 0x0000007436db0b8c libc.so`bionic_trace_begin(char const*) [inlined] __futex_wait_ex(ftx=0x000000743737a548, value=2) at bionic_futex.h:66:10
frame #3: 0x0000007436db0b78 libc.so`bionic_trace_begin(char const*) [inlined] Lock::lock(this=0x000000743737a548) at bionic_lock.h:67:7
frame #4: 0x0000007436db0b74 libc.so`bionic_trace_begin(char const*) [inlined] should_trace() at bionic_systrace.cpp:38:10
frame #5: 0x0000007436db0b74 libc.so`bionic_trace_begin(message="Contending for pthread mutex") at bionic_systrace.cpp:59:8
frame #6: 0x0000007436e193e4 libc.so`NonPI::MutexLockWithTimeout(pthread_mutex_internal_t*, bool, timespec const*) [inlined] NonPI::NormalMutexLock(mutex=0x0000007296cae9f0, shared=0, use_realtime_clock=false, abs_timeout_or_null=0x0000000000000000) at pthread_mutex.cpp:592:17
frame #7: 0x0000007436e193c8 libc.so`NonPI::MutexLockWithTimeout(mutex=0x0000007296cae9f0, use_realtime_clock=false, abs_timeout_or_null=0x0000000000000000) at pthread_mutex.cpp:719:16
frame #8: 0x0000007436e1912c libc.so`::pthread_mutex_lock(mutex_interface=<unavailable>) at pthread_mutex.cpp:839:12 [artificial]
frame #9: 0x00000071a4e5b290 libfdtrack.so`std::__1::mutex::lock() [inlined] std::__1::__libcpp_mutex_lock(__m=<unavailable>) at __threading_support:256:10
frame #10: 0x00000071a4e5b28c libfdtrack.so`std::__1::mutex::lock(this=<unavailable>) at mutex.cpp:31:14
frame #11: 0x00000071a4e32634 libfdtrack.so`unwindstack::Elf::Step(unsigned long, unwindstack::Regs*, unwindstack::Memory*, bool*, bool*) [inlined] std::__1::lock_guard<std::__1::mutex>::lock_guard(__m=0x0000007296cae9f0) at __mutex_base:104:27
frame #12: 0x00000071a4e32618 libfdtrack.so`unwindstack::Elf::Step(this=0x0000007296cae9c0, rel_pc=66116, regs=0x0000007266ca0470, process_memory=0x0000007246caa130, finished=0x0000007ff910efb4, is_signal_frame=0x0000007ff910efb0) at Elf.cpp:206:31
frame #13: 0x00000071a4e2b3b0 libfdtrack.so`unwindstack::LocalUnwinder::Unwind(this=0x00000071a4ea1528, frame_info=<unavailable>, max_frames=34) at LocalUnwinder.cpp:102:22
frame #14: 0x00000071a4e2a3ec libfdtrack.so`fd_hook(event=<unavailable>) at fdtrack.cpp:119:18
frame #15: 0x0000007436dbf684 libc.so`::__open_2(pathname=<unavailable>, flags=<unavailable>) at open.cpp:72:10
frame #16: 0x0000007436db0a04 libc.so`bionic_trace_begin(char const*) [inlined] open(pathname=<unavailable>, flags=524289) at fcntl.h:63:12
frame #17: 0x0000007436db09f0 libc.so`bionic_trace_begin(char const*) [inlined] get_trace_marker_fd() at bionic_systrace.cpp:49:25
frame #18: 0x0000007436db09c0 libc.so`bionic_trace_begin(message="pthread_create") at bionic_systrace.cpp:63:25
```
Bug: 213642769
Change-Id: I10d331859045cb4a8609b007f5c6cf2577ff44df
Unfortunately we have discovered that some applications in the wild
are using PAC instructions incorrectly. To keep those applications
working on PAC enabled devices, disable PAC in application processes
for now.
Bug: 212660282
Change-Id: I3030c47be9d02a27505bd4775c1982a20755758c
When we added the fast path for the common case of ASCII, we forgot to
remove the now-dead code that handled the 1-byte case later in these
functions. This was obvious from the code coverage data.
Note that the 16-bit variants are unaffected because they're implemented
as calls to the 32-bit variants with extra range checks/surrogate
handling surrounding the call.
Test: treehugger
Change-Id: Ibd40f823519acb9aae8037bdeb3f9c5e36b9d9a6
We could remove this line, but it seems reasonable to leave it in for
clarification/safety, especially if it's moved after the common success
case?
Test: treehugger
Change-Id: I5f7e0da8397f80018e6d55321b26371790087f5c
This came up with POSIX recently. Doesn't seem like it matters since
everyone's had this wrong for 40 years, but "meh" --- it's a trivial
fix, and it's strictly correct even if nobody needs this, so let's just
do it...
(Geoff Clare pointed out that my app compat concern "what if someone's
relying on this bug to pass flags to the shell?" isn't relevant because
while you can indeed do that, you then can't pass a command!)
Bug: https://austingroupbugs.net/view.php?id=1440
Test: treehugger
Change-Id: I64f6440da55e2dc29d0136ee62007197d2f00d46
This saves a couple of syscalls in the common case, and also lets static
binaries run in a chroot without /dev/null as long as
stdin/stdout/stderr are actually connected to something (which the
toybox maintainer tried to do).
Test: manual with strace
Change-Id: Ic9a28896a07304a3bd428acfd9ddca9d22015f6e
They're in glibc, though not in musl.
Also add basic doc comments to the whole of <sys/uio.h>.
Bug: http://b/203002492
Test: treehugger
Change-Id: Ic607f7f349e5b7c9bf66c25b7bd68f827da530d6
In the following scenario:
* Heapprofd wants to profile a process.
* The process receives the heapprofd signal, so it sets up the ephemeral
hooks.
* The process does not perform any allocation, so the proper heapprofd
hook is never installed.
* Heapprofd terminates.
* Now heapprofd wants to start a new profiling session.
* The process receives the heapprofd signal (again).
In the signal handler, no action is needed at this point. The ephemeral
hooks are already setup, so, at the next malloc, the proper heapprofd
hooks will be installed.
Before this commit, the code logged an error message, but still worked
correctly.
This commit basically just skips the error_log below.
Example of the error message that is now suppressed:
```
process: heapprofd: failed to transition kInitialState ->
kInstallingEphemeralHook. current state (possible race): 2
```
Tested by:
* Running a process that calls malloc on input from stdin.
* (Optional, tested both cases) Enable GWP-Asan by calling
`android_mallopt(M_INITIALIZE_GWP_ASAN, ...`. The call will return
success.
* Attaching heapprofd:
```
external/perfetto/tools/heap_profile -i 1 -p `adb shell pidof <...>`
```
* Detaching heapprofd (CTRL-C). The trace will be empty.
* (If not enabled before) Enabling GWP-Asan. The call will fail (because
GWP-Asan detects heapprofd hooks).
* Reattaching heapprofd.
* Triggering some malloc()s in the process. The error log from above
will not appear in `adb logcat`.
* Detaching heapprofd (CTRL-C). The trace will NOT be empty.
Bug: 192258849
Change-Id: I01699b10ecd19e52e1e77f83fcca955ebd885942
Strictly this still isn't quite the same, because they won't actually be
profiled, but at least they won't *crash* now if they're sent a
profiling signal.
Bug: http://b/201497662
Test: treehugger
Change-Id: I0728492eed77584cd850d28897056996387e6671
When calling write on an FD for trace_marker, it is expected that the
pointer passed will be paged into memory. If this isn't the case, the
kernel will ignore the string passed and instead write "<faulted>" to
the ring buffer.
For end events, we were passing a constant string which resides in
the rodata section of the ELF file. If this section is paged out, we
end up not closing atrace stacks correctly leading to very broken traces.
For even more context, see the associated bug.
Fix this issue by reading the constant string to the stack first
which should mean the string is always paged in.
Bug: 197620214
Change-Id: I6a444ac6fe83a6a9fb696c5621e392eca7e9437a
When calling android_mallopt using M_INITIALIZE_GWP_ASAN, nothing
was being returned. Fix this, add a test, and also refactor the
code a bit so dynamic and static share the same code.
Test: Unit tests pass in dynamic and static versions.
Test: Passed using both jemalloc and scudo.
Change-Id: Ibe54b6ccabdbd44d2378892e793df393978bc02b
musl libc doesn't provide fts, but elfutils and libabigail need it.
Export bionic's fts as a staic library that can be linked into elfutils
and libabigail when compiling against musl.
fts uses recallocarray, which musl doesn't provide, so also include
recallocarray.c in libfts.a.
Requires minor tweaks to fts.c and a wrapper around fts.h to make them
compatible with musl, primarily by providing local definitions of macros
provided in bionic's sys/cdefs.h.
Bug: 190084016
Test: m libfts
Change-Id: Ifac9a59e7504c0c1f5f8a3a5bd3c19a13980b83c
fts.c is from openbsd and has compatibility macros to make it compile
as part of bionic. Move it into libc_openbsd_ndk where it will
get the workarounds from -include openbsd-compat.h instead.
Test: m libc
Change-Id: I213d423af8f010e39460b611e902acbf3561ae7a
If the DispatchReset fails, the subsequent iteration has the wrong
idea of what the "original" table is, and if a subsequent DispatchReset
succeeds it unhooks them.
Repro in https://r.android.com/1767868.
Bug: 193012939
Bug: 189776979
Change-Id: I30445c053fcb785669f75d9c83056926d850edce
The posix spec says strerror_r returns a positive error number, not
-1 and set errno.
Test: bionic-unit-tests-static
Change-Id: I6a12d50d046f9caac299bf3bff63e6c9496c1b6f
Revert submission 1403568-sysprop_trace
Reason for revert: makes property get/set non-reentrant
Reverted Changes:
I6f85f3f52:Add systrace tag for system property
Id2b93acb2:Adding system property tracing
Id78992d23:Add systrace tag for system property
I1ba9fc7bd:Add systrace tag for system property
Bug: 193050299
Test: build and boot a device
Change-Id: Ic7a83fb01a39113d408ed0c95d27f694d5a2649c
Merged-In: Ic7a83fb01a39113d408ed0c95d27f694d5a2649c
(cherry picked from commit 61a5a8380d)
This reverts commit 1e1c7845aa.
Reason for revert: makes property get/set non-reentrant
Bug: 193050299
Test: build and boot a device
Change-Id: If59e3dc25684a3c2b1d3ff74f995311afe6c6e89
Merged-In: If59e3dc25684a3c2b1d3ff74f995311afe6c6e89
(cherry picked from commit 3ec21f527a)
On devices where the performance of ASYNC mode is similar to SYNC
mode on certain CPUs, OEMs may choose to configure the kernel to
prefer SYNC mode on those CPUs by writing the value "sync" to the
sysfs node: /sys/devices/system/cpu/cpu<N>/mte_tcf_preferred
The kernel will only respect the per-CPU preference if the user program
allows this by specifying the preferred mode as a member of a set of
allowed modes. Since only kernels with r.android.com/1754670 support
specifying multiple modes, fall back to trying to specify a single
mode if that doesn't work.
Bug: 189966263
Change-Id: Ie7ada3b073178b7967f0819cbdadc2d8e3a2c648
This function doesn't return, but it does appear in stack traces. Avoid
using return PAC in this function because we may end up resetting IA,
which may confuse unwinders due to mismatching keys.
Bug: 189808795
Change-Id: I953da9078acd1d43eb7a47fb11f75caa0099fa12
Extend existing restrictions targeting only apps with API level >= 30 to
all apps.
Actual enforcement happens in SELinux. This change just prevents
logspam.
To be merged when automerge to sc-dev ends.
Bug: 170188668
Test: atest bionic-unit-tests-static
Test: atest NetworkInterfaceTest
Test: Connect to Wi-Fi network
Test: atest CtsSelinuxTargetSdk27TestCases
Test: atest CtsSelinuxTargetSdk28TestCasesTest: atest
CtsSelinuxTargetSdk29TestCases
Test: atest CtsSelinuxTargetSdkCurrentTestCases
Change-Id: If1761354216b23a1e55e6b9606de452899afff0c
Processes loaded from vendor partitions may have their own sandboxes
that would reject the prctl. Because no devices launched with PAC
enabled before S, we can avoid issues on upgrading devices by checking
for PAC support before issuing the prctl.
Bug: 186117046
Change-Id: I9905b963df01c9007d9fb4527273062ea87a5075
Revert "Updates CTS tests for MAC address restrictions."
Revert submission 1528409-mac-softrestrict
Reason for revert: App compatibility
Reverted Changes:
I74a50b990:Return anonymized MAC for apps targeting SDK < 30
I8738f7912:Reland: Soft-enable MAC address restrictions with ...
Id13670747:Updates CTS tests for MAC address restrictions.
Change-Id: I64e17cb04acf2862bc657e60694067a456b4f936
Also delete some fdsan code that attempts to check for the post-fork
state, but never will, because we update the cached pid upon fork.
Bug: http://b/174542867
Test: /data/nativetest64/bionic-unit-tests/bionic-unit-tests
Test: treehugger
Change-Id: I9b748dac9de9b4c741897d93e64d31737e52bf8e
Resetting PAC keys on fork appears to lead to a number of problems. One
problem is that we are constrained in where we can run C++ code after
forking, and with ART those places are implementation-defined. For
example, in app zygotes, ART turns out to insert "interpreter frames"
in the stack trace. Returning into these interpreter frames may lead
to crashes due to failing the ROP protection check on return.
It seems better to reset keys on thread creation instead. We only need
to reset IA because only this key needs to be reset for reverse-edge
PAC, and resetting the other keys may be incompatible with future ABIs.
Chrome (and potentially other applications) has a sandbox that prevents
the use of the prctl, so we restrict its use to applications targeting
S and above.
Bug: 183024045
Change-Id: I1e6502a7d7df319d424e2b0f653aad9a343ae71b
This is the second or third time I've scratched my head wondering why
this destructor has no coverage. I was tempted to leave it in with a
comment saying it should never be called, but that seemed sillier than
just replacing it with an assertion.
Test: treehugger
Change-Id: I3442d9f8a391fae668e77c6888a4457ededee494
This works around buggy applications that read a few bytes past the
end of their allocation, which would otherwise cause a segfault with
the concurrent Scudo change that aligns large allocations to the right.
Because the implementation of
android_set_application_target_sdk_version() lives in the linker,
we need to introduce a hook so that libc is notified when the target
SDK version changes.
Bug: 181344545
Change-Id: Id4be6645b94fad3f64ae48afd16c0154f1de448f
Spotted while looking at our shiny new coverage numbers. Though how the
change that removed the code from this file without removing the file
made it through code review... Clearly I wasn't paying attention that
day!
Test: treehugger
Change-Id: Id61bb48bae60660d2e5ba9b26f00a68e51157c6d
__libc_init_scudo() calls directly into the allocator, bypassing the
normal guest to host transition in the native bridge. Therefore we
need to let the native bridge override it with a no-op.
Bug: 159352723
Change-Id: I642c7a058e483cc09335290f66b9c053150fca06
This is undefined behavior, but glibc and macOS are both lenient, and
someone hit this in the wild, so we may as well be lenient too. (The
only cost is that it's now slightly easier to write code that works on
everything except old versions of Android.)
Bug: https://issuetracker.google.com/180598400
Test: treehugger
Change-Id: Ia217169ea6283cc53f4fbf71e5abfa08356c2049
With this change we can report memory errors involving secondary
allocations. Update the existing crasher tests to also test
UAF/overflow/underflow on allocations with sizes sufficient to trigger
the secondary allocator.
Bug: 135772972
Change-Id: Ic8925c1f18621a8f272e26d5630e5d11d6d34d38
Introduces new heap-zero-init API. We've realised that it's better to be
able to individually control MTE and heap zero-init. Having
heap-zero-init not be controllable without affecting MTE affects our
ability to turn off heap-zero-init in zygote-forked applications.
Bug: 135772972
Test: On FVP: atest -s localhost:5555 malloc#zero_init \
Test: malloc#disable_mte heap_tagging_level
Change-Id: I8c6722502733259934c699f4f1269eaf1641a09f
scudo_malloc_* for fill contents in __libc_init_scudo calls scudo's
initializers. We haven't told Scudo whether we want MTE-capable (i.e.
mapped with PROT_MTE) size class regions yet, which happens in
SetDefaultHeapTaggingLevel. This can lead to inconsistent mappings,
where processes without ELF notes get the base region with PROT_MTE
(which is undesirable because the performance implications are not
known).
Make sure that scudo is informed of whether regions need to be mapped
PROT_MTE or not by hoising the tagging level up.
Bug: 135772972
Bug: 172365548
Test: On FVP - 'adb shell MEMTAG_OPTIONS=off sanitizer-status' should
have no PROT_MTE mappings (validation by looking for no 'mt' under
'VmFlags:' in /proc/smaps').
Change-Id: Idad64479c4a9459cb40dd211fe942437f8ca16fd
These are available from mallopt() now, and all callers have been
switched over.
Bug: http://b/135772972
Test: treehugger
Change-Id: I90c7a7573b261c27001a2dfd4589b23861ad613b
These were only available internally via android_mallopt(), but they're
likely to be needed by more code in future, so move them into mallopt().
This change leaves the android_mallopt() options for now, but I plan on
coming back to remove them after I've switched the handful of callers
over to mallopt() instead.
Bug: http://b/135772972
Test: treehugger
Change-Id: Ia154614069a7623c6aca85975a91e6a156f04759
These two options allow for ARM MTE to be enabled dynamically (instead
of at compile time via the ELF note). They are settable from a non-root
shell to allow device owners to test system binaries with MTE.
The following values may be set:
1. 'off' -> No MTE, uses TBI on compatible devices.
2. 'sync' -> SYNC MTE.
3. 'async' -> ASYNC MTE.
The following methods can be used to launch a process (sanitizer-status)
with configurable values:
1. adb shell MEMTAG_OPTIONS=async sanitizer-status
2. adb shell setprop arm64.memtag.process.sanitizer-status async && \
adb shell sanitizer-status
Note: The system server will require some special handing in the zygote
pre-fork to check the sysprops. The zygote should always have the ELF
note. TODO in a subsequent patch.
Bug: 135772972
Bug: 172365548
Test: Launching sanitizer-status above using both the settings.
Change-Id: Ic1dbf3985a3f23521ec86725ec482c8f6739c182
Now that the feature guarded by this flag has landed in Linux 5.10
we no longer need the flag, so we can remove it.
Bug: 135772972
Change-Id: I02fa50848cbd0486c23c8a229bb8f1ab5dd5a56f
I realize that we can probably clean up more of our half-forked code by
reusing the same *-compat.h headers we use for the clean upstream code,
but I'll come back and do that later.
Bug: http://b/177003648
Test: treehugger
Change-Id: I081255aaafd62718b85956c5502911a1cc80225d
Technically, std::atomic does not have an operator(). Previously, this
code was relying on an implicit behavior of our C++ standard library in
order to compile. When compiling this code against a different C++
standard library, I encountered a compiler error on these lines.
This CL makes the std::atomic load() operation explicit, makes it
clearer what this code is actually doing and makes it conform better to
the C++ standard library spec rather than a particular implmentation.
Change-Id: I7f255dffc0a3d8e07c973c18e9ba4098c4b5843e
Technically, C requires that all source files end with a newline. In
practice, most compilers will accept source files without a newline, but
it does trigger the -Wnewline-eof warning.
Change-Id: I64a92b82f4d5724cd8b45821cfd59eb3de39514b
Use a note in executables to specify
(none|sync|async) heap tagging level. To be extended with (heap x stack x
globals) in the future. A missing note disables all tagging.
Bug: b/135772972
Test: bionic-unit-tests (in a future change)
Change-Id: Iab145a922c7abe24cdce17323f9e0c1063cc1321
Soft-limits apps from calling bind() on NETLINK_ROUTE sockets, and
getting link info through getifaddrs(), while still allowing apps on the
allowlist to temporarily perform these actions.
This is different from existing behavior, where apps targeting an API
level < 30 were exempted from this restriction.
Actual enforcement will happen through SELinux (as is currently the
case for apps targeting API >= 30). This temporary change will then be
reverted.
If you arrived at this change due to an app showing unexpected behavior,
please file a bug at go/netlink-bug.
Bug: 170188668
Bug: 170214442
Test: Call bind() on NETLINK_ROUTE for an app on the allowlist.
Test: Call bind() on NETLINK_ROUTE for an app not on the allowlist.
Test: Call getifaddrs() for an app on the allowlist.
Test: Call getifaddrs() for an app not on the allowlist.
Test: Call bind() on a AF_UNIX socket with its protocol set to
NETLINK_ROUTE, confirm it can succeed.
Test: Verify that previously broken apps are no longer broken.
Change-Id: I8738f7912fdc816e0d30205557728ff9e84bf7e6
Revert "Updates CTS tests for MAC address restrictions."
Revert submission 1518603-soft-restrict-mac
Reason for revert: Missing type check
Reverted Changes:
I0488932de:Soft-enable MAC address restrictions with allowlis...
Idb9d940e4:Updates CTS tests for MAC address restrictions.
I9461f287e:Return anonymized MAC for apps targeting SDK < 30
Change-Id: I7e8e593518088ff5c8f6083b34e6966852475b9b
This was a little confusing because a quick glance suggested that
'err' was getting the value of getsockopt(), when actually it was
getting the result of the '<' operation. Since 'err' wasn't
being used, we clarify by just removing it altogether.
Test: TreeHugger
Change-Id: I1ff80812b460973e9d512a558623e0c44c2ecf09
Soft-limits apps from calling bind() on NETLINK_ROUTE sockets, and
getting link info through getifaddrs(), while still allowing apps on the
allowlist to temporarily perform these actions.
This is different from existing behavior, where apps targeting an API
level < 30 were exempted from this restriction.
Actual enforcement will happen through SELinux (as is currently the
case for apps targeting API >= 30). This temporary change will then be
reverted.
If you arrived at this change due to an app showing unexpected behavior,
please file a bug at go/netlink-bug.
Bug: 170188668
Bug: 170214442
Test: Call bind() on NETLINK_ROUTE for an app on the allowlist.
Test: Call bind() on NETLINK_ROUTE for an app not on the allowlist.
Test: Call getifaddrs() for an app on the allowlist.
Test: Call getifaddrs() for an app not on the allowlist.
Change-Id: I0488932deea2a7211e55a24bc33bfa3cfb16fba2
They're both obsolescent in POSIX.1-2008, and you really shouldn't be
using them, but since we can't actually delete them...
This change makes them both obey $TMPDIR if set, and fall back to
/data/local/tmp otherwise. That's as good as we've managed for anything
else such as tmpfile(3).
Also add some tests.
Bug: http://b/174682340
Test: treehugger
Change-Id: Ieef99dcc2062f84b2b7cbae046787fdfe975e772
We can sometimes fail to link a static executable because of
duplicate definitions of std::nothrow in bionic/libc/bionic/new.cpp
and external/libcxx/src/new.cpp. Fix it by making our definition
weak since it doesn't matter which one ends up being chosen.
Change-Id: Iec02ae89f4a3d2ffe298817240f404e54b109a52
aosp/1484976 introduced a breaking change where
DisableMemoryMitigations() now indiscriminately turns tagged pointers
off. When android_mallopt(M_DISABLE_MEMORY_MITIGATIONS) is called, the
correct behaviour is:
- In SYNC/ASYNC MTE mode -> disable all tagged pointers.
- If all tagged pointers are already disabled -> nop.
- If we're in TBI mode -> nop (keep the TBI mode as-is).
In order to do that we have to allow probing of the current heap tagging
mode. In order to prevent TOCTOU between GetHeapTaggingLevel() and
SetHeapTaggingLevel(), we expose a global mutex that should be held when
calling these functions.
Bug: 174263432
Test: atest CtsTaggingHostTestCases on Flame
Change-Id: Ia96f7269d542c9041270458806aee36766d2fbbb
Unnecessary include, and the file was deleted with upstream changes.
Bug: N/A
Test: cd external/gwp_asan && atest
Change-Id: Id8facff0c5e382aa639ce158b7b5862ce157aa25
- Make it apply to every thread, and thus remove the restriction
that it must be called while the program is single threaded.
- Make it change TCF0 itself (on all threads), instead of requiring
callers to do it themselves, which can be error prone.
And update all of the call sites.
Change the implementation of
android_mallopt(M_DISABLE_MEMORY_MITIGATIONS) to call
android_mallopt(M_SET_HEAP_TAGGING_LEVEL) internally. This avoids
crashes during startup that were observed when the two mallopts
updated TCF0 unaware of each other.
I wouldn't expect there to be any out-of-tree callers at this point,
but it's worth noting that the new interface is backwards compatible
with the old one because it strictly expands the set of situations in
which the API can be used (i.e. situations where there are multiple
threads running or where TCF0 hadn't been updated beforehand).
Bug: 135772972
Change-Id: I7746707898ff31ef2e0af01c4f55ba90b72bef51
259776d8ff
The original change was reverted due to InterfaceParamsTest failing.
This test has now been fixed in r.android.com/1498525.
The original change message is below.
Updates getifaddrs() to behave as if RTM_GETLINK requests are not
allowed for non-system apps. This is different from previous behavior,
where apps targeting an API level < 30 were exempted from this
restriction.
Actual enforcement happens in SELinux. This change:
- Soft-enables the behavior until SELinux changes are in place
- Prevents logspam from SELinux denials after they are in place
Bug: 170188668
Test: atest bionic-unit-tests-static
Test: atest NetworkInterfaceTest
Test: Connect to Wi-Fi network
Test: Call getifaddrs() directly from within an app.
Test: Call NetworkInterface#getNetworkInterfaces() from within an app.
Change-Id: Ia9f61819f8fdf878c0e67e57de7e893fb3b1c233
Revert "Enforce RTM_GETLINK restrictions on all 3p apps"
Revert "Updates tests for untrusted app MAC address restrictions"
Revert submission 1450615-mac-address-restrictions
Reason for revert: DroidMonitor: Potential culprit for Bug 173243616 - verifying through Forrest before revert submission. This is part of the standard investigation process, and does not mean your CL will be reverted
Reverted Changes:
I08c709b2b:Enforce RTM_GETLINK restrictions on all 3p apps
I95d124ae8:Soft-enables new MAC address restrictions.
I5392f8339:Updates tests for untrusted app MAC address restri...
I9d214c5d0:Return anonymized MAC for apps targeting SDK < 30
Change-Id: If09920b24370077d647d60cfda7fc0a110b77851
A constructor or destructor function with an integral priority is
placed in an .init_array or .fini_array section with the priority
suffixed to the section name:
- __attribute__((constructor)) ==> .init_array
- __attribute__((constructor(42))) ==> .init_array.42
The suffixed init/fini sections appear before the unsuffixed sections,
so the prioritized functions appeared before the __{INIT,FINI}_ARRAY__
symbols and were dropped when the symbols were used.
The (static) linker doesn't recognize priority suffixes on
.preinit_array.
This bug affected .init_array and .fini_array for static executables.
For dynamic executables, only .fini_array was affected, because
.init_array is handled by the dynamic loader instead, which uses
DT_INIT_ARRAY[SZ]. For DSOs, neither is affected, because the two
sections are only handled by the dynamic loader.
This patch also fixes a minor inconsistency where dynamic init/preinit
were passed argc/argv/envp, but static were not.
Bug: http://b/170983066
Test: bionic-unit-tests
Change-Id: I0fffa776e5d9bdb6f8af06b4c1af148236742fef
The functions now read /etc/group and /etc/passwd on host machines.
Android-specific IDs are not recognized in the host.
getpwent and getgrent are still not working though. They require a
bigger refactoring to sequentially advance in the database files.
Bug: 171718702
Test: run assemble_cvd in aosp_cf_arm64_phone
Change-Id: Ie8da382a467bbd0bffac7b4b8592cd871db80181
/system/bin/sh exists only on Android. When Bionic is built for the
host, use the standard /bin/sh.
Bug: 159685774
Test: run aosp_cf_arm64_phone on rockpi4
Change-Id: Idf4028c134abc128f203fc4d3be591f06b8fe8ff
When an array element is added or removed, make only the relevant page
writable, rather than the entire array. The entire array is still made
writable during recompaction and expansion.
This change fixes most of a large regression in __cxa_atexit runtime
(blueline, taskset 10, performance governor, 100000 registrations,
times are in seconds)
- Q: _Exit=0.292380, exit=0.626801
- R: _Exit=28.435082, exit=95.785110
- new: _Exit=0.352285, exit=0.713893
Test: bionic unit tests
Test: adb shell taskset 10 \
/data/benchmarktest64/bionic-spawn-benchmarks/bionic-spawn-benchmarks \
--benchmark_filter='atexit' \
--benchmark_display_aggregates_only=true \
--benchmark_repetitions=10
Bug: http://b/168043760
Change-Id: I88cc15c29c9890b422b7f621f29f98a03ca1f886
pthread_cond_pulse would unconditionally call futex, which meant that
a number of processes were spending a significant amount of time in
pthread_cond_broadcast and pthread_cond_signal when there were no
threads waiting on that pthread_cond_t.
This change adds a counter to the 64-bit pthread_cond_t struct and
only calls futex() in cases where there is a nonzero waiter count. The
32-bit pthread_cond_t is unchanged due to compatibility reasons.
Test: no pthread_cond_broadcast/signal stacks without try_to_wake_up
in SurfaceFlinger
bug: 168831708
Change-Id: I105e1345cd2a3a75f98cd0acf316e790ba1716f0
Introduce an android_mallopt(M_DISABLE_MEMORY_MITIGATIONS) API call
that may be used to disable zero- or pattern-init on non-MTE hardware,
or memory tagging on MTE hardware. The intent is that this function
may be called at any time, including when there are multiple threads
running.
Disabling zero- or pattern-init is quite trivial, we just need to set
a global variable to 0 via a Scudo API call (although there will be
some separate work required on the Scudo side to make this operation
thread-safe).
It is a bit more tricky to disable MTE across a process, because
the kernel does not provide an API for disabling tag checking in all
threads in a process, only per-thread. We need to send a signal to each
of the process's threads with a handler that issues the required prctl
call, and lock thread creation for the duration of the API call to
avoid races between thread enumeration and calls to pthread_create().
Bug: 135772972
Change-Id: I81ece86ace916eb6b435ab516cd431ec4b48a3bf
Updates getifaddrs() to behave as if RTM_GETLINK requests are not
allowed for non-system apps. This is different from previous behavior,
where apps targeting an API level < 30 were exempted from this
restriction.
Actual enforcement happens in SELinux. This change:
- Soft-enables the behavior until SELinux changes are in place
- Prevents logspam from SELinux denials after they are in place
Bug: 170188668
Test: atest bionic-unit-tests-static
Test: atest NetworkInterfaceTest
Test: Connect to Wi-Fi network
Test: Call getifaddrs() directly from within an app.
Test: Call NetworkInterface#getNetworkInterfaces() from within an app.
Change-Id: I95d124ae81bcb26583db5ad01d95d441d52f973c
In native build of libc it would be inlined and in native bridge mode
it's noinline, extern "C" and thus could be easily intercepted.
Test: m (without weak symbols in native bridge mode x86+arm build would be broken)
Change-Id: I67759858a5bc2174dce1db9732fdbd89ba7689cc
This is already covered by the existing test by virtue of being used for
all threads.
Bug: http://b/168258494
Test: treehugger
Change-Id: I5c872fd7f30a4c79de1d70e7702f4b12d4e94cd3
Some global static variables are only used within a single function,
so moving them inside the function which requires them. This also
ensures those static variables of class types are initialized before
they are being used.
For example, this is needed for CachedProperty(), as some of the
member method, e.g., CachedProperty().Get(), might be invoked,
e.g., in __libc_preinit(), before the constructor is invoked.
This happens after we added property trace points in commit
Id2b93acb2ce02b308c0e4889f836159151af3b46.
For g_lock, we don't move them because it can be initialized by setting
its memory to 0. And it's used in two functions.
https://android.googlesource.com/platform/bionic/+/refs/heads/master/libc/private/bionic_lock.h
Bug: 147275573
Test: atest CtsBionicTestCases
Test: adb shell perfetto -o /data/misc/perfetto-traces/test_trace -t 10s bionic sysprop
Change-Id: I99565ce2442d34f33830778915c737eed834f8b3
Introducing a new systrace tag, TRACE_TAG_SYSPROP, for use with
system property.
For property set, the tracing is added in __system_property_set() instead of
__system_property_update() / __system_property_add() so we can record
control properties like ctl.*, sys.powerctl.*, etc.., which won't be
updated via the latter two functions.
Bug: 147275573
Test: atest CtsBionicTestCases
Test: adb shell perfetto -o /data/misc/perfetto-traces/test_trace -t 10s bionic
Test: adb shell perfetto -o /data/misc/perfetto-traces/test_trace -t 10s sysprop
Test: adb shell /data/benchmarktest64/bionic-benchmarks/bionic-benchmarks \
--benchmark_filter=BM_property --bionic_cpu=4, then compares the results
of property benchmarks before and after the change, didn't see
significant difference.
Change-Id: Id2b93acb2ce02b308c0e4889f836159151af3b46
Merged-In: Id2b93acb2ce02b308c0e4889f836159151af3b46
(cherry picked from commit 26970c3493)
Mostly from extra test cases, but also:
* Move the fgets size < 0 assertion into fgets.
* Use ELF aliases for strtoq/strtouq rather than duplicating code.
* Don't check uname() succeeded, since it can't fail.
Test: treehugger
Change-Id: I2e6b3b88b0a3eb16bd68be68b9bc9f40d8043291
(Based on proposal at https://sourceware.org/glibc/wiki/ThreadPropertiesAPI)
This includes API to:
- locate static and dynamic TLS
- register thread-exit and dynamic TLS creation/destruction callbacks
Change-Id: Icd9d29a5b2f47495395645e19d3b2c96826f19c8
Now we're being marked down for our poor coverage, we may as well remove
more broken cruft. Despite the amount of effort that seems to have gone
into pututline(), it wasn't working with the other utmp.h functions (in
particular, utmpname()), and wasn't declared in the header file!
Test: treehugger
Change-Id: I1a583984189c751168c11c01431433f96f8c548b
Similar to the musl strstr. This patch also increases test coverage for
memmem, again similar to the strstr tests.
Test: treehugger
Change-Id: I7f4a2ab93a610cb692994d06d2512976e657ae9f
For vanity reasons, this CL should be reverted after b/158870657, since
we want to make sure zero/pattern fill always happen when they are
requested.
Bug: 131355925
Bug: 158870657
Test: check build on normal devices hits USE_SCUDO branch with #error
Change-Id: I22d19dbc75004c8f7437e1247226bc3275cd4df5
This was initially just to try on "pty" and "tty" for size, while
discussing with other projects to try to align on vocabulary, but -- in
the implemention and tests at least -- but these work out so well that
I'm tempted to go with them anyway if we can't come to a concensus. We
can always come back and change them again later.
What I really like is that you pass the pty to functions like ptsname()
and grantpt() with a 'p' in the name, and the tty to functions like
ttyname() and tcsetattr() with just 't's.
The use of "parent" and "child" in forkpty() seems helpful too.
Also fix the documentation of forkpty(), which wasn't quite right.
Test: treehugger
Change-Id: Ic010c4b669f6528591c653e3701f4e41e0d0df9e
Normally, getifaddrs() gets its information about interface flags from
RTM_NEWLINK messages. With the ability for non-system apps to send
RTM_GETLINK messages going away, resolve these flags by performing a
SIOCGIFFLAGS ioctl call instead.
This fixes a bug where the flags were erroneously copied over from an
ifaddrmsg's ifa_flags.
Bug: 141455849
Test: atest bionic-unit-tests-static
Test: Connect to wireless network.
Test: Call getifaddrs() from a non-system app targeting API R+, verify
that the interface flags are correct.
Change-Id: I552f3b9d21072f59ee6f0890f47cb1bdf3cfcf20
As scudo is now the default native allocator, there is no need to
keep this library around.
Test: Builds and walleye boots.
Change-Id: Id2918544651348854956d1348d2a634f6425b952
Merged-In: Id2918544651348854956d1348d2a634f6425b952
(cherry picked from commit 941ad56299)
This means that execle() doesn't have to drag in all the path code and
shell script special case code from its relatives, for branches that
will never be taken. Specifically, it means that they disappear from the
monstrously large linker binary after this change.
A drop in the ocean of bloat, yes, but you have to start somewhere.
Bug: http://b/25200716
Test: treehugger, objdump
Change-Id: I21126823d869cee07bf7320bc0a65ea2aaee65a1
We are removing native bridge copy of fork.cpp, but need to
replace call to clone() when it's done for bionic's fork.
The code here will run all pre-/post-clone routines for *guest*,
while native bridge implementation will need to run the
corresponding *host* routines.
Bug: 145028007
Test: bionic-unit-tests
Change-Id: Ic5524e743caa287d7aaa8dc7e5d34acd1c7e1170
clock_gettime() with known arguments can't fail (and we ignore its
return value in most other places already).
Test: treehugger
Change-Id: I2374ae5ba1598a01d4c4f689b9c75c4e7dc926b6
Add SCUDO_OPTIONS to the list of the environment variables that should
not be preserved across a security boundary.
Bug: 157484128
Test: Builds and boots.
Change-Id: Id8644608114ad2fd49baedbdbbe1c899768bd54d
Ensure we don't call sigchain's sigaction64 from bionic's sigaction by
extracting sigaction64 to a static function.
Test: treehugger
Change-Id: I16226c6ac580ece7000c335beb1d3b76429d2a06
It turns out that we weren't actually enabling stack traces due
to a typo in one of the if statements. Fix it.
Bug: 135772972
Change-Id: Ic19352280f65acd621b9d88c361c55680b3327f0
Our various fd debugging facilities get extremely confused by a vforked
process closing file descriptors in preparation to exec: fdsan can
abort, and fdtrack will delete backtraces for any file descriptors that
get closed. Keep track of whether we're in a vforked child in order to
be able to detect this.
Bug: http://b/153926671
Test: 32/64-bit bionic-unit-tests on blueline, x86_64 emulator
Change-Id: I8a082fd06bfdfef0e2a88dbce350b6f667f7df9f
The SYNC tagging level enables stack trace collection for allocations and
deallocations, which allows allocation and deallocation stack traces to
appear in tombstones when encountering a tag check fault in synchronous tag
checking mode.
Bug: 135772972
Change-Id: Ibda9f51b29d2c8e2c993fc74425dea7bfa23ab1e
Some applications may incorrectly assume that a "negative" pointer
indicates error. By setting the top bit in TBI mode, we catch these
cases as well. Although they don't directly indicate incompatibility
with MTE (as MTE uses the 2nd-highest nibble) - this ensures we catch
HWASan errors as well as reserve the bits for future MTE expansion.
Bug: 154272452
Test: Boot flame, device boots successfully.
Change-Id: I94a6821a82ce7ead59e6ca2dd113a5a50ee9e56b
This also removes the ScopedSignalBlocker, which doesn't seem to have
made any sense since threads were invented.
Test: treehugger
Change-Id: I9a323ab4a0b43f14fd5d1f0df1f80184aef63770
1) "fix the system properties design" is written for the old protocol,
so we've already changed the design. There are no other further
planned changes.
2) "don't drag in all the macros, just the types." is not likely to
happen or be particularly impactful.
3) "Find a location suitable for these functions ..." is refering to
legacy code. More likely that this code will be removed before we
find a serious reason to fix this TODO.
4) "(73062966) We still don't have a good way ..." is stale; we fixed
this bug and added the appropriate mechanism.
Test: n/a
Change-Id: I23991692cdeb81ad00844a6a1680900ff384208b
These solves the issue that targetting non-profilable apps crashed them.
There is still a race condition between starting the app and the SIG_IGN
being installed, but that will be fixed in follow-ups.
This also does not cover programs that statically link libc, but those are
rare.
This might be reverted if we find a more general solution to
b/151835887.
Bug: 151328035
Test: java profile sysui, doesn't crash
Test: atest CtsBionicTestCases
Change-Id: I6b99352ed50afe15a609f7ddb85312c2676ddf11
POSIX added these GNU extensions for issue 8.
I've made these always inline without the usual "until API level X"
proviso because they're single instructions that the compiler can inline
and there's really no point providing these if they add function call
overhead --- everyone should just use __builtin_ffs() and friends
instead in that case.
Bug: https://austingroupbugs.net/view.php?id=617
Test: treehugger
Change-Id: I33fc4b8648ea25917329e81c1b4c60eb9a66d667
The double hooking is currently controlled by two separate atomic
booleans. In this state, it is very hard to guard against very subtle
race conditions. Adding an explicit enum to encode the state makes it
easier to reason about the behaviour of the program.
Also introduce a MaybeModifyGlobals to consistently guard accesses to
globals. We would sometimes modify them without swapping the
gGlobalsMutating, introducing a window for race with
HandleHeapprofdSignal.
Test: while true; do atest HeapprofdCtsTest; done
Test: flash blueline and manually test profile
Bug: 150741354
Change-Id: I77102b0bd906b8ec2d6806bd43ba6cbf7191e37c
Simplify:
- Use a single memory-mapped region to hold the table of destructors.
Double its capacity each time it is expanded.
- Add a recompaction pass at the end of __cxa_finalize that shifts
entries forward and uses madvise to clean pages.
Bug: http://b/148055738
Test: bionic-unit-tests
Change-Id: Ieb9da2b88640a8a5277d217b43826b5b7e246781
Bug: 137795072
Test: Built using jemalloc, and verified that the two processes that
Test: use libc_scudo do not crash.
Change-Id: Icf773b656d7e2bcdf41b4979e9b6cd980b02d34d
When the heapprofd lazy-initialization dispatch table is installed, two
threads can call malloc() at the same time. One will do the
lazy-initialization, the other will fail the atomic_exchange of
gHeapprofdInitHookInstalled and go to system malloc. The system malloc
still contains the lazy-init malloc, and will recurse.
Fix it so the second thread goes directly to the previous dispatch
table, or to the system allocator directly (instead of through libc
malloc()).
Bug: 150085813
Test: atest perfetto_integrationtests
Test: TracedPerfCtsTest.SystemWideDebuggableApp on cuttlefish x86.
Change-Id: Ia85ad619a0d5e3f558136d84c34dbada4e8b845d
The values of some constants have changed, and the tag mask has changed from
being an exclusion mask to an inclusion mask.
Bug: 135772972
Change-Id: I322fceae7003bee6b391e7187194ed4c0cb28c58
If an alternate signal stack is set and the frame record is in bounds of
that stack, we need to use the top of the alternate signal stack for bounds
checking rather than the normal stack.
Bug: 150215618
Change-Id: I78b760d61b27da44f8e0cfee3fe94a791011fe58
To prevent unnecessary SELinux denials, the check referred to by the
comment is kept in place. This allows us to keep auditing the
SELinux denial in order to catch apps that intentionally send
RTM_GETLINK messages.
Fix: 141455849
Test: atest bionic-unit-tests-static
Test: atest NetworkInterfaceTest
Change-Id: I41e5ad6f071c820a8246177a0c629b3be788a942
Heapprofd uses an ephemeral dispatch table to ensure that GWP-ASan can
be called during heapprofd initialization. Previously, we grabbed the
backup dispatch table from the globals, which is wrong if GWP-ASan isn't
installed (as the malloc_dispatch_table is linker-initialised and not
set to a known good value if a malloc hooker isn't used).
Instead, grab the correct ephemeral dispatch table. When GWP-ASan is
installed, use a copy of its table as the dispatch. When nothing is
installed, fall back to using the native allocator dispatch.
Bug: 135634846
Bug: 150085813
Test: atest perfetto_integrationtests
Test: TracedPerfCtsTest.SystemWideDebuggableApp on cuttlefish x86.
Change-Id: I4beaf9192acadbe00adc02de2e0b0aab6f7a2190
This is a best-effort mitigation for potential crashes when the
profiling signal handler is triggered within certain secomp'd processes.
In particular, we're working around cases where the seccomp policy
doesn't allow some of the handler syscalls, and has a crashing
disposition towards violations via SECCOMP_RET_TRAP, plus a crashing
SIGSYS handler. While not general, this covers the configurations seen
in practice on Android (which are all using minijail in the same way).
By overriding the SIGSYS handling for the duration of the profiling
handler, we can instead receive such SIGSYS signals, and instead recover
from them in a non-crashing manner (the handler is responsible for
filling the syscall return register, since the syscall itself was
skipped).
For simplicity, we're swallowing all SIGSYS signals during this window,
without trying to figure out whether they're something that could be
caused by the profiling signal handler. I've quite convinced myself that
-ENOSYS seems to be safe to return to all of bionic's syscall wrappers
across the four architectures (looking at gensyscalls + the
special-cases like vfork and clone). It is theoretically possible for
all kinds of conflicting (ab)uses of SIGSYS to exist, but I'm assuming
it's not a realistic concern until proven otherwise.
Tested: manually sigqueue'd configstore on crosshatch, confirmed that
the SIGSYS override log was printed, and the process did not
crash (as it does on master).
Bug: 149328505
Change-Id: Iab8f09e51169807c9d3e1e0bcfd042f09f7df6a4
For interfaces that didn't get their name set, try to resolve their name
using if_indextoname first, before removing them from the list.
This allows getifaddrs() to keep returning interfaces that only have an
IPv6 address set (as opposed to the previous behavior where only
interfaces with an IPv4 address would be returned).
Change-Id: I0e4e6611948b12794cd3e354538f2964fbf31078
Fix: 148886805
Bug: 141455849
Test: atest NetworkInterfaceTest
Test: atest bionic-unit-tests-static
Test: atest IpSecManagerTunnelTest
The tag level may now be async, which is now the default. When the tag level
is set to none, memory tagging is disabled in the allocator using the new
API proposed in https://reviews.llvm.org/D70762 .
Bug: 135772972
Change-Id: I847f5822a70913c446ed9ffa13792177bbfc96af
Current APEX Namespace is named with APEX name itself, which also uses
.(dot) so linker configuration can keep the syntax safe.
For example, if there are APEX modules named 'A' and 'A.link.A', then
'namespace.A.link.A.link.A = a.so' phrase can be ambiguous from the
linker. To allow any additional linker syntax in the future, we should
avoid dot separator from the namespace name.
Bug: 148826508
Test: m -j passed
Test: boot succeeded from cuttlefish and walleye
Change-Id: Ic3fe396aef6366fc6c7a0677bc7f92a57fd4e229
Exports GWP-ASan allocator information callbacks to libdebuggerd so that
tombstoned can get information from the GWP-ASan allocator in the case
of a crash.
Bug: 135634846
Test: atest bionic-unit-tests
Change-Id: Ie16426af55602fb2a76c4e69217773354c365843
The notification that GWP-ASan is enabled causes ART tests to break.
Remove the log for now.
Bug: 135634846
Bug: 149790891
Test: (Attempt to fix the ART tests).
Change-Id: I8a7751a838a64f160b3b7b9f07752bb64644b9db
This patch enables GWP-ASan with process sampling.
**Note**: If you are visiting this patch because this broke a test or
otherwise is causing failures, please contact mitchp@ directly (or
respond to this patchset). GWP-ASan is designed to cause heap-based
memory safety bugs to manifest in SEGV on a sampled basis.
Bug: 135634846
Test: atest bionic-unit-tests gwp_asan_unittest
Change-Id: I58ca9373def105fdd718cf283482b3220b770698
GWP-ASan + heapprofd don't currently play nice together in some
circumstances. heapprofd thinks it's still an only child, and refuses to
accept the existence of its little brother, GWP-ASan.
If GWP-ASan is installed before heapprofd, then heapprofd is *required*
to respect that libc has a favourite child. If an allocation/free is passed
to heapprofd, then heapprofd *must* (eventually) pass that allocation/free to
GWP-ASan. If heapprofd doesn't do this, then a free() of a GWP-ASan
allocation can be passed to the system allocator.
This can happen in two places right now:
1. The heapprofd hooks simply clobber any trace of what was
previously in the default_dispatch_table when enabled through the
heapprofd signal.
2. Heapprofd can die when the system is under significant pressure.
Some pipes can timeout, which ends up in the client calling ShutdownLazy()
-> mallopt(M_RESET_HOOKS) -> DispatchReset(). This also clobbers any
trace of the previous default_dispatch_table.
To fix both these problems, we fix heapprofd to restore the previous
default_dispatch_table whenever either circumstance happens. We do some
tricky copying to avoid race conditions on the malloc_dispatch_table in
fixing #1.
Bug: 135634846
Test: Run HeapprofdEndToEnd.NativeProfilingActiveAtProcessExit/ForkMode
a significant number of times with large amounts of system pressure (I
just run bionic-unit-tests-scudo in parallel). You will see some test
failures where heapprofd died due to system pressure, but never a death
from the allocator. Tests should never fail when the system isn't under
immense pressure.
Change-Id: I20ab340d4bdc35d6d1012da5ee1a25634428d097
When enabled, GWP-ASan sets the current dispatch table. Then, when a
shim layer (malloc_debug, malloc_hooks, heapprofd) comes along, they
should (by design) overwrite the current dispatch table.
Currently, these shim layers check to see whether malloc_limit is
installed by checking the current dispatch table against nullptr.
Because GWP-ASan owns the current dispatch table, the shim thinks that
malloc_limit is installed and falls back to only use the default
dispatch, thinking that malloc_limit will call them. This is not the
case, and they should take over the current dispatch pointer.
Bug: 135634846
Test: atest bionic
Change-Id: Ifb6f8864a15af9ac7f20d9364c40f73c5dd9d870
The WriteProtected mutator for __libc_globals isn't reentrant.
Previously we were calling __libc_globals.mutate() inside of GWP-ASan's
libc initialisation, which is called inside the __libc_globals.mutate().
This causes problems with malloc_debug and other malloc shims, as they
fail to install when GWP-ASan is sampling their processes.
Bug: 135634846
Test: atest bionic
Change-Id: Iae51faa8d78677eeab6204b6ab4f3ae1b7517ba5
Scudo still isn't quite at the same RSS as jemalloc for the svelte config
so only enable this for normal config.
Bug: 137795072
Test: Built svelte config and verified it is still jemalloc.
Test: Ran performance tests on normal config (bionic benchmarks).
Test: Ran trace tests (system/extras/memory_replay).
Test: Ran scudo unit tests.
Test: Ran bionic unit tests.
Test: Ran libmemunreachable tests.
Test: Ran atest CtsRsBlasTestCases on cuttlefish.
Test: Ran atest AslrMallocTest.
Test: Ran atest CtsHiddenApiKillswitchWildcardTestCases and verified it has
Test: the same runtime as the jemalloc.
Change-Id: I241165feb8fe9ea814b7b166e3aaa6563d18524a
This patch introduces GWP-ASan - a sampled allocator framework that
finds use-after-free and heap-buffer-overflow bugs in production
environments.
GWP-ASan is being introduced in an always-disabled mode. This means that
GWP-ASan will be permanently disabled until a further patch turns on
support. As such, there should be no visible functional change for the
time being.
GWP-ASan requires -fno-emulated-tls wherever it's linked from. We
intentionally link GWP-ASan into libc so that it's part of the initial
set of libraries, and thus has static TLS storage (so we can use
Initial-Exec TLS instead of Global-Dynamic). As a benefit, this reduces
overhead for a sampled process.
GWP-ASan is always initialised via. a call to
mallopt(M_INITIALIZE_GWP_ASAN, which must be done before a process is
multithreaded).
More information about GWP-ASan can be found in the upstream
documentation: http://llvm.org/docs/GwpAsan.html
Bug: 135634846
Test: atest bionic
Change-Id: Ib9bd33337d17dab39ac32f4536bff71bd23498b0
tracefs will be mounted at /sys/kernel/tracing when debugfs
is not mounted.
Bug: 134669095
Test: atest bionic-unit-tests-static
Change-Id: Ic224cf13500efc570da8b6a27ce925bbcf068fdd
For consistency, linker namespace for apex modules use its apex name
instead of hard-coded short name.
Bug: 148826508
Test: m / boot
Change-Id: I4bf565cd528d744fc42841fd2d9f8bf652d4d346
We've optimized the ctype functions to the point where they're pretty
much all down to one instruction. This change takes the obvious next
step of just inlining them.
On Android these function have only ever been for ASCII. You need the
<wctype.h> functions for non-ASCII.
libc++ currently has its own inlines for the _l variants, so if we want
to just inline them in bionic directly, we'll need to coordinate that.
Bug: http://b/144165498
Test: treehugger plus benchmarks
Change-Id: I4cc8aa96f7994ae710a562cfc9d4f220ab7babd6
This function will be used by Scudo and GWP-ASan to efficiently collect
stack traces for frames built with frame pointers.
Bug: 135634846
Bug: 135772972
Change-Id: Ic63efdbafe11dfbb1226b5b4b403d53c4dbf28f3
Merged-In: Ic63efdbafe11dfbb1226b5b4b403d53c4dbf28f3
Add a hook that's called upon file descriptor creation to libc, and a
library that uses it to capture backtraces for file descriptor creation,
to make it easier to hunt down file descriptor leaks.
Currently, this doesn't capture all of the ways of creating a file
descriptor, but completeness isn't required for this to be useful as
long as leaked file descriptors are created with a function that is
tracked. The primary unhandled case is binder, which receives file
descriptors as a payload in a not-trivially-parsable byte blob, but
there's a chance that the leak we're currently trying to track down
isn't of a file descriptor received over binder, so leave that for
later.
Bug: http://b/140703823
Test: manual
Change-Id: I308a14c2e234cdba4207157b634ab6b8bc539dd9
(cherry picked from commit b7eccd4b15)