81 lines
2.6 KiB
Diff
81 lines
2.6 KiB
Diff
From 4747e369c1b5b406688ff0be5447ebd0c29575a6 Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Ale=C5=A1=20Mat=C4=9Bj?= <amatej@redhat.com>
|
|
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
|
|
|