Skip to content

excessive stack usage with kernel address sanitizer #38157

Open
@arndb

Description

@arndb
mannequin
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() {

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions