Skip to content

[libc++] stack-buffer-overflow in std::format_to #154670

@seven332

Description

@seven332

https://godbolt.org/z/ccsvq9c1e

#include <format>
#include <iterator>
#include <string>

int main() {
    std::string s;
    std::string content(256, 'a');
    std::format_to(std::back_inserter(s), "{}a", content);
    return 0;
}
==1==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x6e71d38f0190 at pc 0x5d3e8bf1c96c bp 0x7ffd06274850 sp 0x7ffd06274848
WRITE of size 1 at 0x6e71d38f0190 thread T0
    #0 0x5d3e8bf1c96b in std::__1::__format::__output_buffer<char>::push_back[abi:ne220000](char) /opt/compiler-explorer/clang-trunk-20250820/bin/../include/c++/v1/__format/buffer.h:212:23
    #1 0x5d3e8bef775f in std::__1::back_insert_iterator<std::__1::__format::__output_buffer<char>>::operator=[abi:ne220000](char const&) /opt/compiler-explorer/clang-trunk-20250820/bin/../include/c++/v1/__iterator/back_insert_iterator.h:57:16
    #2 0x5d3e8bef416e in std::__1::basic_format_context<std::__1::back_insert_iterator<std::__1::__format::__output_buffer<char>>, char>::iterator std::__1::__format::__vformat_to[abi:ne220000]<std::__1::basic_format_parse_context<char>, std::__1::basic_format_context<std::__1::back_insert_iterator<std::__1::__format::__output_buffer<char>>, char>>(std::__1::basic_format_parse_context<char>&&, std::__1::basic_format_context<std::__1::back_insert_iterator<std::__1::__format::__output_buffer<char>>, char>&&) /opt/compiler-explorer/clang-trunk-20250820/bin/../include/c++/v1/__format/format_functions.h:336:17
    #3 0x5d3e8bef3bed in T std::__1::__vformat_to[abi:ne220000]<std::__1::back_insert_iterator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>>, char, std::__1::back_insert_iterator<std::__1::__format::__output_buffer<char>>>(T, std::__1::basic_string_view<T0, std::__1::char_traits<T0>>, std::__1::basic_format_args<std::__1::basic_format_context<std::__1::back_insert_iterator<std::__1::__format::__output_buffer<char>>, T0>>) /opt/compiler-explorer/clang-trunk-20250820/bin/../include/c++/v1/__format/format_functions.h:417:5
    #4 0x5d3e8bef314f in std::__1::back_insert_iterator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>> std::__1::vformat_to[abi:ne220000]<std::__1::back_insert_iterator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>>>(std::__1::back_insert_iterator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>>, std::__1::basic_string_view<char, std::__1::char_traits<char>>, std::__1::basic_format_args<std::__1::basic_format_context<std::__1::back_insert_iterator<std::__1::__format::__output_buffer<char>>, char>>) /opt/compiler-explorer/clang-trunk-20250820/bin/../include/c++/v1/__format/format_functions.h:428:10
    #5 0x5d3e8bef314f in std::__1::back_insert_iterator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>> std::__1::format_to[abi:ne220000]<std::__1::back_insert_iterator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>>, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>&>(std::__1::back_insert_iterator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>>, std::__1::basic_format_string<char, std::__1::type_identity<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>&>::type>, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>&) /opt/compiler-explorer/clang-trunk-20250820/bin/../include/c++/v1/__format/format_functions.h:442:10
    #6 0x5d3e8bef314f in main /app/example.cpp:8:5
    #7 0x7271d5629d8f  (/lib/x86_64-linux-gnu/libc.so.6+0x29d8f) (BuildId: d5197096f709801829b118af1b7cf6631efa2dcd)
    #8 0x7271d5629e3f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x29e3f) (BuildId: d5197096f709801829b118af1b7cf6631efa2dcd)
    #9 0x5d3e8be0a564 in _start (/app/output.s+0x2f564)

After __output_buffer::__copy, the buffer is full. While in __output_buffer::push_back, the check happens after insertion.

Metadata

Metadata

Assignees

No one assigned

    Labels

    formatC++20 std::format or std::print, and anything related to themlibc++libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions