REDHAT-BUG-2470977: Medium severity rpm/rpm vulnerability
AIONLYREPORT package: rpm-6.0.1-5.1.hum1 ------ Summary: Code Execution via Macro Expansion of Manifest Entries in rpmgi (-q -p / verify manifest flows): attacker-controlled manifest entries are macro-expanded before open, allowing %() shell command execution in the caller context when non-package files are processed as manifests. Requirements to exploit: An attacker must supply a crafted manifest file and cause a user or automation to invoke rpm -q -p or a similar manifest-processing package-file flow on it without --nomanifest. No prior privileges are required beyond supplying the manifest; the resulting command executes with the privileges of the rpm process. Component affected: rpm-6.0.1-5.1.hum1, primarily lib/rpmgi.cc rpmgiOpen(), reached from manifest parsing in lib/manifest.cc during package-file query/verify handling. Version affected: rpm-6.0.1-5.1.hum1 Patch available: no released package fix established; proposed patch included below Version fixed: unknown Upstream coordination: Not notified. CVSS: CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H - 7.8 (HIGH) AV:L - Exploitation occurs through a local manifest file processed by the rpm CLI. AC:L - A single crafted manifest entry using RPM macro syntax is sufficient; no race or uncommon precondition is required. PR:N - The attacker does not need an account on the target system; delivering the crafted manifest is enough. UI:R - A user or automation must run an affected package-file query/verify flow on the attacker-controlled manifest. S:U - Exploitation affects the same security scope as the rpm process that parses the manifest. C:H - Successful command execution can read data available to the invoking context. I:H - Successful command execution can modify files or system state available to the invoking context. A:H - Successful command execution can disrupt or destroy data or service availability available to the invoking context. Impact: Important. This issue requires user-assisted processing of attacker-supplied manifest content, so it does not meet the criteria for Critical impact. However, once triggered it can execute arbitrary commands in the rpm caller context, which is sufficient to fully compromise confidentiality, integrity, and availability for that account. If the affected workflow is run by an administrator or privileged automation, the consequence is correspondingly severe. Embargo: no Reason: This is a user-assisted local CLI issue with a straightforward operational mitigation (--nomanifest) and no silent remote attack surface. Acknowledgement: Aisle Research Vulnerability Details: rpm package-file query handling constructs an rpmgi iterator for -p inputs. When the supplied file is not recognized as an RPM header, the iterator falls back to manifest handling. Manifest entries are read as plaintext strings and later reopened through rpmgiOpen(), which macro-expands the path before Fopen(): cpp static FDt rpmgiOpen(const char path, const char fmode) { char fn = rpmExpand(path, NULL); FDt fd = Fopen(fn, fmode); if (fd == NULL || Ferror(fd)) { rpmlog(RPMLOGERR, ("open of %s failed: %s\n"), fn, Fstrerror(fd)); if (fd != NULL) (void) Fclose(fd); fd = NULL; } free(fn); return fd; } RPM macro expansion supports executable forms, including %() shell escapes. As a result, a manifest entry such as %(id > /tmp/rpmmanifestpoc) is evaluated before the open attempt, and the embedded command runs in the caller context. This is unexpected for rpm-manifest(5), which documents manifests as plaintext glob/path entries naming RPM packages or other manifests rather than executable macro content. The concrete reproduction below demonstrates the issue in -q -p. Query and verify share the same package-file source handling around rpmgi, so manifest-processing verify flows should be treated as relevant as well, but the directly reproduced case here is query mode. Steps to reproduce: 1. Create a proof-of-concept manifest: bash cat > /tmp/poc.mft <<'EOF' %(id > /tmp/rpmmanifestpoc) EOF 2. Run package-file query mode on the manifest: bash rpm -q -p /tmp/poc.mft 3. Confirm the side effect: bash cat /tmp/rpmmanifestpoc 4. A successful reproduction creates /tmp/rpmmanifestpoc containing the output of id from the invoking user context. 5. Control check: disable manifest processing and rerun: bash rpm -q -p --nomanifest /tmp/poc.mft 6. With --nomanifest, the manifest should not be processed and the side-effect file should not be created by this invocation. Mitigation: Until a fix is available, do not run rpm package-file query or verify operations on untrusted manifest files. Use --nomanifest when handling untrusted inputs, and if manifest support is required in automation, pre-validate entries so that only expected literal paths or globs are accepted and macro syntax is rejected. Proposed Fix: Stop macro-expanding manifest-derived paths in rpmgiOpen() and open the original path string directly. diff diff --git a/lib/rpmgi.cc b/lib/rpmgi.cc — a/lib/rpmgi.cc +++ b/lib/rpmgi.cc @@ -49,8 +49,7 @@ static FDt rpmgiOpen(const char path, const char fmode) { char fn = rpmExpand(path, NULL);
FDt fd = Fopen(fn, fmode); + FDt fd = Fopen(path, fmode);
if (fd == NULL || Ferror(fd)) { rpmlog(RPMLOGERR, ("open of %s failed: %s\n"), fn, Fstrerror(fd)); + rpmlog(RPMLOGERR, ("open of %s failed: %s\n"), path, Fstrerror(fd)); if (fd != NULL) (void) Fclose(fd); fd = NULL; }
free(fn);
return fd; } ------ This report was generated using AI technology. Always review AI-generated content prior to use
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Configuration
Use the `--nomanifest` option when running package-file query or verify operations on untrusted manifest files.
rpm manifest processing = disabled - Compensating control
If manifest support is required in automation, pre-validate manifest entries so they contain only expected literal paths or names of RPM packages or other manifests, rejecting executable macro content.