Cheng Shao pushed to branch wip/terrorjack/asan at Glasgow Haskell Compiler / GHC

Commits:

10 changed files:

Changes:

  • hadrian/doc/flavours.md
    ... ... @@ -242,6 +242,10 @@ The supported transformers are listed below:
    242 242
             <td><code>ubsan</code></td>
    
    243 243
             <td>Build all stage1+ C/C++ code with UndefinedBehaviorSanitizer support</td>
    
    244 244
         </tr>
    
    245
    +    <tr>
    
    246
    +        <td><code>asan</code></td>
    
    247
    +        <td>Build all stage1+ C/C++ code with AddressSanitizer support</td>
    
    248
    +    </tr>
    
    245 249
         <tr>
    
    246 250
             <td><code>llvm</code></td>
    
    247 251
             <td>Use GHC's LLVM backend (`-fllvm`) for all stage1+ compilation.</td>
    

  • hadrian/src/Flavour.hs
    ... ... @@ -8,6 +8,7 @@ module Flavour
    8 8
       , splitSections
    
    9 9
       , enableThreadSanitizer
    
    10 10
       , enableUBSan
    
    11
    +  , enableASan
    
    11 12
       , enableLateCCS
    
    12 13
       , enableHashUnitIds
    
    13 14
       , enableDebugInfo, enableTickyGhc
    
    ... ... @@ -56,6 +57,7 @@ flavourTransformers = M.fromList
    56 57
         , "thread_sanitizer" =: enableThreadSanitizer False
    
    57 58
         , "thread_sanitizer_cmm" =: enableThreadSanitizer True
    
    58 59
         , "ubsan"            =: enableUBSan
    
    60
    +    , "asan"             =: enableASan
    
    59 61
         , "llvm"             =: viaLlvmBackend
    
    60 62
         , "profiled_ghc"     =: enableProfiledGhc
    
    61 63
         , "no_dynamic_ghc"   =: disableDynamicGhcPrograms
    
    ... ... @@ -303,6 +305,28 @@ enableUBSan =
    303 305
               builder Testsuite ? arg "--config=have_ubsan=True"
    
    304 306
             ]
    
    305 307
     
    
    308
    +-- | Build all stage1+ C/C++ code with AddressSanitizer support:
    
    309
    +-- https://clang.llvm.org/docs/AddressSanitizer.html
    
    310
    +enableASan :: Flavour -> Flavour
    
    311
    +enableASan =
    
    312
    +  addArgs $
    
    313
    +    notStage0
    
    314
    +      ? mconcat
    
    315
    +        [ package rts
    
    316
    +            ? builder (Cabal Flags)
    
    317
    +            ? arg "+asan"
    
    318
    +            <> (needSharedLibSAN ? arg "+shared-libsan"),
    
    319
    +          builder (Ghc CompileHs) ? arg "-optc-fsanitize=address",
    
    320
    +          builder (Ghc CompileCWithGhc) ? arg "-optc-fsanitize=address",
    
    321
    +          builder (Ghc CompileCppWithGhc) ? arg "-optcxx-fsanitize=address",
    
    322
    +          builder (Ghc LinkHs)
    
    323
    +            ? arg "-optc-fsanitize=address"
    
    324
    +            <> arg "-optl-fsanitize=address"
    
    325
    +            <> (needSharedLibSAN ? arg "-optl-shared-libsan"),
    
    326
    +          builder (Cc CompileC) ? arg "-fsanitize=address",
    
    327
    +          builder Testsuite ? arg "--config=have_asan=True"
    
    328
    +        ]
    
    329
    +
    
    306 330
     -- | Use the LLVM backend in stages 1 and later.
    
    307 331
     viaLlvmBackend :: Flavour -> Flavour
    
    308 332
     viaLlvmBackend = addArgs $ notStage0 ? builder Ghc ? arg "-fllvm"
    

  • rts/.ubsan-suppressions
    1
    +# libraries/bytestring/cbits/is-valid-utf8.c:66:14: runtime load of misaligned address 0x7ae45206f112 for type 'const uint64_t *' (aka 'const unsigned long *'), which requires 8 byte alignment
    
    2
    +alignment:libraries/bytestring/cbits/is-valid-utf8.c
    
    3
    +
    
    1 4
     # libraries/text/cbits/measure_off.c:50:39: runtime left shift of 1 by 31 places cannot be represented in type 'int'
    
    2 5
     shift-base:libraries/text/cbits/measure_off.c
    
    3 6
     
    

  • rts/include/Stg.h
    ... ... @@ -335,6 +335,7 @@ external prototype return neither of these types to workaround #11395.
    335 335
     #include "stg/MachRegsForHost.h"
    
    336 336
     #include "stg/Regs.h"
    
    337 337
     #include "stg/Ticky.h"
    
    338
    +#include "rts/ASANUtils.h"
    
    338 339
     #include "rts/TSANUtils.h"
    
    339 340
     
    
    340 341
     #if IN_STG_CODE
    

  • rts/include/rts/ASANUtils.h
    1
    +#pragma once
    
    2
    +
    
    3
    +#if defined(__SANITIZE_ADDRESS__)
    
    4
    +#define ASAN_ENABLED
    
    5
    +#elif defined(__has_feature)
    
    6
    +#if __has_feature(address_sanitizer)
    
    7
    +#define ASAN_ENABLED
    
    8
    +#endif
    
    9
    +#endif
    
    10
    +
    
    11
    +#if defined(ASAN_ENABLED)
    
    12
    +#include <sanitizer/asan_interface.h>
    
    13
    +#define USED_IF_ASAN
    
    14
    +#else
    
    15
    +#include <stdlib.h>
    
    16
    +#define USED_IF_ASAN __attribute__((unused))
    
    17
    +#endif
    
    18
    +
    
    19
    +static inline void
    
    20
    +__ghc_asan_poison_memory_region(void const volatile *addr USED_IF_ASAN,
    
    21
    +                                size_t size USED_IF_ASAN) {
    
    22
    +#if defined(ASAN_ENABLED)
    
    23
    +  __asan_poison_memory_region(addr, size);
    
    24
    +#endif
    
    25
    +}
    
    26
    +
    
    27
    +static inline void
    
    28
    +__ghc_asan_unpoison_memory_region(void const volatile *addr USED_IF_ASAN,
    
    29
    +                                  size_t size USED_IF_ASAN) {
    
    30
    +#if defined(ASAN_ENABLED)
    
    31
    +  __asan_unpoison_memory_region(addr, size);
    
    32
    +#endif
    
    33
    +}

  • rts/rts.cabal
    ... ... @@ -97,6 +97,12 @@ flag ubsan
    97 97
         UndefinedBehaviorSanitizer.
    
    98 98
       default: False
    
    99 99
       manual: True
    
    100
    +flag asan
    
    101
    +  description:
    
    102
    +    Link with -fsanitize=address, to be enabled when building with
    
    103
    +    AddressSanitizer.
    
    104
    +  default: False
    
    105
    +  manual: True
    
    100 106
     flag shared-libsan
    
    101 107
       description:
    
    102 108
         Link with -shared-libsan, to guarantee only one copy of the
    
    ... ... @@ -216,6 +222,9 @@ library
    216 222
           if flag(ubsan)
    
    217 223
             ld-options: -fsanitize=undefined
    
    218 224
     
    
    225
    +      if flag(asan)
    
    226
    +        ld-options: -fsanitize=address
    
    227
    +
    
    219 228
           if flag(shared-libsan)
    
    220 229
             ld-options: -shared-libsan
    
    221 230
     
    
    ... ... @@ -280,6 +289,7 @@ library
    280 289
                             -- ^ generated
    
    281 290
                             rts/ghc_ffi.h
    
    282 291
                             rts/Adjustor.h
    
    292
    +                        rts/ASANUtils.h
    
    283 293
                             rts/ExecPage.h
    
    284 294
                             rts/BlockSignals.h
    
    285 295
                             rts/Bytecodes.h
    

  • rts/sm/MBlock.c
    ... ... @@ -579,6 +579,8 @@ getMBlocks(uint32_t n)
    579 579
     
    
    580 580
         ret = getCommittedMBlocks(n);
    
    581 581
     
    
    582
    +    __ghc_asan_unpoison_memory_region(ret, (W_)n * MBLOCK_SIZE);
    
    583
    +
    
    582 584
         debugTrace(DEBUG_gc, "allocated %d megablock(s) at %p",n,ret);
    
    583 585
     
    
    584 586
         mblocks_allocated += n;
    
    ... ... @@ -611,6 +613,8 @@ freeMBlocks(void *addr, uint32_t n)
    611 613
     
    
    612 614
         mblocks_allocated -= n;
    
    613 615
     
    
    616
    +    __ghc_asan_poison_memory_region(addr, (W_)n * MBLOCK_SIZE);
    
    617
    +
    
    614 618
         decommitMBlocks(addr, n);
    
    615 619
     }
    
    616 620
     
    

  • testsuite/driver/testglobals.py
    ... ... @@ -189,6 +189,9 @@ class TestConfig:
    189 189
             # Are we running with UndefinedBehaviorSanitizer enabled?
    
    190 190
             self.have_ubsan = False
    
    191 191
     
    
    192
    +        # Are we running with AddressSanitizer enabled?
    
    193
    +        self.have_asan = False
    
    194
    +
    
    192 195
             # Do symbols use leading underscores?
    
    193 196
             self.leading_underscore = False
    
    194 197
     
    

  • testsuite/driver/testlib.py
    ... ... @@ -1093,6 +1093,9 @@ def have_thread_sanitizer( ) -> bool:
    1093 1093
     def have_ubsan( ) -> bool:
    
    1094 1094
         return config.have_ubsan
    
    1095 1095
     
    
    1096
    +def have_asan( ) -> bool:
    
    1097
    +    return config.have_asan
    
    1098
    +
    
    1096 1099
     def gcc_as_cmmp() -> bool:
    
    1097 1100
         return config.cmm_cpp_is_gcc
    
    1098 1101
     
    

  • testsuite/tests/rts/T18623/all.T
    ... ... @@ -8,6 +8,8 @@ test('T18623',
    8 8
          # Recent versions of osx report an error when running `ulimit -v`
    
    9 9
          when(opsys('darwin'), skip),
    
    10 10
          when(arch('powerpc64le'), skip),
    
    11
    +     # ASan can't allocate shadow memory
    
    12
    +     when(have_asan(), skip),
    
    11 13
          cmd_prefix('ulimit -v ' + str(8 * 1024 ** 2) + ' && '),
    
    12 14
          ignore_stdout],
    
    13 15
         run_command,