LCOV - code coverage report
Current view: top level - util/sanitize - fd_asan.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 2 4 50.0 %
Date: 2024-11-13 11:58:15 Functions: 4 2532 0.2 %

          Line data    Source code
       1             : #ifndef HEADER_fd_src_util_sanitize_fd_asan_h
       2             : #define HEADER_fd_src_util_sanitize_fd_asan_h
       3             : 
       4             : #include "../fd_util_base.h"
       5             : 
       6             : /* AddressSanitizer (ASan) tracks allocated memory regions and
       7             :    instruments all memory accesses to detect possible out-of-bounds
       8             :    errors.
       9             : 
      10             :    This API is used to mark memory regions at runtime where default ASan
      11             :    instrumentation is missing.  Firedancer objects are mainly backed by
      12             :    shared memory segments via huge pages managed by a custom memory
      13             :    allocator.
      14             : 
      15             :    More info on ASan:
      16             :      - https://clang.llvm.org/docs/AddressSanitizer.html
      17             :      - https://github.com/google/sanitizers/wiki/AddressSanitizer
      18             : 
      19             :    For a guide on how to setup manual ASan memory poisoning, see
      20             :    https://github.com/google/sanitizers/wiki/AddressSanitizerManualPoisoning */
      21             : 
      22             : /* Based on https://github.com/llvm/llvm-project/blob/main/compiler-rt/include/sanitizer/asan_interface.h
      23             : 
      24             :    Part of the LLVM Project, under the Apache License v2.0 with LLVM
      25             :    Exceptions.  See https://llvm.org/LICENSE.txt for license
      26             :    information.  SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      27             : 
      28             :    This file was originally part of AddressSanitizer (ASan). */
      29             : 
      30             : #ifndef FD_HAS_ASAN
      31             : #if defined(__has_feature)
      32             : #define FD_HAS_ASAN __has_feature(address_sanitizer)
      33             : #elif defined(__SANITIZE_ADDRESS__)
      34             : #define FD_HAS_ASAN 1
      35             : #else
      36             : #define FD_HAS_ASAN 0
      37             : #endif
      38             : #endif
      39             : 
      40             : /* FD_FN_NO_ASAN is a function attribute to disable ASan instrumentation
      41             :    when FD_HAS_ASAN is set (and expands to nothing if not). */
      42             : 
      43             : #if FD_HAS_ASAN
      44             : #define FD_FN_NO_ASAN __attribute__((no_sanitize("address")))
      45             : #else
      46             : #define FD_FN_NO_ASAN
      47             : #endif
      48             : 
      49             : FD_PROTOTYPES_BEGIN
      50             : 
      51             : /* If FD_HAS_ASAN is set:
      52             : 
      53             :    fd_asan_poison marks a memory region `[addr,addr+sz)` as
      54             :    unaddressable and returns addr.  This memory must be previously
      55             :    allocated by your program.  Instrumented code is forbidden from
      56             :    accessing addresses in this region until it is unpoisoned.  This
      57             :    function is not guaranteed to poison the entire region; it might
      58             :    poison only a sub-region of `[addr,addr+sz)` due to ASan alignment
      59             :    restrictions.
      60             : 
      61             :    fd_asan_unpoison marks a memory region `[addr,addr+sz)` as
      62             :    addressable and returns addr.  This memory must be previously
      63             :    allocated by your program.  Accessing addresses in this region is
      64             :    allowed until this region is poisoned again.  This function might
      65             :    unpoison a super-region of `[addr,addr+sz)` due to ASan alignment
      66             :    restrictions.
      67             : 
      68             :    fd_asan_test tests if an address is poisoned.  Returns 1 if addr is
      69             :    poisoned (that is, a 1-byte read/write access to this address would
      70             :    result in an error report from ASan).  Otherwise returns 0.
      71             : 
      72             :    fd_asan_query checks if a region is poisoned.  If at least one byte
      73             :    in `[addr,addr+sz)` is poisoned, returns the address of the first
      74             :    such byte.  Otherwise returns NULL.
      75             : 
      76             :    If FD_HAS_ASAN is not set fd_asan_{poison,unpoison} just return addr,
      77             :    fd_asan_test returns 0 and fd_asan_query returns NULL.
      78             : 
      79             :    FIXME: CONST CORRECT VERSIONS? */
      80             : 
      81             : #ifdef FD_HAS_DEEPASAN
      82             : #define FD_ASAN_ALIGN (8UL)
      83             : #endif 
      84             : 
      85             : #if FD_HAS_ASAN
      86             : 
      87             : /* These are for internal use only */
      88             : 
      89             : void   __asan_poison_memory_region  ( void const volatile * addr, ulong sz );
      90             : void   __asan_unpoison_memory_region( void const volatile * addr, ulong sz );
      91             : int    __asan_address_is_poisoned   ( void const volatile * addr           );
      92             : void * __asan_region_is_poisoned    ( void *                addr, ulong sz );
      93             : 
      94             : static inline void * fd_asan_poison  ( void * addr, ulong sz ) { __asan_poison_memory_region  ( addr, sz ); return addr; }
      95             : static inline void * fd_asan_unpoison( void * addr, ulong sz ) { __asan_unpoison_memory_region( addr, sz ); return addr; }
      96             : static inline int    fd_asan_test    ( void * addr           ) { return __asan_address_is_poisoned( addr );     }
      97             : static inline void * fd_asan_query   ( void * addr, ulong sz ) { return __asan_region_is_poisoned ( addr, sz ); }
      98             : 
      99             : #else
     100             : 
     101           9 : static inline void * fd_asan_poison  ( void * addr, ulong sz ) { (void)sz;             return addr; }
     102           9 : static inline void * fd_asan_unpoison( void * addr, ulong sz ) { (void)sz;             return addr; }
     103           0 : static inline int    fd_asan_test    ( void * addr           ) { (void)addr;           return 0;    }
     104           0 : static inline void * fd_asan_query   ( void * addr, ulong sz ) { (void)addr; (void)sz; return NULL; }
     105             : 
     106             : #endif
     107             : 
     108             : FD_PROTOTYPES_END
     109             : 
     110             : #endif /* HEADER_fd_src_util_sanitize_fd_asan_h */

Generated by: LCOV version 1.14