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

microvu: fix ASAN container-overflow in mVUsetupRange #11818

Merged
merged 1 commit into from
Sep 16, 2024

Conversation

oltolm
Copy link
Contributor

@oltolm oltolm commented Sep 15, 2024

Description of Changes

Fix ASAN container-overflow in mVUsetupRange.

Rationale behind Changes

When the iterator is erased in pcsx2\x86\microVU_Compile.inl:94

				it = ranges->erase(it);

These references get invalidated.

		s32& rStart = mVUrange.start;
		s32& rEnd = mVUrange.end;

These variables should not be references.

Suggested Testing Steps

Build with -fsanize=address and run pcsx2.

=================================================================
==23240==ERROR: AddressSanitizer: container-overflow on address 0x12211936e0d0 at pc 0x7ff67f43d287 bp 0x007a23bf3c60 sp 0x007a23bf3ca8
READ of size 4 at 0x12211936e0d0 thread T3
    #0 0x7ff67f43d286 in mVUsetupRange(microVU&, int, bool) C:/src/pcsx2/pcsx2/x86/microVU_Compile.inl:90:23
    #1 0x7ff67f42f246 in mVUcompile(microVU&, unsigned int, unsigned long long) C:/src/pcsx2/pcsx2/x86/microVU_Compile.inl:946:4
    #2 0x7ff67f44d2c7 in mVUentryGet(microVU&, microBlockManager*, unsigned int, unsigned long long) C:/src/pcsx2/pcsx2/x86/microVU_Compile.inl:1010:10
    #3 0x7ff67f43961f in mVUblockFetch(microVU&, unsigned int, unsigned long long) C:/src/pcsx2/pcsx2/x86/microVU_Compile.inl:1022:9
    #4 0x7ff67f4391b4 in condBranch(microVU&, microFlagCycles&, int) C:/src/pcsx2/pcsx2/x86/microVU_Branch.inl:552:26
    #5 0x7ff67f42f6d9 in mVUcompile(microVU&, unsigned int, unsigned long long) C:/src/pcsx2/pcsx2/x86/microVU_Compile.inl:961:6
    #6 0x7ff67f44d2c7 in mVUentryGet(microVU&, microBlockManager*, unsigned int, unsigned long long) C:/src/pcsx2/pcsx2/x86/microVU_Compile.inl:1010:10
    #7 0x7ff67f43961f in mVUblockFetch(microVU&, unsigned int, unsigned long long) C:/src/pcsx2/pcsx2/x86/microVU_Compile.inl:1022:9
    #8 0x7ff67f4391b4 in condBranch(microVU&, microFlagCycles&, int) C:/src/pcsx2/pcsx2/x86/microVU_Branch.inl:552:26
    #9 0x7ff67f42f6d9 in mVUcompile(microVU&, unsigned int, unsigned long long) C:/src/pcsx2/pcsx2/x86/microVU_Compile.inl:961:6
    #10 0x7ff67f42832d in normBranchCompile(microVU&, unsigned int) C:/src/pcsx2/pcsx2/x86/microVU_Branch.inl:285:3
    #11 0x7ff67f432678 in normBranch(microVU&, microFlagCycles&) C:/src/pcsx2/pcsx2/x86/microVU_Branch.inl:407:2
    #12 0x7ff67f42f693 in mVUcompile(microVU&, unsigned int, unsigned long long) C:/src/pcsx2/pcsx2/x86/microVU_Compile.inl:954:6
    #13 0x7ff67f42832d in normBranchCompile(microVU&, unsigned int) C:/src/pcsx2/pcsx2/x86/microVU_Branch.inl:285:3
    #14 0x7ff67f432678 in normBranch(microVU&, microFlagCycles&) C:/src/pcsx2/pcsx2/x86/microVU_Branch.inl:407:2
    #15 0x7ff67f42f693 in mVUcompile(microVU&, unsigned int, unsigned long long) C:/src/pcsx2/pcsx2/x86/microVU_Compile.inl:954:6
    #16 0x7ff67f44d2c7 in mVUentryGet(microVU&, microBlockManager*, unsigned int, unsigned long long) C:/src/pcsx2/pcsx2/x86/microVU_Compile.inl:1010:10
    #17 0x7ff67f43961f in mVUblockFetch(microVU&, unsigned int, unsigned long long) C:/src/pcsx2/pcsx2/x86/microVU_Compile.inl:1022:9
    #18 0x7ff67f4d03f1 in void* mVUsearchProg<1>(unsigned int, unsigned long long) C:/src/pcsx2/pcsx2/x86/microVU.cpp:274:22
    #19 0x7ff67f4ad532 in void* mVUcompileJIT<1>(unsigned int, unsigned long long) C:/src/pcsx2/pcsx2/x86/microVU_Compile.inl:1052:13
    #20 0x7ff6c4b02a13  (<unknown module>)
