Search code examples
gcc

gcc -fsanitize=address results in an endless loop on program that does nothing


gcc version

gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0

system type

Linux pop-os 6.6.6-76060606-generic #202312111032~1702306143~22.04~d28ffec SMP PREEMPT_DYNAMIC Mon D x86_64 x86_64 x86_64 GNU/Linux

gcc options

-Wall -Werror -pedantic -fsanitize=address

command line

gcc -Wall -Werror -pedantic -fsanitize=address main.c

libraries linked to

  • linux-vdso.so.1
  • libasan.so.6 => /lib/x86_64-linux-gnu/libasan.so.6
  • libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6
  • libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6
  • libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1
  • /lib64/ld-linux-x86-64.so.2

contents of main.c

int main(void) {}

When the resulting a.out is run, I get an endless loop of: AddressSanitizer:DEADLYSIGNAL

However, it only happens some of the time. For example, it almost always runs 5 times in a row fine, but then after that it starts to break.


Solution

  • The issue is caused by an increase of the default value of vm.mmap_rnd_bits:

    This value can be used to select the number of bits to use to determine the random offset to the base address of vma regions resulting from mmap allocations on architectures which support tuning address space randomization. This value will be bounded by the architecture's minimum and maximum supported values.

    On some operating systems like Arch, this value was recently bumped to 32, while ASAN only supports a maximum of 28 randomized bits (30 with some recent, not-yet-released fixes).

    Setting the value to 28 will fix the issue: sudo sysctl -w vm.mmap_rnd_bits=28

    See https://github.com/google/sanitizers/issues/1716 for the related discussion.