-
Notifications
You must be signed in to change notification settings - Fork 16.4k
Description
The following program:
#include <format>
#include <string_view>
int main() {
const char fmt[] = {'{','0'};
char buf[4096];
[[maybe_unused]] auto ignored = std::vformat_to(
buf, std::string_view{fmt, fmt + sizeof(fmt)}, std::make_format_args());
}causes an out of bounds read on the format buffer "fmt". When compiled with libc++ on the current clang trunk (as of what is compiler explorer on the 2023-08-26) and address sanitizer, the message below appears.
Compile flags: -std=c++23 -fsanitize=address,undefined -stdlib=libc++
Link to reproducer: https://godbolt.org/z/bEvYT4b1j
=================================================================
==1==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7fc964b000e2 at pc 0x55efa5b48ff3 bp 0x7ffd9ed4f9f0 sp 0x7ffd9ed4f9e8
READ of size 1 at 0x7fc964b000e2 thread T0
#0 0x55efa5b48ff2 in char const* std::__1::__format::__handle_replacement_field[abi:v180000]<char const*, std::__1::basic_format_parse_context, std::__1::basic_format_context<std::__1::back_insert_iterator<std::__1::__format::__output_buffer>, char>>(char const*, char const*, std::__1::basic_format_parse_context&, std::__1::basic_format_context<std::__1::back_insert_iterator<std::__1::__format::__output_buffer>, char>&) /opt/compiler-explorer/clang-trunk-20230824/bin/../include/c++/v1/__format/format_functions.h:248:18
#1 0x55efa5b47263 in std::__1::basic_format_context<std::__1::back_insert_iterator<std::__1::__format::__output_buffer>, char>::iterator std::__1::__format::__vformat_to[abi:v180000]<std::__1::basic_format_parse_context, std::__1::basic_format_context<std::__1::back_insert_iterator<std::__1::__format::__output_buffer>, char>>(std::__1::basic_format_parse_context&&, std::__1::basic_format_context<std::__1::back_insert_iterator<std::__1::__format::__output_buffer>, char>&&) /opt/compiler-explorer/clang-trunk-20230824/bin/../include/c++/v1/__format/format_functions.h:312:13
#2 0x55efa5b46a17 in char* std::__1::__vformat_to[abi:v180000]<char*, char, std::__1::back_insert_iterator<std::__1::__format::__output_buffer>>(char*, std::__1::basic_string_view<char, std::__1::char_traits>, std::__1::basic_format_args<std::__1::basic_format_context<std::__1::back_insert_iterator<std::__1::__format::__output_buffer>, char>>) /opt/compiler-explorer/clang-trunk-20230824/bin/../include/c++/v1/__format/format_functions.h:387:5
#3 0x55efa5b46109 in char* std::__1::vformat_to[abi:v180000]<char*>(char*, std::__1::basic_string_view<char, std::__1::char_traits>, std::__1::basic_format_args<std::__1::basic_format_context<std::__1::back_insert_iterator<std::__1::__format::__output_buffer>, char>>) /opt/compiler-explorer/clang-trunk-20230824/bin/../include/c++/v1/__format/format_functions.h:399:10
#4 0x55efa5b46109 in main /app/example.cpp:6:37
#5 0x7fc966844082 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x24082) (BuildId: 1878e6b475720c7c51969e69ab2d276fae6d1dee)
#6 0x55efa5a6b4ad in _start (/app/output.s+0x4a4ad)Address 0x7fc964b000e2 is located in stack of thread T0 at offset 226 in frame
#0 0x55efa5b45b87 in main /app/example.cpp:3This frame has 9 object(s):
[32, 48) '__fmt.i'
[64, 80) 'agg.tmp.i'
[96, 120) 'agg.tmp1.i'
[160, 184) 'agg.tmp46'
[224, 226) 'fmt' (line 4) <== Memory access at offset 226 overflows this variable
[240, 4336) 'buf' (line 5)
[4464, 4480) 'agg.tmp' (line 6)
[4496, 4520) 'agg.tmp4' (line 6)
[4560, 4576) 'ref.tmp' (line 6)
HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
(longjmp and C++ exceptions are supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow /opt/compiler-explorer/clang-trunk-20230824/bin/../include/c++/v1/__format/format_functions.h:248:18 in char const* std::__1::__format::__handle_replacement_field[abi:v180000]<char const*, std::__1::basic_format_parse_context, std::__1::basic_format_context<std::__1::back_insert_iterator<std::__1::__format::__output_buffer>, char>>(char const*, char const*, std::__1::basic_format_parse_context&, std::__1::basic_format_context<std::__1::back_insert_iterator<std::__1::__format::__output_buffer>, char>&)
Shadow bytes around the buggy address:
0x7fc964affe00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x7fc964affe80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x7fc964afff00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x7fc964afff80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x7fc964b00000: f1 f1 f1 f1 00 00 f2 f2 00 00 f2 f2 00 00 00 f2
=>0x7fc964b00080: f2 f2 f2 f2 00 00 00 f2 f2 f2 f2 f2[02]f2 00 00
0x7fc964b00100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x7fc964b00180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x7fc964b00200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x7fc964b00280: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x7fc964b00300: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
==1==ABORTING