REDHAT-BUG-2537812: Command Injection
A command injection flaw was found in rpm. The macro engine's %() construct executes an embedded shell command via popen() whenever the macro text is expanded, regardless of where that text came from (rpmio/macro.cc: case '(' at :1678 calls doShellEscape(), which ends in popen(buf, "r") at :499). Installing or rebuilding a .src.rpm routes through rpmInstallSourcePackage(), whose getFiles() calls rpmRelocateSrpmFileList() (lib/relocation.cc:454); that function builds the destination path for every source and spec file with rpmGenPath(rootDir, "%{specdir}"|"%{sourcedir}", bn), and joinpath() (rpmio/rpmfileutil.cc:463) macro-expands each path component individually, including the package-supplied basename bn. A source or spec basename containing a %(cmd) construct is therefore expanded and the embedded command executed. This install path never calls rpmtsRun(), so %pkgverifylevel provides no protection: rpmReadPackageFile() hard-codes vfylevel to 0 (lib/package.cc:315) and accepts a completely unsigned .src.rpm under the distro-default policy, and rpm -i still reports success (exit 0) with nothing to indicate a command ran. rpmbuild --rebuild reaches the same relocation code during install, before any mock/chroot sandbox boundary. This was confirmed by reproducing the reporter's proof of concept with an AddressSanitizer-instrumented build of rpm at both rpm-6.1.0-release and master: rpm -i against a crafted, unsigned .src.rpm silently ran an embedded canary command while the install still exited 0, including with %pkgverifylevel all set, which shows signature policy is not the gate; negative controls (removing the leading %, or using rpm -qpl instead of installing) did not execute the command.
Affected Software
Event History
Frequently Asked Questions
Which workflows are exposed to this issue?
Installing a .src.rpm and rebuilding one with rpmbuild --rebuild both reach the affected source-package relocation path. The issue occurs while destination paths are generated for source and spec files.
What must an attacker control to trigger command execution?
A source or spec file basename in a .src.rpm must contain an RPM macro expression using the %(cmd) construct. When that basename is macro-expanded during relocation, the embedded shell command is executed.
Does RPM signature verification or %_pkgverify_level prevent exploitation?
No. This installation path does not call rpmtsRun(), and rpmReadPackageFile() uses a verification level of 0; under the distribution-default policy, a completely unsigned .src.rpm is accepted.
Will a successful exploit be visible from the RPM command result?
Not necessarily. rpm -i can report success with exit code 0 and provide no indication that an embedded command was run.