Bug 1287883 - gpgcheck performed by yum does not actually validate rpm contents against GPG signature
gpgcheck performed by yum does not actually validate rpm contents against GPG...
Status: CLOSED NOTABUG
Product: Red Hat Enterprise Linux 6
Classification: Red Hat
Component: yum (Show other bugs)
6.3
All Linux
unspecified Severity urgent
: rc
: ---
Assigned To: Valentina Mukhamedzhanova
BaseOS QE Security Team
:
Depends On: 1360864
Blocks: 1355985 1494504 1499203
  Show dependency treegraph
 
Reported: 2015-12-02 17:41 EST by Alex Smith
Modified: 2017-10-13 02:56 EDT (History)
8 users (show)

See Also:
Fixed In Version:
Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of:
: 1343690 (view as bug list)
Environment:
Last Closed: 2017-10-13 02:56:13 EDT
Type: Bug
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)

  None (edit)
Description Alex Smith 2015-12-02 17:41:33 EST
Description of problem:
The gpgcheck option is not equivalent to rpm -K, which would seem to be the implied claim. The root of the problem is that yum implementation for this feature eventually goes into rpmutils.py which checks the rpm headers and it checks for the presence of a GPG signature. It never actually checks that the signature is still valid. It does check for corrupt headers, so modifying the header information will result in a bad DSA and SHA1 error. A simple of an rpm can be performed (echo "0" >> <rpmpackage>) and yum will happily install the package. A clumsy hacking can be performed (modifying a byte within the package binary data) and yum will not complain but cpio fails on extraction. I surmise that a splicing of a modified cpio package into a signed rpm would allow someone to install a modified rpm that passed the yum gpgcheck even though that rpm would fail the rpm -K check.


Version-Release number of selected component (if applicable):
This was tested in 6.3, but likely impacts all releases.

How reproducible:
100%

Steps to Reproduce:
1. In yum repository perform 'echo "0" >> <rpmpackage>'
2. execute rpm -K <rpmpackage> and observe that signature is no longer valid.
2. rebuild yum database
3. on remote system ensure repo is set to gpgcheck=1
4. on remote system perform yum install <rpmpackage>

Actual results:
rpm installs without issues

Expected results:
rpm should fail gpg check and fail to install

Additional info:
yum should execute rpm -K on downloaded rpm prior to beginning installation.
Comment 5 Michal Domonkos 2017-10-12 12:35:39 EDT
(In reply to Alex Smith from comment #0)
> A clumsy hacking can be performed (modifying a
> byte within the package binary data) and yum will not complain but cpio
> fails on extraction. I surmise that a splicing of a modified cpio package
> into a signed rpm would allow someone to install a modified rpm that passed
> the yum gpgcheck even though that rpm would fail the rpm -K check.

Appending data to an rpm file doesn't modify its payload (cpio archive after the header).  When rpm reads the payload, it will only read as many bytes as the header (which is signed) advertises.

Tampering with the payload (including slicing it off completely and attaching your own) is not possible without rpm noticing, either.  If rpm didn't fail while unpacking the archive in the first place, it would detect the tamper before installing the unpacked files to the system because it compares their hashes to the ones recorded in the header.  rpm would abort the transaction if that comparison fails (not doing any cleanup of the already installed files and executed scriptlets), so while no unsigned files would be installed, the package might be left in a partly installed state, which has its own risks (e.g. due to scriptlets not designed to work properly in such cases).

Normally, when installing packages, yum (and rpm) only verifies the signed header, so payload tamper is not detected at this stage.  What "rpm -K" does is that it also verifies the payload signature, so we thought that doing this in yum would prevent such hypothetical partial installations, as the check would be done before the rpm transaction even starts.  In the end, we reused this BZ to add this exact functionality to yum in RHEL-7.4 (which still allows for RFEs) via the new option payload_gpgcheck (bug 1343690).

Anyway, in most cases, yum is used to install packages from repositories, which are often consumed (at least when using subscription-manager) via SSL.  That pretty much eliminates man-in-the-middle attacks for such repos.  In addition to that, yum checksums every package after downloading it and compares the result with the repodata which carries the expected package checksums.  So the risk of installing a broken payload can be narrowed down to installing local rpm files, which is where using payload_gpgcheck makes the most sense.

Note You need to log in before you can comment on or make changes to this bug.