RedbeanW vor 3 Monaten
Ursprung
Commit
738606ed44

+ 24 - 0
packages/x/xz/patches/5.2.13/fix-unknown-cmake-command.patch

@@ -0,0 +1,24 @@
+From 8f2a7e9160612d5aab8c0d2a5eac38fd2d54826c Mon Sep 17 00:00:00 2001
+From: Redbeanw44602 <[email protected]>
+Date: Thu, 24 Apr 2025 13:19:57 +0800
+Subject: [PATCH] fix unknown cmake command
+
+---
+ cmake/tuklib_large_file_support.cmake | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/cmake/tuklib_large_file_support.cmake b/cmake/tuklib_large_file_support.cmake
+index 0800faa..d29bd81 100644
+--- a/cmake/tuklib_large_file_support.cmake
++++ b/cmake/tuklib_large_file_support.cmake
+@@ -14,6 +14,7 @@
+ 
+ include("${CMAKE_CURRENT_LIST_DIR}/tuklib_common.cmake")
+ include(CheckCSourceCompiles)
++include(CMakePushCheckState)
+ 
+ function(tuklib_large_file_support TARGET_OR_ALL)
+     # MSVC must be handled specially in the C code.
+-- 
+2.49.0
+

+ 334 - 0
packages/x/xz/patches/xz-cve-2025-31115.patch

@@ -0,0 +1,334 @@
+# Fix CVE-2025-31115 in XZ Utils 5.3.3alpha to 5.8.0
+# This applies to all affected releases.
+# https://tukaani.org/xz/threaded-decoder-early-free.html
+
+From 831b55b971cf579ee16a854f177c36b20d3c6999 Mon Sep 17 00:00:00 2001
+From: Lasse Collin <[email protected]>
+Date: Thu, 3 Apr 2025 14:34:42 +0300
+Subject: [PATCH 1/4] liblzma: mt dec: Fix a comment
+
+Reviewed-by: Sebastian Andrzej Siewior <[email protected]>
+Thanks-to: Sam James <[email protected]>
+---
+ src/liblzma/common/stream_decoder_mt.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/liblzma/common/stream_decoder_mt.c b/src/liblzma/common/stream_decoder_mt.c
+index 22c9375f..812b745d 100644
+--- a/src/liblzma/common/stream_decoder_mt.c
++++ b/src/liblzma/common/stream_decoder_mt.c
+@@ -347,7 +347,7 @@ worker_enable_partial_update(void *thr_ptr)
+ 
+ 
+ /// Things do to at THR_STOP or when finishing a Block.
+-/// This is called with thr->mutex locked.
++/// This is called with thr->coder->mutex locked.
+ static void
+ worker_stop(struct worker_thread *thr)
+ {
+-- 
+2.49.0
+
+
+From c0c835964dfaeb2513a3c0bdb642105152fe9f34 Mon Sep 17 00:00:00 2001
+From: Lasse Collin <[email protected]>
+Date: Thu, 3 Apr 2025 14:34:42 +0300
+Subject: [PATCH 2/4] liblzma: mt dec: Simplify by removing the THR_STOP state
+
+The main thread can directly set THR_IDLE in threads_stop() which is
+called when errors are detected. threads_stop() won't return the stopped
+threads to the pool or free the memory pointed by thr->in anymore, but
+it doesn't matter because the existing workers won't be reused after
+an error. The resources will be cleaned up when threads_end() is
+called (reinitializing the decoder always calls threads_end()).
+
+Reviewed-by: Sebastian Andrzej Siewior <[email protected]>
+Thanks-to: Sam James <[email protected]>
+---
+ src/liblzma/common/stream_decoder_mt.c | 75 ++++++++++----------------
+ 1 file changed, 29 insertions(+), 46 deletions(-)
+
+diff --git a/src/liblzma/common/stream_decoder_mt.c b/src/liblzma/common/stream_decoder_mt.c
+index 812b745d..82962c64 100644
+--- a/src/liblzma/common/stream_decoder_mt.c
++++ b/src/liblzma/common/stream_decoder_mt.c
+@@ -23,15 +23,10 @@ typedef enum {
+ 	THR_IDLE,
+ 
+ 	/// Decoding is in progress.
+-	/// Main thread may change this to THR_STOP or THR_EXIT.
++	/// Main thread may change this to THR_IDLE or THR_EXIT.
+ 	/// The worker thread may change this to THR_IDLE.
+ 	THR_RUN,
+ 
+-	/// The main thread wants the thread to stop whatever it was doing
+-	/// but not exit. Main thread may change this to THR_EXIT.
+-	/// The worker thread may change this to THR_IDLE.
+-	THR_STOP,
+-
+ 	/// The main thread wants the thread to exit.
+ 	THR_EXIT,
+ 
+@@ -346,27 +341,6 @@ worker_enable_partial_update(void *thr_ptr)
+ }
+ 
+ 
+-/// Things do to at THR_STOP or when finishing a Block.
+-/// This is called with thr->coder->mutex locked.
+-static void
+-worker_stop(struct worker_thread *thr)
+-{
+-	// Update memory usage counters.
+-	thr->coder->mem_in_use -= thr->in_size;
+-	thr->in_size = 0; // thr->in was freed above.
+-
+-	thr->coder->mem_in_use -= thr->mem_filters;
+-	thr->coder->mem_cached += thr->mem_filters;
+-
+-	// Put this thread to the stack of free threads.
+-	thr->next = thr->coder->threads_free;
+-	thr->coder->threads_free = thr;
+-
+-	mythread_cond_signal(&thr->coder->cond);
+-	return;
+-}
+-
+-
+ static MYTHREAD_RET_TYPE
+ worker_decoder(void *thr_ptr)
+ {
+@@ -397,17 +371,6 @@ next_loop_unlocked:
+ 		return MYTHREAD_RET_VALUE;
+ 	}
+ 
+-	if (thr->state == THR_STOP) {
+-		thr->state = THR_IDLE;
+-		mythread_mutex_unlock(&thr->mutex);
+-
+-		mythread_sync(thr->coder->mutex) {
+-			worker_stop(thr);
+-		}
+-
+-		goto next_loop_lock;
+-	}
+-
+ 	assert(thr->state == THR_RUN);
+ 
+ 	// Update progress info for get_progress().
+@@ -510,7 +473,22 @@ next_loop_unlocked:
+ 				&& thr->coder->thread_error == LZMA_OK)
+ 			thr->coder->thread_error = ret;
+ 
+-		worker_stop(thr);
++		// Return the worker thread to the stack of available
++		// threads.
++		{
++			// Update memory usage counters.
++			thr->coder->mem_in_use -= thr->in_size;
++			thr->in_size = 0; // thr->in was freed above.
++
++			thr->coder->mem_in_use -= thr->mem_filters;
++			thr->coder->mem_cached += thr->mem_filters;
++
++			// Put this thread to the stack of free threads.
++			thr->next = thr->coder->threads_free;
++			thr->coder->threads_free = thr;
++		}
++
++		mythread_cond_signal(&thr->coder->cond);
+ 	}
+ 
+ 	goto next_loop_lock;
+@@ -544,17 +522,22 @@ threads_end(struct lzma_stream_coder *coder, const lzma_allocator *allocator)
+ }
+ 
+ 
++/// Tell worker threads to stop without doing any cleaning up.
++/// The clean up will be done when threads_exit() is called;
++/// it's not possible to reuse the threads after threads_stop().
++///
++/// This is called before returning an unrecoverable error code
++/// to the application. It would be waste of processor time
++/// to keep the threads running in such a situation.
+ static void
+ threads_stop(struct lzma_stream_coder *coder)
+ {
+ 	for (uint32_t i = 0; i < coder->threads_initialized; ++i) {
++		// The threads that are in the THR_RUN state will stop
++		// when they check the state the next time. There's no
++		// need to signal coder->threads[i].cond.
+ 		mythread_sync(coder->threads[i].mutex) {
+-			// The state must be changed conditionally because
+-			// THR_IDLE -> THR_STOP is not a valid state change.
+-			if (coder->threads[i].state != THR_IDLE) {
+-				coder->threads[i].state = THR_STOP;
+-				mythread_cond_signal(&coder->threads[i].cond);
+-			}
++			coder->threads[i].state = THR_IDLE;
+ 		}
+ 	}
+ 
+@@ -1941,7 +1924,7 @@ stream_decoder_mt_init(lzma_next_coder *next, const lzma_allocator *allocator,
+ 	// accounting from scratch, too. Changes in filter and block sizes may
+ 	// affect number of threads.
+ 	//
+-	// FIXME? Reusing should be easy but unlike the single-threaded
++	// Reusing threads doesn't seem worth it. Unlike the single-threaded
+ 	// decoder, with some types of input file combinations reusing
+ 	// could leave quite a lot of memory allocated but unused (first
+ 	// file could allocate a lot, the next files could use fewer
+-- 
+2.49.0
+
+
+From d5a2ffe41bb77b918a8c96084885d4dbe4bf6480 Mon Sep 17 00:00:00 2001
+From: Lasse Collin <[email protected]>
+Date: Thu, 3 Apr 2025 14:34:42 +0300
+Subject: [PATCH 3/4] liblzma: mt dec: Don't free the input buffer too early
+ (CVE-2025-31115)
+
+The input buffer must be valid as long as the main thread is writing
+to the worker-specific input buffer. Fix it by making the worker
+thread not free the buffer on errors and not return the worker thread to
+the pool. The input buffer will be freed when threads_end() is called.
+
+With invalid input, the bug could at least result in a crash. The
+effects include heap use after free and writing to an address based
+on the null pointer plus an offset.
+
+The bug has been there since the first committed version of the threaded
+decoder and thus affects versions from 5.3.3alpha to 5.8.0.
+
+As the commit message in 4cce3e27f529 says, I had made significant
+changes on top of Sebastian's patch. This bug was indeed introduced
+by my changes; it wasn't in Sebastian's version.
+
+Thanks to Harri K. Koskinen for discovering and reporting this issue.
+
+Fixes: 4cce3e27f529 ("liblzma: Add threaded .xz decompressor.")
+Reported-by: Harri K. Koskinen <[email protected]>
+Reviewed-by: Sebastian Andrzej Siewior <[email protected]>
+Thanks-to: Sam James <[email protected]>
+---
+ src/liblzma/common/stream_decoder_mt.c | 31 ++++++++++++++++++--------
+ 1 file changed, 22 insertions(+), 9 deletions(-)
+
+diff --git a/src/liblzma/common/stream_decoder_mt.c b/src/liblzma/common/stream_decoder_mt.c
+index 82962c64..98aabcff 100644
+--- a/src/liblzma/common/stream_decoder_mt.c
++++ b/src/liblzma/common/stream_decoder_mt.c
+@@ -435,8 +435,7 @@ next_loop_unlocked:
+ 	}
+ 
+ 	// Either we finished successfully (LZMA_STREAM_END) or an error
+-	// occurred. Both cases are handled almost identically. The error
+-	// case requires updating thr->coder->thread_error.
++	// occurred.
+ 	//
+ 	// The sizes are in the Block Header and the Block decoder
+ 	// checks that they match, thus we know these:
+@@ -444,16 +443,30 @@ next_loop_unlocked:
+ 	assert(ret != LZMA_STREAM_END
+ 		|| thr->out_pos == thr->block_options.uncompressed_size);
+ 
+-	// Free the input buffer. Don't update in_size as we need
+-	// it later to update thr->coder->mem_in_use.
+-	lzma_free(thr->in, thr->allocator);
+-	thr->in = NULL;
+-
+ 	mythread_sync(thr->mutex) {
++		// Block decoder ensures this, but do a sanity check anyway
++		// because thr->in_filled < thr->in_size means that the main
++		// thread is still writing to thr->in.
++		if (ret == LZMA_STREAM_END && thr->in_filled != thr->in_size) {
++			assert(0);
++			ret = LZMA_PROG_ERROR;
++		}
++
+ 		if (thr->state != THR_EXIT)
+ 			thr->state = THR_IDLE;
+ 	}
+ 
++	// Free the input buffer. Don't update in_size as we need
++	// it later to update thr->coder->mem_in_use.
++	//
++	// This step is skipped if an error occurred because the main thread
++	// might still be writing to thr->in. The memory will be freed after
++	// threads_end() sets thr->state = THR_EXIT.
++	if (ret == LZMA_STREAM_END) {
++		lzma_free(thr->in, thr->allocator);
++		thr->in = NULL;
++	}
++
+ 	mythread_sync(thr->coder->mutex) {
+ 		// Move our progress info to the main thread.
+ 		thr->coder->progress_in += thr->in_pos;
+@@ -474,8 +487,8 @@ next_loop_unlocked:
+ 			thr->coder->thread_error = ret;
+ 
+ 		// Return the worker thread to the stack of available
+-		// threads.
+-		{
++		// threads only if no errors occurred.
++		if (ret == LZMA_STREAM_END) {
+ 			// Update memory usage counters.
+ 			thr->coder->mem_in_use -= thr->in_size;
+ 			thr->in_size = 0; // thr->in was freed above.
+-- 
+2.49.0
+
+
+From 8188048854e8d11071b8a50d093c74f4c030acc9 Mon Sep 17 00:00:00 2001
+From: Lasse Collin <[email protected]>
+Date: Thu, 3 Apr 2025 14:34:42 +0300
+Subject: [PATCH 4/4] liblzma: mt dec: Don't modify thr->in_size in the worker
+ thread
+
+Don't set thr->in_size = 0 when returning the thread to the stack of
+available threads. Not only is it useless, but the main thread may
+read the value in SEQ_BLOCK_THR_RUN. With valid inputs, it made
+no difference if the main thread saw the original value or 0. With
+invalid inputs (when worker thread stops early), thr->in_size was
+no longer modified after the previous commit with the security fix
+("Don't free the input buffer too early").
+
+So while the bug appears harmless now, it's important to fix it because
+the variable was being modified without proper locking. It's trivial
+to fix because there is no need to change the value. Only main thread
+needs to set the value in (in SEQ_BLOCK_THR_INIT) when starting a new
+Block before the worker thread is activated.
+
+Fixes: 4cce3e27f529 ("liblzma: Add threaded .xz decompressor.")
+Reviewed-by: Sebastian Andrzej Siewior <[email protected]>
+Thanks-to: Sam James <[email protected]>
+---
+ src/liblzma/common/stream_decoder_mt.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/src/liblzma/common/stream_decoder_mt.c b/src/liblzma/common/stream_decoder_mt.c
+index 98aabcff..1fa92220 100644
+--- a/src/liblzma/common/stream_decoder_mt.c
++++ b/src/liblzma/common/stream_decoder_mt.c
+@@ -491,8 +491,6 @@ next_loop_unlocked:
+ 		if (ret == LZMA_STREAM_END) {
+ 			// Update memory usage counters.
+ 			thr->coder->mem_in_use -= thr->in_size;
+-			thr->in_size = 0; // thr->in was freed above.
+-
+ 			thr->coder->mem_in_use -= thr->mem_filters;
+ 			thr->coder->mem_cached += thr->mem_filters;
+ 
+@@ -1554,6 +1552,10 @@ stream_decode_mt(void *coder_ptr, const lzma_allocator *allocator,
+ 		}
+ 
+ 		// Return if the input didn't contain the whole Block.
++		//
++		// NOTE: When we updated coder->thr->in_filled a few lines
++		// above, the worker thread might by now have finished its
++		// work and returned itself back to the stack of free threads.
+ 		if (coder->thr->in_filled < coder->thr->in_size) {
+ 			assert(*in_pos == in_size);
+ 			return LZMA_OK;
+-- 
+2.49.0
+

+ 47 - 57
packages/x/xz/xmake.lua

@@ -1,14 +1,30 @@
 package("xz")
-
     set_homepage("https://tukaani.org/xz/")
     set_description("General-purpose data compression with high compression ratio.")
 
-    set_urls("https://downloads.sourceforge.net/project/lzmautils/xz-$(version).tar.gz",
-             "https://tukaani.org/xz/xz-$(version).tar.gz")
+    set_urls("https://github.com/tukaani-project/xz/releases/download/v$(version)/xz-$(version).tar.gz",
+             "https://downloads.sourceforge.net/project/lzmautils/xz-$(version).tar.gz")
+    add_versions("5.2.11", "0089d47b966bd9ab48f1d01baf7ce146a3b591716c7477866b807010de3d96ab")
+    add_versions("5.2.12", "61bda930767dcb170a5328a895ec74cab0f5aac4558cdda561c83559db582a13")
+    add_versions("5.2.13", "2942a1a8397cd37688f79df9584947d484dd658db088d51b790317eb3184827b")
+    add_versions("5.4.2", "87947679abcf77cc509d8d1b474218fd16b72281e2797360e909deaee1ac9d05")
+    add_versions("5.4.3", "1c382e0bc2e4e0af58398a903dd62fff7e510171d2de47a1ebe06d1528e9b7e9")
+    add_versions("5.4.4", "aae39544e254cfd27e942d35a048d592959bd7a79f9a624afb0498bb5613bdf8")
+    add_versions("5.4.5", "135c90b934aee8fbc0d467de87a05cb70d627da36abe518c357a873709e5b7d6")
     add_versions("5.4.6", "aeba3e03bf8140ddedf62a0a367158340520f6b384f75ca6045ccc6c0d43fd5c")
-    add_versions("5.2.5", "f6f4910fd033078738bd82bfba4f49219d03b17eb0794eb91efbae419f4aba10")
-    add_versions("5.2.10", "eb7a3b2623c9d0135da70ca12808a214be9c019132baaa61c9e1d198d1d9ded3")
-    add_versions("5.4.1", "e4b0f81582efa155ccf27bb88275254a429d44968e488fc94b806f2a61cd3e22")
+    add_versions("5.4.7", "8db6664c48ca07908b92baedcfe7f3ba23f49ef2476864518ab5db6723836e71")
+    add_versions("5.6.2", "8bfd20c0e1d86f0402f2497cfa71c6ab62d4cd35fd704276e3140bfb71414519")
+    add_versions("5.6.3", "b1d45295d3f71f25a4c9101bd7c8d16cb56348bbef3bbc738da0351e17c73317")
+    add_versions("5.6.4", "269e3f2e512cbd3314849982014dc199a7b2148cf5c91cedc6db629acdf5e09b")
+    add_versions("5.8.1", "507825b599356c10dca1cd720c9d0d0c9d5400b9de300af00e4d1ea150795543")
+
+    add_configs("shared", {description = "Build shared library.", default = false, type = "boolean", readonly = is_plat("wasm")})
+
+    add_patches("5.2.13", "patches/5.2.13/fix-unknown-cmake-command.patch", "88c58a0e4b73d9b3020dd95726908768fa17fdad54bf0cf2cfedfef5cf95f94b")
+    add_patches(">=5.3.0 && <=5.8.0", "patches/xz-cve-2025-31115.patch", "ee188eabc3220684422f62df7a385541a86d2a5c385407f9d8fd94d49b251c4e")
+
+    set_policy("package.cmake_generator.ninja", false)
+    add_deps("cmake")
 
     on_load(function (package)
         if package:is_plat("windows") and not package:config("shared") then
@@ -16,59 +32,33 @@ package("xz")
         end
     end)
 
-    on_install("windows", "mingw@windows,msys", function (package)
-        io.writefile("xmake.lua", [[
-            add_rules("mode.release", "mode.debug")
-            target("lzma")
-                set_kind("$(kind)")
-                add_defines("HAVE_CONFIG_H")
-                add_includedirs("src/common",
-                                "src/liblzma/common",
-                                "src/liblzma/api",
-                                "src/liblzma/check",
-                                "src/liblzma/delta",
-                                "src/liblzma/lz",
-                                "src/liblzma/lzma",
-                                "src/liblzma/rangecoder",
-                                "src/liblzma/simple",
-                                --2013/2017/2019 config.h is the same
-                                "windows/vs2013")
-                add_files("src/common/tuklib_cpucores.c",
-                          "src/common/tuklib_physmem.c",
-                          "src/liblzma/check/*.c|*_small.c|*_tablegen.c",
-                          "src/liblzma/common/*.c",
-                          "src/liblzma/delta/*.c",
-                          "src/liblzma/lzma/*.c|*_tablegen.c",
-                          "src/liblzma/lz/*.c",
-                          "src/liblzma/rangecoder/price_table.c",
-                          "src/liblzma/simple/*.c")
-                if is_kind("shared") and is_plat("windows") then
-                    add_defines("DLL_EXPORT")
-                end
-                add_headerfiles("src/liblzma/api/*.h")
-                add_headerfiles("src/liblzma/api/(lzma/*.h)")
-        ]])
-        import("package.tools.xmake").install(package)
-    end)
-
-    on_install("macosx", "linux", "mingw@linux,macosx", function (package)
-        local configs = {"--disable-dependency-tracking", "--disable-silent-rules"}
-        if package:debug() then
-            table.insert(configs, "--enable-debug")
-        end
-        if package:config("shared") then
-            table.insert(configs, "--enable-static=no")
-            table.insert(configs, "--enable-shared=yes")
-        else
-            table.insert(configs, "--enable-static=yes")
-            table.insert(configs, "--enable-shared=no")
-        end
-        import("package.tools.autoconf").install(package, configs)
-        if not package:is_cross() then
-            package:addenv("PATH", "bin")
+    on_install(function (package)
+        local configs = {
+            "-DXZ_NLS=OFF",
+            "-DENABLE_NLS=OFF", -- before 5.8
+            "-DXZ_TOOL_XZDEC=OFF",
+            "-DXZ_TOOL_LZMADEC=OFF",
+            "-DXZ_TOOL_LZMAINFO=OFF",
+            "-DXZ_TOOL_XZ=OFF",
+            "-DXZ_TOOL_SYMLINKS=OFF",
+            "-DXZ_TOOL_SYMLINKS_LZMA=OFF",
+            "-DXZ_TOOL_SCRIPTS=OFF",
+            "-DXZ_DOXYGEN=OFF",
+            "-DXZ_DOC=OFF"
+        }
+        table.insert(configs, "-DCMAKE_BUILD_TYPE=" .. (package:debug() and "Debug" or "Release"))
+        table.insert(configs, "-DBUILD_SHARED_LIBS=" .. (package:config("shared") and "ON" or "OFF"))
+        local cxflags
+        if not package:is_plat("windows") and package:is_arch("arm.*") then
+            cxflags = "-march=armv8-a+crc+crypto"
         end
+        import("package.tools.cmake").install(package, configs, {cxflags = cxflags})
     end)
 
     on_test(function (package)
-        assert(package:has_cfuncs("lzma_code", {includes = "lzma.h"}))
+        assert(package:check_cxxsnippets({test = [[
+            void test() {
+                lzma_version_string();
+            }
+        ]]}, {configs = {languages = "c11"}, includes = "lzma.h"}))
     end)