REDHAT-BUG-2478495: Medium severity libmodulemd vulnerability

Published May 18, 2026
·
Updated

AIONLYREPORT package: libmodulemd-2.15.2-7.1.hum1 ------ Summary: Incorrect inner loop bound in rpm-map emission causes out-of-bounds read: crafted modulemd v2 metadata with multiple digest types can trigger an out-of-bounds read and likely crash during YAML serialization. Requirements to exploit: An attacker must supply crafted modulemd v2 input to a libmodulemd consumer that parses data.artifacts.rpm-map and later serializes the resulting object. No privileges are needed beyond control of that input. Remote reachability depends on the consuming application; the library itself does not expose a network service. Component affected: libmodulemd-2.15.2-7.1.hum1, modulemd/modulemd-module-stream-v2.c, modulemdmodulestreamv2emitrpmmap() Version affected: libmodulemd-2.15.2-7.1.hum1 Patch available: no released package fix established; proposed patch included below Version fixed: unknown Upstream coordination: This report serves as the initial notification. CVSS: CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - 6.2 (MEDIUM) AV:L - The vulnerable behavior is in a library code path reached when a local caller supplies crafted module metadata; the library does not itself provide a network-facing service. AC:L - The trigger condition is simple: at least two digest algorithms in rpm-map, with fewer checksum entries in one per-digest map than the total digest count. PR:N - No privileges are required beyond the ability to provide the malformed modulemd document to an affected consumer. UI:N - Once the document is parsed and later serialized, the fault occurs automatically. S:U - The impact is limited to the consuming process. C:N - No confidentiality impact is established. I:N - No integrity impact is established. A:H - The out-of-bounds read occurs in the emit path and is likely to abort or crash the process. Impact: Moderate. Under Red Hat guidance, Important is generally reserved for issues that easily compromise confidentiality, integrity, or availability, including easy remote denial of service. Here the established impact is denial of service in a library consumer, but exploitation depends on a specific parse-then-emit workflow rather than a default exposed service. That makes Moderate a better fit than Important, while Low would understate a real memory-safety flaw with a concrete crash path. Embargo: no Reason: This is an availability-focused library flaw with a straightforward one-line fix and usage-dependent reachability. The current evidence does not support an easily exploitable default remote compromise scenario. Acknowledgement: Aisle Research Vulnerability Details: In modulemdmodulestreamv2emitrpmmap(), the outer loop iterates over the top-level digest algorithms in self->rpmartifactmap. Inside that loop, the code creates a checksums array for the current digesttable, but the inner loop incorrectly uses digests->len as its bound instead of checksums->len: c digests = modulemdorderedstrkeys (self->rpmartifactmap, modulemdstrcmpsort); ... checksums = modulemdorderedstrkeys (digesttable, modulemdstrcmpsort); for (guint j = 0; j < digests->len; j++) { checksum = gptrarrayindex (checksums, j); EMITSCALAR (emitter, error, checksum); entry = ghashtablelookup (digesttable, checksum); if (!modulemdrpmmapentryemityaml (entry, emitter, error)) { return FALSE; } } digests is global across digest types, while checksums belongs only to the current digest table. If a document contains two or more digest algorithms but a given digest map has fewer checksum keys than the total number of digest algorithms, gptrarrayindex (checksums, j) reads past the end of checksums. The parse path accepts checksum keys directly from YAML and stores them under the selected digest: c case YAMLSCALAREVENT: / Each key in this map is a checksum with the value being a ModulemdRpmMapEntry / checksum = (const gchar )event.data.scalar.value;

entry = modulemdrpmmapentryparseyaml (parser, strict, &nestederror); if (!entry) { gpropagateerror (error, gstealpointer (&nestederror)); return FALSE; } modulemdmodulestreamv2setrpmartifactmapentry ( modulestream, entry, digest, checksum); No matching cardinality check is visible before the object is later emitted. The established consequence is an out-of-bounds read in a core serialization path, with likely denial-of-service impact. Confidentiality, integrity, and code-execution impact were not established. The flaw is present in libmodulemd-2.15.2-7.1.hum1; a broader affected range is not asserted here without authoritative history. Steps to reproduce: 1. Create a modulemd v2 document with at least two keys under data.artifacts.rpm-map, while leaving only one checksum entry under each digest key. 2. Parse the document with modulemdmodulestreamreadstring(). 3. Add the resulting stream to an index and serialize it with modulemdmoduleindexdumptostring() or another path that reaches modulemdmodulestreamv2emitrpmmap(). 4. The serializer will iterate j < digests->len while indexing the smaller checksums array. The expected result is an out-of-bounds read, typically causing a crash or abort. Minimal trigger YAML: yaml — document: modulemd version: 2 data: name: demo stream: stable version: 1 context: c0ffee43 summary: s description: d license: module: [MIT] artifacts: rpms: pkg-0:1-1.x8664 rpm-map: sha256: aaa: name: pkg epoch: 0 version: "1" release: "1" arch: x8664 nevra: pkg-0:1-1.x8664 sha1: bbb: name: pkg epoch: 0 version: "1" release: "1" arch: x8664 nevra: pkg-0:1-1.x8664 ...

Mitigation: Until a fixed package is available, avoid round-tripping untrusted modulemd v2 documents that include artifacts.rpm-map. If untrusted metadata must be accepted, reject or strip rpm-map content with multiple digest algorithms before serializing the parsed object. Proposed Fix: The inner loop should be bounded by the per-digest checksums array rather than the global digests array. Adding a regression test for multiple digest algorithms with fewer checksum keys in at least one digest map would help prevent recurrence. diff diff --git a/modulemd/modulemd-module-stream-v2.c b/modulemd/modulemd-module-stream-v2.c — a/modulemd/modulemd-module-stream-v2.c +++ b/modulemd/modulemd-module-stream-v2.c @@ -3267,7 +3267,7 @@ modulemdmodulestreamv2emitrpmmap (ModulemdModuleStreamV2 self, checksums = modulemdorderedstrkeys (digesttable, modulemdstrcmpsort); for (guint j = 0; j < digests->len; j++) + for (guint j = 0; j < checksums->len; j++) { checksum = gptrarrayindex (checksums, j); EMITSCALAR (emitter, error, checksum);

------ This report was generated using AI technology. Always review AI-generated content prior to use

Affected Software

1 affected component
libmodulemd=2.15.2-7.1.hum1

Remediation

Recommended actions to resolve this vulnerability, in priority order.

  1. Compensating control

    Until a fixed package is available, avoid round-tripping untrusted modulemd v2 documents that include `artifacts.rpm-map`; if untrusted metadata must be accepted, reject or strip the `rpm-map` content.

Event History

May 18, 2026
Data Sourced
via Red Hat·03:36 AM
DescriptionSeverityAffected Software

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203