From 4268176cce2ca6e216dd543ce3bfae7f58b15b53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ale=C5=A1=20Mat=C4=9Bj?= Date: Tue, 30 Mar 2021 08:18:42 +0200 Subject: [PATCH] Check for specific key string when verifing signatures Also improves handling of return values and exceptions. The function can't return 0 when the signature is malformed. Credit for the original patch goes to Demi Marie Obenour: @DemiMarie = changelog = msg: Check for specific key string when verifing signatures 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 | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/dnf/rpm/miscutils.py b/dnf/rpm/miscutils.py index 9038f98..07451bb 100644 --- a/dnf/rpm/miscutils.py +++ b/dnf/rpm/miscutils.py @@ -18,6 +18,7 @@ from __future__ import unicode_literals import rpm import os +import re from dnf.i18n import ucd @@ -30,7 +31,7 @@ def checkSig(ts, package): return 3 if the key is not trusted return 4 if the pkg is not gpg or pgp signed""" - value = 0 + value = 4 currentflags = ts.setVSFlags(0) fdno = os.open(package, os.O_RDONLY) try: @@ -38,10 +39,12 @@ def checkSig(ts, package): except rpm.error as e: if str(e) == "public key not available": value = 1 - if str(e) == "public key not trusted": + elif str(e) == "public key not trusted": value = 3 - if str(e) == "error reading package header": + elif str(e) == "error reading package header": value = 2 + else: + raise ValueError('Unexpected error value %r from ts.hdrFromFdno when checking signature.' % str(e)) else: # checks signature from an hdr string = '%|DSAHEADER?{%{DSAHEADER:pgpsig}}:{%|RSAHEADER?{%{RSAHEADER:pgpsig}}:' \ @@ -49,17 +52,20 @@ def checkSig(ts, package): try: siginfo = hdr.sprintf(string) siginfo = ucd(siginfo) + rpm_pgpsig_format_regex = re.compile(r'[0-9]{2}:[0-9]{2}:[0-9]{2} [0-9]{4}, Key ID [0-9a-f]{16}\Z') + if siginfo == '(none)': value = 4 + elif rpm_pgpsig_format_regex.search(siginfo): + value = 0 + else: + raise ValueError('Unexpected return value %r from hdr.sprintf when checking signature.' % siginfo) except UnicodeDecodeError: pass del hdr - try: - os.close(fdno) - except OSError as e: # if we're not opened, don't scream about it - pass + os.close(fdno) ts.setVSFlags(currentflags) # put things back like they were before return value -- 1.8.3.1