Mitch Phillips 35b5499d72 Reland: [GWP-ASan] Add recoverable mode.
The GWP-ASan recoverable mode allows a process to continue to function
after a GWP-ASan error is detected. The error will continue to be
dumped, but GWP-ASan now has APIs that a signal handler (like the
example optional crash handler) can call in order to allow the
continuation of a process.

When an error occurs with an allocation, the slot used for that
allocation will be permanently disabled. This means that free() of that
pointer is a no-op, and use-after-frees will succeed (writing and
reading the data present in the page).

For heap-buffer-overflow/underflow, the guard page is marked as accessible
and buffer-overflows will succeed (writing and reading the data present
in the now-accessible guard page). This does impact adjacent
allocations, buffer-underflow and buffer-overflows from adjacent
allocations will no longer touch an inaccessible guard page. This could
be improved in future by having two guard pages between each adjacent
allocation, but that's out of scope of this patch.

Each allocation only ever has a single error report generated. It's
whatever came first between invalid-free, double-free, use-after-free or
heap-buffer-overflow, but only one.

Reviewed By: eugenis, fmayer

Differential Revision: https://reviews.llvm.org/D140173
2023-01-17 10:21:01 -08:00

80 lines
3.9 KiB
C++

//===-- options.inc ---------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef GWP_ASAN_OPTION
#error "Define GWP_ASAN_OPTION prior to including this file!"
#endif
#ifndef GWP_ASAN_DEFAULT_ENABLED
#define GWP_ASAN_DEFAULT_ENABLED true
#endif
#ifndef GWP_ASAN_STRINGIFY
#define GWP_ASAN_STRINGIFY(S) GWP_ASAN_STRINGIFY_(S)
#define GWP_ASAN_STRINGIFY_(S) #S
#endif
GWP_ASAN_OPTION(bool, Enabled, GWP_ASAN_DEFAULT_ENABLED,
"Is GWP-ASan enabled? Defaults to " GWP_ASAN_STRINGIFY(
GWP_ASAN_DEFAULT_ENABLED) ".")
GWP_ASAN_OPTION(int, MaxSimultaneousAllocations, 16,
"Number of simultaneously-guarded allocations available in the "
"pool. Defaults to 16.")
GWP_ASAN_OPTION(int, SampleRate, 5000,
"The probability (1 / SampleRate) that an allocation is "
"selected for GWP-ASan sampling. Default is 5000. Sample rates "
"up to (2^30 - 1) are supported.")
// Developer note - This option is not actually processed by GWP-ASan itself. It
// is included here so that a user can specify whether they want signal handlers
// or not. The supporting allocator should inspect this value to see whether
// signal handlers need to be installed, and then use
// crash_handler::installSignalHandlers() in order to install the handlers. Note
// that in order to support signal handlers, you will need to link against the
// optional crash_handler component.
GWP_ASAN_OPTION(
bool, InstallSignalHandlers, true,
"Install GWP-ASan signal handlers for SIGSEGV during dynamic loading. This "
"allows better error reports by providing stack traces for allocation and "
"deallocation when reporting a memory error. GWP-ASan's signal handler "
"will forward the signal to any previously-installed handler, and user "
"programs that install further signal handlers should make sure they do "
"the same. Note, if the previously installed SIGSEGV handler is SIG_IGN, "
"we terminate the process after dumping the error report.")
GWP_ASAN_OPTION(
bool, Recoverable, false,
"Install GWP-ASan's signal handler in recoverable mode. This means that "
"upon GWP-ASan detecting an error, it'll print the error report, but *not* "
"crash. Only one crash per sampled allocation will ever be recorded, and "
"if a sampled allocation does actually cause a crash, it'll permanently "
"occupy a slot in the pool. The recoverable mode also means that "
"previously-installed signal handlers will only be triggered for "
"non-GWP-ASan errors, as all GWP-ASan errors won't be forwarded.")
GWP_ASAN_OPTION(bool, InstallForkHandlers, true,
"Install GWP-ASan atfork handlers to acquire internal locks "
"before fork and release them after.")
GWP_ASAN_OPTION(bool, help, false, "Print a summary of the available options.")
// =============================================================================
// ==== WARNING
// =============================================================================
// If you are adding flags to GWP-ASan, please note that GWP-ASan flag strings
// may be parsed by trusted system components (on Android, GWP-ASan flag strings
// are parsed by libc during the dynamic loader). This means that GWP-ASan
// should never feature flags like log paths on disk, because this can lead to
// arbitrary file write and thus privilege escalation. For an example, see the
// setuid ASan log_path exploits: https://www.exploit-db.com/exploits/46241.
//
// Please place all new flags above this warning, so that the warning always
// stays at the bottom.