ASLR entropy导致的TSan报错

写操作系统lab的时候遇到的问题。

在Ubuntu22.04下用自带的gcc11.4.0编译如下极其简单绝对不可能有问题的C代码

1
int main() {}

用指令gcc -Wall -Wextra -Werror -fsanitize=address -o test test.c

然后不停地去跑./test ,大概十次左右就能见到一次这样的bug输出

1
2
3
4
5
6
7
8
    ...
    AddressSanitizer:DEADLYSIGNAL
    AddressSanitizer:DEADLYSIGNAL
    AddressSanitizer:DEADLYSIGNAL
    AddressSanitizer:DEADLYSIGNAL
    AddressSanitizer:DEADLYSIGNAL
    AddressSanitizer:DEADLYSIGNAL
    ...

目前试了三个环境,只有Ubuntu22.04会这样

1
2
3
22.04: 6.5.0-26-generic #26~22.04.1-Ubuntu, gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0
18.04: 5.4.0-152-generic #169~18.04.1-Ubuntu, gcc (Ubuntu 11.4.0-2ubuntu1~18.04) 11.4.0
kali: 5.15.0-102-generic #112-Ubuntu, gcc (Debian 13.2.0-13) 13.2.0

另外,把18.04编译出来的可执行文件移到22.04上跑,也会一样出这个bug

非常正式地做了一个解释~

Problem

Even a program like that will also meet the problem:

1
    int main() {}

After running gcc -Wall -Wextra -Werror -fsanitize=address -o test test.c, I repeatedly run ./test. And occasionally, AddressSanitizer:DEADLYSIGNAL is printed repeatedly.

The executable binary is the same, while it behaves differently.

1
2
3
4
5
    ...
    AddressSanitizer:DEADLYSIGNAL
    AddressSanitizer:DEADLYSIGNAL
    AddressSanitizer:DEADLYSIGNAL
    ...

Environment

In Ubuntu22.04, it occurs 1 time when I run about 10 times. In Ubuntu18.04, I run 50 times but the bug does not occur even once. In kali-rolling 2024.1, I run 50 times but the bug does not occur even once.

I move the executable \textbf{test} generated by 18.04 to 22.04, it runs. And the bug of repeating AddressSanitizer:DEADLYSIGNAL also occurs! Holy shit!

Solution

If I run setarch 'uname -m' -R ./test, the bug is fixed. This command mainly disable ASLR(Address Space Layout Randomization). Command cat /proc/sys/kernel/randomize_va_space can check if ASLR is running by default. 18.04 ,22.04 and kali all returned 2, which means is fully working.

Command sudo sysctl vm.mmap_rnd_bits can check the number of bits of entropy for address space layout randomization. 18.04 and kali returns 28 and 22.04 returns 32.

If I run sudo sysctl vm.mmap_rnd_bits=32 in 18.04, then run ./test, the bug exists in 18.04.

If I run sudo sysctl vm.mmap_rnd_bits=28 in 22.04, then run ./test, the bug disappears in 22.04.

Why

Due to https://bugs.launchpad.net/ubuntu/+source/linux/+bug/2056762 and Thread Sanitizer FATAL error on kernel version 6.6.6-x · Issue #1716 · google/sanitizers · GitHub, it is because TSan(ThreadSanitizer) only supports 28 or 30 bits(depends on its version) of ASLR entropy. While in the new version of Ubuntu, the default setting is changed from 28 to 32, which caused this bug to occur. High entropy ASLR will allocate memory to some address that TSan believes illegal, so it returns the error. And as the memory allocation is random, so the bug just occurs occasionally.

Brilliant!