Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

<xstring>: ASAN report container-overflow in a legal case #3955

Closed
zlsun opened this issue Aug 12, 2023 · 0 comments · Fixed by #3956
Closed

<xstring>: ASAN report container-overflow in a legal case #3955

zlsun opened this issue Aug 12, 2023 · 0 comments · Fixed by #3956
Labels
ASan Address Sanitizer bug Something isn't working fixed Something works now, yay!

Comments

@zlsun
Copy link

zlsun commented Aug 12, 2023

Describe the bug

ASAN report container-overflow in a legal case.

Command-line test case

C:\Temp>type repro.cpp
#include <iostream>
#include <string>

int main()
{
    std::string fontName = "ui/font/test.ttf";
    int nFindPos = (int)fontName.rfind("/");
    fontName = &fontName[nFindPos + 1];
}

C:\Temp>cl /EHsc /W4 /WX /std:c++latest /fsanitize=address /Zi .\repro.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 19.37.32822 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.

repro.cpp
Microsoft (R) Incremental Linker Version 14.37.32822.0
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:repro.exe
/InferAsanLibs
/debug
repro.obj

C:\Temp>.\repro.exe
=================================================================
==11212==ERROR: AddressSanitizer: container-overflow on address 0x124a920a0949 at pc 0x7ffcdc4714bb bp 0x00939796f490 sp 0x00939796ec20
READ of size 8 at 0x124a920a0949 thread T0
    #0 0x7ffcdc4714ba in __asan_wrap_memcpy D:\a\_work\1\s\src\vctools\asan\llvm\compiler-rt\lib\sanitizer_common\sanitizer_common_interceptors.inc:840
    #1 0x7ff7a0835936 in std::_Char_traits<char, int>::move(char *const, char const *const, unsigned __int64) C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.37.32822\include\xstring:119
    #2 0x7ff7a0834e2b in std::basic_string<char, struct std::char_traits<char>, class std::allocator<char>>::assign(char const *const, unsigned __int64) C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.37.32822\include\xstring:3380
    #3 0x7ff7a0834bd1 in std::basic_string<char, struct std::char_traits<char>, class std::allocator<char>>::assign(char const *const) C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.37.32822\include\xstring:3395
    #4 0x7ff7a083311c in std::basic_string<char, struct std::char_traits<char>, class std::allocator<char>>::operator=(char const *const) C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.37.32822\include\xstring:3204
    #5 0x7ff7a0831133 in main D:\tmp\asan\repro.cpp:8
    #6 0x7ff7a08388bb in invoke_main D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:78
    #7 0x7ff7a08388bb in __scrt_common_main_seh D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288
    #8 0x7ffd47457613  (C:\WINDOWS\System32\KERNEL32.DLL+0x180017613)
    #9 0x7ffd48c826b0  (C:\WINDOWS\SYSTEM32\ntdll.dll+0x1800526b0)

0x124a920a0949 is located 9 bytes inside of 32-byte region [0x124a920a0940,0x124a920a0960)
allocated by thread T0 here:
    #0 0x7ff7a08382e5 in operator new(unsigned __int64) D:\a\_work\1\s\src\vctools\asan\llvm\compiler-rt\lib\asan\asan_win_new_scalar_thunk.cpp:40
    #1 0x7ff7a0833712 in std::_Default_allocate_traits::_Allocate(unsigned __int64) C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.37.32822\include\xmemory:87
    #2 0x7ff7a08311fd in std::_Allocate<16, struct std::_Default_allocate_traits, 0>(unsigned __int64) C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.37.32822\include\xmemory:245
    #3 0x7ff7a08349bf in std::allocator<char>::allocate(unsigned __int64) C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.37.32822\include\xmemory:974
    #4 0x7ff7a08316e2 in std::basic_string<char, struct std::char_traits<char>, class std::allocator<char>>::_Construct<1, char const *>(char const *const, unsigned __int64) C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.37.32822\include\xstring:2652
    #5 0x7ff7a0832b2b 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.37.32822\include\xstring:2540
    #6 0x7ff7a08310ee in main D:\tmp\asan\repro.cpp:6
    #7 0x7ff7a08388bb in invoke_main D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:78
    #8 0x7ff7a08388bb in __scrt_common_main_seh D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288
    #9 0x7ffd47457613  (C:\WINDOWS\System32\KERNEL32.DLL+0x180017613)
    #10 0x7ffd48c826b0  (C:\WINDOWS\SYSTEM32\ntdll.dll+0x1800526b0)