0x12211936e0d0 is located 2000 bytes inside of 4096-byte region [0x12211936d900,0x12211936e900)
allocated by thread T3 here:
    #0 0x7ffa77d24d91 in operator new(unsigned long long) (C:\msys64\clang64\bin\libclang_rt.asan_dynamic-x86_64.dll+0x180054d91)
    #1 0x7ff67de091c2 in void* std::__1::__libcpp_operator_new[abi:nn180100]<unsigned long long>(unsigned long long) C:/msys64/clang64/include/c++/v1/new:271:10
    #2 0x7ff67de09121 in std::__1::__libcpp_allocate[abi:nn180100](unsigned long long, unsigned long long) C:/msys64/clang64/include/c++/v1/new:295:10
    #3 0x7ff67f4ded6f in std::__1::allocator<microRange>::allocate[abi:nn180100](unsigned long long) C:/msys64/clang64/include/c++/v1/__memory/allocator.h:125:32
    #4 0x7ff67f4daf5c in std::__1::allocator_traits<std::__1::allocator<microRange>>::allocate[abi:nn180100](std::__1::allocator<microRange>&, unsigned long long) C:/msys64/clang64/include/c++/v1/__memory/allocator_traits.h:269:16
    #5 0x7ff67f4d9520 in std::__1::deque<microRange, std::__1::allocator<microRange>>::__add_front_capacity() C:/msys64/clang64/include/c++/v1/deque:2040:37
    #6 0x7ff67f4ae541 in std::__1::deque<microRange, std::__1::allocator<microRange>>::push_front(microRange const&) C:/msys64/clang64/include/c++/v1/deque:1554:5
    #7 0x7ff67f43cd20 in mVUsetupRange(microVU&, int, bool) C:/src/pcsx2/pcsx2/x86/microVU_Compile.inl:77:11
    #8 0x7ff67f428725 in mVUcompile(microVU&, unsigned int, unsigned long long) C:/src/pcsx2/pcsx2/x86/microVU_Compile.inl:702:2
    #9 0x7ff67f44d2c7 in mVUentryGet(microVU&, microBlockManager*, unsigned int, unsigned long long) C:/src/pcsx2/pcsx2/x86/microVU_Compile.inl:1010:10
    #10 0x7ff67f43961f in mVUblockFetch(microVU&, unsigned int, unsigned long long) C:/src/pcsx2/pcsx2/x86/microVU_Compile.inl:1022:9
    #11 0x7ff67f4d03f1 in void* mVUsearchProg<1>(unsigned int, unsigned long long) C:/src/pcsx2/pcsx2/x86/microVU.cpp:274:22
    #12 0x7ff67f4ad532 in void* mVUcompileJIT<1>(unsigned int, unsigned long long) C:/src/pcsx2/pcsx2/x86/microVU_Compile.inl:1052:13
    #13 0x7ff6c4b02a13  (<unknown module>)
Thread T3 created by T2 here:
    #0 0x7ffa77d24536 in CreateThread (C:\msys64\clang64\bin\libclang_rt.asan_dynamic-x86_64.dll+0x180054536)
    #1 0x7ffb27d21896  (C:\WINDOWS\System32\ucrtbase.dll+0x180021896)
    #2 0x7ff67f3d6547 in Threading::Thread::Start(std::__1::function<void ()>) C:/src/pcsx2/common/Windows/WinThreads.cpp:174:44
    #3 0x7ff67f3db883 in VU_Thread::Open() C:/src/pcsx2/pcsx2/MTVU.cpp:101:11
    #4 0x7ff67f478605 in recMicroVU1::Reserve() C:/src/pcsx2/pcsx2/x86/microVU.cpp:315:12
    #5 0x7ff67e9bd757 in VMManager::InitializeCPUProviders() C:/src/pcsx2/pcsx2/VMManager.cpp:2557:14
    #6 0x7ff67e9bce67 in VMManager::Internal::CPUThreadInitialize() C:/src/pcsx2/pcsx2/VMManager.cpp:402:2
    #7 0x7ff67df91d8a in EmuThread::run() C:/src/pcsx2/pcsx2-qt/QtHost.cpp:376:7
    #8 0x7ffa73f87a6a in QThreadPrivate::start(void*) (C:\msys64\clang64\bin\Qt6Core.dll+0x180237a6a)
    #9 0x7ffa77d24609 in CreateThread (C:\msys64\clang64\bin\libclang_rt.asan_dynamic-x86_64.dll+0x180054609)
    #10 0x7ffb29997373  (C:\WINDOWS\System32\KERNEL32.DLL+0x180017373)
    #11 0x7ffb2a1bcc90  (C:\WINDOWS\SYSTEM32\ntdll.dll+0x18004cc90)
Thread T2 created by T0 here:
    #0 0x7ffa77d24536 in CreateThread (C:\msys64\clang64\bin\libclang_rt.asan_dynamic-x86_64.dll+0x180054536)
    #1 0x7ffa73f87e6c in QThread::start(QThread::Priority) (C:\msys64\clang64\bin\Qt6Core.dll+0x180237e6c)
    #2 0x7ff67df8eab7 in EmuThread::start() C:/src/pcsx2/pcsx2-qt/QtHost.cpp:115:25
    #3 0x7ff67dfa2f25 in qMain(int, char**) C:/src/pcsx2/pcsx2-qt/QtHost.cpp:2329:2
    #4 0x7ff67f062cf7 in main C:/M/B/src/mingw-w64/mingw-w64-crt/crt/crtexewin.c:67:10
    #5 0x7ff67ddc1312 in __tmainCRTStartup C:/M/B/src/mingw-w64/mingw-w64-crt/crt/crtexe.c:258:15
    #6 0x7ff67ddc1155 in .l_startw C:/M/B/src/mingw-w64/mingw-w64-crt/crt/crtexe.c:148:9
    #7 0x7ffb29997373  (C:\WINDOWS\System32\KERNEL32.DLL+0x180017373)
    #8 0x7ffb2a1bcc90  (C:\WINDOWS\SYSTEM32\ntdll.dll+0x18004cc90)
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 C:/src/pcsx2/pcsx2/x86/microVU_Compile.inl:90:23 in mVUsetupRange(microVU&, int, bool)
Shadow bytes around the buggy address:
  0x12211936de00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
  0x12211936de80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
  0x12211936df00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
  0x12211936df80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
  0x12211936e000: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
=>0x12211936e080: fc fc fc fc fc fc fc fc fc fc[fc]00 00 00 00 00
  0x12211936e100: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
  0x12211936e180: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
  0x12211936e200: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
  0x12211936e280: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
  0x12211936e300: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
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
==23240==ABORTING

Copy link
Member

@F0bes F0bes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice find, iterator invalidation is always fun

@F0bes F0bes merged commit 4c267c4 into PCSX2:master Sep 16, 2024
12 checks passed
@oltolm oltolm deleted the microvu-fix branch September 16, 2024 17:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants