Version in base suite: 5.8.1-1+deb13u1 Base version: xz-utils_5.8.1-1+deb13u1 Target version: xz-utils_5.8.1-1+deb13u2 Base file: /srv/ftp-master.debian.org/ftp/pool/main/x/xz-utils/xz-utils_5.8.1-1+deb13u1.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/x/xz-utils/xz-utils_5.8.1-1+deb13u2.dsc changelog | 8 gbp.conf | 2 patches/0001-liblzma-Fix-a-buffer-overflow-in-lzma_index_append.patch | 6 patches/liblzma-Clean-up-after-a-filter-chain-initialization-erro.patch | 93 ++++++++++ patches/liblzma-Make-lzma_lz_decoder_init-safe-to-reinit-after-al.patch | 28 +++ patches/liblzma-Make-lzma_simple_coder_init-reinit-safe-after-all.patch | 53 +++++ patches/liblzma-mt-dec-Protect-progress_in-update-with-mutex.patch | 39 ++++ patches/series | 4 8 files changed, 227 insertions(+), 6 deletions(-) dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmp4xbrjjr0/xz-utils_5.8.1-1+deb13u1.dsc: no acceptable signature found dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmp4xbrjjr0/xz-utils_5.8.1-1+deb13u2.dsc: no acceptable signature found diff -Nru xz-utils-5.8.1/debian/changelog xz-utils-5.8.1/debian/changelog --- xz-utils-5.8.1/debian/changelog 2026-07-01 19:00:37.000000000 +0000 +++ xz-utils-5.8.1/debian/changelog 2026-09-27 13:30:44.000000000 +0000 @@ -1,3 +1,11 @@ +xz-utils (5.8.1-1+deb13u2) trixie-security; urgency=medium + + * GHSA-5qpq-xqfv-j9pg ("Invalid write if a decoder is reinitialized after + allocation failure") (Closes: #1147318). + * Protect progress variable with a mutex. + + -- Sebastian Andrzej Siewior Sun, 27 Sep 2026 15:30:44 +0200 + xz-utils (5.8.1-1+deb13u1) trixie; urgency=medium * Non-maintainer upload. diff -Nru xz-utils-5.8.1/debian/gbp.conf xz-utils-5.8.1/debian/gbp.conf --- xz-utils-5.8.1/debian/gbp.conf 2025-04-03 20:58:15.000000000 +0000 +++ xz-utils-5.8.1/debian/gbp.conf 2026-09-27 13:17:50.000000000 +0000 @@ -1,5 +1,5 @@ [DEFAULT] -debian-branch=debian/unstable +debian-branch=debian/trixie upstream-branch=upstream/v5.8 [pq] diff -Nru xz-utils-5.8.1/debian/patches/0001-liblzma-Fix-a-buffer-overflow-in-lzma_index_append.patch xz-utils-5.8.1/debian/patches/0001-liblzma-Fix-a-buffer-overflow-in-lzma_index_append.patch --- xz-utils-5.8.1/debian/patches/0001-liblzma-Fix-a-buffer-overflow-in-lzma_index_append.patch 2026-07-01 19:00:13.000000000 +0000 +++ xz-utils-5.8.1/debian/patches/0001-liblzma-Fix-a-buffer-overflow-in-lzma_index_append.patch 2026-09-27 13:21:17.000000000 +0000 @@ -1,4 +1,3 @@ -From ec8eb76979750630211ddbda41c7c64dac36d73d Mon Sep 17 00:00:00 2001 From: Lasse Collin Date: Sun, 29 Mar 2026 19:11:21 +0300 Subject: liblzma: Fix a buffer overflow in lzma_index_append() @@ -19,7 +18,7 @@ 1 file changed, 21 insertions(+) diff --git a/src/liblzma/common/index.c b/src/liblzma/common/index.c -index 6add6a68..c4aadb9b 100644 +index 6add6a6..c4aadb9 100644 --- a/src/liblzma/common/index.c +++ b/src/liblzma/common/index.c @@ -433,6 +433,26 @@ lzma_index_prealloc(lzma_index *i, lzma_vli records) @@ -57,6 +56,3 @@ g = lzma_alloc(sizeof(index_group) + i->prealloc * sizeof(index_record), allocator); --- -2.47.3 - diff -Nru xz-utils-5.8.1/debian/patches/liblzma-Clean-up-after-a-filter-chain-initialization-erro.patch xz-utils-5.8.1/debian/patches/liblzma-Clean-up-after-a-filter-chain-initialization-erro.patch --- xz-utils-5.8.1/debian/patches/liblzma-Clean-up-after-a-filter-chain-initialization-erro.patch 1970-01-01 00:00:00.000000000 +0000 +++ xz-utils-5.8.1/debian/patches/liblzma-Clean-up-after-a-filter-chain-initialization-erro.patch 2026-09-27 13:21:17.000000000 +0000 @@ -0,0 +1,93 @@ +From: Lasse Collin +Date: Wed, 9 Sep 2026 14:14:40 +0300 +Subject: liblzma: Clean up after a filter chain initialization error + +Filter coders are initialized using lzma_next_filter_init(). If filter +chain initialization fails, the entire filter chain should be cleaned up +with lzma_next_end(). lzma_raw_encoder_init() and lzma_raw_decoder_init() +have always done this via lzma_raw_coder_init() in filter_common.c. +(Separate cleanup is weird, but it must have made sense to the young me.) + +The following decoders initialize LZMA1 filter directly without using the +raw filter chain API. This avoids needlessly pulling in all other filters +when a program is linked against static liblzma. These functions didn't +call lzma_next_end() after an initialization error, which left the state +available for later reinitialization. + + - lzma_alone_decoder() + - lzma_lzip_decoder() + - lzma_auto_decoder() [*] + - lzma_microlzma_decoder() + +[*] lzma_auto_decoder() is only indirectly affected due to the first two + functions. lzma_auto_decoder() itself doesn't need a fix. + +There are also encoder functions that initialize the LZMA1 encoder +directly. They don't have this issue because the whole lzma_stream +is cleaned up when encoder initialization fails. + +Reported-by: GitHub user christos-cantina-security (christos-spearbit) +(cherry picked from commit e5e63d50eac1b4357a5a7a0abd3c5f99a5c47881) +--- + src/liblzma/common/alone_decoder.c | 8 ++++++-- + src/liblzma/common/lzip_decoder.c | 8 ++++++-- + src/liblzma/common/microlzma_decoder.c | 8 ++++++-- + 3 files changed, 18 insertions(+), 6 deletions(-) + +diff --git a/src/liblzma/common/alone_decoder.c b/src/liblzma/common/alone_decoder.c +index e2b58e1..00d7f25 100644 +--- a/src/liblzma/common/alone_decoder.c ++++ b/src/liblzma/common/alone_decoder.c +@@ -150,8 +150,12 @@ alone_decode(void *coder_ptr, const lzma_allocator *allocator, + } + }; + +- return_if_error(lzma_next_filter_init(&coder->next, +- allocator, filters)); ++ const lzma_ret ret = lzma_next_filter_init(&coder->next, ++ allocator, filters); ++ if (ret != LZMA_OK) { ++ lzma_next_end(&coder->next, allocator); ++ return ret; ++ } + + coder->sequence = SEQ_CODE; + break; +diff --git a/src/liblzma/common/lzip_decoder.c b/src/liblzma/common/lzip_decoder.c +index 4dff2d5..9870a5b 100644 +--- a/src/liblzma/common/lzip_decoder.c ++++ b/src/liblzma/common/lzip_decoder.c +@@ -236,8 +236,12 @@ lzip_decode(void *coder_ptr, const lzma_allocator *allocator, + } + }; + +- return_if_error(lzma_next_filter_init(&coder->lzma_decoder, +- allocator, filters)); ++ const lzma_ret ret = lzma_next_filter_init( ++ &coder->lzma_decoder, allocator, filters); ++ if (ret != LZMA_OK) { ++ lzma_next_end(&coder->lzma_decoder, allocator); ++ return ret; ++ } + + coder->crc32 = 0; + coder->sequence = SEQ_LZMA_STREAM; +diff --git a/src/liblzma/common/microlzma_decoder.c b/src/liblzma/common/microlzma_decoder.c +index 882cb2c..a7720cc 100644 +--- a/src/liblzma/common/microlzma_decoder.c ++++ b/src/liblzma/common/microlzma_decoder.c +@@ -108,8 +108,12 @@ microlzma_decode(void *coder_ptr, const lzma_allocator *allocator, + } + }; + +- return_if_error(lzma_next_filter_init(&coder->lzma, +- allocator, filters)); ++ const lzma_ret ret = lzma_next_filter_init(&coder->lzma, ++ allocator, filters); ++ if (ret != LZMA_OK) { ++ lzma_next_end(&coder->lzma, allocator); ++ return ret; ++ } + + // Pass one dummy 0x00 byte to the LZMA decoder since that + // is what it expects the first byte to be. diff -Nru xz-utils-5.8.1/debian/patches/liblzma-Make-lzma_lz_decoder_init-safe-to-reinit-after-al.patch xz-utils-5.8.1/debian/patches/liblzma-Make-lzma_lz_decoder_init-safe-to-reinit-after-al.patch --- xz-utils-5.8.1/debian/patches/liblzma-Make-lzma_lz_decoder_init-safe-to-reinit-after-al.patch 1970-01-01 00:00:00.000000000 +0000 +++ xz-utils-5.8.1/debian/patches/liblzma-Make-lzma_lz_decoder_init-safe-to-reinit-after-al.patch 2026-09-27 13:21:17.000000000 +0000 @@ -0,0 +1,28 @@ +From: Lasse Collin +Date: Wed, 9 Sep 2026 14:14:40 +0300 +Subject: liblzma: Make lzma_lz_decoder_init() safe to reinit after alloc + failure + +If memory allocation fails and the resulting coder state is reused, +ensure that memory allocation is attempted again. However, coders that +are initialized via lzma_next_filter_init() shouldn't be reinitialized +after failure; they should be cleaned up with lzma_next_end(). + +Reported-by: GitHub user christos-cantina-security (christos-spearbit) +(cherry picked from commit fe4d763d566a38ad61d4c5022520c25578a3a464) +--- + src/liblzma/lz/lz_decoder.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/liblzma/lz/lz_decoder.c b/src/liblzma/lz/lz_decoder.c +index 1cb120a..6dc4cef 100644 +--- a/src/liblzma/lz/lz_decoder.c ++++ b/src/liblzma/lz/lz_decoder.c +@@ -278,6 +278,7 @@ lzma_lz_decoder_init(lzma_next_coder *next, const lzma_allocator *allocator, + + // Allocate and initialize the dictionary. + if (coder->dict.size != alloc_size) { ++ coder->dict.size = 0; + lzma_free(coder->dict.buf, allocator); + + // The LZ_DICT_EXTRA bytes at the end of the buffer aren't diff -Nru xz-utils-5.8.1/debian/patches/liblzma-Make-lzma_simple_coder_init-reinit-safe-after-all.patch xz-utils-5.8.1/debian/patches/liblzma-Make-lzma_simple_coder_init-reinit-safe-after-all.patch --- xz-utils-5.8.1/debian/patches/liblzma-Make-lzma_simple_coder_init-reinit-safe-after-all.patch 1970-01-01 00:00:00.000000000 +0000 +++ xz-utils-5.8.1/debian/patches/liblzma-Make-lzma_simple_coder_init-reinit-safe-after-all.patch 2026-09-27 13:21:17.000000000 +0000 @@ -0,0 +1,53 @@ +From: Lasse Collin +Date: Wed, 9 Sep 2026 14:14:40 +0300 +Subject: liblzma: Make lzma_simple_coder_init() reinit-safe after alloc + failure + +lzma_raw_coder_init() always calls lzma_next_end() if an error occurs +in filter initialization, and no other code path can call +lzma_simple_coder_init(), so this change doesn't fix any bug. +This is just to reduce likelyhood of future bugs. + +(cherry picked from commit c3b290c3dc536d16884a6c695618eb08fdbc700a) +--- + src/liblzma/simple/simple_coder.c | 20 +++++++++++--------- + 1 file changed, 11 insertions(+), 9 deletions(-) + +diff --git a/src/liblzma/simple/simple_coder.c b/src/liblzma/simple/simple_coder.c +index 5cbfa82..48ae90d 100644 +--- a/src/liblzma/simple/simple_coder.c ++++ b/src/liblzma/simple/simple_coder.c +@@ -252,6 +252,17 @@ lzma_simple_coder_init(lzma_next_coder *next, const lzma_allocator *allocator, + if (coder == NULL) + return LZMA_MEM_ERROR; + ++ // Allocate memory for the filter-specific data structure. ++ if (simple_size > 0) { ++ coder->simple = lzma_alloc(simple_size, allocator); ++ if (coder->simple == NULL) { ++ lzma_free(coder, allocator); ++ return LZMA_MEM_ERROR; ++ } ++ } else { ++ coder->simple = NULL; ++ } ++ + next->coder = coder; + next->code = &simple_code; + next->end = &simple_coder_end; +@@ -260,15 +271,6 @@ lzma_simple_coder_init(lzma_next_coder *next, const lzma_allocator *allocator, + coder->next = LZMA_NEXT_CODER_INIT; + coder->filter = filter; + coder->allocated = 2 * unfiltered_max; +- +- // Allocate memory for filter-specific data structure. +- if (simple_size > 0) { +- coder->simple = lzma_alloc(simple_size, allocator); +- if (coder->simple == NULL) +- return LZMA_MEM_ERROR; +- } else { +- coder->simple = NULL; +- } + } + + if (filters[0].options != NULL) { diff -Nru xz-utils-5.8.1/debian/patches/liblzma-mt-dec-Protect-progress_in-update-with-mutex.patch xz-utils-5.8.1/debian/patches/liblzma-mt-dec-Protect-progress_in-update-with-mutex.patch --- xz-utils-5.8.1/debian/patches/liblzma-mt-dec-Protect-progress_in-update-with-mutex.patch 1970-01-01 00:00:00.000000000 +0000 +++ xz-utils-5.8.1/debian/patches/liblzma-mt-dec-Protect-progress_in-update-with-mutex.patch 2026-09-27 13:21:17.000000000 +0000 @@ -0,0 +1,39 @@ +From: Trithem90 <149891156+Trithem90@users.noreply.github.com> +Date: Thu, 3 Sep 2026 19:52:23 +0200 +Subject: liblzma: mt dec: Protect progress_in update with mutex + +Worker threads update coder->progress_in while holding coder->mutex, but +the main thread updated the same field without the mutex while decoding +the next Block Header. ThreadSanitizer reported the concurrent writes and +lzma_get_progress() under-reported input progress by one Block. + +All other coder->progress_in/progress_out accesses in stream_decode_mt() +are done when the worker threads aren't active, so only the access in +SEQ_BLOCK_HEADER needs to lock coder->mutex. + +Co-authored-by: Lasse Collin +Fixes: 4cce3e27f529 ("liblzma: Add threaded .xz decompressor.") +Closes: https://github.com/tukaani-project/xz/pull/243 +(cherry picked from commit c6e3aadbb510e44cecfe870408ecfea1d1ca792c) +--- + src/liblzma/common/stream_decoder_mt.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/src/liblzma/common/stream_decoder_mt.c b/src/liblzma/common/stream_decoder_mt.c +index 271f9b0..c880ab3 100644 +--- a/src/liblzma/common/stream_decoder_mt.c ++++ b/src/liblzma/common/stream_decoder_mt.c +@@ -1079,7 +1079,12 @@ stream_decode_mt(void *coder_ptr, const lzma_allocator *allocator, + const size_t in_old = *in_pos; + const lzma_ret ret = decode_block_header(coder, allocator, + in, in_pos, in_size); +- coder->progress_in += *in_pos - in_old; ++ ++ // Worker threads may finish earlier Blocks and need to update ++ // coder->progress_in at the same time with us. ++ mythread_sync(coder->mutex) { ++ coder->progress_in += *in_pos - in_old; ++ } + + if (ret == LZMA_OK) { + // We didn't decode the whole Block Header yet. diff -Nru xz-utils-5.8.1/debian/patches/series xz-utils-5.8.1/debian/patches/series --- xz-utils-5.8.1/debian/patches/series 2026-07-01 19:00:37.000000000 +0000 +++ xz-utils-5.8.1/debian/patches/series 2026-09-27 13:21:17.000000000 +0000 @@ -1 +1,5 @@ 0001-liblzma-Fix-a-buffer-overflow-in-lzma_index_append.patch +liblzma-mt-dec-Protect-progress_in-update-with-mutex.patch +liblzma-Make-lzma_lz_decoder_init-safe-to-reinit-after-al.patch +liblzma-Clean-up-after-a-filter-chain-initialization-erro.patch +liblzma-Make-lzma_simple_coder_init-reinit-safe-after-all.patch