From 317a652f2af3d6710a06b3791739002b05672b82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20H=C3=A4rer?= Date: Sat, 6 Jul 2024 20:03:41 +0200 Subject: [PATCH] RecursiveMutex: Prevent initialization-order-fiasco of mutex attribute ASAN error: ==226990==ERROR: AddressSanitizer: initialization-order-fiasco on address 0x5a8f25b81ce0 at pc 0x5a8f17dd10ae bp 0x7ffe5391ce50 sp 0x7ffe5391ce48 READ of size 1 at 0x5a8f25b81ce0 thread T0 #0 0x5a8f17dd10ad in XbmcThreads::CRecursiveMutex::getRecursiveAttr() xbmc/platform/posix/threads/RecursiveMutex.cpp:37:8 #1 0x5a8f17817a4e in XbmcThreads::CRecursiveMutex::CRecursiveMutex() xbmc/platform/posix/threads/RecursiveMutex.h:35:60 #2 0x5a8f17817998 in XbmcThreads::CountingLockable::CountingLockable() xbmc/threads/Lockables.h:47:12 #3 0x5a8f1780dae8 in CCriticalSection::CCriticalSection() xbmc/threads/CriticalSection.h:16:7 #4 0x5a8f1b27fd98 in CComponentContainer::CComponentContainer() xbmc/utils/ComponentContainer.h:26:7 #5 0x5a8f1b1f3273 in CApplication::CApplication() xbmc/application/Application.cpp:217:15 #6 0x5a8f17918fe0 in xbmcutil::GlobalsSingleton::getInstance() xbmc/utils/GlobalsHandling.h:147:23 #7 0x5a8f17918f0f in __cxx_global_var_init.1 xbmc/application/Application.h:250:1 #8 0x5a8f17918f49 in _GLOBAL__sub_I_UPnPRenderer.cpp xbmc/network/upnp/UPnPRenderer.cpp #9 0x7c5016639dc3 in __libc_start_main (/usr/lib/libc.so.6+0x25dc3) (BuildId: 32a656aa5562eece8c59a585f5eacd6cf5e2307b) #10 0x5a8f17636814 in _start (/home/mark/Coding/Repos/kodi-git/build_clang_debug_sanitizer/kodi.bin+0x9fa3814) (BuildId: 6cfd7dacce8a4a587ad47d2f082a4e50dad4c176) 0x5a8f25b81ce0 is located 32 bytes before global variable 'XbmcThreads::recursiveAttr' defined in 'xbmc/platform/posix/threads/RecursiveMutex.cpp' (0x5a8f25b81d00) of size 4 registered at: #0 0x5a8f17651629 in __asan_register_globals.part.0 (/home/mark/Coding/Repos/kodi-git/build_clang_debug_sanitizer/kodi.bin+0x9fbe629) (BuildId: 6cfd7dacce8a4a587ad47d2f082a4e50dad4c176) #1 0x5a8f17651cce in __asan_register_elf_globals (/home/mark/Coding/Repos/kodi-git/build_clang_debug_sanitizer/kodi.bin+0x9fbecce) (BuildId: 6cfd7dacce8a4a587ad47d2f082a4e50dad4c176) #2 0x7c5016639dc3 in __libc_start_main (/usr/lib/libc.so.6+0x25dc3) (BuildId: 32a656aa5562eece8c59a585f5eacd6cf5e2307b) #3 0x5a8f17636814 in _start (/home/mark/Coding/Repos/kodi-git/build_clang_debug_sanitizer/kodi.bin+0x9fa3814) (BuildId: 6cfd7dacce8a4a587ad47d2f082a4e50dad4c176) 0x5a8f25b81ce0 is located 0 bytes inside of global variable 'XbmcThreads::recursiveAttrSet' defined in 'xbmc/platform/posix/threads/RecursiveMutex.cpp' (0x5a8f25b81ce0) of size 1 'XbmcThreads::recursiveAttrSet' is ascii string '' registered at: #0 0x5a8f17651629 in __asan_register_globals.part.0 (/home/mark/Coding/Repos/kodi-git/build_clang_debug_sanitizer/kodi.bin+0x9fbe629) (BuildId: 6cfd7dacce8a4a587ad47d2f082a4e50dad4c176) #1 0x5a8f17651cce in __asan_register_elf_globals (/home/mark/Coding/Repos/kodi-git/build_clang_debug_sanitizer/kodi.bin+0x9fbecce) (BuildId: 6cfd7dacce8a4a587ad47d2f082a4e50dad4c176) #2 0x7c5016639dc3 in __libc_start_main (/usr/lib/libc.so.6+0x25dc3) (BuildId: 32a656aa5562eece8c59a585f5eacd6cf5e2307b) #3 0x5a8f17636814 in _start (/home/mark/Coding/Repos/kodi-git/build_clang_debug_sanitizer/kodi.bin+0x9fa3814) (BuildId: 6cfd7dacce8a4a587ad47d2f082a4e50dad4c176) SUMMARY: AddressSanitizer: initialization-order-fiasco xbmc/platform/posix/threads/RecursiveMutex.cpp:37:8 in XbmcThreads::CRecursiveMutex::getRecursiveAttr() Shadow bytes around the buggy address: 0x5a8f25b81a00: f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 00 00 00 00 0x5a8f25b81a80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x5a8f25b81b00: 00 00 f9 f9 f9 f9 f9 f9 00 f9 f9 f9 00 00 00 00 0x5a8f25b81b80: f6 f6 f6 f6 00 00 00 00 f6 f6 f6 f6 f6 f6 f6 f6 0x5a8f25b81c00: f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 =>0x5a8f25b81c80: 00 00 00 00 f6 f6 f6 f6 00 00 00 00[f6]f6 f6 f6 0x5a8f25b81d00: 04 f9 f9 f9 01 f9 f9 f9 00 00 00 00 f6 f6 f6 f6 0x5a8f25b81d80: 00 00 00 00 f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 f6 0x5a8f25b81e00: 00 00 00 00 f6 f6 f6 f6 00 00 00 00 f9 f9 f9 f9 0x5a8f25b81e80: 00 f9 f9 f9 00 f9 f9 f9 f6 f6 f6 f6 f6 f6 f6 f6 0x5a8f25b81f00: f6 f6 f6 f6 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 --- .../platform/posix/threads/RecursiveMutex.cpp | 23 ++++--------------- 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/xbmc/platform/posix/threads/RecursiveMutex.cpp b/xbmc/platform/posix/threads/RecursiveMutex.cpp index 652bc3722eece..19a940e518bca 100644 --- a/xbmc/platform/posix/threads/RecursiveMutex.cpp +++ b/xbmc/platform/posix/threads/RecursiveMutex.cpp @@ -11,31 +11,18 @@ namespace XbmcThreads { -static pthread_mutexattr_t recursiveAttr; - -static bool SetRecursiveAttr() +pthread_mutexattr_t& CRecursiveMutex::getRecursiveAttr() { - static bool alreadyCalled = false; - - if (!alreadyCalled) + static pthread_mutexattr_t recursiveAttr = []() { + pthread_mutexattr_t recursiveAttr; pthread_mutexattr_init(&recursiveAttr); pthread_mutexattr_settype(&recursiveAttr, PTHREAD_MUTEX_RECURSIVE); #if !defined(TARGET_ANDROID) pthread_mutexattr_setprotocol(&recursiveAttr, PTHREAD_PRIO_INHERIT); #endif - alreadyCalled = true; - } - - return true; // note, we never call destroy. -} - -static bool recursiveAttrSet = SetRecursiveAttr(); - -pthread_mutexattr_t& CRecursiveMutex::getRecursiveAttr() -{ - if (!recursiveAttrSet) // this is only possible in the single threaded startup code - recursiveAttrSet = SetRecursiveAttr(); + return recursiveAttr; + }(); return recursiveAttr; }