static-delta: Reject oversized parts at generation time
authorJoseph Marrero Corchado <jmarrero@redhat.com>
Tue, 28 Jul 2026 18:16:09 +0000 (14:16 -0400)
committerJoseph Marrero Corchado <jmarrero@redhat.com>
Tue, 28 Jul 2026 18:16:09 +0000 (14:16 -0400)
Error in finish_part() when the uncompressed payload exceeds the
consumer-side limit, so that an oversized --max-chunk-size fails
at delta creation rather than producing content clients reject.

src/libostree/ostree-repo-static-delta-compilation.c
src/ostree/ot-builtin-static-delta.c

index 54e4801fe8e8bc36c7f8a670f4065a48f521dc9b..25c77d06609f467f2c32b2ad31eb14ba118c085b 100644 (file)
@@ -251,6 +251,21 @@ finish_part (OstreeStaticDeltaBuilder *builder, GError **error)
     g_variant_ref_sink (delta_part_content);
   }
 
+  /* Reject parts whose uncompressed payload exceeds the hard limit that
+   * consumers enforce (OSTREE_STATIC_DELTA_PART_MAX_USIZE_BYTES).  Without
+   * this check, a large --max-chunk-size would produce deltas that every
+   * client rejects at apply time (CVE / RHEL-189208).
+   */
+  {
+    gsize payload_size = g_variant_get_size (delta_part_content);
+    if (payload_size > OSTREE_STATIC_DELTA_PART_MAX_USIZE_BYTES)
+      return glnx_throw (error,
+                         "Delta part %u uncompressed payload size %" G_GSIZE_FORMAT
+                         " bytes exceeds maximum %" G_GUINT64_FORMAT "; reduce --max-chunk-size",
+                         builder->parts->len, payload_size,
+                         (guint64)OSTREE_STATIC_DELTA_PART_MAX_USIZE_BYTES);
+  }
+
   /* Hardcode xz for now */
   compressor = (GConverter *)_ostree_lzma_compressor_new (NULL);
   compression_type_char = 'x';
@@ -1237,7 +1252,7 @@ get_fallback_headers (OstreeRepo *self, OstreeStaticDeltaBuilder *builder, GVari
  * are known:
  *   - min-fallback-size: u: Minimum uncompressed size in megabytes to use fallback, 0 to disable
  * fallbacks
- *   - max-chunk-size: u: Maximum size in megabytes of a delta part
+ *   - max-chunk-size: u: Maximum size in megabytes of a delta part (hard cap: 512 MiB)
  *   - max-bsdiff-size: u: Maximum size in megabytes to consider bsdiff compression
  *   for input files
  *   - compression: y: Compression type: 0=none, x=lzma, g=gzip
index ba91175e4553c1ef778051505aed9b302216873b..66d5faa6f8508ebc3a2f58ebe7e636831039ee5b 100644 (file)
@@ -96,7 +96,7 @@ static GOptionEntry generate_options[] = {
   { "max-bsdiff-size", 0, 0, G_OPTION_ARG_STRING, &opt_max_bsdiff_size,
     "Maximum size in megabytes to consider bsdiff compression for input files", NULL },
   { "max-chunk-size", 0, 0, G_OPTION_ARG_STRING, &opt_max_chunk_size,
-    "Maximum size of delta chunks in megabytes", NULL },
+    "Maximum size of delta chunks in megabytes (hard cap: 512 MiB)", NULL },
   { "filename", 0, 0, G_OPTION_ARG_FILENAME, &opt_filename,
     "Write the delta content to PATH (a directory).  If not specified, the OSTree repository is "
     "used",