Add patches for release 8

Resolves: #1965147, #1999009, #1999012, #2015407, #2026079, #2018937
Resolves: #1943724
This commit is contained in:
Michal Domonkos 2021-12-09 17:38:25 +01:00
parent 6a3e594a7c
commit e2e5e2b2d1
6 changed files with 820 additions and 1 deletions

View File

@ -0,0 +1,36 @@
From 7f0b7217fb1c20ec6ce0c0e0bfee0349f27a2511 Mon Sep 17 00:00:00 2001
From: Panu Matilainen <pmatilai@redhat.com>
Date: Fri, 8 Jan 2021 13:59:59 +0200
Subject: [PATCH] Ensure ELF files get stripped when debuginfo is disabled
Depending on libmagic version, PIE executables can be reported as
"shared object" avoiding the strip. And so will any libraries because
we're explicitly skipping them for whatever historical reason - perhaps
because there's a separate script for stripping the libraries, but that
has been never enabled in rpm, and relying on "file" strings to do this
is hopelessly unreliable.
Also drop file permissions checks: making shared libraries executable
just to have them stripped is not sensical, especially in the light of
commit 80818e4f902ba3cf85e4cfcd8a7a4c71c601f3cf
Reported once upon time as RhBug:988812 and later RhBug:1634084
---
scripts/brp-strip | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/scripts/brp-strip b/scripts/brp-strip
index c3484fe3c..35fbb593a 100755
--- a/scripts/brp-strip
+++ b/scripts/brp-strip
@@ -13,5 +13,5 @@ Darwin*) exit 0 ;;
esac
# Strip ELF binaries
-find "$RPM_BUILD_ROOT" -type f \( -perm -0100 -or -perm -0010 -or -perm -0001 \) \! -regex "${RPM_BUILD_ROOT}/*usr/lib/debug.*" -print0 | \
- xargs -0 -r -P$NCPUS -n32 sh -c "file \"\$@\" | grep -v ' shared object,' | sed -n -e 's/^\(.*\):[ ]*ELF.*, not stripped.*/\1/p' | xargs -I\{\} $STRIP -g \{\}" ARG0
+find "$RPM_BUILD_ROOT" -type f \! -regex "${RPM_BUILD_ROOT}/*usr/lib/debug.*" -print0 | \
+ xargs -0 -r -P$NCPUS -n32 sh -c "file \"\$@\" | sed -n -e 's/^\(.*\):[ ]*ELF.*, not stripped.*/\1/p' | xargs -I\{\} $STRIP -g \{\}" ARG0
--
2.33.1

View File

@ -0,0 +1,194 @@
From 495f25f7198fb1e0163a7ae55de55576d9dc6fe5 Mon Sep 17 00:00:00 2001
From: Panu Matilainen <pmatilai@redhat.com>
Date: Mon, 29 Nov 2021 14:01:39 +0200
Subject: [PATCH] Fix IMA signature lengths assumed constant (#1833,
RhBug:2018937)
At least ECDSA and RSA signatures can vary in length, but the IMA code
assumes constant lengths and thus may either place invalid signatures on
disk from either truncating or overshooting, and segfault if the stars are
just so.
Luckily the signatures are stored as strings so we can calculate the
actual lengths at runtime and ignore the stored constant length info.
Extend hex2bin() to optionally calculate the lengths and maximum,
and use these for returning IMA data from the rpmfi(les) API.
Additionally update the signing code to store the largest IMA signature
length rather than what happened to be last to be on the safe side.
We can't rely on this value due to invalid packages being out there,
but then we need to calculate the lengths on rpmfiles populate so there's
not a lot to gain anyhow.
Fixes: #1833
Combined with 0c1ad364d65c4144ff71c376e0b49fbc322b686d and backported
for 4.16.1.3. Note that the test case has been removed due to it
including a binary file (test package) for which we'd have to use -Sgit
with %autopatch and thus depend on git-core at build time.
Nevertheless, we do have this BZ covered in our internal test suite, so
no need for it anyway.
---
lib/rpmfi.c | 43 ++++++++++++++++++++++++++++++++++---------
python/rpmfiles-py.c | 18 ++++++++++++++++++
sign/rpmsignfiles.c | 5 ++++-
3 files changed, 56 insertions(+), 10 deletions(-)
diff --git a/lib/rpmfi.c b/lib/rpmfi.c
index af428468c..0878d78f2 100644
--- a/lib/rpmfi.c
+++ b/lib/rpmfi.c
@@ -115,7 +115,8 @@ struct rpmfiles_s {
struct fingerPrint_s * fps; /*!< File fingerprint(s). */
int digestalgo; /*!< File digest algorithm */
- int signaturelength; /*!< File signature length */
+ int *signaturelengths; /*!< File signature length */
+ int signaturemaxlen; /*!< Largest file signature length */
unsigned char * digests; /*!< File digests in binary. */
unsigned char * signatures; /*!< File signatures in binary. */
@@ -575,9 +576,9 @@ const unsigned char * rpmfilesFSignature(rpmfiles fi, int ix, size_t *len)
if (fi != NULL && ix >= 0 && ix < rpmfilesFC(fi)) {
if (fi->signatures != NULL)
- signature = fi->signatures + (fi->signaturelength * ix);
+ signature = fi->signatures + (fi->signaturemaxlen * ix);
if (len)
- *len = fi->signaturelength;
+ *len = fi->signaturelengths[ix];
}
return signature;
}
@@ -1257,6 +1258,7 @@ rpmfiles rpmfilesFree(rpmfiles fi)
fi->flangs = _free(fi->flangs);
fi->digests = _free(fi->digests);
fi->signatures = _free(fi->signatures);
+ fi->signaturelengths = _free(fi->signaturelengths);
fi->fcaps = _free(fi->fcaps);
fi->cdict = _free(fi->cdict);
@@ -1486,15 +1488,38 @@ err:
}
/* Convert a tag of hex strings to binary presentation */
-static uint8_t *hex2bin(Header h, rpmTagVal tag, rpm_count_t num, size_t len)
+/* If lengths is non-NULL, assume variable length strings */
+static uint8_t *hex2bin(Header h, rpmTagVal tag, rpm_count_t num, size_t len,
+ int **lengths, int *maxlen)
{
struct rpmtd_s td;
uint8_t *bin = NULL;
if (headerGet(h, tag, &td, HEADERGET_MINMEM) && rpmtdCount(&td) == num) {
- uint8_t *t = bin = xmalloc(num * len);
const char *s;
+ /* Figure string sizes + max length for allocation purposes */
+ if (lengths) {
+ int maxl = 0;
+ int *lens = xmalloc(num * sizeof(*lens));
+ int i = 0;
+
+ while ((s = rpmtdNextString(&td))) {
+ lens[i] = strlen(s) / 2;
+ if (lens[i] > maxl)
+ maxl = lens[i];
+ i++;
+ }
+
+ *lengths = lens;
+ *maxlen = maxl;
+ len = maxl;
+
+ /* Reinitialize iterator for next round */
+ rpmtdInit(&td);
+ }
+
+ uint8_t *t = bin = xmalloc(num * len);
while ((s = rpmtdNextString(&td))) {
if (*s == '\0') {
memset(t, 0, len);
@@ -1570,15 +1595,15 @@ static int rpmfilesPopulate(rpmfiles fi, Header h, rpmfiFlags flags)
/* grab hex digests from header and store in binary format */
if (!(flags & RPMFI_NOFILEDIGESTS)) {
size_t diglen = rpmDigestLength(fi->digestalgo);
- fi->digests = hex2bin(h, RPMTAG_FILEDIGESTS, totalfc, diglen);
+ fi->digests = hex2bin(h, RPMTAG_FILEDIGESTS, totalfc, diglen,
+ NULL, NULL);
}
fi->signatures = NULL;
/* grab hex signatures from header and store in binary format */
if (!(flags & RPMFI_NOFILESIGNATURES)) {
- fi->signaturelength = headerGetNumber(h, RPMTAG_FILESIGNATURELENGTH);
- fi->signatures = hex2bin(h, RPMTAG_FILESIGNATURES,
- totalfc, fi->signaturelength);
+ fi->signatures = hex2bin(h, RPMTAG_FILESIGNATURES, totalfc, 0,
+ &fi->signaturelengths, &fi->signaturemaxlen);
}
/* XXX TR_REMOVED doesn;t need fmtimes, frdevs, finodes */
diff --git a/python/rpmfiles-py.c b/python/rpmfiles-py.c
index 27666021d..48189a0ac 100644
--- a/python/rpmfiles-py.c
+++ b/python/rpmfiles-py.c
@@ -152,6 +152,22 @@ static PyObject *rpmfile_digest(rpmfileObject *s)
Py_RETURN_NONE;
}
+static PyObject *bytebuf(const unsigned char *buf, size_t len)
+{
+ if (buf) {
+ PyObject *o = PyBytes_FromStringAndSize((const char *)buf, len);
+ return o;
+ }
+ Py_RETURN_NONE;
+}
+
+static PyObject *rpmfile_imasig(rpmfileObject *s)
+{
+ size_t len = 0;
+ const unsigned char *sig = rpmfilesFSignature(s->files, s->ix, &len);
+ return bytebuf(sig, len);
+}
+
static PyObject *rpmfile_class(rpmfileObject *s)
{
return utf8FromString(rpmfilesFClass(s->files, s->ix));
@@ -278,6 +294,8 @@ static PyGetSetDef rpmfile_getseters[] = {
"language the file provides (typically for doc files)" },
{ "caps", (getter) rpmfile_caps, NULL,
"file capabilities" },
+ { "imasig", (getter) rpmfile_imasig, NULL,
+ "IMA signature" },
{ NULL, NULL, NULL, NULL }
};
diff --git a/sign/rpmsignfiles.c b/sign/rpmsignfiles.c
index b143c5b9b..6f39db6be 100644
--- a/sign/rpmsignfiles.c
+++ b/sign/rpmsignfiles.c
@@ -98,8 +98,9 @@ rpmRC rpmSignFiles(Header sigh, Header h, const char *key, char *keypass)
td.count = 1;
while (rpmfiNext(fi) >= 0) {
+ uint32_t slen;
digest = rpmfiFDigest(fi, NULL, NULL);
- signature = signFile(algoname, digest, diglen, key, keypass, &siglen);
+ signature = signFile(algoname, digest, diglen, key, keypass, &slen);
if (!signature) {
rpmlog(RPMLOG_ERR, _("signFile failed\n"));
goto exit;
@@ -110,6 +111,8 @@ rpmRC rpmSignFiles(Header sigh, Header h, const char *key, char *keypass)
goto exit;
}
signature = _free(signature);
+ if (slen > siglen)
+ siglen = slen;
}
if (siglen > 0) {
--
2.33.1

View File

@ -0,0 +1,39 @@
From c771ae28e28b2971869b7801ffc7961f4dcb6544 Mon Sep 17 00:00:00 2001
From: Panu Matilainen <pmatilai@redhat.com>
Date: Thu, 10 Jun 2021 10:32:12 +0300
Subject: [PATCH] Support hash v8 databases from BDB < 4.6 in bdb_ro
In Hash v8 databases page type differs from newer ones to denote
the difference between sorted and unsorted pages.
Fixes reading rpm databases from older distros like SLES 11 and RHEL 5
(RhBug:1965147)
---
lib/backend/bdb_ro.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/lib/backend/bdb_ro.c b/lib/backend/bdb_ro.c
index 2667ec845..695ef78e3 100644
--- a/lib/backend/bdb_ro.c
+++ b/lib/backend/bdb_ro.c
@@ -276,7 +276,7 @@ static int hash_lookup(struct bdb_cur *cur, const unsigned char *key, unsigned i
pg = hash_bucket_to_page(cur->db, bucket);
if (bdb_getpage(cur->db, cur->page, pg))
return -1;
- if (cur->page[25] != 8 && cur->page[25] != 13)
+ if (cur->page[25] != 8 && cur->page[25] != 13 && cur->page[25] != 2)
return -1;
cur->idx = (unsigned int)-2;
cur->numidx = *(uint16_t *)(cur->page + 20);
@@ -323,7 +323,7 @@ static int hash_next(struct bdb_cur *cur)
}
if (bdb_getpage(cur->db, cur->page, pg))
return -1;
- if (cur->page[25] != 8 && cur->page[25] != 13)
+ if (cur->page[25] != 8 && cur->page[25] != 13 && cur->page[25] != 2)
return -1;
cur->numidx = *(uint16_t *)(cur->page + 20);
continue;
--
2.33.1

View File

@ -0,0 +1,144 @@
From 137ecc2e1841c2b27b99d4db9006253dd1c73dde Mon Sep 17 00:00:00 2001
From: Michael Schroeder <mls@suse.de>
Date: Fri, 4 Jun 2021 23:30:49 +0200
Subject: [PATCH] Unbreak checking of installed rich dependencies
Commit ddb32b9187e9ce85819a84ca8d202131fd9f8b9f added an
extra check that tests if the provide we are checking really
intersects the dependency from rpmdb. Unfortunately the
rpmdsCompare() call does not understand rich dependencies and
will consider them as not intersecting.
Unbreak the check by not doing the intersection test for
rich dependencies. We'll improve this in a later commit.
Also add test cases for dependency problems with installed
rich dependencies.
---
lib/depends.c | 2 +-
tests/rpmdeps.at | 99 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 100 insertions(+), 1 deletion(-)
diff --git a/lib/depends.c b/lib/depends.c
index c10ba4bda..fecbd9675 100644
--- a/lib/depends.c
+++ b/lib/depends.c
@@ -846,7 +846,7 @@ static void checkInstDeps(rpmts ts, depCache dcache, rpmte te,
rpmdsSetIx(ds, rpmdbGetIteratorFileNum(mi));
/* Is it in our range at all? (but file deps have no range) */
- if (depds)
+ if (depds && !rpmdsIsRich(ds))
match = rpmdsCompare(ds, depds);
if (match && unsatisfiedDepend(ts, dcache, ds) == is_problem) {
diff --git a/tests/rpmdeps.at b/tests/rpmdeps.at
index 67bde1dc8..8357af9df 100644
--- a/tests/rpmdeps.at
+++ b/tests/rpmdeps.at
@@ -732,3 +732,102 @@ runroot rpm -U /build/RPMS/noarch/deptest-one-1.0-1.noarch.rpm /build/RPMS/noarc
[],
[])
AT_CLEANUP
+
+# ------------------------------
+#
+AT_SETUP([install to break installed rich dependency])
+AT_KEYWORDS([install, boolean])
+RPMDB_INIT
+
+runroot rpmbuild --quiet -bb \
+ --define "pkg one" \
+ --define "cfls (deptest-three or deptest-five)" \
+ /data/SPECS/deptest.spec
+runroot rpmbuild --quiet -bb \
+ --define "pkg two" \
+ --define "reqs (deptest-five if deptest-four)" \
+ /data/SPECS/deptest.spec
+runroot rpmbuild --quiet -bb \
+ --define "pkg three" \
+ /data/SPECS/deptest.spec
+runroot rpmbuild --quiet -bb \
+ --define "pkg four" \
+ /data/SPECS/deptest.spec
+
+# installed conflict with "or" clause
+AT_CHECK([
+RPMDB_INIT
+
+runroot rpm -U /build/RPMS/noarch/deptest-one-1.0-1.noarch.rpm
+runroot rpm -U /build/RPMS/noarch/deptest-three-1.0-1.noarch.rpm
+],
+[1],
+[],
+[error: Failed dependencies:
+ (deptest-three or deptest-five) conflicts with (installed) deptest-one-1.0-1.noarch
+])
+
+# installed requires with "if" clause
+AT_CHECK([
+RPMDB_INIT
+
+runroot rpm -U /build/RPMS/noarch/deptest-two-1.0-1.noarch.rpm
+runroot rpm -U /build/RPMS/noarch/deptest-four-1.0-1.noarch.rpm
+],
+[1],
+[],
+[error: Failed dependencies:
+ (deptest-five if deptest-four) is needed by (installed) deptest-two-1.0-1.noarch
+])
+AT_CLEANUP
+
+# ------------------------------
+#
+AT_SETUP([erase to break installed rich dependency])
+AT_KEYWORDS([install, boolean])
+RPMDB_INIT
+
+runroot rpmbuild --quiet -bb \
+ --define "pkg one" \
+ --define "reqs (deptest-three or deptest-five)" \
+ /data/SPECS/deptest.spec
+runroot rpmbuild --quiet -bb \
+ --define "pkg two" \
+ --define "cfls (deptest-five unless deptest-four)" \
+ /data/SPECS/deptest.spec
+runroot rpmbuild --quiet -bb \
+ --define "pkg three" \
+ /data/SPECS/deptest.spec
+runroot rpmbuild --quiet -bb \
+ --define "pkg four" \
+ /data/SPECS/deptest.spec
+runroot rpmbuild --quiet -bb \
+ --define "pkg five" \
+ /data/SPECS/deptest.spec
+
+# installed requires with "or" clause
+AT_CHECK([
+RPMDB_INIT
+
+runroot rpm -U /build/RPMS/noarch/deptest-one-1.0-1.noarch.rpm /build/RPMS/noarch/deptest-three-1.0-1.noarch.rpm
+runroot rpm -e deptest-three
+],
+[1],
+[],
+[error: Failed dependencies:
+ (deptest-three or deptest-five) is needed by (installed) deptest-one-1.0-1.noarch
+])
+
+# installed conflicts with "unless" clause
+AT_CHECK([
+RPMDB_INIT
+
+runroot rpm -U /build/RPMS/noarch/deptest-two-1.0-1.noarch.rpm /build/RPMS/noarch/deptest-four-1.0-1.noarch.rpm /build/RPMS/noarch/deptest-five-1.0-1.noarch.rpm
+runroot rpm -e deptest-four
+],
+[1],
+[],
+[error: Failed dependencies:
+ (deptest-five unless deptest-four) conflicts with (installed) deptest-two-1.0-1.noarch
+])
+AT_CLEANUP
--
2.33.1

View File

@ -0,0 +1,386 @@
From a73895e6f03bef5e95a738ff680f7c42151f3959 Mon Sep 17 00:00:00 2001
From: Demi Marie Obenour <demi@invisiblethingslab.com>
Date: Thu, 6 May 2021 18:34:45 -0400
Subject: [PATCH] Validate and require subkey binding signatures on PGP public
keys
All subkeys must be followed by a binding signature by the primary key
as per the OpenPGP RFC, enforce the presence and validity in the parser.
The implementation is as kludgey as they come to work around our
simple-minded parser structure without touching API, to maximise
backportability. Store all the raw packets internally as we decode them
to be able to access previous elements at will, needed to validate ordering
and access the actual data. Add testcases for manipulated keys whose
import previously would succeed.
Combined with:
5ff86764b17f31535cb247543a90dd739076ec38
b5e8bc74b2b05aa557f663fe227b94d2bc64fbd8
9f03f42e2614a68f589f9db8fe76287146522c0c
Fixes CVE-2021-3521.
---
rpmio/rpmpgp.c | 123 +++++++++++++++---
tests/Makefile.am | 3 +
tests/data/keys/CVE-2021-3521-badbind.asc | 25 ++++
.../data/keys/CVE-2021-3521-nosubsig-last.asc | 25 ++++
tests/data/keys/CVE-2021-3521-nosubsig.asc | 37 ++++++
tests/rpmsigdig.at | 28 ++++
6 files changed, 224 insertions(+), 17 deletions(-)
create mode 100644 tests/data/keys/CVE-2021-3521-badbind.asc
create mode 100644 tests/data/keys/CVE-2021-3521-nosubsig-last.asc
create mode 100644 tests/data/keys/CVE-2021-3521-nosubsig.asc
diff --git a/rpmio/rpmpgp.c b/rpmio/rpmpgp.c
index d0688ebe9..b12410d67 100644
--- a/rpmio/rpmpgp.c
+++ b/rpmio/rpmpgp.c
@@ -515,7 +515,7 @@ pgpDigAlg pgpDigAlgFree(pgpDigAlg alg)
return NULL;
}
-static int pgpPrtSigParams(pgpTag tag, uint8_t pubkey_algo, uint8_t sigtype,
+static int pgpPrtSigParams(pgpTag tag, uint8_t pubkey_algo,
const uint8_t *p, const uint8_t *h, size_t hlen,
pgpDigParams sigp)
{
@@ -528,10 +528,8 @@ static int pgpPrtSigParams(pgpTag tag, uint8_t pubkey_algo, uint8_t sigtype,
int mpil = pgpMpiLen(p);
if (p + mpil > pend)
break;
- if (sigtype == PGPSIGTYPE_BINARY || sigtype == PGPSIGTYPE_TEXT) {
- if (sigalg->setmpi(sigalg, i, p))
- break;
- }
+ if (sigalg->setmpi(sigalg, i, p))
+ break;
p += mpil;
}
@@ -604,7 +602,7 @@ static int pgpPrtSig(pgpTag tag, const uint8_t *h, size_t hlen,
}
p = ((uint8_t *)v) + sizeof(*v);
- rc = pgpPrtSigParams(tag, v->pubkey_algo, v->sigtype, p, h, hlen, _digp);
+ rc = pgpPrtSigParams(tag, v->pubkey_algo, p, h, hlen, _digp);
} break;
case 4:
{ pgpPktSigV4 v = (pgpPktSigV4)h;
@@ -662,7 +660,7 @@ static int pgpPrtSig(pgpTag tag, const uint8_t *h, size_t hlen,
if (p > (h + hlen))
return 1;
- rc = pgpPrtSigParams(tag, v->pubkey_algo, v->sigtype, p, h, hlen, _digp);
+ rc = pgpPrtSigParams(tag, v->pubkey_algo, p, h, hlen, _digp);
} break;
default:
rpmlog(RPMLOG_WARNING, _("Unsupported version of key: V%d\n"), version);
@@ -1041,36 +1039,128 @@ unsigned int pgpDigParamsAlgo(pgpDigParams digp, unsigned int algotype)
return algo;
}
+static pgpDigParams pgpDigParamsNew(uint8_t tag)
+{
+ pgpDigParams digp = xcalloc(1, sizeof(*digp));
+ digp->tag = tag;
+ return digp;
+}
+
+static int hashKey(DIGEST_CTX hash, const struct pgpPkt *pkt, int exptag)
+{
+ int rc = -1;
+ if (pkt->tag == exptag) {
+ uint8_t head[] = {
+ 0x99,
+ (pkt->blen >> 8),
+ (pkt->blen ),
+ };
+
+ rpmDigestUpdate(hash, head, 3);
+ rpmDigestUpdate(hash, pkt->body, pkt->blen);
+ rc = 0;
+ }
+ return rc;
+}
+
+static int pgpVerifySelf(pgpDigParams key, pgpDigParams selfsig,
+ const struct pgpPkt *all, int i)
+{
+ int rc = -1;
+ DIGEST_CTX hash = NULL;
+
+ switch (selfsig->sigtype) {
+ case PGPSIGTYPE_SUBKEY_BINDING:
+ hash = rpmDigestInit(selfsig->hash_algo, 0);
+ if (hash) {
+ rc = hashKey(hash, &all[0], PGPTAG_PUBLIC_KEY);
+ if (!rc)
+ rc = hashKey(hash, &all[i-1], PGPTAG_PUBLIC_SUBKEY);
+ }
+ break;
+ default:
+ /* ignore types we can't handle */
+ rc = 0;
+ break;
+ }
+
+ if (hash && rc == 0)
+ rc = pgpVerifySignature(key, selfsig, hash);
+
+ rpmDigestFinal(hash, NULL, NULL, 0);
+
+ return rc;
+}
+
int pgpPrtParams(const uint8_t * pkts, size_t pktlen, unsigned int pkttype,
pgpDigParams * ret)
{
const uint8_t *p = pkts;
const uint8_t *pend = pkts + pktlen;
pgpDigParams digp = NULL;
- struct pgpPkt pkt;
+ pgpDigParams selfsig = NULL;
+ int i = 0;
+ int alloced = 16; /* plenty for normal cases */
+ struct pgpPkt *all = xmalloc(alloced * sizeof(*all));
int rc = -1; /* assume failure */
+ int expect = 0;
+ int prevtag = 0;
while (p < pend) {
- if (decodePkt(p, (pend - p), &pkt))
+ struct pgpPkt *pkt = &all[i];
+ if (decodePkt(p, (pend - p), pkt))
break;
if (digp == NULL) {
- if (pkttype && pkt.tag != pkttype) {
+ if (pkttype && pkt->tag != pkttype) {
break;
} else {
- digp = xcalloc(1, sizeof(*digp));
- digp->tag = pkt.tag;
+ digp = pgpDigParamsNew(pkt->tag);
}
}
- if (pgpPrtPkt(&pkt, digp))
+ if (expect) {
+ if (pkt->tag != expect)
+ break;
+ selfsig = pgpDigParamsNew(pkt->tag);
+ }
+
+ if (pgpPrtPkt(pkt, selfsig ? selfsig : digp))
break;
- p += (pkt.body - pkt.head) + pkt.blen;
+ if (selfsig) {
+ /* subkeys must be followed by binding signature */
+ if (prevtag == PGPTAG_PUBLIC_SUBKEY) {
+ if (selfsig->sigtype != PGPSIGTYPE_SUBKEY_BINDING)
+ break;
+ }
+
+ int xx = pgpVerifySelf(digp, selfsig, all, i);
+
+ selfsig = pgpDigParamsFree(selfsig);
+ if (xx)
+ break;
+ expect = 0;
+ }
+
+ if (pkt->tag == PGPTAG_PUBLIC_SUBKEY)
+ expect = PGPTAG_SIGNATURE;
+ prevtag = pkt->tag;
+
+ i++;
+ p += (pkt->body - pkt->head) + pkt->blen;
+ if (pkttype == PGPTAG_SIGNATURE)
+ break;
+
+ if (alloced <= i) {
+ alloced *= 2;
+ all = xrealloc(all, alloced * sizeof(*all));
+ }
}
- rc = (digp && (p == pend)) ? 0 : -1;
+ rc = (digp && (p == pend) && expect == 0) ? 0 : -1;
+ free(all);
if (ret && rc == 0) {
*ret = digp;
} else {
@@ -1105,8 +1195,7 @@ int pgpPrtParamsSubkeys(const uint8_t *pkts, size_t pktlen,
digps = xrealloc(digps, alloced * sizeof(*digps));
}
- digps[count] = xcalloc(1, sizeof(**digps));
- digps[count]->tag = PGPTAG_PUBLIC_SUBKEY;
+ digps[count] = pgpDigParamsNew(PGPTAG_PUBLIC_SUBKEY);
/* Copy UID from main key to subkey */
digps[count]->userid = xstrdup(mainkey->userid);
diff --git a/tests/Makefile.am b/tests/Makefile.am
index f742a9e1d..328234278 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -107,6 +107,9 @@ EXTRA_DIST += data/SPECS/hello-config-buildid.spec
EXTRA_DIST += data/SPECS/hello-cd.spec
EXTRA_DIST += data/keys/rpm.org-rsa-2048-test.pub
EXTRA_DIST += data/keys/rpm.org-rsa-2048-test.secret
+EXTRA_DIST += data/keys/CVE-2021-3521-badbind.asc
+EXTRA_DIST += data/keys/CVE-2021-3521-nosubsig.asc
+EXTRA_DIST += data/keys/CVE-2021-3521-nosubsig-last.asc
EXTRA_DIST += data/macros.testfile
EXTRA_DIST += data/macros.debug
EXTRA_DIST += data/SOURCES/foo.c
diff --git a/tests/data/keys/CVE-2021-3521-badbind.asc b/tests/data/keys/CVE-2021-3521-badbind.asc
new file mode 100644
index 000000000..aea00f9d7
--- /dev/null
+++ b/tests/data/keys/CVE-2021-3521-badbind.asc
@@ -0,0 +1,25 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: rpm-4.17.90 (NSS-3)
+
+mQENBFjmORgBCAC7TMEk6wnjSs8Dr4yqSScWdU2pjcqrkTxuzdWvowcIUPZI0w/g
+HkRqGd4apjvY2V15kjL10gk3QhFP3pZ/9p7zh8o8NHX7aGdSGDK7NOq1eFaErPRY
+91LW9RiZ0lbOjXEzIL0KHxUiTQEmdXJT43DJMFPyW9fkCWg0OltiX618FUdWWfI8
+eySdLur1utnqBvdEbCUvWK2RX3vQZQdvEBODnNk2pxqTyV0w6VPQ96W++lF/5Aas
+7rUv3HIyIXxIggc8FRrnH+y9XvvHDonhTIlGnYZN4ubm9i4y3gOkrZlGTrEw7elQ
+1QeMyG2QQEbze8YjpTm4iLABCBrRfPRaQpwrABEBAAG0IXJwbS5vcmcgUlNBIHRl
+c3RrZXkgPHJzYUBycG0ub3JnPokBNwQTAQgAIQUCWOY5GAIbAwULCQgHAgYVCAkK
+CwIEFgIDAQIeAQIXgAAKCRBDRFkeGWTF/MxxCACnjqFL+MmPh9W9JQKT2DcLbBzf
+Cqo6wcEBoCOcwgRSk8dSikhARoteoa55JRJhuMyeKhhEAogE9HRmCPFdjezFTwgB
+BDVBpO2dZ023mLXDVCYX3S8pShOgCP6Tn4wqCnYeAdLcGg106N4xcmgtcssJE+Pr
+XzTZksbZsrTVEmL/Ym+R5w5jBfFnGk7Yw7ndwfQsfNXQb5AZynClFxnX546lcyZX
+fEx3/e6ezw57WNOUK6WT+8b+EGovPkbetK/rGxNXuWaP6X4A/QUm8O98nCuHYFQq
++mvNdsCBqGf7mhaRGtpHk/JgCn5rFvArMDqLVrR9hX0LdCSsH7EGE+bR3r7wuQEN
+BFjmORgBCACk+vDZrIXQuFXEYToZVwb2attzbbJJCqD71vmZTLsW0QxuPKRgbcYY
+zp4K4lVBnHhFrF8MOUOxJ7kQWIJZMZFt+BDcptCYurbD2H4W2xvnWViiC+LzCMzz
+iMJT6165uefL4JHTDPxC2fFiM9yrc72LmylJNkM/vepT128J5Qv0gRUaQbHiQuS6
+Dm/+WRnUfx3i89SV4mnBxb/Ta93GVqoOciWwzWSnwEnWYAvOb95JL4U7c5J5f/+c
+KnQDHsW7sIiIdscsWzvgf6qs2Ra1Zrt7Fdk4+ZS2f/adagLhDO1C24sXf5XfMk5m
+L0OGwZSr9m5s17VXxfspgU5ugc8kBJfzABEBAAE=
+=WCfs
+-----END PGP PUBLIC KEY BLOCK-----
+
diff --git a/tests/data/keys/CVE-2021-3521-nosubsig-last.asc b/tests/data/keys/CVE-2021-3521-nosubsig-last.asc
new file mode 100644
index 000000000..aea00f9d7
--- /dev/null
+++ b/tests/data/keys/CVE-2021-3521-nosubsig-last.asc
@@ -0,0 +1,25 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: rpm-4.17.90 (NSS-3)
+
+mQENBFjmORgBCAC7TMEk6wnjSs8Dr4yqSScWdU2pjcqrkTxuzdWvowcIUPZI0w/g
+HkRqGd4apjvY2V15kjL10gk3QhFP3pZ/9p7zh8o8NHX7aGdSGDK7NOq1eFaErPRY
+91LW9RiZ0lbOjXEzIL0KHxUiTQEmdXJT43DJMFPyW9fkCWg0OltiX618FUdWWfI8
+eySdLur1utnqBvdEbCUvWK2RX3vQZQdvEBODnNk2pxqTyV0w6VPQ96W++lF/5Aas
+7rUv3HIyIXxIggc8FRrnH+y9XvvHDonhTIlGnYZN4ubm9i4y3gOkrZlGTrEw7elQ
+1QeMyG2QQEbze8YjpTm4iLABCBrRfPRaQpwrABEBAAG0IXJwbS5vcmcgUlNBIHRl
+c3RrZXkgPHJzYUBycG0ub3JnPokBNwQTAQgAIQUCWOY5GAIbAwULCQgHAgYVCAkK
+CwIEFgIDAQIeAQIXgAAKCRBDRFkeGWTF/MxxCACnjqFL+MmPh9W9JQKT2DcLbBzf
+Cqo6wcEBoCOcwgRSk8dSikhARoteoa55JRJhuMyeKhhEAogE9HRmCPFdjezFTwgB
+BDVBpO2dZ023mLXDVCYX3S8pShOgCP6Tn4wqCnYeAdLcGg106N4xcmgtcssJE+Pr
+XzTZksbZsrTVEmL/Ym+R5w5jBfFnGk7Yw7ndwfQsfNXQb5AZynClFxnX546lcyZX
+fEx3/e6ezw57WNOUK6WT+8b+EGovPkbetK/rGxNXuWaP6X4A/QUm8O98nCuHYFQq
++mvNdsCBqGf7mhaRGtpHk/JgCn5rFvArMDqLVrR9hX0LdCSsH7EGE+bR3r7wuQEN
+BFjmORgBCACk+vDZrIXQuFXEYToZVwb2attzbbJJCqD71vmZTLsW0QxuPKRgbcYY
+zp4K4lVBnHhFrF8MOUOxJ7kQWIJZMZFt+BDcptCYurbD2H4W2xvnWViiC+LzCMzz
+iMJT6165uefL4JHTDPxC2fFiM9yrc72LmylJNkM/vepT128J5Qv0gRUaQbHiQuS6
+Dm/+WRnUfx3i89SV4mnBxb/Ta93GVqoOciWwzWSnwEnWYAvOb95JL4U7c5J5f/+c
+KnQDHsW7sIiIdscsWzvgf6qs2Ra1Zrt7Fdk4+ZS2f/adagLhDO1C24sXf5XfMk5m
+L0OGwZSr9m5s17VXxfspgU5ugc8kBJfzABEBAAE=
+=WCfs
+-----END PGP PUBLIC KEY BLOCK-----
+
diff --git a/tests/data/keys/CVE-2021-3521-nosubsig.asc b/tests/data/keys/CVE-2021-3521-nosubsig.asc
new file mode 100644
index 000000000..3a2e7417f
--- /dev/null
+++ b/tests/data/keys/CVE-2021-3521-nosubsig.asc
@@ -0,0 +1,37 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: rpm-4.17.90 (NSS-3)
+
+mQENBFjmORgBCAC7TMEk6wnjSs8Dr4yqSScWdU2pjcqrkTxuzdWvowcIUPZI0w/g
+HkRqGd4apjvY2V15kjL10gk3QhFP3pZ/9p7zh8o8NHX7aGdSGDK7NOq1eFaErPRY
+91LW9RiZ0lbOjXEzIL0KHxUiTQEmdXJT43DJMFPyW9fkCWg0OltiX618FUdWWfI8
+eySdLur1utnqBvdEbCUvWK2RX3vQZQdvEBODnNk2pxqTyV0w6VPQ96W++lF/5Aas
+7rUv3HIyIXxIggc8FRrnH+y9XvvHDonhTIlGnYZN4ubm9i4y3gOkrZlGTrEw7elQ
+1QeMyG2QQEbze8YjpTm4iLABCBrRfPRaQpwrABEBAAG0IXJwbS5vcmcgUlNBIHRl
+c3RrZXkgPHJzYUBycG0ub3JnPokBNwQTAQgAIQUCWOY5GAIbAwULCQgHAgYVCAkK
+CwIEFgIDAQIeAQIXgAAKCRBDRFkeGWTF/MxxCACnjqFL+MmPh9W9JQKT2DcLbBzf
+Cqo6wcEBoCOcwgRSk8dSikhARoteoa55JRJhuMyeKhhEAogE9HRmCPFdjezFTwgB
+BDVBpO2dZ023mLXDVCYX3S8pShOgCP6Tn4wqCnYeAdLcGg106N4xcmgtcssJE+Pr
+XzTZksbZsrTVEmL/Ym+R5w5jBfFnGk7Yw7ndwfQsfNXQb5AZynClFxnX546lcyZX
+fEx3/e6ezw57WNOUK6WT+8b+EGovPkbetK/rGxNXuWaP6X4A/QUm8O98nCuHYFQq
++mvNdsCBqGf7mhaRGtpHk/JgCn5rFvArMDqLVrR9hX0LdCSsH7EGE+bR3r7wuQEN
+BFjmORgBCACk+vDZrIXQuFXEYToZVwb2attzbbJJCqD71vmZTLsW0QxuPKRgbcYY
+zp4K4lVBnHhFrF8MOUOxJ7kQWIJZMZFt+BDcptCYurbD2H4W2xvnWViiC+LzCMzz
+iMJT6165uefL4JHTDPxC2fFiM9yrc72LmylJNkM/vepT128J5Qv0gRUaQbHiQuS6
+Dm/+WRnUfx3i89SV4mnBxb/Ta93GVqoOciWwzWSnwEnWYAvOb95JL4U7c5J5f/+c
+KnQDHsW7sIiIdscsWzvgf6qs2Ra1Zrt7Fdk4+ZS2f/adagLhDO1C24sXf5XfMk5m
+L0OGwZSr9m5s17VXxfspgU5ugc8kBJfzABEBAAG5AQ0EWOY5GAEIAKT68NmshdC4
+VcRhOhlXBvZq23NtskkKoPvW+ZlMuxbRDG48pGBtxhjOngriVUGceEWsXww5Q7En
+uRBYglkxkW34ENym0Ji6tsPYfhbbG+dZWKIL4vMIzPOIwlPrXrm558vgkdMM/ELZ
+8WIz3KtzvYubKUk2Qz+96lPXbwnlC/SBFRpBseJC5LoOb/5ZGdR/HeLz1JXiacHF
+v9Nr3cZWqg5yJbDNZKfASdZgC85v3kkvhTtzknl//5wqdAMexbuwiIh2xyxbO+B/
+qqzZFrVmu3sV2Tj5lLZ/9p1qAuEM7ULbixd/ld8yTmYvQ4bBlKv2bmzXtVfF+ymB
+Tm6BzyQEl/MAEQEAAYkBHwQYAQgACQUCWOY5GAIbDAAKCRBDRFkeGWTF/PANB/9j
+mifmj6z/EPe0PJFhrpISt9PjiUQCt0IPtiL5zKAkWjHePIzyi+0kCTBF6DDLFxos
+3vN4bWnVKT1kBhZAQlPqpJTg+m74JUYeDGCdNx9SK7oRllATqyu+5rncgxjWVPnQ
+zu/HRPlWJwcVFYEVXYL8xzfantwQTqefjmcRmBRdA2XJITK+hGWwAmrqAWx+q5xX
+Pa8wkNMxVzNS2rUKO9SoVuJ/wlUvfoShkJ/VJ5HDp3qzUqncADfdGN35TDzscngQ
+gHvnMwVBfYfSCABV1hNByoZcc/kxkrWMmsd/EnIyLd1Q1baKqc3cEDuC6E6/o4yJ
+E4XX4jtDmdZPreZALsiB
+=rRop
+-----END PGP PUBLIC KEY BLOCK-----
+
diff --git a/tests/rpmsigdig.at b/tests/rpmsigdig.at
index e1a3ab062..705fc5870 100644
--- a/tests/rpmsigdig.at
+++ b/tests/rpmsigdig.at
@@ -240,6 +240,34 @@ gpg(185e6146f00650f8) = 4:185e6146f00650f8-58e63918
[])
AT_CLEANUP
+AT_SETUP([rpmkeys --import invalid keys])
+AT_KEYWORDS([rpmkeys import])
+RPMDB_INIT
+
+AT_CHECK([
+runroot rpmkeys --import /data/keys/CVE-2021-3521-badbind.asc
+],
+[1],
+[],
+[error: /data/keys/CVE-2021-3521-badbind.asc: key 1 import failed.]
+)
+AT_CHECK([
+runroot rpmkeys --import /data/keys/CVE-2021-3521-nosubsig.asc
+],
+[1],
+[],
+[error: /data/keys/CVE-2021-3521-nosubsig.asc: key 1 import failed.]
+)
+
+AT_CHECK([
+runroot rpmkeys --import /data/keys/CVE-2021-3521-nosubsig-last.asc
+],
+[1],
+[],
+[error: /data/keys/CVE-2021-3521-nosubsig-last.asc: key 1 import failed.]
+)
+AT_CLEANUP
+
# ------------------------------
# Test pre-built package verification
AT_SETUP([rpmkeys -K <signed> 1])
--
2.33.1

View File

@ -32,7 +32,7 @@
%global rpmver 4.16.1.3 %global rpmver 4.16.1.3
#global snapver rc1 #global snapver rc1
%global rel 7 %global rel 8
%global sover 9 %global sover 9
%global srcver %{rpmver}%{?snapver:-%{snapver}} %global srcver %{rpmver}%{?snapver:-%{snapver}}
@ -72,6 +72,11 @@ Patch100: rpm-4.16.1.3-imp-covscan-fixes.patch
Patch101: rpm-4.16.1.3-rpmsign-support-EdDSA-sig.patch Patch101: rpm-4.16.1.3-rpmsign-support-EdDSA-sig.patch
Patch102: rpm-4.16.1.3-add-fapolicyd-plugin.patch Patch102: rpm-4.16.1.3-add-fapolicyd-plugin.patch
Patch103: rpm-4.16.1.3-unblock-signals-in-forked-scriptlets.patch Patch103: rpm-4.16.1.3-unblock-signals-in-forked-scriptlets.patch
Patch104: rpm-4.16.1.3-support-bdb-hash-v8.patch
Patch105: rpm-4.16.1.3-ELF-files-strip-when-debuginfo-disabled.patch
Patch106: rpm-4.16.1.3-unbreak-checking-of-installed-rich-deps.patch
Patch107: rpm-4.16.1.3-fix-IMA-sig-len-assumed-const.patch
Patch108: rpm-4.16.1.3-validate-and-require-subkey-binding-sigs.patch
# These are not yet upstream # These are not yet upstream
Patch906: rpm-4.7.1-geode-i686.patch Patch906: rpm-4.7.1-geode-i686.patch
@ -368,6 +373,7 @@ done;
--with-cap \ --with-cap \
--with-acl \ --with-acl \
%{?with_ndb: --enable-ndb} \ %{?with_ndb: --enable-ndb} \
%{!?with_libarchive: --without-archive} \
%{?with_libimaevm: --with-imaevm} \ %{?with_libimaevm: --with-imaevm} \
%{?with_zstd: --enable-zstd} \ %{?with_zstd: --enable-zstd} \
%{?with_sqlite: --enable-sqlite} \ %{?with_sqlite: --enable-sqlite} \
@ -461,7 +467,9 @@ fi
%attr(0644, root, root) %ghost /var/lib/rpm/.*.lock %attr(0644, root, root) %ghost /var/lib/rpm/.*.lock
%{_bindir}/rpm %{_bindir}/rpm
%if %{with libarchive}
%{_bindir}/rpm2archive %{_bindir}/rpm2archive
%endif
%{_bindir}/rpm2cpio %{_bindir}/rpm2cpio
%{_bindir}/rpmdb %{_bindir}/rpmdb
%{_bindir}/rpmkeys %{_bindir}/rpmkeys
@ -471,7 +479,9 @@ fi
%{_mandir}/man8/rpm.8* %{_mandir}/man8/rpm.8*
%{_mandir}/man8/rpmdb.8* %{_mandir}/man8/rpmdb.8*
%{_mandir}/man8/rpmkeys.8* %{_mandir}/man8/rpmkeys.8*
%if %{with libarchive}
%{_mandir}/man8/rpm2archive.8* %{_mandir}/man8/rpm2archive.8*
%endif
%{_mandir}/man8/rpm2cpio.8* %{_mandir}/man8/rpm2cpio.8*
%{_mandir}/man8/rpm-misc.8* %{_mandir}/man8/rpm-misc.8*
%{_mandir}/man8/rpm-plugins.8* %{_mandir}/man8/rpm-plugins.8*
@ -596,6 +606,16 @@ fi
%doc doc/librpm/html/* %doc doc/librpm/html/*
%changelog %changelog
* Thu Dec 09 2021 Michal Domonkos <mdomonko@redhat.com> - 4.16.1.3-8
- Support hash v8 databases from BDB < 4.6 (#1965147)
- Ensure ELF files get stripped when debuginfo is disabled (#1999009)
- Actually honor libarchive bcond at configure time (#1999012)
- Unbreak checking of installed rich dependencies (#2015407)
- Rebuild against soname bump in ima-evm-utils (#2026079)
- Fix IMA signature lengths assumed constant (#2018937)
- Validate and require subkey binding sigs on PGP pubkeys (#1943724)
- Fixes CVE-2021-3521
* Thu Aug 19 2021 Michal Domonkos <mdomonko@redhat.com> - 4.16.1.3-7 * Thu Aug 19 2021 Michal Domonkos <mdomonko@redhat.com> - 4.16.1.3-7
- Unblock signals in forked scriptlets (#1991667) - Unblock signals in forked scriptlets (#1991667)