https://github.com/melver created
https://github.com/llvm/llvm-project/pull/162484
A recent change adding a new sanitizer kind (via Sanitizer.defs) was reverted
in c74fa20c955b ("Revert "[Clang][CodeGen] Introduce the AllocToken
SanitizerKind" (#162413)"). The reason was this ASan report, when running the
test in clang/test/Preprocessor/print-header-json.c:
```
==clang==483265==ERROR: AddressSanitizer: heap-buffer-overflow on address
0x7d82b97e8b58 at pc 0x562cd432231f bp 0x7fff3fad0850 sp 0x7fff3fad0848
READ of size 16 at 0x7d82b97e8b58 thread T0
#0 0x562cd432231e in __copy_non_overlapping_range<const unsigned long *,
const unsigned long *>
zorg-test/libcxx_install_asan_ubsan/include/c++/v1/string:2144:38
#1 0x562cd432231e in void std::__1::basic_string<char,
std::__1::char_traits<char>,
std::__1::allocator<char>>::__init_with_size[abi:nn220000]<unsigned long
const*, unsigned long const*>(unsigned long const*, unsigned long const*,
unsigned long) zorg-test/libcxx_install_asan_ubsan/include/c++/v1/string:2685:18
#2 0x562cd41e2797 in __init<const unsigned long *, 0>
zorg-test/libcxx_install_asan_ubsan/include/c++/v1/string:2673:3
#3 0x562cd41e2797 in basic_string<const unsigned long *, 0>
zorg-test/libcxx_install_asan_ubsan/include/c++/v1/string:1174:5
#4 0x562cd41e2797 in
clang::ASTReader::ReadString(llvm::SmallVectorImpl<unsigned long> const&,
unsigned int&) clang/lib/Serialization/ASTReader.cpp:10171:15
#5 0x562cd41fd89a in
clang::ASTReader::ParseLanguageOptions(llvm::SmallVector<unsigned long, 64u>
const&, llvm::StringRef, bool, clang::ASTReaderListener&, bool)
clang/lib/Serialization/ASTReader.cpp:6475:28
#6 0x562cd41eea53 in
clang::ASTReader::ReadOptionsBlock(llvm::BitstreamCursor&, llvm::StringRef,
unsigned int, bool, clang::ASTReaderListener&, std::__1::basic_string<char,
std::__1::char_traits<char>, std::__1::allocator<char>>&)
clang/lib/Serialization/ASTReader.cpp:3069:11
#7 0x562cd4204ab8 in
clang::ASTReader::ReadControlBlock(clang::serialization::ModuleFile&,
llvm::SmallVectorImpl<clang::ASTReader::ImportedModule>&,
clang::serialization::ModuleFile const*, unsigned int)
clang/lib/Serialization/ASTReader.cpp:3249:15
#8 0x562cd42097d2 in clang::ASTReader::ReadASTCore(llvm::StringRef,
clang::serialization::ModuleKind, clang::SourceLocation,
clang::serialization::ModuleFile*,
llvm::SmallVectorImpl<clang::ASTReader::ImportedModule>&, long, long,
clang::ASTFileSignature, unsigned int)
clang/lib/Serialization/ASTReader.cpp:5182:15
#9 0x562cd421ec77 in clang::ASTReader::ReadAST(llvm::StringRef,
clang::serialization::ModuleKind, clang::SourceLocation, unsigned int,
clang::serialization::ModuleFile**)
clang/lib/Serialization/ASTReader.cpp:4828:11
#10 0x562cd3d07b74 in
clang::CompilerInstance::findOrCompileModuleAndReadAST(llvm::StringRef,
clang::SourceLocation, clang::SourceLocation, bool)
clang/lib/Frontend/CompilerInstance.cpp:1805:27
#11 0x562cd3d0b2ef in
clang::CompilerInstance::loadModule(clang::SourceLocation,
llvm::ArrayRef<clang::IdentifierLoc>, clang::Module::NameVisibilityKind, bool)
clang/lib/Frontend/CompilerInstance.cpp:1956:31
#12 0x562cdb04eb1c in
clang::Preprocessor::HandleHeaderIncludeOrImport(clang::SourceLocation,
clang::Token&, clang::Token&, clang::SourceLocation,
clang::detail::SearchDirIteratorImpl<true>, clang::FileEntry const*)
clang/lib/Lex/PPDirectives.cpp:2423:49
#13 0x562cdb042222 in
clang::Preprocessor::HandleIncludeDirective(clang::SourceLocation,
clang::Token&, clang::detail::SearchDirIteratorImpl<true>, clang::FileEntry
const*) clang/lib/Lex/PPDirectives.cpp:2101:17
#14 0x562cdb043366 in clang::Preprocessor::HandleDirective(clang::Token&)
clang/lib/Lex/PPDirectives.cpp:1338:14
#15 0x562cdafa84bc in clang::Lexer::LexTokenInternal(clang::Token&, bool)
clang/lib/Lex/Lexer.cpp:4512:7
#16 0x562cdaf9f20b in clang::Lexer::Lex(clang::Token&)
clang/lib/Lex/Lexer.cpp:3729:24
#17 0x562cdb0d4ffa in clang::Preprocessor::Lex(clang::Token&)
clang/lib/Lex/Preprocessor.cpp:896:11
#18 0x562cd77da950 in clang::ParseAST(clang::Sema&, bool, bool)
clang/lib/Parse/ParseAST.cpp:163:7
[...]
0x7d82b97e8b58 is located 0 bytes after 3288-byte region
[0x7d82b97e7e80,0x7d82b97e8b58)
allocated by thread T0 here:
#0 0x562cca76f604 in malloc
zorg-test/llvm-project/compiler-rt/lib/asan/asan_malloc_linux.cpp:67:3
#1 0x562cd1cce452 in safe_malloc llvm/include/llvm/Support/MemAlloc.h:26:18
#2 0x562cd1cce452 in llvm::SmallVectorBase<unsigned int>::grow_pod(void*,
unsigned long, unsigned long) llvm/lib/Support/SmallVector.cpp:151:15
#3 0x562cdbe1768b in grow_pod llvm/include/llvm/ADT/SmallVector.h:139:11
#4 0x562cdbe1768b in grow llvm/include/llvm/ADT/SmallVector.h:525:41
#5 0x562cdbe1768b in reserve llvm/include/llvm/ADT/SmallVector.h:665:13
#6 0x562cdbe1768b in llvm::BitstreamCursor::readRecord(unsigned int,
llvm::SmallVectorImpl<unsigned long>&, llvm::StringRef*)
llvm/lib/Bitstream/Reader/BitstreamReader.cpp:230:10
#7 0x562cd41ee8ab in
clang::ASTReader::ReadOptionsBlock(llvm::BitstreamCursor&, llvm::StringRef,
unsigned int, bool, clang::ASTReaderListener&, std::__1::basic_string<char,
std::__1::char_traits<char>, std::__1::allocator<char>>&)
clang/lib/Serialization/ASTReader.cpp:3060:49
#8 0x562cd4204ab8 in
clang::ASTReader::ReadControlBlock(clang::serialization::ModuleFile&,
llvm::SmallVectorImpl<clang::ASTReader::ImportedModule>&,
clang::serialization::ModuleFile const*, unsigned int)
clang/lib/Serialization/ASTReader.cpp:3249:15
#9 0x562cd42097d2 in clang::ASTReader::ReadASTCore(llvm::StringRef,
clang::serialization::ModuleKind, clang::SourceLocation,
clang::serialization::ModuleFile*,
llvm::SmallVectorImpl<clang::ASTReader::ImportedModule>&, long, long,
clang::ASTFileSignature, unsigned int)
clang/lib/Serialization/ASTReader.cpp:5182:15
#10 0x562cd421ec77 in clang::ASTReader::ReadAST(llvm::StringRef,
clang::serialization::ModuleKind, clang::SourceLocation, unsigned int,
clang::serialization::ModuleFile**)
clang/lib/Serialization/ASTReader.cpp:4828:11
#11 0x562cd3d07b74 in
clang::CompilerInstance::findOrCompileModuleAndReadAST(llvm::StringRef,
clang::SourceLocation, clang::SourceLocation, bool)
clang/lib/Frontend/CompilerInstance.cpp:1805:27
#12 0x562cd3d0b2ef in
clang::CompilerInstance::loadModule(clang::SourceLocation,
llvm::ArrayRef<clang::IdentifierLoc>, clang::Module::NameVisibilityKind, bool)
clang/lib/Frontend/CompilerInstance.cpp:1956:31
#13 0x562cdb04eb1c in
clang::Preprocessor::HandleHeaderIncludeOrImport(clang::SourceLocation,
clang::Token&, clang::Token&, clang::SourceLocation,
clang::detail::SearchDirIteratorImpl<true>, clang::FileEntry const*)
clang/lib/Lex/PPDirectives.cpp:2423:49
#14 0x562cdb042222 in
clang::Preprocessor::HandleIncludeDirective(clang::SourceLocation,
clang::Token&, clang::detail::SearchDirIteratorImpl<true>, clang::FileEntry
const*) clang/lib/Lex/PPDirectives.cpp:2101:17
#15 0x562cdb043366 in clang::Preprocessor::HandleDirective(clang::Token&)
clang/lib/Lex/PPDirectives.cpp:1338:14
#16 0x562cdafa84bc in clang::Lexer::LexTokenInternal(clang::Token&, bool)
clang/lib/Lex/Lexer.cpp:4512:7
#17 0x562cdaf9f20b in clang::Lexer::Lex(clang::Token&)
clang/lib/Lex/Lexer.cpp:3729:24
#18 0x562cdb0d4ffa in clang::Preprocessor::Lex(clang::Token&)
clang/lib/Lex/Preprocessor.cpp:896:11
#19 0x562cd77da950 in clang::ParseAST(clang::Sema&, bool, bool)
clang/lib/Parse/ParseAST.cpp:163:7
[...]
SUMMARY: AddressSanitizer: heap-buffer-overflow
clang/lib/Serialization/ASTReader.cpp:10171:15 in
clang::ASTReader::ReadString(llvm::SmallVectorImpl<unsigned long> const&,
unsigned int&)
```
The reason is this particular RUN line:
```
// RUN: env CC_PRINT_HEADERS_FORMAT=json
CC_PRINT_HEADERS_FILTERING=direct-per-file CC_PRINT_HEADERS_FILE=%t.txt %clang
-fsyntax-only -I %S/Inputs/print-header-json -isystem
%S/Inputs/print-header-json/system -fmodules -fimplicit-module-maps
-fmodules-cache-path=%t %s -o /dev/null
```
which was added in 8df194f6a933 ("[Clang] Support includes translated to module
imports in -header-include-filtering=direct-per-file (#156756)").
The problem is caused by an incremental build reusing stale cached module files
(.pcm) that are no longer binary-compatible with the updated compiler. Adding a
new sanitizer option altered the implicit binary layout of the serialized
LangOptions data structure. The build + test system is oblivious to such
changes. When the new compiler attempted to read the old module file (from the
previous test invocation), it misinterpreted the data due to the layout
mismatch, resulting in a heap-buffer-overflow. Unfortunately Clang's PCM format
does not encode nor detect version mismatches here; a more graceful failure
mode would be preferable.
For now, fix the test to be more robust with incremental build + test.
>From ca136ac4479cd826e86e3b73b51a76387afdf742 Mon Sep 17 00:00:00 2001
From: Marco Elver <[email protected]>
Date: Wed, 8 Oct 2025 15:33:30 +0200
Subject: [PATCH] [Clang] Fix brittle print-header-json.c test
A recent change adding a new sanitizer kind (via Sanitizer.defs) was
reverted in c74fa20c955b ("Revert "[Clang][CodeGen] Introduce the
AllocToken SanitizerKind" (#162413)"). The reason was this ASan report,
when running the test in clang/test/Preprocessor/print-header-json.c:
```
==clang==483265==ERROR: AddressSanitizer: heap-buffer-overflow on address
0x7d82b97e8b58 at pc 0x562cd432231f bp 0x7fff3fad0850 sp 0x7fff3fad0848
READ of size 16 at 0x7d82b97e8b58 thread T0
#0 0x562cd432231e in __copy_non_overlapping_range<const unsigned long *,
const unsigned long *>
zorg-test/libcxx_install_asan_ubsan/include/c++/v1/string:2144:38
#1 0x562cd432231e in void std::__1::basic_string<char,
std::__1::char_traits<char>,
std::__1::allocator<char>>::__init_with_size[abi:nn220000]<unsigned long
const*, unsigned long const*>(unsigned long const*, unsigned long const*,
unsigned long) zorg-test/libcxx_install_asan_ubsan/include/c++/v1/string:2685:18
#2 0x562cd41e2797 in __init<const unsigned long *, 0>
zorg-test/libcxx_install_asan_ubsan/include/c++/v1/string:2673:3
#3 0x562cd41e2797 in basic_string<const unsigned long *, 0>
zorg-test/libcxx_install_asan_ubsan/include/c++/v1/string:1174:5
#4 0x562cd41e2797 in
clang::ASTReader::ReadString(llvm::SmallVectorImpl<unsigned long> const&,
unsigned int&) clang/lib/Serialization/ASTReader.cpp:10171:15
#5 0x562cd41fd89a in
clang::ASTReader::ParseLanguageOptions(llvm::SmallVector<unsigned long, 64u>
const&, llvm::StringRef, bool, clang::ASTReaderListener&, bool)
clang/lib/Serialization/ASTReader.cpp:6475:28
#6 0x562cd41eea53 in
clang::ASTReader::ReadOptionsBlock(llvm::BitstreamCursor&, llvm::StringRef,
unsigned int, bool, clang::ASTReaderListener&, std::__1::basic_string<char,
std::__1::char_traits<char>, std::__1::allocator<char>>&)
clang/lib/Serialization/ASTReader.cpp:3069:11
#7 0x562cd4204ab8 in
clang::ASTReader::ReadControlBlock(clang::serialization::ModuleFile&,
llvm::SmallVectorImpl<clang::ASTReader::ImportedModule>&,
clang::serialization::ModuleFile const*, unsigned int)
clang/lib/Serialization/ASTReader.cpp:3249:15
#8 0x562cd42097d2 in clang::ASTReader::ReadASTCore(llvm::StringRef,
clang::serialization::ModuleKind, clang::SourceLocation,
clang::serialization::ModuleFile*,
llvm::SmallVectorImpl<clang::ASTReader::ImportedModule>&, long, long,
clang::ASTFileSignature, unsigned int)
clang/lib/Serialization/ASTReader.cpp:5182:15
#9 0x562cd421ec77 in clang::ASTReader::ReadAST(llvm::StringRef,
clang::serialization::ModuleKind, clang::SourceLocation, unsigned int,
clang::serialization::ModuleFile**)
clang/lib/Serialization/ASTReader.cpp:4828:11
#10 0x562cd3d07b74 in
clang::CompilerInstance::findOrCompileModuleAndReadAST(llvm::StringRef,
clang::SourceLocation, clang::SourceLocation, bool)
clang/lib/Frontend/CompilerInstance.cpp:1805:27
#11 0x562cd3d0b2ef in
clang::CompilerInstance::loadModule(clang::SourceLocation,
llvm::ArrayRef<clang::IdentifierLoc>, clang::Module::NameVisibilityKind, bool)
clang/lib/Frontend/CompilerInstance.cpp:1956:31
#12 0x562cdb04eb1c in
clang::Preprocessor::HandleHeaderIncludeOrImport(clang::SourceLocation,
clang::Token&, clang::Token&, clang::SourceLocation,
clang::detail::SearchDirIteratorImpl<true>, clang::FileEntry const*)
clang/lib/Lex/PPDirectives.cpp:2423:49
#13 0x562cdb042222 in
clang::Preprocessor::HandleIncludeDirective(clang::SourceLocation,
clang::Token&, clang::detail::SearchDirIteratorImpl<true>, clang::FileEntry
const*) clang/lib/Lex/PPDirectives.cpp:2101:17
#14 0x562cdb043366 in clang::Preprocessor::HandleDirective(clang::Token&)
clang/lib/Lex/PPDirectives.cpp:1338:14
#15 0x562cdafa84bc in clang::Lexer::LexTokenInternal(clang::Token&, bool)
clang/lib/Lex/Lexer.cpp:4512:7
#16 0x562cdaf9f20b in clang::Lexer::Lex(clang::Token&)
clang/lib/Lex/Lexer.cpp:3729:24
#17 0x562cdb0d4ffa in clang::Preprocessor::Lex(clang::Token&)
clang/lib/Lex/Preprocessor.cpp:896:11
#18 0x562cd77da950 in clang::ParseAST(clang::Sema&, bool, bool)
clang/lib/Parse/ParseAST.cpp:163:7
[...]
0x7d82b97e8b58 is located 0 bytes after 3288-byte region
[0x7d82b97e7e80,0x7d82b97e8b58)
allocated by thread T0 here:
#0 0x562cca76f604 in malloc
zorg-test/llvm-project/compiler-rt/lib/asan/asan_malloc_linux.cpp:67:3
#1 0x562cd1cce452 in safe_malloc llvm/include/llvm/Support/MemAlloc.h:26:18
#2 0x562cd1cce452 in llvm::SmallVectorBase<unsigned int>::grow_pod(void*,
unsigned long, unsigned long) llvm/lib/Support/SmallVector.cpp:151:15
#3 0x562cdbe1768b in grow_pod llvm/include/llvm/ADT/SmallVector.h:139:11
#4 0x562cdbe1768b in grow llvm/include/llvm/ADT/SmallVector.h:525:41
#5 0x562cdbe1768b in reserve llvm/include/llvm/ADT/SmallVector.h:665:13
#6 0x562cdbe1768b in llvm::BitstreamCursor::readRecord(unsigned int,
llvm::SmallVectorImpl<unsigned long>&, llvm::StringRef*)
llvm/lib/Bitstream/Reader/BitstreamReader.cpp:230:10
#7 0x562cd41ee8ab in
clang::ASTReader::ReadOptionsBlock(llvm::BitstreamCursor&, llvm::StringRef,
unsigned int, bool, clang::ASTReaderListener&, std::__1::basic_string<char,
std::__1::char_traits<char>, std::__1::allocator<char>>&)
clang/lib/Serialization/ASTReader.cpp:3060:49
#8 0x562cd4204ab8 in
clang::ASTReader::ReadControlBlock(clang::serialization::ModuleFile&,
llvm::SmallVectorImpl<clang::ASTReader::ImportedModule>&,
clang::serialization::ModuleFile const*, unsigned int)
clang/lib/Serialization/ASTReader.cpp:3249:15
#9 0x562cd42097d2 in clang::ASTReader::ReadASTCore(llvm::StringRef,
clang::serialization::ModuleKind, clang::SourceLocation,
clang::serialization::ModuleFile*,
llvm::SmallVectorImpl<clang::ASTReader::ImportedModule>&, long, long,
clang::ASTFileSignature, unsigned int)
clang/lib/Serialization/ASTReader.cpp:5182:15
#10 0x562cd421ec77 in clang::ASTReader::ReadAST(llvm::StringRef,
clang::serialization::ModuleKind, clang::SourceLocation, unsigned int,
clang::serialization::ModuleFile**)
clang/lib/Serialization/ASTReader.cpp:4828:11
#11 0x562cd3d07b74 in
clang::CompilerInstance::findOrCompileModuleAndReadAST(llvm::StringRef,
clang::SourceLocation, clang::SourceLocation, bool)
clang/lib/Frontend/CompilerInstance.cpp:1805:27
#12 0x562cd3d0b2ef in
clang::CompilerInstance::loadModule(clang::SourceLocation,
llvm::ArrayRef<clang::IdentifierLoc>, clang::Module::NameVisibilityKind, bool)
clang/lib/Frontend/CompilerInstance.cpp:1956:31
#13 0x562cdb04eb1c in
clang::Preprocessor::HandleHeaderIncludeOrImport(clang::SourceLocation,
clang::Token&, clang::Token&, clang::SourceLocation,
clang::detail::SearchDirIteratorImpl<true>, clang::FileEntry const*)
clang/lib/Lex/PPDirectives.cpp:2423:49
#14 0x562cdb042222 in
clang::Preprocessor::HandleIncludeDirective(clang::SourceLocation,
clang::Token&, clang::detail::SearchDirIteratorImpl<true>, clang::FileEntry
const*) clang/lib/Lex/PPDirectives.cpp:2101:17
#15 0x562cdb043366 in clang::Preprocessor::HandleDirective(clang::Token&)
clang/lib/Lex/PPDirectives.cpp:1338:14
#16 0x562cdafa84bc in clang::Lexer::LexTokenInternal(clang::Token&, bool)
clang/lib/Lex/Lexer.cpp:4512:7
#17 0x562cdaf9f20b in clang::Lexer::Lex(clang::Token&)
clang/lib/Lex/Lexer.cpp:3729:24
#18 0x562cdb0d4ffa in clang::Preprocessor::Lex(clang::Token&)
clang/lib/Lex/Preprocessor.cpp:896:11
#19 0x562cd77da950 in clang::ParseAST(clang::Sema&, bool, bool)
clang/lib/Parse/ParseAST.cpp:163:7
[...]
SUMMARY: AddressSanitizer: heap-buffer-overflow
clang/lib/Serialization/ASTReader.cpp:10171:15 in
clang::ASTReader::ReadString(llvm::SmallVectorImpl<unsigned long> const&,
unsigned int&)
```
The reason is this particular RUN line:
```
// RUN: env CC_PRINT_HEADERS_FORMAT=json
CC_PRINT_HEADERS_FILTERING=direct-per-file CC_PRINT_HEADERS_FILE=%t.txt %clang
-fsyntax-only -I %S/Inputs/print-header-json -isystem
%S/Inputs/print-header-json/system -fmodules -fimplicit-module-maps
-fmodules-cache-path=%t %s -o /dev/null
```
which was added in 8df194f6a933 ("[Clang] Support includes translated to
module imports in -header-include-filtering=direct-per-file (#156756)").
The problem is caused by an incremental build reusing stale cached
module files (.pcm) that are no longer binary-compatible with the
updated compiler. Adding a new sanitizer option altered the implicit
binary layout of the serialized LangOptions data structure. The build +
test system is oblivious to such changes. When the new compiler
attempted to read the old module file (from the previous test
invocation), it misinterpreted the data due to the layout mismatch,
resulting in a heap-buffer-overflow. Unfortunately Clang's PCM format
does not encode nor detect version mismatches here; a more graceful
failure mode would be preferable.
For now, fix the test to be more robust with incremental build + test.
---
clang/test/Preprocessor/print-header-json.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/clang/test/Preprocessor/print-header-json.c
b/clang/test/Preprocessor/print-header-json.c
index 057dcc27d8238..e0533cd8f0e4f 100644
--- a/clang/test/Preprocessor/print-header-json.c
+++ b/clang/test/Preprocessor/print-header-json.c
@@ -22,6 +22,7 @@
#include "system2.h"
// RUN: rm %t.txt
+// RUN: rm -rf %t
// RUN: env CC_PRINT_HEADERS_FORMAT=json
CC_PRINT_HEADERS_FILTERING=direct-per-file CC_PRINT_HEADERS_FILE=%t.txt %clang
-fsyntax-only -I %S/Inputs/print-header-json -isystem
%S/Inputs/print-header-json/system -fmodules -fimplicit-module-maps
-fmodules-cache-path=%t %s -o /dev/null
// RUN: cat %t.txt | FileCheck %s --check-prefix=SUPPORTED_PERFILE_MODULES
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits