From d7e82a1adad833a523b0bd387d89e4d12a087ad2 Mon Sep 17 00:00:00 2001 From: rwx403335 Date: Thu, 11 Aug 2022 16:51:35 +0800 Subject: [PATCH] sync some patches from upstream --- ...t-Add-a-hashed-flag-to-pgpPrtSubtype.patch | 55 ++++++++ ...e-frees-if-EVP_PKEY_assign_RSA-fails.patch | 95 +++++++++++++ backport-Avoid-unneded-MPI-reparsing.patch | 39 ++++++ ...ix-OpenPGP-key-ID-parsing-regression.patch | 28 ++++ ...rsing-affecting-caller-timezone-stat.patch | 30 ++++ ...rt-Fix-memory-leak-in-pgpPrtParams-1.patch | 25 ++++ ...-return-value-checks-in-OpenSSL-code.patch | 131 ++++++++++++++++++ ...ting-of-version-strings-in-expressio.patch | 50 +++++++ ...keys-that-cannot-be-used-for-signing.patch | 104 ++++++++++++++ backport-Parse-key-usage-flags.patch | 78 +++++++++++ ...Prevent-NULL-deref-in-rpmfsGetStates.patch | 25 ++++ ...internet-access-during-rpaths-checki.patch | 32 +++++ ...reation-time-to-be-unique-and-hashed.patch | 101 ++++++++++++++ ...on-t-drop-newlines-from-header-sizes.patch | 35 +++++ rpm.spec | 20 ++- 15 files changed, 847 insertions(+), 1 deletion(-) create mode 100644 backport-Add-a-hashed-flag-to-pgpPrtSubtype.patch create mode 100644 backport-Avoid-double-frees-if-EVP_PKEY_assign_RSA-fails.patch create mode 100644 backport-Avoid-unneded-MPI-reparsing.patch create mode 100644 backport-Fix-OpenPGP-key-ID-parsing-regression.patch create mode 100644 backport-Fix-changelog-parsing-affecting-caller-timezone-stat.patch create mode 100644 backport-Fix-memory-leak-in-pgpPrtParams-1.patch create mode 100644 backport-Fix-return-value-checks-in-OpenSSL-code.patch create mode 100644 backport-Fix-short-circuiting-of-version-strings-in-expressio.patch create mode 100644 backport-Ignore-subkeys-that-cannot-be-used-for-signing.patch create mode 100644 backport-Parse-key-usage-flags.patch create mode 100644 backport-Prevent-NULL-deref-in-rpmfsGetStates.patch create mode 100644 backport-Prevent-readelf-internet-access-during-rpaths-checki.patch create mode 100644 backport-Require-creation-time-to-be-unique-and-hashed.patch create mode 100644 backport-rpm2cpio.sh-Don-t-drop-newlines-from-header-sizes.patch diff --git a/backport-Add-a-hashed-flag-to-pgpPrtSubtype.patch b/backport-Add-a-hashed-flag-to-pgpPrtSubtype.patch new file mode 100644 index 0000000..6912082 --- /dev/null +++ b/backport-Add-a-hashed-flag-to-pgpPrtSubtype.patch @@ -0,0 +1,55 @@ +From 55849d2d6e16096dbd30fd3a5c751f13bb03484b Mon Sep 17 00:00:00 2001 +From: Demi Marie Obenour +Date: Sun, 27 Mar 2022 12:04:46 -0400 +Subject: [PATCH] Add a hashed flag to pgpPrtSubtype() + +This is needed for key usage flags parsing, as key usage flags outside +of the hashed region must be ignored. For now, just use it to +unconditionally ignore unhashed creation time subpackets. +--- + rpmio/rpmpgp.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/rpmio/rpmpgp.c b/rpmio/rpmpgp.c +index 59c80d7..9b8503e 100644 +--- a/rpmio/rpmpgp.c ++++ b/rpmio/rpmpgp.c +@@ -437,7 +437,7 @@ int pgpSignatureType(pgpDigParams _digp) + } + + static int pgpPrtSubType(const uint8_t *h, size_t hlen, pgpSigType sigtype, +- pgpDigParams _digp) ++ pgpDigParams _digp, int hashed) + { + const uint8_t *p = h; + size_t plen = 0, i; +@@ -474,6 +474,8 @@ static int pgpPrtSubType(const uint8_t *h, size_t hlen, pgpSigType sigtype, + pgpPrtVal(" ", pgpKeyServerPrefsTbl, p[i]); + break; + case PGPSUBTYPE_SIG_CREATE_TIME: /* signature creation time */ ++ if (!hashed) ++ break; /* RFC 4880 §5.2.3.4 creation time MUST be hashed */ + if (plen-1 != sizeof(_digp->time)) + break; /* other lengths not understood */ + if (_digp->saved & PGPDIG_SIG_HAS_CREATION_TIME) +@@ -666,7 +668,7 @@ static int pgpPrtSig(pgpTag tag, const uint8_t *h, size_t hlen, + _digp->hashlen = sizeof(*v) + plen; + _digp->hash = memcpy(xmalloc(_digp->hashlen), v, _digp->hashlen); + } +- if (pgpPrtSubType(p, plen, v->sigtype, _digp)) ++ if (pgpPrtSubType(p, plen, v->sigtype, _digp, 1)) + return 1; + p += plen; + +@@ -680,7 +682,7 @@ static int pgpPrtSig(pgpTag tag, const uint8_t *h, size_t hlen, + if ((p + plen) > hend) + return 1; + +- if (pgpPrtSubType(p, plen, v->sigtype, _digp)) ++ if (pgpPrtSubType(p, plen, v->sigtype, _digp, 0)) + return 1; + p += plen; + +-- +1.8.3.1 + diff --git a/backport-Avoid-double-frees-if-EVP_PKEY_assign_RSA-fails.patch b/backport-Avoid-double-frees-if-EVP_PKEY_assign_RSA-fails.patch new file mode 100644 index 0000000..7b63d29 --- /dev/null +++ b/backport-Avoid-double-frees-if-EVP_PKEY_assign_RSA-fails.patch @@ -0,0 +1,95 @@ +From 0a91d1f62d5b6e1cac4d0a7c2ac9f75faad50534 Mon Sep 17 00:00:00 2001 +From: Demi Marie Obenour +Date: Fri, 9 Apr 2021 13:34:12 -0400 +Subject: [PATCH] Avoid double frees if EVP_PKEY_assign_RSA fails + +Previously, the bignums would be left as dangling and double-freed. +--- + rpmio/digest_openssl.c | 32 +++++++++++++++++--------------- + 1 file changed, 17 insertions(+), 15 deletions(-) + +diff --git a/rpmio/digest_openssl.c b/rpmio/digest_openssl.c +index 20c272d..02f34a9 100644 +--- a/rpmio/digest_openssl.c ++++ b/rpmio/digest_openssl.c +@@ -292,8 +292,8 @@ struct pgpDigKeyRSA_s { + + BIGNUM *n; /* Common Modulus */ + BIGNUM *e; /* Public Exponent */ +- + EVP_PKEY *evp_pkey; /* Fully constructed key */ ++ unsigned char immutable; /* if set, this key cannot be mutated */ + }; + + static int constructRSASigningKey(struct pgpDigKeyRSA_s *key) +@@ -301,33 +301,34 @@ static int constructRSASigningKey(struct pgpDigKeyRSA_s *key) + if (key->evp_pkey) { + /* We've already constructed it, so just reuse it */ + return 1; +- } ++ } else if (key->immutable) ++ return 0; ++ key->immutable = 1; + + /* Create the RSA key */ + RSA *rsa = RSA_new(); + if (!rsa) return 0; + +- if (!RSA_set0_key(rsa, key->n, key->e, NULL)) { +- RSA_free(rsa); +- return 0; +- } ++ if (RSA_set0_key(rsa, key->n, key->e, NULL) <= 0) ++ goto exit; ++ key->n = key->e = NULL; + + /* Create an EVP_PKEY container to abstract the key-type. */ +- key->evp_pkey = EVP_PKEY_new(); +- if (!key->evp_pkey) { +- RSA_free(rsa); +- return 0; +- } ++ if (!(key->evp_pkey = EVP_PKEY_new())) ++ goto exit; + + /* Assign the RSA key to the EVP_PKEY structure. + This will take over memory management of the RSA key */ + if (!EVP_PKEY_assign_RSA(key->evp_pkey, rsa)) { + EVP_PKEY_free(key->evp_pkey); + key->evp_pkey = NULL; +- RSA_free(rsa); ++ goto exit; + } + + return 1; ++exit: ++ RSA_free(rsa); ++ return 0; + } + + static int pgpSetKeyMpiRSA(pgpDigAlg pgpkey, int num, const uint8_t *p) +@@ -335,9 +336,10 @@ static int pgpSetKeyMpiRSA(pgpDigAlg pgpkey, int num, const uint8_t *p) + size_t mlen = pgpMpiLen(p) - 2; + struct pgpDigKeyRSA_s *key = pgpkey->data; + +- if (!key) { ++ if (!key) + key = pgpkey->data = xcalloc(1, sizeof(*key)); +- } ++ else if (key->immutable) ++ return 1; + + switch (num) { + case 0: +@@ -347,7 +349,7 @@ static int pgpSetKeyMpiRSA(pgpDigAlg pgpkey, int num, const uint8_t *p) + return 1; + } + +- key->nbytes = mlen; ++ key->nbytes = mlen; + /* Create a BIGNUM from the pointer. + Note: this assumes big-endian data as required by PGP */ + key->n = BN_bin2bn(p+2, mlen, NULL); +-- +1.8.3.1 + diff --git a/backport-Avoid-unneded-MPI-reparsing.patch b/backport-Avoid-unneded-MPI-reparsing.patch new file mode 100644 index 0000000..a3bf260 --- /dev/null +++ b/backport-Avoid-unneded-MPI-reparsing.patch @@ -0,0 +1,39 @@ +From 8948ec79f6c300e91319469ba72b9bd3480fe686 Mon Sep 17 00:00:00 2001 +From: Demi Marie Obenour +Date: Sun, 27 Mar 2022 12:54:36 -0400 +Subject: [PATCH] Avoid unneded MPI reparsing + +Modify pgpPrtSig() to ignore the MPIs of a signature if its `tag` +parameter is 0. The only caller that sets `tag` to 0 is +pgpPrtParamSubkeys() (via parseSubkeySig()), which does not actually +check any cryptographic signatures. The subkey binding signature has +been checked earlier in pgpPrtParams(). +--- + rpmio/rpmpgp.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/rpmio/rpmpgp.c b/rpmio/rpmpgp.c +index 22ac9c8..2b93661 100644 +--- a/rpmio/rpmpgp.c ++++ b/rpmio/rpmpgp.c +@@ -637,7 +637,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, p, h, hlen, _digp); ++ rc = tag ? pgpPrtSigParams(tag, v->pubkey_algo, p, h, hlen, _digp) : 0; + } break; + case 4: + { pgpPktSigV4 v = (pgpPktSigV4)h; +@@ -700,7 +700,7 @@ static int pgpPrtSig(pgpTag tag, const uint8_t *h, size_t hlen, + return 1; + + _digp->data = p; +- rc = pgpPrtSigParams(tag, v->pubkey_algo, p, h, hlen, _digp); ++ rc = tag ? pgpPrtSigParams(tag, v->pubkey_algo, p, h, hlen, _digp) : 0; + } break; + default: + rpmlog(RPMLOG_WARNING, _("Unsupported version of signature: V%d\n"), version); +-- +1.8.3.1 + diff --git a/backport-Fix-OpenPGP-key-ID-parsing-regression.patch b/backport-Fix-OpenPGP-key-ID-parsing-regression.patch new file mode 100644 index 0000000..b6189f9 --- /dev/null +++ b/backport-Fix-OpenPGP-key-ID-parsing-regression.patch @@ -0,0 +1,28 @@ +From 7f830132fe717d4b31c035bb3d08379451e3cd81 Mon Sep 17 00:00:00 2001 +From: Demi Marie Obenour +Date: Thu, 14 Apr 2022 15:38:11 -0400 +Subject: [PATCH] Fix OpenPGP key ID parsing regression + +This fixes a regression in 598a771d8b4f4f480d4990ccf59b978d537201dd, +which caused RPM to parse key flags from a hashed key ID subpacket. As +a result, RPM would wrongly reject a signature that had both key ID and +key usage flags subpackets in the hashed section. +--- + rpmio/rpmpgp.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/rpmio/rpmpgp.c b/rpmio/rpmpgp.c +index 93c1be2..ea3905b 100644 +--- a/rpmio/rpmpgp.c ++++ b/rpmio/rpmpgp.c +@@ -323,6 +323,7 @@ static int pgpPrtSubType(const uint8_t *h, size_t hlen, pgpSigType sigtype, + _digp->saved |= PGPDIG_SAVED_ID; + memcpy(_digp->signid, p+1, sizeof(_digp->signid)); + } ++ break; + case PGPSUBTYPE_KEY_FLAGS: /* Key usage flags */ + /* Subpackets in the unhashed section cannot be trusted */ + if (!hashed) +-- +1.8.3.1 + diff --git a/backport-Fix-changelog-parsing-affecting-caller-timezone-stat.patch b/backport-Fix-changelog-parsing-affecting-caller-timezone-stat.patch new file mode 100644 index 0000000..4b236e8 --- /dev/null +++ b/backport-Fix-changelog-parsing-affecting-caller-timezone-stat.patch @@ -0,0 +1,30 @@ +From 1a7de551a74d73f01eb40cb744c1dbba5faeb651 Mon Sep 17 00:00:00 2001 +From: Panu Matilainen +Date: Mon, 30 May 2022 14:24:45 +0300 +Subject: [PATCH] Fix changelog parsing affecting caller timezone state + +We meddle with TZ environ which then propagates to other values through +mktime() implicitly calling tzset(), but that other data doesn't get +reset by just restoring the TZ variable. Restore initial state by explicitly +call tzset() after we're done with it. + +Fixes: #1821 +--- + build/parseChangelog.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/build/parseChangelog.c b/build/parseChangelog.c +index 65c0952..c59786f 100644 +--- a/build/parseChangelog.c ++++ b/build/parseChangelog.c +@@ -175,6 +175,7 @@ static int dateToTimet(const char * datestr, time_t * secs, int * date_words) + setenv("TZ", tz, 1); + free(tz); + } ++ tzset(); + + if (*secs == -1) goto exit; + +-- +1.8.3.1 + diff --git a/backport-Fix-memory-leak-in-pgpPrtParams-1.patch b/backport-Fix-memory-leak-in-pgpPrtParams-1.patch new file mode 100644 index 0000000..16e5cca --- /dev/null +++ b/backport-Fix-memory-leak-in-pgpPrtParams-1.patch @@ -0,0 +1,25 @@ +From 10ac962bf2f71af927c8eaaea427135441663497 Mon Sep 17 00:00:00 2001 +From: Demi Marie Obenour +Date: Thu, 17 Mar 2022 03:16:59 -0400 +Subject: [PATCH] Fix memory leak in pgpPrtParams() + +Found by leak sanitizer on a fuzzed test case. +--- + rpmio/rpmpgp.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/rpmio/rpmpgp.c b/rpmio/rpmpgp.c +index eb5701b..f9e2658 100644 +--- a/rpmio/rpmpgp.c ++++ b/rpmio/rpmpgp.c +@@ -1163,6 +1163,7 @@ int pgpPrtParams(const uint8_t * pkts, size_t pktlen, unsigned int pkttype, + rc = (digp && (p == pend) && expect == 0) ? 0 : -1; + + free(all); ++ selfsig = pgpDigParamsFree(selfsig); + if (ret && rc == 0) { + *ret = digp; + } else { +-- +1.8.3.1 + diff --git a/backport-Fix-return-value-checks-in-OpenSSL-code.patch b/backport-Fix-return-value-checks-in-OpenSSL-code.patch new file mode 100644 index 0000000..9ef25c7 --- /dev/null +++ b/backport-Fix-return-value-checks-in-OpenSSL-code.patch @@ -0,0 +1,131 @@ +From 1ddaeddffa52f02db198417ebf73cb6c5d432250 Mon Sep 17 00:00:00 2001 +From: Demi Marie Obenour +Date: Sun, 7 Feb 2021 16:46:31 -0500 +Subject: [PATCH] Fix return value checks in OpenSSL code + +According to `man 3ssl` the only successful return value for +EVP_PKEY_verify_init() is 1, and EVP_PKEY_CTX_set_rsa_padding() and +EVP_PKEY_CTX_set_signature_md() can both return 0 or a negative number +on failure or any positive number on success. BN_bn2binpad() returns -1 +on error, but 0 (an empty key or signature) is also not valid. +Therefore use != 1 to check the return value of EVP_PKEY_verify_init(), +<= 0 to check the return values of the other three functions mentioned +above. Also delete a bunch of cruft. +--- + rpmio/digest_openssl.c | 55 +++++++++++--------------------------------------- + 1 file changed, 12 insertions(+), 43 deletions(-) + +diff --git a/rpmio/digest_openssl.c b/rpmio/digest_openssl.c +index 0cb781e..20c272d 100644 +--- a/rpmio/digest_openssl.c ++++ b/rpmio/digest_openssl.c +@@ -450,7 +450,7 @@ static void pgpFreeSigRSA(pgpDigAlg pgpsig) + static int pgpVerifySigRSA(pgpDigAlg pgpkey, pgpDigAlg pgpsig, + uint8_t *hash, size_t hashlen, int hash_algo) + { +- int rc, ret; ++ int rc = 1; /* assume failure */ + EVP_PKEY_CTX *pkey_ctx = NULL; + struct pgpDigSigRSA_s *sig = pgpsig->data; + +@@ -458,53 +458,32 @@ static int pgpVerifySigRSA(pgpDigAlg pgpkey, pgpDigAlg pgpsig, + + struct pgpDigKeyRSA_s *key = pgpkey->data; + +- if (!constructRSASigningKey(key)) { +- rc = 1; ++ if (!constructRSASigningKey(key)) + goto done; +- } + + pkey_ctx = EVP_PKEY_CTX_new(key->evp_pkey, NULL); +- if (!pkey_ctx) { +- rc = 1; ++ if (!pkey_ctx) + goto done; +- } + +- ret = EVP_PKEY_verify_init(pkey_ctx); +- if (ret < 0) { +- rc = 1; ++ if (EVP_PKEY_verify_init(pkey_ctx) != 1) + goto done; +- } + +- ret = EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PADDING); +- if (ret < 0) { +- rc = 1; ++ if (EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PADDING) <= 0) + goto done; +- } + +- ret = EVP_PKEY_CTX_set_signature_md(pkey_ctx, getEVPMD(hash_algo)); +- if (ret < 0) { +- rc = 1; ++ if (EVP_PKEY_CTX_set_signature_md(pkey_ctx, getEVPMD(hash_algo)) <= 0) + goto done; +- } + + int pkey_len = EVP_PKEY_size(key->evp_pkey); + padded_sig = xcalloc(1, pkey_len); +- if (!BN_bn2binpad(sig->bn, padded_sig, pkey_len)) { +- rc = 1; ++ if (BN_bn2binpad(sig->bn, padded_sig, pkey_len) <= 0) + goto done; +- } + +- ret = EVP_PKEY_verify(pkey_ctx, padded_sig, pkey_len, hash, hashlen); +- if (ret == 1) ++ if (EVP_PKEY_verify(pkey_ctx, padded_sig, pkey_len, hash, hashlen) == 1) + { + /* Success */ + rc = 0; + } +- else +- { +- /* Failure */ +- rc = 1; +- } + + done: + EVP_PKEY_CTX_free(pkey_ctx); +@@ -735,32 +714,22 @@ static void pgpFreeSigDSA(pgpDigAlg pgpsig) + static int pgpVerifySigDSA(pgpDigAlg pgpkey, pgpDigAlg pgpsig, + uint8_t *hash, size_t hashlen, int hash_algo) + { +- int rc, ret; ++ int rc = 1; /* assume failure */ + struct pgpDigSigDSA_s *sig = pgpsig->data; + + struct pgpDigKeyDSA_s *key = pgpkey->data; + +- if (!constructDSASigningKey(key)) { +- rc = 1; ++ if (!constructDSASigningKey(key)) + goto done; +- } + +- if (!constructDSASignature(sig)) { +- rc = 1; ++ if (!constructDSASignature(sig)) + goto done; +- } + +- ret = DSA_do_verify(hash, hashlen, sig->dsa_sig, key->dsa_key); +- if (ret == 1) ++ if (DSA_do_verify(hash, hashlen, sig->dsa_sig, key->dsa_key) == 1) + { + /* Success */ + rc = 0; + } +- else +- { +- /* Failure */ +- rc = 1; +- } + + done: + return rc; +-- +1.8.3.1 + diff --git a/backport-Fix-short-circuiting-of-version-strings-in-expressio.patch b/backport-Fix-short-circuiting-of-version-strings-in-expressio.patch new file mode 100644 index 0000000..9effafb --- /dev/null +++ b/backport-Fix-short-circuiting-of-version-strings-in-expressio.patch @@ -0,0 +1,50 @@ +From 321933f060896f721e361a1c8a8d3731bdcee827 Mon Sep 17 00:00:00 2001 +From: Michael Schroeder +Date: Wed, 22 Jun 2022 14:07:01 +0200 +Subject: [PATCH] Fix short circuiting of version strings in expressions + +We use an empty string when discarding a value due to short circuiting, but +an empty string is not allowed for versions. So use "0" in that case. + +Fixes: #1883 +--- + rpmio/expression.c | 2 +- + tests/rpmmacro.at | 2 ++ + 2 files changed, 3 insertions(+), 1 deletion(-) + +diff --git a/rpmio/expression.c b/rpmio/expression.c +index a389a04..98a44bb 100644 +--- a/rpmio/expression.c ++++ b/rpmio/expression.c +@@ -477,7 +477,7 @@ static int rdToken(ParseState state) + if (qtok == TOK_STRING) { + v = valueMakeString(temp); + } else { +- v = valueMakeVersion(temp); ++ v = valueMakeVersion(state->flags & RPMEXPR_DISCARD ? "0" : temp); + free(temp); /* version doesn't take ownership of the string */ + if (v == 0) { + exprErr(state, _("invalid version"), p+1); +diff --git a/tests/rpmmacro.at b/tests/rpmmacro.at +index d1490b4..c4376d4 100644 +--- a/tests/rpmmacro.at ++++ b/tests/rpmmacro.at +@@ -533,6 +533,7 @@ runroot rpm \ + --eval '%["%{aaa}"]' \ + --eval '%[%{?ccc}]' \ + --eval '%[v"1:2.3-4"]' \ ++ --eval '%[v"0" && v"0"]' \ + ]], + [0], + [4096 +@@ -542,6 +543,7 @@ runroot rpm \ + 5 + 0 + 1:2.3-4 ++0 + ], + []) + AT_CLEANUP +-- +1.8.3.1 + diff --git a/backport-Ignore-subkeys-that-cannot-be-used-for-signing.patch b/backport-Ignore-subkeys-that-cannot-be-used-for-signing.patch new file mode 100644 index 0000000..bb6b95c --- /dev/null +++ b/backport-Ignore-subkeys-that-cannot-be-used-for-signing.patch @@ -0,0 +1,104 @@ +From a9cca032a2b7c0c6bcacc6ab4ecd25c95cc75305 Mon Sep 17 00:00:00 2001 +From: Demi Marie Obenour +Date: Sun, 27 Mar 2022 12:49:07 -0400 +Subject: [PATCH] Ignore subkeys that cannot be used for signing + +This ensures that a signature is only accepted if the subkey that made +it is actually allowed to sign. Test 265 verifies that RPM ignores +subkeys that cannot sign. + +A subkey is considered to be capable of signing if, and only if, its +subkey binding signature has a hashed key flags subpacket that contains +the flag 0x02. RFC4880 requires that the subkey binding signature be +v4, which this requirement enforces implicitly. RFC4880 also requires +that primary key binding signatures be present and checked. This is not +yet implemented, but may be implemented later. + +Fixes #1911. +--- + rpmio/rpmpgp.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++- + tests/rpmsigdig.at | 2 -- + 2 files changed, 47 insertions(+), 3 deletions(-) + +diff --git a/rpmio/rpmpgp.c b/rpmio/rpmpgp.c +index 66837b1..22ac9c8 100644 +--- a/rpmio/rpmpgp.c ++++ b/rpmio/rpmpgp.c +@@ -1133,6 +1133,31 @@ static int pgpVerifySelf(pgpDigParams key, pgpDigParams selfsig, + return rc; + } + ++static int parseSubkeySig(const struct pgpPkt *pkt, uint8_t tag, ++ pgpDigParams *params_p) { ++ pgpDigParams params = *params_p = NULL; /* assume failure */ ++ ++ if (pkt->tag != PGPTAG_SIGNATURE) ++ goto fail; ++ ++ params = pgpDigParamsNew(tag); ++ ++ if (pgpPrtSig(tag, pkt->body, pkt->blen, params)) ++ goto fail; ++ ++ if (params->sigtype != PGPSIGTYPE_SUBKEY_BINDING && ++ params->sigtype != PGPSIGTYPE_SUBKEY_REVOKE) ++ { ++ goto fail; ++ } ++ ++ *params_p = params; ++ return 0; ++fail: ++ pgpDigParamsFree(params); ++ return -1; ++} ++ + int pgpPrtParams(const uint8_t * pkts, size_t pktlen, unsigned int pkttype, + pgpDigParams * ret) + { +@@ -1238,7 +1263,28 @@ int pgpPrtParamsSubkeys(const uint8_t *pkts, size_t pktlen, + pgpDigParamsFree(digps[count]); + continue; + } +- count++; ++ ++ pgpDigParams subkey_sig = NULL; ++ if (decodePkt(p, pend - p, &pkt) || ++ parseSubkeySig(&pkt, 0, &subkey_sig)) ++ { ++ pgpDigParamsFree(digps[count]); ++ break; ++ } ++ ++ /* Is the subkey revoked or incapable of signing? */ ++ int ignore = subkey_sig->sigtype != PGPSIGTYPE_SUBKEY_BINDING || ++ !((subkey_sig->saved & PGPDIG_SIG_HAS_KEY_FLAGS) && ++ (subkey_sig->key_flags & 0x02)); ++ if (ignore) { ++ pgpDigParamsFree(digps[count]); ++ } else { ++ digps[count]->key_flags = subkey_sig->key_flags; ++ digps[count]->saved |= PGPDIG_SIG_HAS_KEY_FLAGS; ++ count++; ++ } ++ p += (pkt.body - pkt.head) + pkt.blen; ++ pgpDigParamsFree(subkey_sig); + } + } + rc = (p == pend) ? 0 : -1; +diff --git a/tests/rpmsigdig.at b/tests/rpmsigdig.at +index 5d781d8..ab9b473 100644 +--- a/tests/rpmsigdig.at ++++ b/tests/rpmsigdig.at +@@ -247,8 +247,6 @@ UNW2iqnN3BA7guhOv6OMiROF1+I7Q5nWT63mQC7IgQ== + gpg(rpm.org RSA testkey ) = 4:4344591e1964c5fc-58e63918 + gpg(1964c5fc) = 4:4344591e1964c5fc-58e63918 + gpg(4344591e1964c5fc) = 4:4344591e1964c5fc-58e63918 +-gpg(f00650f8) = 4:185e6146f00650f8-58e63918 +-gpg(185e6146f00650f8) = 4:185e6146f00650f8-58e63918 + ], + []) + AT_CLEANUP +-- +1.8.3.1 + diff --git a/backport-Parse-key-usage-flags.patch b/backport-Parse-key-usage-flags.patch new file mode 100644 index 0000000..3d20288 --- /dev/null +++ b/backport-Parse-key-usage-flags.patch @@ -0,0 +1,78 @@ +From 598a771d8b4f4f480d4990ccf59b978d537201dd Mon Sep 17 00:00:00 2001 +From: Demi Marie Obenour +Date: Sun, 27 Mar 2022 12:07:34 -0400 +Subject: [PATCH] Parse key usage flags + +RPM needs to know if a subkey can be used for signing. Signatures made +by a subkey that cannot be used for signing are invalid. Add a +key_flags member to pgpDigParams_s to store this information, and a +PGPDIG_SIG_HAS_KEY_FLAGS flag to indicate that it is valid. The key +usage flags are reset for every signature. Key usage flags in the +unhashed section are ignored. If there is more than one key usage flags +subpacket in the hashed section, the signature is rejected. +--- + rpmio/digest.h | 2 ++ + rpmio/rpmpgp.c | 13 ++++++++++++- + 2 files changed, 14 insertions(+), 1 deletion(-) + +diff --git a/rpmio/digest.h b/rpmio/digest.h +index ec7f339..6a326d2 100644 +--- a/rpmio/digest.h ++++ b/rpmio/digest.h +@@ -28,6 +28,7 @@ struct pgpDigParams_s { + const uint8_t * data; + uint8_t tag; + ++ uint8_t key_flags; /*!< key usage flags */ + uint8_t version; /*!< version number. */ + uint32_t time; /*!< key/signature creation time. */ + uint8_t pubkey_algo; /*!< public key algorithm. */ +@@ -41,6 +42,7 @@ struct pgpDigParams_s { + #define PGPDIG_SAVED_TIME (1 << 0) + #define PGPDIG_SAVED_ID (1 << 1) + #define PGPDIG_SIG_HAS_CREATION_TIME (1 << 2) ++#define PGPDIG_SIG_HAS_KEY_FLAGS (1 << 3) + + pgpDigAlg alg; + }; +diff --git a/rpmio/rpmpgp.c b/rpmio/rpmpgp.c +index 9b8503e..66837b1 100644 +--- a/rpmio/rpmpgp.c ++++ b/rpmio/rpmpgp.c +@@ -500,6 +500,17 @@ static int pgpPrtSubType(const uint8_t *h, size_t hlen, pgpSigType sigtype, + _digp->saved |= PGPDIG_SAVED_ID; + memcpy(_digp->signid, p+1, sizeof(_digp->signid)); + } ++ case PGPSUBTYPE_KEY_FLAGS: /* Key usage flags */ ++ /* Subpackets in the unhashed section cannot be trusted */ ++ if (!hashed) ++ break; ++ /* Reject duplicate key usage flags */ ++ if (_digp->saved & PGPDIG_SIG_HAS_KEY_FLAGS) ++ return 1; ++ impl = *p; ++ _digp->saved |= PGPDIG_SIG_HAS_KEY_FLAGS; ++ _digp->key_flags = plen >= 2 ? p[1] : 0; ++ break; + case PGPSUBTYPE_EXPORTABLE_CERT: + case PGPSUBTYPE_TRUST_SIG: + case PGPSUBTYPE_REGEX: +@@ -510,7 +521,6 @@ static int pgpPrtSubType(const uint8_t *h, size_t hlen, pgpSigType sigtype, + case PGPSUBTYPE_PREFER_KEYSERVER: + case PGPSUBTYPE_PRIMARY_USERID: + case PGPSUBTYPE_POLICY_URL: +- case PGPSUBTYPE_KEY_FLAGS: + case PGPSUBTYPE_SIGNER_USERID: + case PGPSUBTYPE_REVOKE_REASON: + case PGPSUBTYPE_FEATURES: +@@ -602,6 +612,7 @@ static int pgpPrtSig(pgpTag tag, const uint8_t *h, size_t hlen, + + /* Reset the saved flags */ + _digp->saved &= PGPDIG_SAVED_TIME | PGPDIG_SAVED_ID; ++ _digp->key_flags = 0; + + if (pgpVersion(h, hlen, &version)) + return rc; +-- +1.8.3.1 + diff --git a/backport-Prevent-NULL-deref-in-rpmfsGetStates.patch b/backport-Prevent-NULL-deref-in-rpmfsGetStates.patch new file mode 100644 index 0000000..771f92e --- /dev/null +++ b/backport-Prevent-NULL-deref-in-rpmfsGetStates.patch @@ -0,0 +1,25 @@ +From d747bf045ea20b0cb5813a83c13bdfb4ca424699 Mon Sep 17 00:00:00 2001 +From: Ludwig Nussel +Date: Mon, 14 Mar 2022 14:20:56 +0100 +Subject: [PATCH] Prevent NULL deref in rpmfsGetStates() + +--- + lib/rpmfs.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/rpmfs.c b/lib/rpmfs.c +index 84887a0..5f91cd2 100644 +--- a/lib/rpmfs.c ++++ b/lib/rpmfs.c +@@ -98,7 +98,7 @@ rpmfileState rpmfsGetState(rpmfs fs, unsigned int ix) + + rpm_fstate_t * rpmfsGetStates(rpmfs fs) + { +- return fs->states; ++ return (fs != NULL) ? fs->states : NULL; + } + + rpmFileAction rpmfsGetAction(rpmfs fs, unsigned int ix) +-- +1.8.3.1 + diff --git a/backport-Prevent-readelf-internet-access-during-rpaths-checki.patch b/backport-Prevent-readelf-internet-access-during-rpaths-checki.patch new file mode 100644 index 0000000..c472084 --- /dev/null +++ b/backport-Prevent-readelf-internet-access-during-rpaths-checki.patch @@ -0,0 +1,32 @@ +From 3cec59812c8126088a51924c6aeea112ce9b545a Mon Sep 17 00:00:00 2001 +From: Panu Matilainen +Date: Wed, 22 Jun 2022 13:22:00 +0300 +Subject: [PATCH] Prevent readelf internet access during rpaths checking + (RhBug:2079600) + +Recent binutils can do debug section lookups over the internet, but this +is something we never want during rpmbuild (everything else aside, we're +just building the thing so there wont be anything on the net anyhow). +Disable the lookups by setting DEBUGINFOD_URLS to empty rather than +using the specific option as this is compatible with any old version of +readelf. +--- + scripts/check-rpaths-worker | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/scripts/check-rpaths-worker b/scripts/check-rpaths-worker +index e32e823..26f74f0 100755 +--- a/scripts/check-rpaths-worker ++++ b/scripts/check-rpaths-worker +@@ -94,7 +94,7 @@ function msg() + + function check_rpath() { + pos=0 +- rpath=$(readelf -W -d "$1" 2>/dev/null | LANG=C grep -E "\((RPATH|RUNPATH)\).*:") || return 0 ++ rpath=$(DEBUGINFOD_URLS="" readelf -W -d "$1" 2>/dev/null | LANG=C grep -E "\((RPATH|RUNPATH)\).*:") || return 0 + rpath=$(echo "$rpath" | LANG=C sed -e "s!.*\(RPATH\|RUNPATH\).*: \[\(.*\)\]!\2!p;d") + + tmp=aux:$rpath:/lib/aux || : +-- +1.8.3.1 + diff --git a/backport-Require-creation-time-to-be-unique-and-hashed.patch b/backport-Require-creation-time-to-be-unique-and-hashed.patch new file mode 100644 index 0000000..5268282 --- /dev/null +++ b/backport-Require-creation-time-to-be-unique-and-hashed.patch @@ -0,0 +1,101 @@ +From 7e7266c9af883ce49b3516a5bd099d218e8e3fac Mon Sep 17 00:00:00 2001 +From: Demi Marie Obenour +Date: Sun, 6 Feb 2022 15:52:48 -0500 +Subject: [PATCH] Require creation time to be unique and hashed +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +According to RFC 4880 §5.2.3.4 the signature creation time MUST be a +hashed subpacket. Enforce this requirement in RPM. Also set the saved +flags to PGPDIG_SAVED_TIME | PGPDIG_SAVED_ID | +PGPDIG_SAVED_CREATION_TIME for v3 signatures, and do not overwrite an +already saved key ID with one taken from a v3 signature. +--- + rpmio/digest.h | 4 +++- + rpmio/rpmpgp.c | 29 +++++++++++++++++++---------- + 2 files changed, 22 insertions(+), 11 deletions(-) + +diff --git a/rpmio/digest.h b/rpmio/digest.h +index 3b72a28..ec7f339 100644 +--- a/rpmio/digest.h ++++ b/rpmio/digest.h +@@ -36,9 +36,11 @@ struct pgpDigParams_s { + uint32_t hashlen; + uint8_t signhash16[2]; + pgpKeyID_t signid; +- uint8_t saved; ++ uint8_t saved; /*!< Various flags. `PGPDIG_SAVED_*` are never reset. ++ * `PGPDIG_SIG_HAS_*` are reset for each signature. */ + #define PGPDIG_SAVED_TIME (1 << 0) + #define PGPDIG_SAVED_ID (1 << 1) ++#define PGPDIG_SIG_HAS_CREATION_TIME (1 << 2) + + pgpDigAlg alg; + }; +diff --git a/rpmio/rpmpgp.c b/rpmio/rpmpgp.c +index f9e2658..0200900 100644 +--- a/rpmio/rpmpgp.c ++++ b/rpmio/rpmpgp.c +@@ -473,16 +473,16 @@ static int pgpPrtSubType(const uint8_t *h, size_t hlen, pgpSigType sigtype, + for (i = 1; i < plen; i++) + pgpPrtVal(" ", pgpKeyServerPrefsTbl, p[i]); + break; +- case PGPSUBTYPE_SIG_CREATE_TIME: ++ case PGPSUBTYPE_SIG_CREATE_TIME: /* signature creation time */ ++ if (plen-1 != sizeof(_digp->time)) ++ break; /* other lengths not understood */ ++ if (_digp->saved & PGPDIG_SIG_HAS_CREATION_TIME) ++ return 1; /* duplicate timestamps not allowed */ + impl = *p; +- if (!(_digp->saved & PGPDIG_SAVED_TIME) && +- (sigtype == PGPSIGTYPE_POSITIVE_CERT || sigtype == PGPSIGTYPE_BINARY || sigtype == PGPSIGTYPE_TEXT || sigtype == PGPSIGTYPE_STANDALONE)) +- { +- if (plen-1 != sizeof(_digp->time)) +- break; +- _digp->saved |= PGPDIG_SAVED_TIME; ++ if (!(_digp->saved & PGPDIG_SAVED_TIME)) + _digp->time = pgpGrab(p+1, sizeof(_digp->time)); +- } ++ _digp->saved |= PGPDIG_SAVED_TIME | PGPDIG_SIG_HAS_CREATION_TIME; ++ break; + case PGPSUBTYPE_SIG_EXPIRE_TIME: + case PGPSUBTYPE_KEY_EXPIRE_TIME: + pgpPrtTime(" ", p+1, plen-1); +@@ -598,6 +598,9 @@ static int pgpPrtSig(pgpTag tag, const uint8_t *h, size_t hlen, + unsigned int plen; + int rc = 1; + ++ /* Reset the saved flags */ ++ _digp->saved &= PGPDIG_SAVED_TIME | PGPDIG_SAVED_ID; ++ + if (pgpVersion(h, hlen, &version)) + return rc; + +@@ -625,8 +628,11 @@ static int pgpPrtSig(pgpTag tag, const uint8_t *h, size_t hlen, + _digp->hashlen = v->hashlen; + _digp->sigtype = v->sigtype; + _digp->hash = memcpy(xmalloc(v->hashlen), &v->sigtype, v->hashlen); +- _digp->time = pgpGrab(v->time, sizeof(v->time)); +- memcpy(_digp->signid, v->signid, sizeof(_digp->signid)); ++ if (!(_digp->saved & PGPDIG_SAVED_TIME)) ++ _digp->time = pgpGrab(v->time, sizeof(v->time)); ++ if (!(_digp->saved & PGPDIG_SAVED_ID)) ++ memcpy(_digp->signid, v->signid, sizeof(_digp->signid)); ++ _digp->saved = PGPDIG_SAVED_TIME | PGPDIG_SIG_HAS_CREATION_TIME | PGPDIG_SAVED_ID; + _digp->pubkey_algo = v->pubkey_algo; + _digp->hash_algo = v->hash_algo; + memcpy(_digp->signhash16, v->signhash16, sizeof(_digp->signhash16)); +@@ -664,6 +670,9 @@ static int pgpPrtSig(pgpTag tag, const uint8_t *h, size_t hlen, + return 1; + p += plen; + ++ if (!(_digp->saved & PGPDIG_SIG_HAS_CREATION_TIME)) ++ return 1; /* RFC 4880 §5.2.3.4 creation time MUST be hashed */ ++ + if (pgpGet(p, 2, hend, &plen)) + return 1; + p += 2; +-- +1.8.3.1 + diff --git a/backport-rpm2cpio.sh-Don-t-drop-newlines-from-header-sizes.patch b/backport-rpm2cpio.sh-Don-t-drop-newlines-from-header-sizes.patch new file mode 100644 index 0000000..fbe4a78 --- /dev/null +++ b/backport-rpm2cpio.sh-Don-t-drop-newlines-from-header-sizes.patch @@ -0,0 +1,35 @@ +From a18a11924a715ace4b2d8e101688d164390cb188 Mon Sep 17 00:00:00 2001 +From: Florian Festi +Date: Fri, 1 Jul 2022 14:44:11 +0200 +Subject: [PATCH] rpm2cpio.sh: Don't drop newlines from header sizes + +This script converts binary header sizes to decimal numbers. Shell is +not that well suited for this task as it drops newlines at the end of +command substitutions. Add a . character at the end and strip it right +after that to avoid this problem. + +Resolves: rhbz#1983015 +--- + scripts/rpm2cpio.sh | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/scripts/rpm2cpio.sh b/scripts/rpm2cpio.sh +index c1c505f..f77d5f8 100755 +--- a/scripts/rpm2cpio.sh ++++ b/scripts/rpm2cpio.sh +@@ -27,7 +27,11 @@ calcsize() { + + i=0 + while [ $i -lt 8 ]; do +- b="$(_dd $(($offset + $i)) bs=1 count=1)" ++ # add . to not loose \n ++ # strip \0 as it gets dropped with warning otherwise ++ b="$(_dd $(($offset + $i)) bs=1 count=1 | tr -d '\0' ; echo .)" ++ b=${b%.} # strip . again ++ + [ -z "$b" ] && + b="0" || + b="$(exec printf '%u\n' "'$b")" +-- +1.8.3.1 + diff --git a/rpm.spec b/rpm.spec index fa80bef..6864c6f 100644 --- a/rpm.spec +++ b/rpm.spec @@ -1,6 +1,6 @@ Name: rpm Version: 4.17.0 -Release: 7 +Release: 8 Summary: RPM Package Manager License: GPLv2+ URL: http://www.rpm.org/ @@ -54,6 +54,21 @@ Patch6021: backport-Make-rpmfiSetFX-return-code-meaningful.patch Patch6022: backport-Avoid-reading-out-of-bounds-of-the-i18ntable.patch Patch6023: backport-rpmkeys-exit-non-zero-on-I-O-errors.patch +Patch6024: backport-Prevent-NULL-deref-in-rpmfsGetStates.patch +Patch6025: backport-Fix-memory-leak-in-pgpPrtParams-1.patch +Patch6026: backport-Fix-return-value-checks-in-OpenSSL-code.patch +Patch6027: backport-Avoid-double-frees-if-EVP_PKEY_assign_RSA-fails.patch +Patch6028: backport-Require-creation-time-to-be-unique-and-hashed.patch +Patch6029: backport-Add-a-hashed-flag-to-pgpPrtSubtype.patch +Patch6030: backport-Parse-key-usage-flags.patch +Patch6031: backport-Ignore-subkeys-that-cannot-be-used-for-signing.patch +Patch6032: backport-Avoid-unneded-MPI-reparsing.patch +Patch6033: backport-Fix-OpenPGP-key-ID-parsing-regression.patch +Patch6034: backport-Fix-changelog-parsing-affecting-caller-timezone-stat.patch +Patch6035: backport-rpm2cpio.sh-Don-t-drop-newlines-from-header-sizes.patch +Patch6036: backport-Prevent-readelf-internet-access-during-rpaths-checki.patch +Patch6037: backport-Fix-short-circuiting-of-version-strings-in-expressio.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 BuildRequires: dbus-devel fakechroot elfutils-devel elfutils-libelf-devel ima-evm-utils @@ -322,6 +337,9 @@ make check || (cat tests/rpmtests.log; exit 0) %{_mandir}/man1/gendiff.1* %changelog +* Thu Aug 11 2022 renhongxun - 4.17.0-8 +- sync some patches from upstream + * Thu Aug 11 2022 renhongxun - 4.17.0-7 - sync some patches from upstream