From 446e0f2e6c79e2fbf012861c91e678a389c8852f Mon Sep 17 00:00:00 2001 From: Kyle Evans Date: Wed, 15 Dec 2021 23:36:04 -0600 Subject: games/gzdoom: fix wildmidi crash get_patch_data() may recurse on itself, which is not OK to do while using std::lock_guard<>. Move the contents of get_patch_data() to a get_patch_data_locked() that may recurse on itself. This is a direct commit to quarterly, as this has since been fixed by the version present in main. Specifically, a later refactoring ends up dropping the patch_lock entirely after get_patch_data() and friends are pushed into an Instruments class anyways. Based on triage work and an initial patch by wpaul@. --- .../patch-src_sound_wildmidi_wildmidi__lib.cpp | 49 ++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 games/gzdoom/files/patch-src_sound_wildmidi_wildmidi__lib.cpp diff --git a/games/gzdoom/files/patch-src_sound_wildmidi_wildmidi__lib.cpp b/games/gzdoom/files/patch-src_sound_wildmidi_wildmidi__lib.cpp new file mode 100644 index 000000000000..eaa3681841db --- /dev/null +++ b/games/gzdoom/files/patch-src_sound_wildmidi_wildmidi__lib.cpp @@ -0,0 +1,49 @@ +--- src/sound/wildmidi/wildmidi_lib.cpp.orig 2019-05-04 19:58:35 UTC ++++ src/sound/wildmidi/wildmidi_lib.cpp +@@ -1318,11 +1318,9 @@ static int load_sample(struct _patch *sample_patch) { + } + + static struct _patch * +-get_patch_data(unsigned short patchid) { ++get_patch_data_locked(unsigned short patchid) { + struct _patch *search_patch; + +- std::lock_guard lock(patch_lock); +- + search_patch = patch[patchid & 0x007F]; + + if (search_patch == NULL) { +@@ -1335,12 +1333,32 @@ get_patch_data(unsigned short patchid) { + } + search_patch = search_patch->next; + } + if ((patchid >> 8) != 0) { +- return (get_patch_data(patchid & 0x00FF)); ++ return (get_patch_data_locked(patchid & 0x00FF)); + } + return NULL; + } + ++static struct _patch * ++get_patch_data(unsigned short patchid) { ++ struct _patch *patch; ++ ++ /* ++ * Uh, hey, no, sorry pal, you can't use this ++ * construction here. This function can call itself ++ * recursively, which means you will recursively ++ * try to acquire the patch_lock mutex, which is ++ * not allowed with lock_guard. ++ */ ++ ++/* std::lock_guard lock(patch_lock); */ ++ ++ patch_lock.lock(); ++ patch = get_patch_data_locked(patchid); ++ patch_lock.unlock(); ++ return (patch); ++} ++ + static void load_patch(struct _mdi *mdi, unsigned short patchid) { + unsigned int i; + struct _patch *tmp_patch = NULL; -- cgit v1.2.3