Hi,

On Fri, Oct 23, 2026 at 05:18:42AM +0200, Salvatore Bonaccorso wrote:
> Source: brotli
> Version: 1.1.0-2
> X-Debbugs-CC: [email protected]
> Severity: grave
> Tags: security upstream
> 
> Hi,
> 
> The following vulnerability was published for brotli.
> 
> CVE-2026-111497[0]:
> | A buffer overflow vulnerability in the Brotli decoder
> | (c/dec/decode.c) in Google Brotli versions 1.0.3 through 1.2.0 on
> | all platforms allows a remote unauthenticated attacker to corrupt
> | adjacent decoder state memory, disclose sensitive memory contents,
> | cause a denial of service, or potentially execute arbitrary code
> | using a crafted Brotli-compressed stream.      Users need to update
> | any Brotli libraries or binaries between 1.0.3 through 1.2.0 to the
> | latest available version: 1.0.10 or 1.1.1 or 1.2.1.

For trixie-security did the attached debdiff, which is still as well
beeing tested against autopkgtest of reverse dependencies:
https://debusine.debian.net/debian/developers/work-request/1516700/

Regards,
Salvatore
diff -Nru brotli-1.1.0/debian/changelog brotli-1.1.0/debian/changelog
--- brotli-1.1.0/debian/changelog       2023-11-23 11:41:29.000000000 +0100
+++ brotli-1.1.0/debian/changelog       2026-10-23 05:22:51.000000000 +0200
@@ -1,3 +1,11 @@
+brotli (1.1.0-2+deb13u1) trixie-security; urgency=high
+
+  * Non-maintainer upload by the Security Team.
+  * Detect and report invalid stream earlier (CVE-2026-111497)
+    (Closes: #1151690)
+
+ -- Salvatore Bonaccorso <[email protected]>  Fri, 23 Oct 2026 05:22:51 +0200
+
 brotli (1.1.0-2) unstable; urgency=medium
 
   * Team upload
diff -Nru 
brotli-1.1.0/debian/patches/Detect-and-report-invalid-stream-earlier.patch 
brotli-1.1.0/debian/patches/Detect-and-report-invalid-stream-earlier.patch
--- brotli-1.1.0/debian/patches/Detect-and-report-invalid-stream-earlier.patch  
1970-01-01 01:00:00.000000000 +0100
+++ brotli-1.1.0/debian/patches/Detect-and-report-invalid-stream-earlier.patch  
2026-10-23 05:21:39.000000000 +0200
@@ -0,0 +1,239 @@
+From: Evgenii Kliuchnikov <[email protected]>
+Date: Fri, 27 Feb 2026 05:10:32 -0800
+Subject: Detect and report invalid stream earlier.
+Origin: 
https://github.com/google/brotli/commit/da9806362874b9bd4b552a3af360b5d6347beb12
+Bug-Debian: https://bugs.debian.org/1151690
+Bug-Debian-Security: 
https://security-tracker.debian.org/tracker/CVE-2026-111497
+
+PiperOrigin-RevId: 876198329
+(cherry picked from commit 0ed4268a4401abcb4472096340477cf4af7d1a2b)
+---
+ c/dec/decode.c            | 89 ++++++++++++++++++++++++++-------------
+ c/include/brotli/decode.h |  4 +-
+ 2 files changed, 60 insertions(+), 33 deletions(-)
+
+diff --git a/c/dec/decode.c b/c/dec/decode.c
+index 220c7e85c633..2b4576556346 100644
+--- a/c/dec/decode.c
++++ b/c/dec/decode.c
+@@ -1124,7 +1124,7 @@ static BrotliDecoderErrorCode 
DecodeContextMap(brotli_reg_t context_map_size,
+ 
+ /* Decodes a command or literal and updates block type ring-buffer.
+    Reads 3..54 bits. */
+-static BROTLI_INLINE BROTLI_BOOL DecodeBlockTypeAndLength(
++static BROTLI_INLINE BrotliDecoderErrorCode DecodeBlockTypeAndLength(
+     int safe, BrotliDecoderState* s, int tree_type) {
+   brotli_reg_t max_block_type = s->num_block_types[tree_type];
+   const HuffmanCode* type_tree = &s->block_type_trees[
+@@ -1135,7 +1135,7 @@ static BROTLI_INLINE BROTLI_BOOL 
DecodeBlockTypeAndLength(
+   brotli_reg_t* ringbuffer = &s->block_type_rb[tree_type * 2];
+   brotli_reg_t block_type;
+   if (max_block_type <= 1) {
+-    return BROTLI_FALSE;
++    return BROTLI_DECODER_ERROR_FORMAT_BLOCK_SWITCH;
+   }
+ 
+   /* Read 0..15 + 3..39 bits. */
+@@ -1145,11 +1145,13 @@ static BROTLI_INLINE BROTLI_BOOL 
DecodeBlockTypeAndLength(
+   } else {
+     BrotliBitReaderState memento;
+     BrotliBitReaderSaveState(br, &memento);
+-    if (!SafeReadSymbol(type_tree, br, &block_type)) return BROTLI_FALSE;
++    if (!SafeReadSymbol(type_tree, br, &block_type)) {
++      return BROTLI_DECODER_NEEDS_MORE_INPUT;
++    }
+     if (!SafeReadBlockLength(s, &s->block_length[tree_type], len_tree, br)) {
+       s->substate_read_block_length = BROTLI_STATE_READ_BLOCK_LENGTH_NONE;
+       BrotliBitReaderRestoreState(br, &memento);
+-      return BROTLI_FALSE;
++      return BROTLI_DECODER_NEEDS_MORE_INPUT;
+     }
+   }
+ 
+@@ -1165,7 +1167,7 @@ static BROTLI_INLINE BROTLI_BOOL 
DecodeBlockTypeAndLength(
+   }
+   ringbuffer[0] = ringbuffer[1];
+   ringbuffer[1] = block_type;
+-  return BROTLI_TRUE;
++  return BROTLI_DECODER_SUCCESS;
+ }
+ 
+ static BROTLI_INLINE void DetectTrivialLiteralBlockTypes(
+@@ -1202,62 +1204,68 @@ static BROTLI_INLINE void 
PrepareLiteralDecoding(BrotliDecoderState* s) {
+ 
+ /* Decodes the block type and updates the state for literal context.
+    Reads 3..54 bits. */
+-static BROTLI_INLINE BROTLI_BOOL DecodeLiteralBlockSwitchInternal(
++static BROTLI_INLINE BrotliDecoderErrorCode DecodeLiteralBlockSwitchInternal(
+     int safe, BrotliDecoderState* s) {
+-  if (!DecodeBlockTypeAndLength(safe, s, 0)) {
+-    return BROTLI_FALSE;
++  BrotliDecoderErrorCode result = DecodeBlockTypeAndLength(safe, s, 0);
++  if (result != BROTLI_DECODER_SUCCESS) {
++    return result;
+   }
+   PrepareLiteralDecoding(s);
+-  return BROTLI_TRUE;
++  return BROTLI_DECODER_SUCCESS;
+ }
+ 
+-static void BROTLI_NOINLINE DecodeLiteralBlockSwitch(BrotliDecoderState* s) {
+-  DecodeLiteralBlockSwitchInternal(0, s);
++static BROTLI_NOINLINE BrotliDecoderErrorCode
++DecodeLiteralBlockSwitch(BrotliDecoderState* s) {
++  return DecodeLiteralBlockSwitchInternal(0, s);
+ }
+ 
+-static BROTLI_BOOL BROTLI_NOINLINE SafeDecodeLiteralBlockSwitch(
++static BROTLI_NOINLINE BrotliDecoderErrorCode SafeDecodeLiteralBlockSwitch(
+     BrotliDecoderState* s) {
+   return DecodeLiteralBlockSwitchInternal(1, s);
+ }
+ 
+ /* Block switch for insert/copy length.
+    Reads 3..54 bits. */
+-static BROTLI_INLINE BROTLI_BOOL DecodeCommandBlockSwitchInternal(
++static BROTLI_INLINE BrotliDecoderErrorCode DecodeCommandBlockSwitchInternal(
+     int safe, BrotliDecoderState* s) {
+-  if (!DecodeBlockTypeAndLength(safe, s, 1)) {
+-    return BROTLI_FALSE;
++  BrotliDecoderErrorCode result = DecodeBlockTypeAndLength(safe, s, 1);
++  if (result != BROTLI_DECODER_SUCCESS) {
++    return result;
+   }
+   s->htree_command = s->insert_copy_hgroup.htrees[s->block_type_rb[3]];
+-  return BROTLI_TRUE;
++  return BROTLI_DECODER_SUCCESS;
+ }
+ 
+-static void BROTLI_NOINLINE DecodeCommandBlockSwitch(BrotliDecoderState* s) {
+-  DecodeCommandBlockSwitchInternal(0, s);
++static BROTLI_NOINLINE BrotliDecoderErrorCode
++DecodeCommandBlockSwitch(BrotliDecoderState* s) {
++  return DecodeCommandBlockSwitchInternal(0, s);
+ }
+ 
+-static BROTLI_BOOL BROTLI_NOINLINE SafeDecodeCommandBlockSwitch(
+-    BrotliDecoderState* s) {
++static BROTLI_NOINLINE BrotliDecoderErrorCode
++SafeDecodeCommandBlockSwitch(BrotliDecoderState* s) {
+   return DecodeCommandBlockSwitchInternal(1, s);
+ }
+ 
+ /* Block switch for distance codes.
+    Reads 3..54 bits. */
+-static BROTLI_INLINE BROTLI_BOOL DecodeDistanceBlockSwitchInternal(
++static BROTLI_INLINE BrotliDecoderErrorCode DecodeDistanceBlockSwitchInternal(
+     int safe, BrotliDecoderState* s) {
+-  if (!DecodeBlockTypeAndLength(safe, s, 2)) {
+-    return BROTLI_FALSE;
++  BrotliDecoderErrorCode result = DecodeBlockTypeAndLength(safe, s, 2);
++  if (result != BROTLI_DECODER_SUCCESS) {
++    return result;
+   }
+   s->dist_context_map_slice = s->dist_context_map +
+       (s->block_type_rb[5] << BROTLI_DISTANCE_CONTEXT_BITS);
+   s->dist_htree_index = s->dist_context_map_slice[s->distance_context];
+-  return BROTLI_TRUE;
++  return BROTLI_DECODER_SUCCESS;
+ }
+ 
+-static void BROTLI_NOINLINE DecodeDistanceBlockSwitch(BrotliDecoderState* s) {
+-  DecodeDistanceBlockSwitchInternal(0, s);
++static BROTLI_NOINLINE BrotliDecoderErrorCode
++DecodeDistanceBlockSwitch(BrotliDecoderState* s) {
++  return DecodeDistanceBlockSwitchInternal(0, s);
+ }
+ 
+-static BROTLI_BOOL BROTLI_NOINLINE SafeDecodeDistanceBlockSwitch(
++static BROTLI_NOINLINE BrotliDecoderErrorCode SafeDecodeDistanceBlockSwitch(
+     BrotliDecoderState* s) {
+   return DecodeDistanceBlockSwitchInternal(1, s);
+ }
+@@ -1887,6 +1895,9 @@ static BROTLI_INLINE BROTLI_BOOL CheckInputAmount(
+   return BrotliCheckInputAmount(br);
+ }
+ 
++/* NB: METHOD should return BROTLI_FALSE only in case there is not enough 
input;
++       in case of "unsafe" execution, when input is guaranteed to be 
sufficient,
++       result is ignored. */
+ #define BROTLI_SAFE(METHOD)                       \
+   {                                               \
+     if (safe) {                                   \
+@@ -1899,6 +1910,22 @@ static BROTLI_INLINE BROTLI_BOOL CheckInputAmount(
+     }                                             \
+   }
+ 
++/* NB: METHOD should return BROTLI_DECODER_SUCCESS, BROTLI_DECODER_ERROR_*, or
++   BROTLI_DECODER_NEEDS_MORE_INPUT; the later two break the processing. */
++#define BROTLI_SAFE_WITH_STATUS(METHOD)         \
++  {                                             \
++    BrotliDecoderErrorCode status;              \
++    if (safe) {                                 \
++      status = Safe##METHOD;                    \
++    } else {                                    \
++      status = METHOD;                          \
++    }                                           \
++    if (status != BROTLI_DECODER_SUCCESS) {     \
++      result = status;                          \
++      goto saveStateAndReturn;                  \
++    }                                           \
++  }
++
+ static BROTLI_INLINE BrotliDecoderErrorCode ProcessCommandsInternal(
+     int safe, BrotliDecoderState* s) {
+   int pos = s->pos;
+@@ -1938,7 +1965,7 @@ CommandBegin:
+     goto saveStateAndReturn;
+   }
+   if (BROTLI_PREDICT_FALSE(s->block_length[1] == 0)) {
+-    BROTLI_SAFE(DecodeCommandBlockSwitch(s));
++    BROTLI_SAFE_WITH_STATUS(DecodeCommandBlockSwitch(s));
+     goto CommandBegin;
+   }
+   /* Read the insert/copy length in the command. */
+@@ -2046,7 +2073,7 @@ CommandPostDecodeLiterals:
+   } else {
+     /* Read distance code in the command, unless it was implicitly zero. */
+     if (BROTLI_PREDICT_FALSE(s->block_length[2] == 0)) {
+-      BROTLI_SAFE(DecodeDistanceBlockSwitch(s));
++      BROTLI_SAFE_WITH_STATUS(DecodeDistanceBlockSwitch(s));
+     }
+     BROTLI_SAFE(ReadDistance(s, br));
+   }
+@@ -2240,7 +2267,7 @@ CommandPostWrapCopy:
+   }
+ 
+ NextLiteralBlock:
+-  BROTLI_SAFE(DecodeLiteralBlockSwitch(s));
++  BROTLI_SAFE_WITH_STATUS(DecodeLiteralBlockSwitch(s));
+   goto CommandInner;
+ 
+ saveStateAndReturn:
+@@ -2462,6 +2489,8 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
+         if (result != BROTLI_DECODER_SUCCESS) {
+           break;
+         }
++        BROTLI_DCHECK(s->meta_block_remaining_len <=
++                      (int)BROTLI_BLOCK_SIZE_CAP);
+         BROTLI_LOG_UINT(s->is_last_metablock);
+         BROTLI_LOG_UINT(s->meta_block_remaining_len);
+         BROTLI_LOG_UINT(s->is_metadata);
+diff --git a/c/include/brotli/decode.h b/c/include/brotli/decode.h
+index af1aa23f60d7..18ca1482d759 100644
+--- a/c/include/brotli/decode.h
++++ b/c/include/brotli/decode.h
+@@ -85,9 +85,7 @@ typedef enum {
+   BROTLI_ERROR_CODE(_ERROR_FORMAT_, PADDING_1, -14) SEPARATOR              \
+   BROTLI_ERROR_CODE(_ERROR_FORMAT_, PADDING_2, -15) SEPARATOR              \
+   BROTLI_ERROR_CODE(_ERROR_FORMAT_, DISTANCE, -16) SEPARATOR               \
+-                                                                           \
+-  /* -17 code is reserved */                                               \
+-                                                                           \
++  BROTLI_ERROR_CODE(_ERROR_FORMAT_, BLOCK_SWITCH, -17) SEPARATOR           \
+   BROTLI_ERROR_CODE(_ERROR_, COMPOUND_DICTIONARY, -18) SEPARATOR           \
+   BROTLI_ERROR_CODE(_ERROR_, DICTIONARY_NOT_SET, -19) SEPARATOR            \
+   BROTLI_ERROR_CODE(_ERROR_, INVALID_ARGUMENTS, -20) SEPARATOR             \
+-- 
+2.55.0
+
diff -Nru brotli-1.1.0/debian/patches/series brotli-1.1.0/debian/patches/series
--- brotli-1.1.0/debian/patches/series  2023-11-23 11:40:28.000000000 +0100
+++ brotli-1.1.0/debian/patches/series  2026-10-23 05:22:02.000000000 +0200
@@ -1 +1,2 @@
 0001-build-static-libraries-by-default.patch
+Detect-and-report-invalid-stream-earlier.patch

Reply via email to