-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Closed as duplicate of#5276
Labels
bugSomething isn't workingSomething isn't working
Description
Describe the bug
std::system_error (in _System_error) constructs a temporary std::string with _Makestr, then stores a .c_str() to it without retaining it, which is invalid.
In my real application, I am seeing an stdext::bad_alloc from within _Throw_fs_error, even in release builds. In debug builds, I see the use-after-free bit pattern, with a trace like this:
The debugger shows that at the time of the _Doraise() call, the string has been overwritten with the 0xdd - use-after-free bit pattern.
I'm able to reproduce this with /fsanitize-address-use-after-return.
Command-line test case
Either of these repros works:
#include <filesystem>
#include <print>
int main(int argc, char** argv) {
// REPRO 1:
auto ex = []() {
std::string what{"abc"};
std::error_code ec{2, std::system_category()};
return std::system_error{ec, what};
}();
std::println("{}", ex.what());
// REPRO 2:
try {
const std::filesystem::path p { "does-not-exist" };
std::println("Empty? {}", std::filesystem::is_empty(p));
} catch (const std::filesystem::filesystem_error& e) {
std::println("Ex: {}", e.what());
}
return 0;
}The std::filesystem::is_empty() case has a user-after free both for _What and for the path.
PS C:\Users\fred\code\filesystem-test> cl /std:c++latest /EHsc /MDd /Zi /W4 /fsanitize=address /fsanitize-address-use-after-return test.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 19.42.34435 for x64
Copyright (C) Microsoft Corporation. All rights reserved.
/std:c++latest is provided as a preview of language features from the latest C++
working draft, and we're eager to hear about bugs and suggestions for improvements.
However, note that these features are provided as-is without support, and subject
to changes or removal as the working draft evolves. See
https://go.microsoft.com/fwlink/?linkid=2045807 for details.
test.cpp
test.cpp(4): warning C4100: 'argv': unreferenced formal parameter
test.cpp(4): warning C4100: 'argc': unreferenced formal parameter
Microsoft (R) Incremental Linker Version 14.42.34435.0
Copyright (C) Microsoft Corporation. All rights reserved.
/out:test.exe
/debug
/InferAsanLibs
test.obj
PS C:\Users\fred\code\filesystem-test> ./test.exe
=================================================================
==29036==ERROR: AddressSanitizer: stack-buffer-underflow on address 0x00161e0ff210 at pc 0x7ff67786271f bp 0x00161e0ff0d0 sp 0x00161e0ff0d8
WRITE of size 8 at 0x00161e0ff210 thread T0
#0 0x7ff67786271e in std::_Container_base12::_Container_base12(void) C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.42.34433\include\xmemory:1199
#1 0x7ff67785fbbe in std::_String_val<struct std::_Simple_types<char>>::_String_val<struct std::_Simple_types<char>>(void) C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.42.34433\include\xstring:402
#2 0x7ff6778119b3 in std::_Compressed_pair<class std::allocator<char>, class std::_String_val<struct std::_Simple_types<char>>, 1>::_Compressed_pair<class std::allocator<char>, class std::_String_val<struct std::_Simple_types<char>>, 1><>(struct std::_Zero_then_variadic_args_t) C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.42.34433\include\xmemory:1495
#3 0x7ff677861bf6 in std::basic_string<char, struct std::char_traits<char>, class std::allocator<char>>::basic_string<char, struct std::char_traits<char>, class std::allocator<char>>(char const *const) C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.42.34433\include\xstring:749
#4 0x7ff6778116eb in `main'::`2'::<lambda_1>::operator() C:\Users\fred\code\filesystem-test\test.cpp:7
#5 0x7ff677811292 in main C:\Users\fred\code\filesystem-test\test.cpp:6
#6 0x7ff6778cb238 in invoke_main D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:78
#7 0x7ff6778cb181 in __scrt_common_main_seh D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288
#8 0x7ff6778cb03d in __scrt_common_main D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:330
#9 0x7ff6778cb2ad in mainCRTStartup D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_main.cpp:16
#10 0x7ff94bd0259c (C:\WINDOWS\System32\KERNEL32.DLL+0x18001259c)
#11 0x7ff94d58af37 (C:\WINDOWS\SYSTEM32\ntdll.dll+0x18005af37)
Address 0x00161e0ff210 is located in stack of thread T0 at offset 0 in frame
#0 0x7ff67781155f in `main'::`2'::<lambda_1>::operator() C:\Users\fred\code\filesystem-test\test.cpp:6
This frame has 2 object(s):
[32, 72) 'what'
[48, 64) 'ec'
HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
(longjmp, SEH and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-underflow C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.42.34433\include\xmemory:1199 in std::_Container_base12::_Container_base12(void)
Shadow bytes around the buggy address:
0x00161e0fef80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x00161e0ff000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x00161e0ff080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x00161e0ff100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x00161e0ff180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x00161e0ff200: 00 00[f1]f1 f1 f1 00 00 00 00 00 f2 f2 f2 f2 00
0x00161e0ff280: 00 f3 f3 f3 f3 00 00 00 00 00 00 00 00 00 00 00
0x00161e0ff300: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x00161e0ff380: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x00161e0ff400: 00 00 00 00 00 00 00 00 00 f2 f2 f2 f2 00 00 00
0x00161e0ff480: 00 00 f2 f2 f2 f2 01 f2 f8 f2 f8 f2 f8 f3 f3 f3
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
==29036==ABORTING
Expected behavior
std::system_errorshould manage lifetime of temporary strings it createsstd::filesystem::is_empty()should throw an exception on error, not internally crash
STL version
Microsoft Visual Studio Community 2022
Version 17.12.3
Additional context
None.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working
