Description
Bugzilla Link | 38809 |
Version | unspecified |
OS | Linux |
Blocks | #4440 |
Attachments | linux/drivers/video/backlight/ltv350qv.c, preprocessed, reduced |
CC | @KernelAddress,@melver,@eugenis,@kcc,@lalozano,@maxim-kuvyrkov,@nathanchance,@nickdesaulniers,@rengolin,@stephenhines |
Extended Description
Building the Linux kernel with clang KASAN enabled shows many warnings about possible stack overflow (we limit the frame size per function to 1024 to 2048 byte, depending on configuration, because the per-thread stack is very limited).
I created a reduced test case from one of the scarier warnings:
$ clang-8 ltv350qv.c --target=aarch64-linux-gnu -c -O2 -Wframe-larger-than=500 -fsanitize=kernel-address -Wall -Wno-unused -Wno-sometimes-uninitialized -Werror -mllvm -asan-stack=1 -mllvm -asan-use-after-scope=0
ltv350qv.c:181:6: error: stack frame size of 1760 bytes in function 'fn6' [-Werror,-Wframe-larger-than=]
void fn6() {
^
ltv350qv.c:209:6: error: stack frame size of 10048 bytes in function 'fn7' [-Werror,-Wframe-larger-than=]
void fn7() {
I tested this using clang-8.0.0-svn341106-1exp1+020180830200353.1747~1.gbp19b9f6 on Ubuntu, but an old clang-3.9 shows the same behavior.
With gcc, the same function is fine with "asan-use-after-scope" disabled:
$ aarch-linux-gcc-8.0.1 -xc ltv350qv.c -S -O2 -Wframe-larger-than=100 -fsanitize=kernel-address -Wall -Wno-unused -Wno-attributes -fno-strict-aliasing --param asan-stack=1 -Werror -fno-sanitize-address-use-after-scope
ltv350qv.c: In function 'fn5':
ltv350qv.c:180:1: error: the frame size of 448 bytes is larger than 100 bytes [-Werror=frame-larger-than=]
}
^
ltv350qv.c: In function 'fn6':
ltv350qv.c:208:1: error: the frame size of 512 bytes is larger than 100 bytes [-Werror=frame-larger-than=]
}
^
cc1: all warnings being treated as errors
but turning on asan-use-after-scope makes gcc as bad as clang, which is expected from the source code (the kernel turns it off by default for this reason):
ltv350qv.c: In function 'fn5':
ltv350qv.c:180:1: error: the frame size of 10000 bytes is larger than 100 bytes [-Werror=frame-larger-than=]
}
^
ltv350qv.c: In function 'fn6':
ltv350qv.c:208:1: error: the frame size of 1984 bytes is larger than 100 bytes [-Werror=frame-larger-than=]
}
Using -fsantize=address in place of -fsanitize=kernel-address completely avoids the high stack usage with clang, even with asan-use-after-scope enabled:
$ clang-8 ltv350qv.c --target=aarch64-linux-gnu -c -O2 -Wframe-larger-than=64 -fsanitize=address -Wall -Wno-unused -Wno-sometimes-uninitialized -Werror -mllvm -asan-stack=1 -mllvm -asan-use-after-scope=1
ltv350qv.c:181:6: error: stack frame size of 96 bytes in function 'fn6' [-Werror,-Wframe-larger-than=]
void fn6() {
^
ltv350qv.c:209:6: error: stack frame size of 96 bytes in function 'fn7' [-Werror,-Wframe-larger-than=]
void fn7() {