diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5c3b4b059..81a65e15b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -45,7 +45,7 @@ jobs: sudo apt-get update -y sudo apt-get install -y --no-install-recommends \ $(xargs < .github/workflows/deps-ubuntu-24.04-gcc.txt) - sudo apt-get install -y --install-recommends g++-multilib gcc-multilib winehq-stable wine-stable-dev + sudo apt-get install -y --install-recommends g++-multilib gcc-multilib winehq-devel wine-devel-dev sudo apt-get install -y --install-recommends \ $(xargs < .github/workflows/deps-ubuntu-24.04-fltk.txt) - name: Cache ccache data diff --git a/CMakeLists.txt b/CMakeLists.txt index f439815cb..e45d8b7b2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -596,6 +596,9 @@ if(WANT_VST) else() set(STATUS_VST "No hosts selected and available") endif() + if(WINE_ASLR_ENABLED) + set(STATUS_VST_64 "${STATUS_VST_64}\n\tWARNING: You are using wine ${WINE_VERSION} which cannot disable ASLR, please consider upgrading to wine 10.14 or higher. ASLR may cause crashes with older VSTs.") + endif() endif() IF(WANT_DEBUG_FPE) diff --git a/cmake/modules/FindWine.cmake b/cmake/modules/FindWine.cmake index ea8d90cd2..db8808c0b 100644 --- a/cmake/modules/FindWine.cmake +++ b/cmake/modules/FindWine.cmake @@ -11,6 +11,8 @@ # WINE_32_FLAGS - 32-bit linker flags # WINE_64_LIBRARY_DIRS - Path(s) to 64-bit wine libs # WINE_64_FLAGS - 64-bit linker flags +# WINE_VERSION - Wine version +# WINE_ASLR_ENABLED - If binaries will use dynamicbase/ASLR; influenced by wine version and WINE_WANT_ASLR # MACRO(_findwine_find_flags output expression result) @@ -69,7 +71,33 @@ FIND_PROGRAM(WINE_GCC NAMES NO_DEFAULT_PATH ) +FIND_PROGRAM(WINE NAMES wine PATHS ${WINE_CXX_LOCATIONS} NO_DEFAULT_PATH) FIND_PROGRAM(WINE_BUILD NAMES winebuild PATHS ${WINE_CXX_LOCATIONS} NO_DEFAULT_PATH) + +# Detect wine version +if(WINE) + # Wine version can be formatted: + # wine-1.4 + # wine-6.0.3 (Ubuntu 6.0.3~repack-1) + # wine-9.8 (Staging) + # wine-9.22 + execute_process(COMMAND "${WINE}" --version OUTPUT_VARIABLE WINE_VERSION_OUTPUT ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) + string(REGEX REPLACE "^wine-([^\ \t]+).*$" "\\1" WINE_VERSION "${WINE_VERSION_OUTPUT}") + if(WINE_VERSION VERSION_LESS 8.17) + # Wine versions prior to 8.17 did not use ASLR by default. Assume off. + set(WINE_ASLR_ENABLED false) + elseif(WINE_VERSION VERSION_GREATER_EQUAL 10.14 AND NOT WINE_WANT_ASLR) + # Wine 10.14 introduced the ability to disable ASLR, preventing crashes with older VSTs (See issue #7987) + # Explicitly set '/DYNAMICBASE:NO' per #7987 (effectively setting '/HIGHENTROPYVA:NO' as well for 64-bit) + set(WINE_32_FLAGS "-Wb,--disable-dynamicbase") + set(WINE_64_FLAGS "-Wb,--disable-dynamicbase") + set(WINE_ASLR_ENABLED false) + else() + # Wine versions 8.17 - 10.13 use ASLR by default, but provide no option to disable. Assume on. + set(WINE_ASLR_ENABLED true) + endif() +endif() + # Detect wine paths and handle linking problems IF(WINE_CXX) # call wineg++ to obtain implied includes and libs @@ -149,13 +177,13 @@ mark_as_advanced(WINE_INCLUDE_DIR WINE_LIBRARY WINE_CXX WINE_BUILD) IF(WINE_32_LIBRARY_DIR) IF(WINE_32_LIBRARY_DIR MATCHES "^/opt/wine-.*") # winehq uses a singular lib directory - SET(WINE_32_FLAGS "-L${WINE_32_LIBRARY_DIR}") + SET(WINE_32_FLAGS "-L${WINE_32_LIBRARY_DIR} ${WINE_32_FLAGS}") SET(WINE_32_LIBRARY_DIRS "${WINE_32_LIBRARY_DIR}") ELSEIF(WINE_32_LIBRARY_DIR MATCHES "wine*/lib") - SET(WINE_32_FLAGS "-L${WINE_32_LIBRARY_DIR} -L${WINE_32_LIBRARY_DIR}../") + SET(WINE_32_FLAGS "-L${WINE_32_LIBRARY_DIR} -L${WINE_32_LIBRARY_DIR}../ ${WINE_32_FLAGS}") SET(WINE_32_LIBRARY_DIRS "${WINE_32_LIBRARY_DIR}:${WINE_32_LIBRARY_DIR}/..") ELSE() - SET(WINE_32_FLAGS "-L${WINE_32_LIBRARY_DIR} -L${WINE_32_LIBRARY_DIR}wine/") + SET(WINE_32_FLAGS "-L${WINE_32_LIBRARY_DIR} -L${WINE_32_LIBRARY_DIR}wine/ ${WINE_32_FLAGS}") SET(WINE_32_LIBRARY_DIRS "${WINE_32_LIBRARY_DIR}:${WINE_32_LIBRARY_DIR}wine/") ENDIF() ENDIF() @@ -163,13 +191,13 @@ ENDIF() IF(WINE_64_LIBRARY_DIR) IF(WINE_32_LIBRARY_DIR MATCHES "^/opt/wine-.*") # winehq uses a singular lib directory - SET(WINE_64_FLAGS "-L${WINE_64_LIBRARY_DIR}") + SET(WINE_64_FLAGS "-L${WINE_64_LIBRARY_DIR} ${WINE_64_FLAGS}") SET(WINE_64_LIBRARY_DIRS "${WINE_64_LIBRARY_DIR}") ELSEIF(WINE_64_LIBRARY_DIR MATCHES "wine*/lib") - SET(WINE_64_FLAGS "-L${WINE_64_LIBRARY_DIR} -L${WINE_64_LIBRARY_DIR}../") + SET(WINE_64_FLAGS "-L${WINE_64_LIBRARY_DIR} -L${WINE_64_LIBRARY_DIR}../ ${WINE_64_FLAGS}") SET(WINE_64_LIBRARY_DIRS "${WINE_64_LIBRARY_DIR}:${WINE_64_LIBRARY_DIR}/..") ELSE() - SET(WINE_64_FLAGS "-L${WINE_64_LIBRARY_DIR} -L${WINE_64_LIBRARY_DIR}wine/") + SET(WINE_64_FLAGS "-L${WINE_64_LIBRARY_DIR} -L${WINE_64_LIBRARY_DIR}wine/ ${WINE_64_FLAGS}") SET(WINE_64_LIBRARY_DIRS "${WINE_64_LIBRARY_DIR}:${WINE_64_LIBRARY_DIR}wine/") ENDIF() ENDIF() @@ -179,6 +207,8 @@ message(STATUS " WINE_CXX: ${WINE_CXX}") message(STATUS " WINE_GCC: ${WINE_GCC}") message(STATUS " WINE_32_FLAGS: ${WINE_32_FLAGS}") message(STATUS " WINE_64_FLAGS: ${WINE_64_FLAGS}") +message(STATUS " WINE_VERSION: ${WINE_VERSION}") +message(STATUS " WINE_ASLR_ENABLED: ${WINE_ASLR_ENABLED}") # Create winegcc (technically, wineg++) wrapper configure_file(${CMAKE_CURRENT_LIST_DIR}/winegcc_wrapper.in winegcc_wrapper @ONLY) diff --git a/plugins/VstBase/CMakeLists.txt b/plugins/VstBase/CMakeLists.txt index 53c7c32e8..15d47200c 100644 --- a/plugins/VstBase/CMakeLists.txt +++ b/plugins/VstBase/CMakeLists.txt @@ -47,25 +47,6 @@ foreach(var ${export_variables}) _export_var_to_external(${var}) endforeach() -# If we're building wine-powered RemoteVstPlugins for Linux, -# use a custom winebuild to fix ASLR-related VST crashes. -# See upstream bug report: https://bugs.winehq.org/show_bug.cgi?id=58480 -if(LMMS_BUILD_LINUX AND (LMMS_HAVE_VST_32 OR LMMS_HAVE_VST_64)) - ExternalProject_Add(wine - GIT_REPOSITORY https://github.com/tresf/wine - GIT_TAG 1f8bb63e75baa5c9f901c8f50b4ea9dd69e0baa0 - GIT_SHALLOW ON - SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/wine" - SOURCE_SUBDIR tools/winebuild - BUILD_ALWAYS ON - BUILD_IN_SOURCE ON - INSTALL_COMMAND "" - ) - ExternalProject_Get_Property(wine SOURCE_DIR) - set(CUSTOM_WINEBUILD_EXECUTABLE "${SOURCE_DIR}/tools/winebuild/winebuild") - message(STATUS "Using custom winebuild: ${CUSTOM_WINEBUILD_EXECUTABLE}") -endif() - # build 32 bit version of RemoteVstPlugin if(LMMS_HAVE_VST_32) INCLUDE("${CMAKE_CURRENT_LIST_DIR}/RemoteVstPlugin32.cmake") diff --git a/plugins/VstBase/RemoteVstPlugin32.cmake b/plugins/VstBase/RemoteVstPlugin32.cmake index 72d3149f8..5afb7db81 100644 --- a/plugins/VstBase/RemoteVstPlugin32.cmake +++ b/plugins/VstBase/RemoteVstPlugin32.cmake @@ -34,9 +34,7 @@ ELSEIF(LMMS_BUILD_LINUX) CMAKE_ARGS "${EXTERNALPROJECT_CMAKE_ARGS}" "-DCMAKE_CXX_COMPILER=${WINEGCC}" - # Pass /DYNAMICBASE:NO to custom winebuild per #7987 - "-DCMAKE_CXX_FLAGS=-m32 --winebuild \"${CUSTOM_WINEBUILD_EXECUTABLE}\" -Wb,--disable-dynamicbase" - DEPENDS wine + "-DCMAKE_CXX_FLAGS=-m32" ) INSTALL(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/../32/RemoteVstPlugin32" "${CMAKE_CURRENT_BINARY_DIR}/../32/RemoteVstPlugin32.exe.so" DESTINATION "${PLUGIN_DIR}/32") diff --git a/plugins/VstBase/RemoteVstPlugin64.cmake b/plugins/VstBase/RemoteVstPlugin64.cmake index 4e788da6f..a36d1777f 100644 --- a/plugins/VstBase/RemoteVstPlugin64.cmake +++ b/plugins/VstBase/RemoteVstPlugin64.cmake @@ -9,9 +9,7 @@ ELSEIF(LMMS_BUILD_LINUX) CMAKE_ARGS "${EXTERNALPROJECT_CMAKE_ARGS}" "-DCMAKE_CXX_COMPILER=${WINEGCC}" - # Pass /DYNAMICBASE:NO to custom winebuild per #7987 - "-DCMAKE_CXX_FLAGS=${CXX_FLAGS} --winebuild \"${CUSTOM_WINEBUILD_EXECUTABLE}\" -Wb,--disable-dynamicbase" - DEPENDS wine + "-DCMAKE_CXX_FLAGS=${CXX_FLAGS}" ) INSTALL(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/../RemoteVstPlugin64" "${CMAKE_CURRENT_BINARY_DIR}/../RemoteVstPlugin64.exe.so" DESTINATION "${PLUGIN_DIR}") ENDIF()