llvm/llvm-project

Stack-overflow as a result of stack exhaustion in function `assign()`

Open

#121,952 opened on 2025年1月7日

GitHub で見る
 (10 comments) (0 reactions) (0 assignees)C++ (10,782 forks)batch import
clang:frontendcompiler-rt:asancrash-on-invalidgenerated by fuzzergood first issue

Repository metrics

Stars
 (26,378 stars)
PR merge metrics
 (平均マージ 1d 2h) (30d で 1,000 merged PRs)

説明

Description

While testing the clang-fuzzer fuzzing harness with ASan enabled, we found a stack-overflow, which appears to be caused by stack exhaustion in a recursion starting from the function ParsePostfixExpressionSuffix(). The actual overflow then happens in the function __asan_memset(), called from the function lvm::SmallVectorImpl::assign().

The bug does not reproduce outside the ASan build, and doubling the stack size through ulimit allows the ASan build to not detect the issue as well. Given these limitations, we were not sure whether or not we should report this potential bug; we decided to be conservative and report it, and we kindly ask you to confirm whether or not we should report bugs like this in the future.

To Reproduce

Attached to this report, you will find the testcase we used to trigger this bug. Simply run it with an ASan-compiled version of the clang-fuzzer harness. To compile the harness, we used the OSS-Fuzz default building system, with AFL++ as fuzzing engine and the --sanitizer=address flag to enable ASan.

ASan output


Running LLVMFuzzerInitialize ...
continue...
Reading 25029 bytes from /data/asan/d7f462176af1574931ca1d5efb42174cbd220b30
AddressSanitizer:DEADLYSIGNAL
=================================================================
==158==ERROR: AddressSanitizer: stack-overflow on address 0x7ffc426e0cf8 (pc 0x5e082cc6cf75 bp 0x7ffc426e1530 sp 0x7ffc426e0d00 T0)
    #0 0x5e082cc6cf75 in __asan_memset /src/llvm-project/compiler-rt/lib/asan/asan_interceptors_memintrinsics.cpp:67:3
    #1 0x5e0834a244bc in unsigned long* std::__1::__uninitialized_fill_n[abi:nn180100]<unsigned long, unsigned long*, unsigned long, unsigned long>(unsigned long*, unsigned long, unsigned long const&) /usr/local/bin/../include/c++/v1/__memory/uninitialized_algorithms.h:155:7
    #2 0x5e0834a244bc in unsigned long* std::__1::uninitialized_fill_n[abi:nn180100]<unsigned long*, unsigned long, unsigned long>(unsigned long*, unsigned long, unsigned long const&) /usr/local/bin/../include/c++/v1/__memory/uninitialized_algorithms.h:170:10
    #3 0x5e0834a244bc in llvm::SmallVectorImpl<unsigned long>::assign(unsigned long, unsigned long) /src/llvm-project/llvm/include/llvm/ADT/SmallVector.h:714:7
…

    #271 0x5e08329e59ad in clang::Parser::ParseCastExpression(clang::Parser::CastParseKind, bool, bool&, clang::Parser::TypeCastState, bool, bool*) /src/llvm-project/clang/lib/Parse/ParseExpr.cpp:1944:9
    #272 0x5e08329d3c17 in clang::Parser::ParseCastExpression(clang::Parser::CastParseKind, bool, clang::Parser::TypeCastState, bool, bool*) /src/llvm-project/clang/lib/Parse/ParseExpr.cpp:710:20
    #273 0x5e08329d3c17 in clang::Parser::ParseRHSOfBinaryExpression(clang::ActionResult<clang::Expr*, true>, clang::prec::Level) /src/llvm-project/clang/lib/Parse/ParseExpr.cpp:575:13
    #274 0x5e08329d1ad0 in clang::Parser::ParseAssignmentExpression(clang::Parser::TypeCastState) /src/llvm-project/clang/lib/Parse/ParseExpr.cpp:187:10
    #275 0x5e08329d177b in clang::Parser::ParseExpression(clang::Parser::TypeCastState) /src/llvm-project/clang/lib/Parse/ParseExpr.cpp:135:18
    #276 0x5e0832c1a70f in clang::Parser::ParseExprStatement(clang::Parser::ParsedStmtContext) /src/llvm-project/clang/lib/Parse/ParseStmt.cpp:564:19
    #277 0x5e0832c0fb97 in clang::Parser::ParseStatementOrDeclarationAfterAttributes(llvm::SmallVector<clang::Stmt*, 32u>&, clang::Parser::ParsedStmtContext, clang::SourceLocation*, clang::ParsedAttributes&, clang::ParsedAttributes&) /src/llvm-project/clang/lib/Parse/ParseStmt.cpp:293:14
    #278 0x5e0832c0d818 in clang::Parser::ParseStatementOrDeclaration(llvm::SmallVector<clang::Stmt*, 32u>&, clang::Parser::ParsedStmtContext, clang::SourceLocation*) /src/llvm-project/clang/lib/Parse/ParseStmt.cpp:125:20
    #279 0x5e0832c3869f in clang::Parser::ParseCompoundStatementBody(bool) /src/llvm-project/clang/lib/Parse/ParseStmt.cpp:1267:11
    #280 0x5e0832a01ace in clang::Parser::ParseBlockLiteralExpression() /src/llvm-project/clang/lib/Parse/ParseExpr.cpp:3891:19
    #281 0x5e08329e3a09 in clang::Parser::ParseCastExpression(clang::Parser::CastParseKind, bool, bool&, clang::Parser::TypeCastState, bool, bool*) /src/llvm-project/clang/lib/Parse/ParseExpr.cpp:1847:11
    #282 0x5e08329d3c17 in clang::Parser::ParseCastExpression(clang::Parser::CastParseKind, bool, clang::Parser::TypeCastState, bool, bool*) /src/llvm-project/clang/lib/Parse/ParseExpr.cpp:710:20
    #283 0x5e08329d3c17 in clang::Parser::ParseRHSOfBinaryExpression(clang::ActionResult<clang::Expr*, true>, clang::prec::Level) /src/llvm-project/clang/lib/Parse/ParseExpr.cpp:575:13
    #284 0x5e08329d1ad0 in clang::Parser::ParseAssignmentExpression(clang::Parser::TypeCastState) /src/llvm-project/clang/lib/Parse/ParseExpr.cpp:187:10
    #285 0x5e0832a0286c in clang::Parser::ParseExpressionList(llvm::SmallVectorImpl<clang::Expr*>&, llvm::function_ref<void ()>, bool, bool, bool*) /src/llvm-project/clang/lib/Parse/ParseExpr.cpp:3684:14
    #286 0x5e08329daab0 in clang::Parser::ParsePostfixExpressionSuffix(clang::ActionResult<clang::Expr*, true>) /src/llvm-project/clang/lib/Parse/ParseExpr.cpp:2203:27

SUMMARY: AddressSanitizer: stack-overflow /src/llvm-project/llvm/include/llvm/ADT/SmallVector.h:714:7 in llvm::SmallVectorImpl<unsigned long>::assign(unsigned long, unsigned long)
==158==ABORTING

コントリビューターガイド