diff --git a/backport-Check-file-iterator-for-being-NULL-consistently.patch b/backport-Check-file-iterator-for-being-NULL-consistently.patch new file mode 100644 index 0000000..ecc32bb --- /dev/null +++ b/backport-Check-file-iterator-for-being-NULL-consistently.patch @@ -0,0 +1,67 @@ +From 470498bd5a51f8d98ae8e721beea58ef81c19a51 Mon Sep 17 00:00:00 2001 +From: Florian Festi +Date: Wed, 22 Sep 2021 16:10:53 +0200 +Subject: [PATCH] Check file iterator for being NULL consistently + +No point in allowing NULL only for one of the arguments. + +Thanks to ex0z3 (https://github.com/ex0z3) for reporting! + +Resolves: #1782 +--- + lib/rpmfi.c | 13 +++++++------ + 1 file changed, 7 insertions(+), 6 deletions(-) + +diff --git a/lib/rpmfi.c b/lib/rpmfi.c +index c6c9699..b67680c 100644 +--- a/lib/rpmfi.c ++++ b/lib/rpmfi.c +@@ -735,7 +735,7 @@ uint32_t rpmfilesFLinks(rpmfiles fi, int ix, const int ** files) + + uint32_t rpmfiFLinks(rpmfi fi, const int ** files) + { +- return rpmfilesFLinks(fi->files, fi ? fi->i : -1, files); ++ return rpmfilesFLinks(fi ? fi->files : NULL, fi ? fi->i : -1, files); + } + + uint32_t rpmfilesFNlink(rpmfiles fi, int ix) +@@ -1948,22 +1948,22 @@ const char * rpmfiOFN(rpmfi fi) + + const unsigned char * rpmfiFDigest(rpmfi fi, int *algo, size_t *len) + { +- return rpmfilesFDigest(fi->files, fi ? fi->i : -1, algo, len); ++ return rpmfilesFDigest(fi ? fi->files : NULL, fi ? fi->i : -1, algo, len); + } + + const unsigned char * rpmfiFSignature(rpmfi fi, size_t *len) + { +- return rpmfilesFSignature(fi->files, fi ? fi->i : -1, len); ++ return rpmfilesFSignature(fi ? fi->files : NULL, fi ? fi->i : -1, len); + } + + const unsigned char * rpmfiVSignature(rpmfi fi, size_t *len, uint16_t *algo) + { +- return rpmfilesVSignature(fi->files, fi ? fi->i : -1, len, algo); ++ return rpmfilesVSignature(fi ? fi->files : NULL, fi ? fi->i : -1, len, algo); + } + + uint32_t rpmfiFDepends(rpmfi fi, const uint32_t ** fddictp) + { +- return rpmfilesFDepends(fi->files, fi ? fi->i : -1, fddictp); ++ return rpmfilesFDepends(fi ? fi->files : NULL, fi ? fi->i : -1, fddictp); + } + + int rpmfiStat(rpmfi fi, int flags, struct stat *sb) +@@ -1983,7 +1983,8 @@ int rpmfiStat(rpmfi fi, int flags, struct stat *sb) + + int rpmfiCompare(const rpmfi afi, const rpmfi bfi) + { +- return rpmfilesCompare(afi->files, afi ? afi->i : -1, bfi->files, bfi ? bfi->i : -1); ++ return rpmfilesCompare(afi ? afi->files : NULL, afi ? afi->i : -1, ++ bfi ? bfi->files : NULL, bfi ? bfi->i : -1); + } + + rpmVerifyAttrs rpmfiVerify(rpmfi fi, rpmVerifyAttrs omitMask) +-- +1.8.3.1 + diff --git a/backport-Fix-a-memleak-in-ndb-from-opened-but-not-closed-dbis.patch b/backport-Fix-a-memleak-in-ndb-from-opened-but-not-closed-dbis.patch new file mode 100644 index 0000000..baeb339 --- /dev/null +++ b/backport-Fix-a-memleak-in-ndb-from-opened-but-not-closed-dbis.patch @@ -0,0 +1,26 @@ +From 5c5cd9f30b31f0255a484f7d2e3f9cfacc0ec3bf Mon Sep 17 00:00:00 2001 +From: Panu Matilainen +Date: Wed, 15 Dec 2021 10:01:41 +0200 +Subject: [PATCH] Fix a memleak in ndb from opened but not closed dbis. + +Fixes: #1861 +--- + lib/backend/ndb/glue.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/backend/ndb/glue.c b/lib/backend/ndb/glue.c +index 7ba3056..d528ebc 100644 +--- a/lib/backend/ndb/glue.c ++++ b/lib/backend/ndb/glue.c +@@ -77,7 +77,7 @@ static int ndb_Close(dbiIndex dbi, unsigned int flags) + } + if (rdb->db_dbenv) + closeEnv(rdb); +- dbi->dbi_db = 0; ++ dbiFree(dbi); + return 0; + } + +-- +1.8.3.1 + diff --git a/backport-Fix-hash-context-leak.patch b/backport-Fix-hash-context-leak.patch new file mode 100644 index 0000000..f8fda68 --- /dev/null +++ b/backport-Fix-hash-context-leak.patch @@ -0,0 +1,34 @@ +From 6e9531430d70fe80b67782ed57f1526aec9ed711 Mon Sep 17 00:00:00 2001 +From: Justus Winter +Date: Thu, 28 Oct 2021 13:32:22 +0200 +Subject: [PATCH] Fix hash context leak + +The hash context is duplicated unconditionally, but there is an +execution path exiting the function without it being finalized. +--- + rpmio/rpmpgp.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/rpmio/rpmpgp.c b/rpmio/rpmpgp.c +index 861f670..1e4f667 100644 +--- a/rpmio/rpmpgp.c ++++ b/rpmio/rpmpgp.c +@@ -1310,6 +1310,7 @@ rpmRC pgpVerifySignature(pgpDigParams key, pgpDigParams sig, DIGEST_CTX hashctx) + } + + rpmDigestFinal(ctx, (void **)&hash, &hashlen, 0); ++ ctx = NULL; + + /* Compare leading 16 bits of digest for quick check. */ + if (hash == NULL || memcmp(hash, sig->signhash16, 2) != 0) +@@ -1333,6 +1334,7 @@ rpmRC pgpVerifySignature(pgpDigParams key, pgpDigParams sig, DIGEST_CTX hashctx) + + exit: + free(hash); ++ rpmDigestFinal(ctx, NULL, NULL, 0); + return res; + + } +-- +1.8.3.1 + diff --git a/backport-Fix-hashlen-overflow.patch b/backport-Fix-hashlen-overflow.patch new file mode 100644 index 0000000..4717174 --- /dev/null +++ b/backport-Fix-hashlen-overflow.patch @@ -0,0 +1,46 @@ +From 3f142b210ae0c01e1b21c2c057b12db574386e7a Mon Sep 17 00:00:00 2001 +From: Justus Winter +Date: Wed, 27 Oct 2021 09:51:13 +0200 +Subject: [PATCH] Fix hashlen overflow + +struct pgpDigParams_s keeps a copy of the verbatim key material for +hashing. The length of this data is kept in 'hashlen' which +previously was a uint8_t. However, the size of the signature's hashed +subpacket area can be up to 2^16 bytes, and one needs to hash some of +the signature packet's fields on top of that. + +Hence, 'hashlen' must be at least a uint32_t. + +This overflow happens in practice as soon as the signature's hashed +subpacket area contains an embedded signature. See section 11.1 of +RFC4880: + + Each Subkey packet MUST be followed by one Signature packet, which + should be a subkey binding signature issued by the top-level key. + For subkeys that can issue signatures, the subkey binding signature + MUST contain an Embedded Signature subpacket with a primary key + binding signature (0x19) issued by the subkey on the top-level key. + +While the embedded signature may be in the unhashed subpacket area +because it is self-authenticating, it is more robust to put it in the +hashed area. +--- + rpmio/digest.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/rpmio/digest.h b/rpmio/digest.h +index 690d176..3b72a28 100644 +--- a/rpmio/digest.h ++++ b/rpmio/digest.h +@@ -33,7 +33,7 @@ struct pgpDigParams_s { + + uint8_t hash_algo; + uint8_t sigtype; +- uint8_t hashlen; ++ uint32_t hashlen; + uint8_t signhash16[2]; + pgpKeyID_t signid; + uint8_t saved; +-- +1.8.3.1 + diff --git a/backport-Fix-some-Lua-stack-leaks-in-our-initialization-code.patch b/backport-Fix-some-Lua-stack-leaks-in-our-initialization-code.patch new file mode 100644 index 0000000..7166cce --- /dev/null +++ b/backport-Fix-some-Lua-stack-leaks-in-our-initialization-code.patch @@ -0,0 +1,35 @@ +From 3aa1abc4cabaa77bd9d3d05064466990d7e68a59 Mon Sep 17 00:00:00 2001 +From: Panu Matilainen +Date: Thu, 18 Nov 2021 11:53:17 +0200 +Subject: [PATCH] Fix some Lua stack leaks in our initialization code + +--- + rpmio/rpmlua.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/rpmio/rpmlua.c b/rpmio/rpmlua.c +index 8459cd8..6ad9119 100644 +--- a/rpmio/rpmlua.c ++++ b/rpmio/rpmlua.c +@@ -131,14 +131,18 @@ rpmlua rpmluaNew() + + for (lib = extlibs; lib->name; lib++) { + luaL_requiref(L, lib->name, lib->func, 1); ++ lua_pop(L, 1); + } + lua_pushcfunction(L, rpm_print); + lua_setglobal(L, "print"); + + lua_getglobal(L, "os"); + luaL_setfuncs(L, os_overrides, 0); ++ lua_pop(L, 1); ++ + lua_getglobal(L, "posix"); + luaL_setfuncs(L, posix_overrides, 0); ++ lua_pop(L, 1); + + lua_getglobal(L, "package"); + lua_pushfstring(L, "%s/%s", rpmConfigDir(), "/lua/?.lua"); +-- +1.8.3.1 + diff --git a/backport-Process-MPI-s-from-all-kinds-of-signatures.patch b/backport-Process-MPI-s-from-all-kinds-of-signatures.patch new file mode 100644 index 0000000..457b406 --- /dev/null +++ b/backport-Process-MPI-s-from-all-kinds-of-signatures.patch @@ -0,0 +1,57 @@ +From b5e8bc74b2b05aa557f663fe227b94d2bc64fbd8 Mon Sep 17 00:00:00 2001 +From: Panu Matilainen +Date: Thu, 30 Sep 2021 09:51:10 +0300 +Subject: [PATCH] Process MPI's from all kinds of signatures + +No immediate effect but needed by the following commits. +--- + rpmio/rpmpgp.c | 12 +++++------- + 1 file changed, 5 insertions(+), 7 deletions(-) + +diff --git a/rpmio/rpmpgp.c b/rpmio/rpmpgp.c +index ee5c81e..340de5f 100644 +--- a/rpmio/rpmpgp.c ++++ b/rpmio/rpmpgp.c +@@ -543,7 +543,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) + { +@@ -556,10 +556,8 @@ static int pgpPrtSigParams(pgpTag tag, uint8_t pubkey_algo, uint8_t sigtype, + int mpil = pgpMpiLen(p); + if (pend - p < mpil) + break; +- if (sigtype == PGPSIGTYPE_BINARY || sigtype == PGPSIGTYPE_TEXT) { +- if (sigalg->setmpi(sigalg, i, p)) +- break; +- } ++ if (sigalg->setmpi(sigalg, i, p)) ++ break; + p += mpil; + } + +@@ -618,7 +618,7 @@ static int pgpPrtSig(pgpTag tag, const uint8_t *h, size_t hlen, + + p = ((uint8_t *)v) + sizeof(*v); + _digp->data = p; +- 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; +@@ -678,7 +678,7 @@ static int pgpPrtSig(pgpTag tag, const uint8_t *h, size_t hlen, + return 1; + + _digp->data = p; +- 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 signature: V%d\n"), version); +-- +1.8.3.1 + diff --git a/backport-Refactor-pgpDigParams-construction-to-helper-functio.patch b/backport-Refactor-pgpDigParams-construction-to-helper-functio.patch new file mode 100644 index 0000000..05287be --- /dev/null +++ b/backport-Refactor-pgpDigParams-construction-to-helper-functio.patch @@ -0,0 +1,52 @@ +From 9f03f42e2614a68f589f9db8fe76287146522c0c Mon Sep 17 00:00:00 2001 +From: Panu Matilainen +Date: Thu, 30 Sep 2021 09:56:20 +0300 +Subject: [PATCH] Refactor pgpDigParams construction to helper function + +No functional changes, just to reduce code duplication and needed by +the following commits. +--- + rpmio/rpmpgp.c | 13 +++++++++---- + 1 file changed, 9 insertions(+), 4 deletions(-) + +diff --git a/rpmio/rpmpgp.c b/rpmio/rpmpgp.c +index 340de5f..aad7c27 100644 +--- a/rpmio/rpmpgp.c ++++ b/rpmio/rpmpgp.c +@@ -1055,6 +1055,13 @@ 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; ++} ++ + int pgpPrtParams(const uint8_t * pkts, size_t pktlen, unsigned int pkttype, + pgpDigParams * ret) + { +@@ -1072,8 +1079,7 @@ int pgpPrtParams(const uint8_t * pkts, size_t pktlen, unsigned int pkttype, + if (pkttype && pkt.tag != pkttype) { + break; + } else { +- digp = xcalloc(1, sizeof(*digp)); +- digp->tag = pkt.tag; ++ digp = pgpDigParamsNew(pkt.tag); + } + } + +@@ -1121,8 +1127,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); + +-- +1.8.3.1 + diff --git a/backport-Revert-Explictly-skip-non-installed-files-on-erasur.patch b/backport-Revert-Explictly-skip-non-installed-files-on-erasur.patch new file mode 100644 index 0000000..cb30a46 --- /dev/null +++ b/backport-Revert-Explictly-skip-non-installed-files-on-erasur.patch @@ -0,0 +1,32 @@ +From 26bb41e1cb7f7836302b3555cff8f20f9fc19188 Mon Sep 17 00:00:00 2001 +From: licunlong1 +Date: Thu, 21 Oct 2021 21:29:25 +0800 +Subject: [PATCH] don not skip abnormal files + +This reverts 2d52726bd55f008ea23262c2a3a31ae689cd2af4, as when removing +the same file of different archs, if the file state is WRONGCOLOR, it +sets the action to `skip`. This will result in some elf files left over. + +--- + lib/transaction.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/lib/transaction.c b/lib/transaction.c +index 55bc2d9..20cf680 100644 +--- a/lib/transaction.c ++++ b/lib/transaction.c +@@ -689,10 +689,8 @@ assert(otherFi != NULL); + } + if (XFA_SKIPPING(rpmfsGetAction(fs, i))) + break; +- if (rpmfilesFState(fi, i) != RPMFILE_STATE_NORMAL) { +- rpmfsSetAction(fs, i, FA_SKIP); ++ if (rpmfilesFState(fi, i) != RPMFILE_STATE_NORMAL) + break; +- } + + /* Pre-existing modified config files need to be saved. */ + if (rpmfilesConfigConflict(fi, i)) { +-- +1.8.3.1 + diff --git a/backport-Simplify-rpm_print-fixing-a-Lua-stack-leak-as-a-bonu.patch b/backport-Simplify-rpm_print-fixing-a-Lua-stack-leak-as-a-bonu.patch new file mode 100644 index 0000000..c0f0968 --- /dev/null +++ b/backport-Simplify-rpm_print-fixing-a-Lua-stack-leak-as-a-bonu.patch @@ -0,0 +1,39 @@ +From d41143cb5f6d88eb6e8bd999ad5ea2992bfb10f7 Mon Sep 17 00:00:00 2001 +From: Panu Matilainen +Date: Thu, 18 Nov 2021 13:38:20 +0200 +Subject: [PATCH] Simplify rpm_print(), fixing a Lua stack leak as a bonus + +Rather than laborously call tostring() in Lua, use the C-side equivalent +of luaL_tostring(). This was new as of Lua 5.2, which explains why the +original version from 2004 did things the hard way. + +Also fixes a stack leak from not popping "tostring" function after use. +--- + rpmio/rpmlua.c | 9 +-------- + 1 file changed, 1 insertion(+), 8 deletions(-) + +diff --git a/rpmio/rpmlua.c b/rpmio/rpmlua.c +index 6ad9119..7402307 100644 +--- a/rpmio/rpmlua.c ++++ b/rpmio/rpmlua.c +@@ -688,16 +688,9 @@ static int rpm_print (lua_State *L) + int n = lua_gettop(L); /* number of arguments */ + int i; + if (!lua) return 0; +- lua_getglobal(L, "tostring"); + for (i = 1; i <= n; i++) { +- const char *s; + size_t sl; +- lua_pushvalue(L, -1); /* function to be called */ +- lua_pushvalue(L, i); /* value to print */ +- lua_call(L, 1, 1); +- s = lua_tolstring(L, -1, &sl); /* get result */ +- if (s == NULL) +- return luaL_error(L, "`tostring' must return a string to `print'"); ++ const char *s = luaL_tolstring(L, i, &sl); + if (lua->printbuf) { + rpmluapb prbuf = lua->printbuf; + if (prbuf->used+sl+1 > prbuf->alloced) { +-- +1.8.3.1 + diff --git a/backport-Switch-the-floating-point-type-in-rpmhook-from-float.patch b/backport-Switch-the-floating-point-type-in-rpmhook-from-float.patch new file mode 100644 index 0000000..1b9a924 --- /dev/null +++ b/backport-Switch-the-floating-point-type-in-rpmhook-from-float.patch @@ -0,0 +1,57 @@ +From a34bf5bdf601d6d0ae5d28193090a29b9ef12600 Mon Sep 17 00:00:00 2001 +From: Michael Schroeder +Date: Mon, 22 Nov 2021 11:12:20 +0100 +Subject: [PATCH] Switch the floating point type in rpmhook from float to + double + +There's no real reason why it should be float. Plus, the test if +the number is an integer does not work for big integers that +do not fit into a float. +--- + rpmio/rpmhook.c | 2 +- + rpmio/rpmhook.h | 2 +- + rpmio/rpmlua.c | 2 +- + 3 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/rpmio/rpmhook.c b/rpmio/rpmhook.c +index 9fe2a21..1197983 100644 +--- a/rpmio/rpmhook.c ++++ b/rpmio/rpmhook.c +@@ -187,7 +187,7 @@ static rpmhookArgs rpmhookArgsParse(const char *argt, va_list ap) + args->argv[i].i = va_arg(ap, int); + break; + case 'f': +- args->argv[i].f = (float)va_arg(ap, double); ++ args->argv[i].f = va_arg(ap, double); + break; + case 'p': + args->argv[i].p = va_arg(ap, void *); +diff --git a/rpmio/rpmhook.h b/rpmio/rpmhook.h +index 52f5634..842c126 100644 +--- a/rpmio/rpmhook.h ++++ b/rpmio/rpmhook.h +@@ -4,7 +4,7 @@ + typedef union { + const char * s; + int i; +- float f; ++ double f; + void * p; + } rpmhookArgv; + +diff --git a/rpmio/rpmlua.c b/rpmio/rpmlua.c +index fe2e513..c5bdf42 100644 +--- a/rpmio/rpmlua.c ++++ b/rpmio/rpmlua.c +@@ -650,7 +650,7 @@ static int rpm_call(lua_State *L) + args->argv[i].p = NULL; + break; + case LUA_TNUMBER: { +- float f = (float)lua_tonumber(L, i+1); ++ double f = (double)lua_tonumber(L, i+1); + if (f == (int)f) { + argt[i] = 'i'; + args->argv[i].i = (int)f; +-- +1.8.3.1 + diff --git a/backport-Validate-and-require-subkey-binding-signatures-on-PG.patch b/backport-Validate-and-require-subkey-binding-signatures-on-PG.patch new file mode 100644 index 0000000..33c7402 --- /dev/null +++ b/backport-Validate-and-require-subkey-binding-signatures-on-PG.patch @@ -0,0 +1,327 @@ +From bd36c5dc9fb6d90c46fbfed8c2d67516fc571ec8 Mon Sep 17 00:00:00 2001 +From: Panu Matilainen +Date: Thu, 30 Sep 2021 09:59:30 +0300 +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. + +Depends on the two previous commits: +7b399fcb8f52566e6f3b4327197a85facd08db91 and +236b802a4aa48711823a191d1b7f753c82a89ec5 + +Fixes CVE-2021-3521. +--- + rpmio/rpmpgp.c | 98 +++++++++++++++++++++++-- + tests/Makefile.am | 3 + + tests/data/keys/CVE-2021-3521-badbind.asc | 25 +++++++ + tests/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, 209 insertions(+), 7 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 aad7c27..d70802a 100644 +--- a/rpmio/rpmpgp.c ++++ b/rpmio/rpmpgp.c +@@ -1062,37 +1062,121 @@ static pgpDigParams pgpDigParamsNew(uint8_t 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 = pgpDigParamsNew(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 { +diff --git a/tests/Makefile.am b/tests/Makefile.am +index b4a2e2e..bc535d2 100644 +--- a/tests/Makefile.am ++++ b/tests/Makefile.am +@@ -108,6 +108,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 0000000..aea00f9 +--- /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 0000000..aea00f9 +--- /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 0000000..3a2e741 +--- /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) ++ ++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 ++E4XX4jtDmdZPreZALsiB ++=rRop ++-----END PGP PUBLIC KEY BLOCK----- ++ +diff --git a/tests/rpmsigdig.at b/tests/rpmsigdig.at +index 0f8f2b4..c8b9f13 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 1]) +-- +1.8.3.1 + diff --git a/rpm.spec b/rpm.spec index 55d5e72..fcdba6e 100644 --- a/rpm.spec +++ b/rpm.spec @@ -1,6 +1,6 @@ Name: rpm Version: 4.17.0 -Release: 5 +Release: 6 Summary: RPM Package Manager License: GPLv2+ URL: http://www.rpm.org/ @@ -30,6 +30,17 @@ Patch21: Avoid-generating-digest-lists-if-they-are-already-pa.patch Patch22: dont-remove-ima-xattr-of-parser-when-upgrading.patch Patch6000: backport-Use-root-as-default-UID_0_USER-and-UID_0_GROUP.patch +Patch6001: backport-Check-file-iterator-for-being-NULL-consistently.patch +Patch6002: backport-Process-MPI-s-from-all-kinds-of-signatures.patch +Patch6003: backport-Refactor-pgpDigParams-construction-to-helper-functio.patch +Patch6004: backport-Validate-and-require-subkey-binding-signatures-on-PG.patch +Patch6005: backport-Revert-Explictly-skip-non-installed-files-on-erasur.patch +Patch6006: backport-Fix-hash-context-leak.patch +Patch6007: backport-Fix-hashlen-overflow.patch +Patch6008: backport-Fix-some-Lua-stack-leaks-in-our-initialization-code.patch +Patch6009: backport-Simplify-rpm_print-fixing-a-Lua-stack-leak-as-a-bonu.patch +Patch6010: backport-Switch-the-floating-point-type-in-rpmhook-from-float.patch +Patch6011: backport-Fix-a-memleak-in-ndb-from-opened-but-not-closed-dbis.patch BuildRequires: gcc autoconf automake libtool make gawk popt-devel openssl-devel readline-devel BuildRequires: zlib-devel libzstd-devel xz-devel bzip2-devel libarchive-devel ima-evm-utils-devel @@ -299,6 +310,9 @@ make check || (cat tests/rpmtests.log; exit 0) %{_mandir}/man1/gendiff.1* %changelog +* Thu Aug 11 2022 renhongxun - 4.17.0-6 +- sync some patches from upstream + * Tue Aug 09 2022 renhongxun - 4.17.0-5 - Type:bugfix - ID:NA