From 4747e369c1b5b406688ff0be5447ebd0c29575a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ale=C5=A1=20Mat=C4=9Bj?= Date: Tue, 30 Mar 2021 08:19:37 +0200 Subject: [PATCH] Use rpmkeys to verify package signature with _pkgverify_level rpm doesn't provide any API how to check package signature with _pkgverify_level signature therefore we call rpmkeys binary. Credit for the original patch goes to Demi Marie Obenour: @DemiMarie = changelog = msg: Use rpmkeys binary to verify package signature type: security resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1915990 CVE-2021-3445 RhBug:1915990 Related: CVE-2021-3421, CVE-2021-20271 --- dnf/rpm/miscutils.py | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/dnf/rpm/miscutils.py b/dnf/rpm/miscutils.py index 07451bb..49d3717 100644 --- a/dnf/rpm/miscutils.py +++ b/dnf/rpm/miscutils.py @@ -19,10 +19,40 @@ from __future__ import unicode_literals import rpm import os import re +import subprocess +import logging from dnf.i18n import ucd +from shutil import which +logger = logging.getLogger('dnf') + + +def _verifyPkgUsingRpmkeys(package, installroot): + rpmkeys_binary = '/usr/bin/rpmkeys' + if not rpmkeys_binary: + rpmkeys_binary = which("rpmkeys") + logger.info(_('Using rpmkeys executable from {path} to verify signature for package: {package}.').format( + path=rpmkeys_binary, package=package)) + + if not rpmkeys_binary: + logger.critical(_('Cannot find rpmkeys executable to verify signatures.')) + return 0 + + args = ('rpmkeys', '--checksig', '--root', installroot, '--define', '_pkgverify_level all', '--', package) + with subprocess.Popen( + args=args, + executable=rpmkeys_binary, + env={'LC_ALL': 'C'}, + stdout=subprocess.PIPE, + cwd='/') as p: + data, _ = p.communicate() + if p.returncode != 0 or data != (package.encode('ascii', 'strict') + b': digests signatures OK\n'): + return 0 + else: + return 1 + def checkSig(ts, package): """Takes a transaction set and a package, check it's sigs, return 0 if they are all fine @@ -56,7 +86,7 @@ def checkSig(ts, package): if siginfo == '(none)': value = 4 - elif rpm_pgpsig_format_regex.search(siginfo): + elif rpm_pgpsig_format_regex.search(siginfo) and _verifyPkgUsingRpmkeys(package, ts.ts.rootDir): value = 0 else: raise ValueError('Unexpected return value %r from hdr.sprintf when checking signature.' % siginfo) -- 1.8.3.1