upgrade to 4.10.0
(cherry picked from commit ede7489d239e42b6c1449614baefb7b9d95dc97e)
This commit is contained in:
parent
495c916755
commit
be8b921188
@ -1,35 +0,0 @@
|
||||
From e74a5fa5d23ab7903709faebf20449461d7c7575 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Ale=C5=A1=20Mat=C4=9Bj?= <amatej@redhat.com>
|
||||
Date: Mon, 12 Apr 2021 09:02:42 +0200
|
||||
Subject: [PATCH] Add missing check if path exists, fixes dead code
|
||||
|
||||
CVE-2021-3445
|
||||
RhBug:1915990
|
||||
|
||||
Related: CVE-2021-3421, CVE-2021-20271
|
||||
---
|
||||
dnf/rpm/miscutils.py | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/dnf/rpm/miscutils.py b/dnf/rpm/miscutils.py
|
||||
index 24456f3..235aaf2 100644
|
||||
--- a/dnf/rpm/miscutils.py
|
||||
+++ b/dnf/rpm/miscutils.py
|
||||
@@ -30,12 +30,12 @@ logger = logging.getLogger('dnf')
|
||||
|
||||
def _verifyPkgUsingRpmkeys(package, installroot):
|
||||
rpmkeys_binary = '/usr/bin/rpmkeys'
|
||||
- if not rpmkeys_binary:
|
||||
+ if not os.path.isfile(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:
|
||||
+ if not os.path.isfile(rpmkeys_binary):
|
||||
logger.critical(_('Cannot find rpmkeys executable to verify signatures.'))
|
||||
return 0
|
||||
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,87 +0,0 @@
|
||||
From 4268176cce2ca6e216dd543ce3bfae7f58b15b53 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: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
|
||||
|
||||
@ -1,29 +0,0 @@
|
||||
From 7d10ddea6291399b3ed794c1d7fff326d2ec3e86 Mon Sep 17 00:00:00 2001
|
||||
From: Jaroslav Mracek <jmracek@redhat.com>
|
||||
Date: Tue, 8 Dec 2020 08:48:34 +0100
|
||||
Subject: [PATCH] Fix module remove --all when no match spec (RhBug:1904490)
|
||||
|
||||
It resolves a traceback.
|
||||
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=1904490
|
||||
|
||||
Closes: #1699
|
||||
Approved by: kontura
|
||||
---
|
||||
dnf/cli/commands/module.py | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/dnf/cli/commands/module.py b/dnf/cli/commands/module.py
|
||||
index 4cdc915e21..0f584f9080 100644
|
||||
--- a/dnf/cli/commands/module.py
|
||||
+++ b/dnf/cli/commands/module.py
|
||||
@@ -45,6 +45,9 @@ def _get_modules_from_name_stream_specs(self):
|
||||
modules_from_specs = set()
|
||||
for module_spec in self.opts.module_spec:
|
||||
__, nsvcap = self.module_base._get_modules(module_spec)
|
||||
+ # When there is no match, the problem was already reported by module_base.remove()
|
||||
+ if nsvcap is None:
|
||||
+ continue
|
||||
name = nsvcap.name if nsvcap.name else ""
|
||||
stream = nsvcap.stream if nsvcap.stream else ""
|
||||
if (nsvcap.version and nsvcap.version != -1) or nsvcap.context:
|
||||
@ -1,56 +0,0 @@
|
||||
From 134b095b0833956cadfc02a9a1e7ca1344cd5aaa Mon Sep 17 00:00:00 2001
|
||||
From: Demi Marie Obenour <demi@invisiblethingslab.com>
|
||||
Date: Tue, 27 Apr 2021 21:07:19 -0400
|
||||
Subject: [PATCH] Pass the package to rpmkeys stdin
|
||||
|
||||
This avoids having to compute the expected stdout value, which will
|
||||
always be the constant "-: digests signatures OK\n".
|
||||
---
|
||||
dnf/rpm/miscutils.py | 10 ++++++----
|
||||
1 file changed, 6 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/dnf/rpm/miscutils.py b/dnf/rpm/miscutils.py
|
||||
index 7e33d4c..5f2621c 100644
|
||||
--- a/dnf/rpm/miscutils.py
|
||||
+++ b/dnf/rpm/miscutils.py
|
||||
@@ -29,7 +29,8 @@ from shutil import which
|
||||
logger = logging.getLogger('dnf')
|
||||
|
||||
|
||||
-def _verifyPkgUsingRpmkeys(package, installroot):
|
||||
+def _verifyPkgUsingRpmkeys(package, installroot, fdno):
|
||||
+ os.lseek(fdno, 0, os.SEEK_SET)
|
||||
rpmkeys_binary = '/usr/bin/rpmkeys'
|
||||
if not os.path.isfile(rpmkeys_binary):
|
||||
rpmkeys_binary = which("rpmkeys")
|
||||
@@ -40,15 +41,16 @@ def _verifyPkgUsingRpmkeys(package, installroot):
|
||||
logger.critical(_('Cannot find rpmkeys executable to verify signatures.'))
|
||||
return 0
|
||||
|
||||
- args = ('rpmkeys', '--checksig', '--root', installroot, '--define', '_pkgverify_level all', '--', package)
|
||||
+ args = ('rpmkeys', '--checksig', '--root', installroot, '--define', '_pkgverify_level all', '-')
|
||||
with subprocess.Popen(
|
||||
args=args,
|
||||
executable=rpmkeys_binary,
|
||||
env={'LC_ALL': 'C'},
|
||||
+ stdin=fdno,
|
||||
stdout=subprocess.PIPE,
|
||||
cwd='/') as p:
|
||||
data, err = p.communicate()
|
||||
- if p.returncode != 0 or data != (package.encode('ascii', 'strict') + b': digests signatures OK\n'):
|
||||
+ if p.returncode != 0 or data != b'-: digests signatures OK\n':
|
||||
return 0
|
||||
else:
|
||||
return 1
|
||||
@@ -85,7 +87,7 @@ def checkSig(ts, package):
|
||||
|
||||
if siginfo == '(none)':
|
||||
value = 4
|
||||
- elif "Key ID" in siginfo and _verifyPkgUsingRpmkeys(package, ts.ts.rootDir):
|
||||
+ elif "Key ID" in siginfo and _verifyPkgUsingRpmkeys(package, ts.ts.rootDir, fdno):
|
||||
value = 0
|
||||
else:
|
||||
raise ValueError('Unexpected return value %r from hdr.sprintf when checking signature.' % siginfo)
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,25 +0,0 @@
|
||||
From 643780709fbc62a58da3f71d32ee3e7399a8cdcc Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Ale=C5=A1=20Mat=C4=9Bj?= <amatej@redhat.com>
|
||||
Date: Mon, 29 Mar 2021 09:26:16 +0200
|
||||
Subject: [PATCH] Prevent traceback (catch ValueError) if pkg is from cmdline
|
||||
|
||||
---
|
||||
dnf/cli/cli.py | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/dnf/cli/cli.py b/dnf/cli/cli.py
|
||||
index c2c04c9..6576997 100644
|
||||
--- a/dnf/cli/cli.py
|
||||
+++ b/dnf/cli/cli.py
|
||||
@@ -292,7 +292,7 @@ class BaseCli(dnf.Base):
|
||||
fn = lambda x, y, z: self.output.userconfirm()
|
||||
try:
|
||||
self._get_key_for_package(po, fn)
|
||||
- except dnf.exceptions.Error as e:
|
||||
+ except (dnf.exceptions.Error, ValueError) as e:
|
||||
error_messages.append(str(e))
|
||||
|
||||
else:
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,51 +0,0 @@
|
||||
From a9b5c39787e97e9955e6de1c6f25da93bc0a4c02 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Ale=C5=A1=20Mat=C4=9Bj?= <amatej@redhat.com>
|
||||
Date: Mon, 12 Apr 2021 07:31:15 +0200
|
||||
Subject: [PATCH] Remove key regex matching, rpm sprintf output varies too much
|
||||
|
||||
Depending on locale it can return:
|
||||
`RSA/SHA256, Fri 19 Feb 2021 12:14:18 AM CET, Key ID db4639719867c58f`
|
||||
vs
|
||||
`RSA/SHA256, Fri Feb 19 00:14:18 2021, Key ID db4639719867c58f`
|
||||
(with LC_ALL=C.UTF-8)
|
||||
|
||||
We only check presence of the signature header to distinguish between
|
||||
signed and unsigned RPMs. The actual signature validation is done by
|
||||
calling rpmkeys in _verifyPkgUsingRpmkeys().
|
||||
|
||||
CVE-2021-3445
|
||||
RhBug:1915990
|
||||
|
||||
Related: CVE-2021-3421, CVE-2021-20271
|
||||
---
|
||||
dnf/rpm/miscutils.py | 4 +---
|
||||
1 file changed, 1 insertion(+), 3 deletions(-)
|
||||
|
||||
diff --git a/dnf/rpm/miscutils.py b/dnf/rpm/miscutils.py
|
||||
index 49d3717..24456f3 100644
|
||||
--- a/dnf/rpm/miscutils.py
|
||||
+++ b/dnf/rpm/miscutils.py
|
||||
@@ -18,7 +18,6 @@ from __future__ import unicode_literals
|
||||
|
||||
import rpm
|
||||
import os
|
||||
-import re
|
||||
import subprocess
|
||||
import logging
|
||||
|
||||
@@ -82,11 +81,10 @@ 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) and _verifyPkgUsingRpmkeys(package, ts.ts.rootDir):
|
||||
+ elif "Key ID" in 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
|
||||
|
||||
@ -1,174 +0,0 @@
|
||||
From a21880fbac479968546304beeeae3ed3bb899373 Mon Sep 17 00:00:00 2001
|
||||
From: Demi Marie Obenour <demi@invisiblethingslab.com>
|
||||
Date: Fri, 9 Apr 2021 13:03:03 -0400
|
||||
Subject: [PATCH] Use rpmkeys alone to verify signature
|
||||
|
||||
This avoids having to actually parse the package to check its signature,
|
||||
which reduces attack surface. If the output of rpmkeys cannot be
|
||||
parsed, we assume the package is corrupt (the most likely cause).
|
||||
---
|
||||
dnf/rpm/miscutils.py | 126 +++++++++++++++++++++++++++------------------------
|
||||
1 file changed, 66 insertions(+), 60 deletions(-)
|
||||
|
||||
diff --git a/dnf/rpm/miscutils.py b/dnf/rpm/miscutils.py
|
||||
index 5f2621c..9d5b286 100644
|
||||
--- a/dnf/rpm/miscutils.py
|
||||
+++ b/dnf/rpm/miscutils.py
|
||||
@@ -13,47 +13,84 @@
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
# Copyright 2003 Duke University
|
||||
|
||||
-from __future__ import print_function, absolute_import
|
||||
-from __future__ import unicode_literals
|
||||
+from __future__ import print_function, absolute_import, unicode_literals
|
||||
|
||||
-import rpm
|
||||
import os
|
||||
import subprocess
|
||||
import logging
|
||||
-
|
||||
-from dnf.i18n import ucd
|
||||
-from dnf.i18n import _
|
||||
from shutil import which
|
||||
|
||||
+from dnf.i18n import _
|
||||
|
||||
-logger = logging.getLogger('dnf')
|
||||
+_logger = logging.getLogger('dnf')
|
||||
+_rpmkeys_binary = None
|
||||
|
||||
+def _find_rpmkeys_binary():
|
||||
+ global _rpmkeys_binary
|
||||
+ if _rpmkeys_binary is None:
|
||||
+ _rpmkeys_binary = which("rpmkeys")
|
||||
+ _logger.debug(_('Using rpmkeys executable at %s to verify signatures'),
|
||||
+ _rpmkeys_binary)
|
||||
+ return _rpmkeys_binary
|
||||
|
||||
-def _verifyPkgUsingRpmkeys(package, installroot, fdno):
|
||||
- os.lseek(fdno, 0, os.SEEK_SET)
|
||||
- rpmkeys_binary = '/usr/bin/rpmkeys'
|
||||
- if not os.path.isfile(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))
|
||||
+def _process_rpm_output(data):
|
||||
+ # No signatures or digests = corrupt package.
|
||||
+ # There is at least one line for -: and another (empty) entry after the
|
||||
+ # last newline.
|
||||
+ if len(data) < 3 or data[0] != b'-:' or data[-1]:
|
||||
+ return 2
|
||||
+ seen_sig, missing_key, not_trusted, not_signed = False, False, False, False
|
||||
+ for i in data[1:-1]:
|
||||
+ if b': BAD' in i:
|
||||
+ return 2
|
||||
+ elif i.endswith(b': NOKEY'):
|
||||
+ missing_key = True
|
||||
+ elif i.endswith(b': NOTTRUSTED'):
|
||||
+ not_trusted = True
|
||||
+ elif i.endswith(b': NOTFOUND'):
|
||||
+ not_signed = True
|
||||
+ elif not i.endswith(b': OK'):
|
||||
+ return 2
|
||||
+ if not_trusted:
|
||||
+ return 3
|
||||
+ elif missing_key:
|
||||
+ return 1
|
||||
+ elif not_signed:
|
||||
+ return 4
|
||||
+ # we still check return code, so this is safe
|
||||
+ return 0
|
||||
|
||||
- if not os.path.isfile(rpmkeys_binary):
|
||||
- logger.critical(_('Cannot find rpmkeys executable to verify signatures.'))
|
||||
- return 0
|
||||
+def _verifyPackageUsingRpmkeys(package, installroot):
|
||||
+ rpmkeys_binary = _find_rpmkeys_binary()
|
||||
+ if rpmkeys_binary is None or not os.path.isfile(rpmkeys_binary):
|
||||
+ _logger.critical(_('Cannot find rpmkeys executable to verify signatures.'))
|
||||
+ return 2
|
||||
|
||||
- args = ('rpmkeys', '--checksig', '--root', installroot, '--define', '_pkgverify_level all', '-')
|
||||
+ # "--define=_pkgverify_level all" enforces signature checking;
|
||||
+ # "--define=_pkgverify_flags 0x0" ensures that all signatures and digests
|
||||
+ # are checked.
|
||||
+ args = ('rpmkeys', '--checksig', '--root', installroot, '--verbose',
|
||||
+ '--define=_pkgverify_level all', '--define=_pkgverify_flags 0x0',
|
||||
+ '-')
|
||||
with subprocess.Popen(
|
||||
args=args,
|
||||
executable=rpmkeys_binary,
|
||||
env={'LC_ALL': 'C'},
|
||||
- stdin=fdno,
|
||||
stdout=subprocess.PIPE,
|
||||
- cwd='/') as p:
|
||||
- data, err = p.communicate()
|
||||
- if p.returncode != 0 or data != b'-: digests signatures OK\n':
|
||||
- return 0
|
||||
- else:
|
||||
- return 1
|
||||
+ cwd='/',
|
||||
+ stdin=package) as p:
|
||||
+ data = p.communicate()[0]
|
||||
+ returncode = p.returncode
|
||||
+ if type(returncode) is not int:
|
||||
+ raise AssertionError('Popen set return code to non-int')
|
||||
+ # rpmkeys can return something other than 0 or 1 in the case of a
|
||||
+ # fatal error (OOM, abort() called, SIGSEGV, etc)
|
||||
+ if returncode >= 2 or returncode < 0:
|
||||
+ return 2
|
||||
+ ret = _process_rpm_output(data.split(b'\n'))
|
||||
+ if ret:
|
||||
+ return ret
|
||||
+ return 2 if returncode else 0
|
||||
|
||||
def checkSig(ts, package):
|
||||
"""Takes a transaction set and a package, check it's sigs,
|
||||
@@ -63,40 +100,9 @@ def checkSig(ts, package):
|
||||
return 3 if the key is not trusted
|
||||
return 4 if the pkg is not gpg or pgp signed"""
|
||||
|
||||
- value = 4
|
||||
- currentflags = ts.setVSFlags(0)
|
||||
- fdno = os.open(package, os.O_RDONLY)
|
||||
+ fdno = os.open(package, os.O_RDONLY|os.O_NOCTTY|os.O_CLOEXEC)
|
||||
try:
|
||||
- hdr = ts.hdrFromFdno(fdno)
|
||||
- except rpm.error as e:
|
||||
- if str(e) == "public key not available":
|
||||
- value = 1
|
||||
- elif str(e) == "public key not trusted":
|
||||
- value = 3
|
||||
- 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}}:' \
|
||||
- '{%|SIGGPG?{%{SIGGPG:pgpsig}}:{%|SIGPGP?{%{SIGPGP:pgpsig}}:{(none)}|}|}|}|'
|
||||
- try:
|
||||
- siginfo = hdr.sprintf(string)
|
||||
- siginfo = ucd(siginfo)
|
||||
-
|
||||
- if siginfo == '(none)':
|
||||
- value = 4
|
||||
- elif "Key ID" in siginfo and _verifyPkgUsingRpmkeys(package, ts.ts.rootDir, fdno):
|
||||
- value = 0
|
||||
- else:
|
||||
- raise ValueError('Unexpected return value %r from hdr.sprintf when checking signature.' % siginfo)
|
||||
- except UnicodeDecodeError:
|
||||
- pass
|
||||
-
|
||||
- del hdr
|
||||
-
|
||||
- os.close(fdno)
|
||||
-
|
||||
- ts.setVSFlags(currentflags) # put things back like they were before
|
||||
+ value = _verifyPackageUsingRpmkeys(fdno, ts.ts.rootDir)
|
||||
+ finally:
|
||||
+ os.close(fdno)
|
||||
return value
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,80 +0,0 @@
|
||||
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
|
||||
|
||||
BIN
dnf-4.10.0.tar.gz
Normal file
BIN
dnf-4.10.0.tar.gz
Normal file
Binary file not shown.
Binary file not shown.
@ -1,36 +0,0 @@
|
||||
From 8823feb5f42f8c579fdab80d9e22112b88d0ad2b Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Kanavin <alex.kanavin@gmail.com>
|
||||
Date: Tue, 4 May 2021 22:03:30 +0200
|
||||
Subject: [PATCH] dnf/rpm/miscutils.py: fix usage of _()
|
||||
|
||||
Specifically:
|
||||
- an import of _ was missing
|
||||
- _ was reused for a different purpose
|
||||
---
|
||||
dnf/rpm/miscutils.py | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/dnf/rpm/miscutils.py b/dnf/rpm/miscutils.py
|
||||
index 235aaf2..7e33d4c 100644
|
||||
--- a/dnf/rpm/miscutils.py
|
||||
+++ b/dnf/rpm/miscutils.py
|
||||
@@ -22,6 +22,7 @@ import subprocess
|
||||
import logging
|
||||
|
||||
from dnf.i18n import ucd
|
||||
+from dnf.i18n import _
|
||||
from shutil import which
|
||||
|
||||
|
||||
@@ -46,7 +47,7 @@ def _verifyPkgUsingRpmkeys(package, installroot):
|
||||
env={'LC_ALL': 'C'},
|
||||
stdout=subprocess.PIPE,
|
||||
cwd='/') as p:
|
||||
- data, _ = p.communicate()
|
||||
+ data, err = p.communicate()
|
||||
if p.returncode != 0 or data != (package.encode('ascii', 'strict') + b': digests signatures OK\n'):
|
||||
return 0
|
||||
else:
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
122
dnf.spec
122
dnf.spec
@ -1,24 +1,14 @@
|
||||
%global py3pluginpath %{python3_sitelib}/%{name}-plugins
|
||||
%global relate_libdnf_version 0.48.0-3
|
||||
%global relate_libdnf_version 0.65.0
|
||||
|
||||
Name: dnf
|
||||
Version: 4.2.23
|
||||
Release: 6
|
||||
Version: 4.10.0
|
||||
Release: 1
|
||||
Summary: A software package manager that manages packages on Linux distributions.
|
||||
License: GPLv2+ and GPLv2 and GPL
|
||||
URL: https://github.com/rpm-software-management/dnf
|
||||
Source0: https://github.com/rpm-software-management/dnf/archive/%{version}/%{name}-%{version}.tar.gz
|
||||
|
||||
Patch0: Fix-module-remove-all-when-no-match.patch
|
||||
Patch1: Prevent-traceback-catch-ValueError-if-pkg-is-from-cmdline.patch
|
||||
Patch2: Check-for-specific-key-string-when-verifing-signatures.patch
|
||||
Patch3: Use-rpmkeys-to-verify-package-signature-with-_pkgverify_level.patch
|
||||
Patch4: Remove-key-regex-matching-rpm-sprintf-output-varies-too-much.patch
|
||||
Patch5: Add-missing-check-if-path-exists-fixes-dead-code.patch
|
||||
Patch6: dnf-rpm-miscutils.py-fix-usage-of-_.patch
|
||||
Patch7: Pass-the-package-to-rpmkeys-stdin.patch
|
||||
Patch8: Use-rpmkeys-alone-to-verify-signature.patch
|
||||
|
||||
BuildArch: noarch
|
||||
BuildRequires: cmake gettext systemd bash-completion python3-sphinx
|
||||
Requires: python3-%{name} = %{version}-%{release} libreport-filesystem
|
||||
@ -30,8 +20,6 @@ Provides: dnf-command(mark) dnf-command(provides) dnf-command(reinst
|
||||
Provides: dnf-command(repolist) dnf-command(repoquery) dnf-command(repository-packages)
|
||||
Provides: dnf-command(search) dnf-command(updateinfo) dnf-command(upgrade) dnf-command(upgrade-to)
|
||||
Conflicts: python2-dnf-plugins-core < 4.0.6 python3-dnf-plugins-core < 4.0.6
|
||||
Provides: dnf-data %{name}-conf = %{version}-%{release} %{name}-automatic = %{version}-%{release}
|
||||
Obsoletes: dnf-data %{name}-conf < %{version}-%{release} %{name}-automatic < %{version}-%{release}
|
||||
|
||||
%description
|
||||
DNF is a software package manager that installs, updates, and removespackages
|
||||
@ -53,7 +41,7 @@ Summary: Python 3 interface to DNF
|
||||
%{?python_provide:%python_provide python3-%{name}}
|
||||
BuildRequires: python3-devel python3-hawkey >= 0.48.0 python3-libdnf >= 0.48.0
|
||||
BuildRequires: python3-libcomps >= 0.1.8 libmodulemd >= 1.4.0
|
||||
BuildRequires: python3-nose python3-gpg python3-rpm >= 4.14.0
|
||||
BuildRequires: python3-gpg python3-rpm >= 4.14.0
|
||||
Requires: python3-gpg %{name}-data = %{version}-%{release} libmodulemd >= 1.4.0
|
||||
Requires: python3-hawkey >= 0.48.0 python3-libdnf >= %{relate_libdnf_version}
|
||||
Requires: python3-libcomps >= 0.1.8 python3-rpm >= 4.14.0
|
||||
@ -63,6 +51,24 @@ Obsoletes: python2-%{name}
|
||||
%description -n python3-%{name}
|
||||
Python 3 interface to DNF.
|
||||
|
||||
%package data
|
||||
Summary: Common data and configuration files for DNF
|
||||
Requires: libreport-filesystem
|
||||
Obsoletes: %{name}-conf <= %{version}-%{release}
|
||||
Provides: %{name}-conf = %{version}-%{release}
|
||||
|
||||
%description data
|
||||
Common data and configuration files for DNF
|
||||
|
||||
%package automatic
|
||||
Summary: %{pkg_summary} - automated upgrades
|
||||
BuildRequires: systemd
|
||||
Requires: %{name} = %{version}-%{release}
|
||||
%{?systemd_requires}
|
||||
|
||||
%description automatic
|
||||
Systemd units that can periodically download package upgrades and apply them.
|
||||
|
||||
%package help
|
||||
Summary: Documents for dnf and yum
|
||||
Buildarch: noarch
|
||||
@ -110,12 +116,6 @@ ln -sr %{buildroot}%{_sysconfdir}/%{name}/plugins %{buildroot}%{_sysconfdir}/yu
|
||||
ln -sr %{buildroot}%{_sysconfdir}/%{name}/protected.d %{buildroot}%{_sysconfdir}/yum/protected.d
|
||||
ln -sr %{buildroot}%{_sysconfdir}/%{name}/vars %{buildroot}%{_sysconfdir}/yum/vars
|
||||
|
||||
%check
|
||||
export TERM=linux
|
||||
pushd build-py3
|
||||
ctest -VV
|
||||
popd
|
||||
|
||||
%post
|
||||
%systemd_post dnf-makecache.timer
|
||||
%systemd_post dnf-automatic.timer
|
||||
@ -141,43 +141,10 @@ popd
|
||||
%license COPYING PACKAGE-LICENSING
|
||||
%doc AUTHORS README.rst
|
||||
%{_bindir}/%{name}
|
||||
%{_bindir}/%{name}-automatic
|
||||
%{_sysconfdir}/bash_completion.d/%{name}
|
||||
%{_unitdir}/%{name}-automatic.timer
|
||||
%{_unitdir}/%{name}-makecache.timer
|
||||
%{_unitdir}/%{name}-automatic.service
|
||||
%{_unitdir}/%{name}-makecache.service
|
||||
%{_unitdir}/%{name}-automatic-notifyonly.service
|
||||
%{_unitdir}/%{name}-automatic-notifyonly.timer
|
||||
%{_unitdir}/%{name}-automatic-download.service
|
||||
%{_unitdir}/%{name}-automatic-download.timer
|
||||
%{_unitdir}/%{name}-automatic-install.service
|
||||
%{_unitdir}/%{name}-automatic-install.timer
|
||||
%{_var}/cache/%{name}/
|
||||
%{python3_sitelib}/%{name}/automatic/
|
||||
%dir %{_sysconfdir}/%{name}
|
||||
%dir %{_sysconfdir}/%{name}/modules.d
|
||||
%dir %{_sysconfdir}/%{name}/modules.defaults.d
|
||||
%dir %{_sysconfdir}/%{name}/plugins
|
||||
%dir %{_sysconfdir}/%{name}/protected.d
|
||||
%dir %{_sysconfdir}/%{name}/vars
|
||||
%dir %{_sysconfdir}/%{name}/aliases.d
|
||||
%exclude %{_sysconfdir}/%{name}/aliases.d/zypper.conf
|
||||
%config(noreplace) %{_sysconfdir}/%{name}/automatic.conf
|
||||
%config(noreplace) %{_sysconfdir}/%{name}/%{name}.conf
|
||||
%config(noreplace) %{_sysconfdir}/logrotate.d/%{name}
|
||||
%config(noreplace) %{_sysconfdir}/%{name}/protected.d/%{name}.conf
|
||||
%ghost %attr(644,-,-) %{_localstatedir}/log/hawkey.log
|
||||
%ghost %attr(644,-,-) %{_localstatedir}/log/%{name}.log
|
||||
%ghost %attr(644,-,-) %{_localstatedir}/log/%{name}.librepo.log
|
||||
%ghost %attr(644,-,-) %{_localstatedir}/log/%{name}.rpm.log
|
||||
%ghost %attr(644,-,-) %{_localstatedir}/log/%{name}.plugin.log
|
||||
%ghost %attr(755,-,-) %dir %{_sharedstatedir}/%{name}
|
||||
%ghost %attr(644,-,-) %{_sharedstatedir}/%{name}/groups.json
|
||||
%ghost %attr(755,-,-) %dir %{_sharedstatedir}/%{name}/yumdb
|
||||
%ghost %attr(755,-,-) %dir %{_sharedstatedir}/%{name}/history
|
||||
%{_tmpfilesdir}/%{name}.conf
|
||||
%{_sysconfdir}/libreport/events.d/collect_dnf.conf
|
||||
|
||||
%files -n yum
|
||||
%{_bindir}/yum
|
||||
@ -194,6 +161,47 @@ popd
|
||||
%dir %{py3pluginpath}
|
||||
%dir %{py3pluginpath}/__pycache__
|
||||
|
||||
%files data
|
||||
%license COPYING PACKAGE-LICENSING
|
||||
%doc AUTHORS README.rst
|
||||
%dir %{_sysconfdir}/%{name}
|
||||
%dir %{_sysconfdir}/%{name}/modules.d
|
||||
%dir %{_sysconfdir}/%{name}/modules.defaults.d
|
||||
%dir %{_sysconfdir}/%{name}/plugins
|
||||
%dir %{_sysconfdir}/%{name}/protected.d
|
||||
%dir %{_sysconfdir}/%{name}/vars
|
||||
%dir %{_sysconfdir}/%{name}/aliases.d
|
||||
%exclude %{_sysconfdir}/%{name}/aliases.d/zypper.conf
|
||||
%config(noreplace) %{_sysconfdir}/%{name}/%{name}.conf
|
||||
%config(noreplace) %{_sysconfdir}/%{name}/protected.d/%{name}.conf
|
||||
%config(noreplace) %{_sysconfdir}/logrotate.d/%{name}
|
||||
%ghost %attr(644,-,-) %{_localstatedir}/log/hawkey.log
|
||||
%ghost %attr(644,-,-) %{_localstatedir}/log/%{name}.log
|
||||
%ghost %attr(644,-,-) %{_localstatedir}/log/%{name}.librepo.log
|
||||
%ghost %attr(644,-,-) %{_localstatedir}/log/%{name}.rpm.log
|
||||
%ghost %attr(644,-,-) %{_localstatedir}/log/%{name}.plugin.log
|
||||
%ghost %attr(755,-,-) %dir %{_sharedstatedir}/%{name}
|
||||
%ghost %attr(644,-,-) %{_sharedstatedir}/%{name}/groups.json
|
||||
%ghost %attr(755,-,-) %dir %{_sharedstatedir}/%{name}/yumdb
|
||||
%ghost %attr(755,-,-) %dir %{_sharedstatedir}/%{name}/history
|
||||
%{_mandir}/man5/%{name}.conf.5*
|
||||
%{_tmpfilesdir}/%{name}.conf
|
||||
%{_sysconfdir}/libreport/events.d/collect_dnf.conf
|
||||
|
||||
%files automatic
|
||||
%{_bindir}/%{name}-automatic
|
||||
%config(noreplace) %{_sysconfdir}/%{name}/automatic.conf
|
||||
%{_mandir}/man8/%{name}-automatic.8*
|
||||
%{_unitdir}/%{name}-automatic.service
|
||||
%{_unitdir}/%{name}-automatic.timer
|
||||
%{_unitdir}/%{name}-automatic-notifyonly.service
|
||||
%{_unitdir}/%{name}-automatic-notifyonly.timer
|
||||
%{_unitdir}/%{name}-automatic-download.service
|
||||
%{_unitdir}/%{name}-automatic-download.timer
|
||||
%{_unitdir}/%{name}-automatic-install.service
|
||||
%{_unitdir}/%{name}-automatic-install.timer
|
||||
%{python3_sitelib}/%{name}/automatic/
|
||||
|
||||
%files help
|
||||
%{_datadir}/locale/*
|
||||
%{_datadir}/bash-completion/*
|
||||
@ -204,10 +212,14 @@ popd
|
||||
%{_mandir}/man8/yum-shell.8*
|
||||
%{_mandir}/man1/yum-aliases.1*
|
||||
%{_mandir}/man5/%{name}.conf.5*
|
||||
%{_mandir}/man5/dnf-transaction-json.5.gz
|
||||
%{_mandir}/man7/dnf.modularity.7*
|
||||
%{_mandir}/man8/%{name}-automatic.8*
|
||||
|
||||
%changelog
|
||||
* Wed Dec 29 2021 yangcheng <yangcheng87@huawei.com> - 4.10.0-1
|
||||
- upgrade to 4.10.0
|
||||
|
||||
* Thu Jul 15 2021 gaihuiying <gaihuiying1@huawei.com> - 4.2.23-6
|
||||
- Type:bugfix
|
||||
- ID:NA
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user