checkedc / checkedc-llvm-project

This was a fork of Checked C clang used from 2021-2024. The changes have been merged into the original Checked C clang repo, which is now at https://github.com/checkedc/checkedc-clang.
https://www.checkedc.org
13 stars 19 forks source link

Minimalized code based on Linux kernel file `init/do_mounts.c` that causes clang to crash #1220

Closed souragc closed 10 months ago

souragc commented 11 months ago

Code:

# 1 "<built-in>"
# 1 "./crash.c"
void foo()
{
        int *a = ({0;});
        int *b = ({0;});
}

Command to reproduce

# Crash reproducer for clang version 12.0.0 (https://github.com/checkedc/checkedc-llvm-project.git 9d329e1130ccab7bc045722a3c911da273459293)
# Driver args: "-c" "./crash.c"
# Original command:  "/home/sourag/Desktop/checkedc/checkedc-llvm-project/build/bin/clang-12" "-cc1" "-triple" "x86_64-unknown-linux-gnu" "-emit-obj" "-mrelax-all" "--mrelax-relocations" "-disable-free" "-main-file-name" "crash.c" "-mrelocation-model" "static" "-mframe-pointer=all" "-fmath-errno" "-fno-rounding-math" "-mconstructor-aliases" "-munwind-tables" "-target-cpu" "x86-64" "-tune-cpu" "generic" "-fno-split-dwarf-inlining" "-debugger-tuning=gdb" "-resource-dir" "/home/sourag/Desktop/checkedc/checkedc-llvm-project/build/lib/clang/12.0.0" "-internal-isystem" "/usr/local/include" "-internal-isystem" "/home/sourag/Desktop/checkedc/checkedc-llvm-project/build/lib/clang/12.0.0/include" "-internal-externc-isystem" "/usr/include/x86_64-linux-gnu" "-internal-externc-isystem" "/include" "-internal-externc-isystem" "/usr/include" "-fdebug-compilation-dir" "/home/sourag/Desktop/kernel/linux-6.6" "-ferror-limit" "19" "-fgnuc-version=4.2.1" "-fcolor-diagnostics" "-faddrsig" "-o" "crash.o" "-x" "c" "./crash.c"
 "/home/sourag/Desktop/checkedc/checkedc-llvm-project/build/bin/clang-12" "-cc1" "-triple" "x86_64-unknown-linux-gnu" "-emit-obj" "-mrelax-all" "--mrelax-relocations" "-disable-free" "-main-file-name" "crash.c" "-mrelocation-model" "static" "-mframe-pointer=all" "-fmath-errno" "-fno-rounding-math" "-mconstructor-aliases" "-munwind-tables" "-target-cpu" "x86-64" "-tune-cpu" "generic" "-fno-split-dwarf-inlining" "-debugger-tuning=gdb" "-ferror-limit" "19" "-fgnuc-version=4.2.1" "-fcolor-diagnostics" "-faddrsig" "-x" "c" "crash-2b8e0c.c"
dtarditi commented 10 months ago

This code uses statement expressions, which is a GCC extension to C. This was never an officially supported C extension for Checked C, although the compiler does attempt to compile the code. The compiler support is only partly done and not well-tested.

A statement expression is an expression that wraps a compound block. The specific bug is at line 499 in CanonBounds.cpp, which is doing lexicographic comparison of expressions. The code assumes that the children of all expressions in the AST are also expressions. For statement expressions, this assumption is violated. The child node of a statement expression is a statement.

We can improve he support more so to avoid this crash. Statement expressions should not be appearing in bounds expression, so we should not even be reaching the code doing a lexicographic comparison. The likely fix is to mark all statement expressions as modifying expressions, even though this particular example isn't a modifying expression. We likely should look at what kinds of bounds are being inferred for statement expressions also.