Skip to content

Latest commit

 

History

History
110 lines (93 loc) · 7.73 KB

dependencies.md

File metadata and controls

110 lines (93 loc) · 7.73 KB

Dependencies

GWPSan was co-designed along with necessary compiler and OS kernel support. Development of the runtime informed new compiler and kernel support, which we developed and upstreamed to LLVM and the Linux kernel.

Other platforms that do not meet the below requirements are unsupported.

Compiler Support

To perform certain detailed runtime binary analysis on an otherwise unmodified binary, semantic metadata is required that is lost when generating machine code. For example, data race detection requires knowledge of atomic accesses to avoid false positives. For deployment in production, however, this metadata needs to be stored in the binary and needs to be accessible efficiently at runtime: the presence of the metadata should not affect performance of the binary unless it is accessed, and overall binary size should be minimally Impacted. We implemented support in the LLVM Compiler Infrastructure.

The implementation consists of a new middle-end pass, and backend pass, which rely on PC Sections Metadata (LLVM RFC) to emit the metadata into separate ELF binary sections.

Currently we store PC-keyed metadata for atomic operations and functions suitable for use-after-return detection. But other types of metadata can be added in future if required (for example, signed int operations that are subject for overflow checking, or fixed-array indexing for the purposes of out-of-bounds checking).

Also see the runtime implementation that parses and makes the PC-keyed metadata queryable.

Clang 18 or later includes all the above changes, which can be enabled with -fexperimental-sanitize-metadata. Some earlier versions of Clang already support -fexperimental-sanitize-metadata, but do not include optimizations and necessary fixes. Since the compiler support is still marked experimental, the runtime does not support earlier versions of the metadata (but we detect if an older version is present and fail initialization).

Linux Kernel Support

Several new features, performance optimizations, and fixes were contributed to the Linux kernel to support GWPSan and similar use cases.

Efficient process-wide hardware breakpoint and watchpoint support. Prior to these changes, each thread would have had to create its own PERF_TYPE_BREAKPOINT perf event. Manually managing perf events of all running threads would have been too slow and complex in heavily multi-threaded applications. See runtime implementation here.

  1. perf: Rework perf_event_exit_event()
  2. perf: Apply PERF_EVENT_IOC_MODIFY_ATTRIBUTES to children
  3. perf: Support only inheriting events if cloned with CLONE_THREAD
  4. perf: Add support for event removal on exec
  5. signal: Introduce TRAP_PERF si_code and si_perf to siginfo
  6. perf: Add support for SIGTRAP on perf events
  7. selftests/perf_events: Add kselftest for process-wide sigtrap handling
  8. selftests/perf_events: Add kselftest for remove_on_exec
  9. signal, perf: Fix siginfo_t by avoiding u64 on 32-bit architectures
  10. signal, perf: Add missing TRAP_PERF case in siginfo_layout()
  11. signal: Factor force_sig_perf out of perf_sigtrap
  12. signal: Deliver all of the siginfo perf data in _perf
  13. perf: Fix required permissions if sigtrap is requested
  14. perf: Ignore sigtrap for tracepoints destined for other tasks
  15. perf test sigtrap: Add basic stress test for sigtrap handling
  16. perf: Copy perf_event_attr::sig_data on modification
  17. signal: Deliver SIGTRAP on perf event asynchronously if blocked
  18. perf: Fix missing SIGTRAPs
  19. perf: Improve missing SIGTRAP checking
  20. perf: Fix perf_pending_task() UaF

Optimizing breakpoint accounting in the kernel. Prior to these changes, enabling/disabling breakpoints had noticeable performance impact on systems with high CPU counts. These changes did not change the kernel ABI, but prior to these changes we do not recommend enabling GWPSan.

  1. perf/hw_breakpoint: Add KUnit test for constraints accounting
  2. perf/hw_breakpoint: Provide hw_breakpoint_is_used() and use in test
  3. perf/hw_breakpoint: Clean up headers
  4. perf/hw_breakpoint: Optimize list of per-task breakpoints
  5. perf/hw_breakpoint: Mark data __ro_after_init
  6. perf/hw_breakpoint: Optimize constant number of breakpoint slots
  7. perf/hw_breakpoint: Make hw_breakpoint_weight() inlinable
  8. perf/hw_breakpoint: Remove useless code related to flexible breakpoints
  9. powerpc/hw_breakpoint: Avoid relying on caller synchronization
  10. locking/percpu-rwsem: Add percpu_is_write_locked() and percpu_is_read_locked()
  11. perf/hw_breakpoint: Reduce contention with large number of tasks
  12. perf/hw_breakpoint: Introduce bp_slots_histogram
  13. perf/hw_breakpoint: Optimize max_bp_pinned_slots() for CPU-independent task targets
  14. perf/hw_breakpoint: Optimize toggle_bp_slot() for CPU-independent task targets
  15. perf, hw_breakpoint: Fix use-after-free if perf_event_open() fails
  16. perf/hw_breakpoint: Annotate tsk->perf_event_mutex vs ctx->mutex

Low-overhead POSIX timer based sampling. Prior to this change, the kernel would prefer the main thread to deliver the signal to, in which case the runtime would fallback to a slightly more expensive manual signal distribution algorithm. See runtime implementation here.

  1. posix-timers: Prefer delivery of signals to the current thread

Linux kernel 6.4 or later includes all the above changes.