HINT: if you don't care about these errors you may set ASAN_OPTIONS=detect_container_overflow=0.
If you suspect a false positive see also: https://github.com/google/sanitizers/wiki/AddressSanitizerContainerOverflow.
SUMMARY: AddressSanitizer: container-overflow D:\a\_work\1\s\src\vctools\asan\llvm\compiler-rt\lib\sanitizer_common\sanitizer_common_interceptors.inc:840 in __asan_wrap_memcpy
Shadow bytes around the buggy address:
  0x048de44940d0: 06 fa fa fa 00 00 00 01 fa fa 00 00 00 03 fa fa
  0x048de44940e0: 00 00 07 fa fa fa 00 00 00 03 fa fa 00 00 00 01
  0x048de44940f0: fa fa 00 00 00 03 fa fa 00 00 00 fa fa fa 00 00
  0x048de4494100: 07 fa fa fa 00 00 01 fa fa fa 00 00 02 fa fa fa
  0x048de4494110: 00 00 00 00 fa fa 00 00 02 fa fa fa 00 00 05 fa
=>0x048de4494120: fa fa 00 00 00 06 fa fa 00[01]fc fc fa fa fd fd
  0x048de4494130: fd fd fa fa fd fd fd fd fa fa fd fd fd fd fa fa
  0x048de4494140: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x048de4494150: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x048de4494160: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x048de4494170: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
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
==11212==ABORTING

Expected behavior

ASAN should not report container-overflow in this case.

STL version

  Microsoft Visual Studio Community 2022
  Version 17.7.0

Additional context

Cause

fontName = &fontName[nFindPos + 1]; call assign method in <xstring>

STL/stl/inc/xstring

Lines 3370 to 3381 in 8674b3d

_CONSTEXPR20 basic_string& assign(
_In_reads_(_Count) const _Elem* const _Ptr, _CRT_GUARDOVERFLOW const size_type _Count) {
// assign [_Ptr, _Ptr + _Count)
if (_Count <= _Mypair._Myval2._Myres) {
_ASAN_STRING_MODIFY(*this, _Mypair._Myval2._Mysize, _Count);
_Elem* const _Old_ptr = _Mypair._Myval2._Myptr();
_Mypair._Myval2._Mysize = _Count;
_Traits::move(_Old_ptr, _Ptr, _Count);
_Traits::assign(_Old_ptr[_Count], _Elem());
return *this;
}

_ASAN_STRING_MODIFY shrink the valid range of string fontName

Then _Traits::move copy chars from invalid range.

This code is introduced in #3164

Original source code

The example code is copy from https://github.com/cocos2d/cocos2d-x/blob/76903dee64046c7bfdba50790be283484b4be271/cocos/platform/win32/CCDevice-win32.cpp#L115-L119

This is VSO-1854245 / AB#1854245.

@zlsun zlsun changed the title <xstring>: ASAN report container-overflow in a legal case <xstring>: ASAN report container-overflow in a legal case Aug 12, 2023
@StephanTLavavej StephanTLavavej added bug Something isn't working ASan Address Sanitizer labels Aug 13, 2023
@StephanTLavavej StephanTLavavej added the fixed Something works now, yay! label Aug 18, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ASan Address Sanitizer bug Something isn't working fixed Something works now, yay!
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants