diff options
106 files changed, 7623 insertions, 0 deletions
@@ -0,0 +1 @@ +/rpm-4.17.0.tar.bz2 diff --git a/0001-add-default-machine-name-to-support-loongarch.patch b/0001-add-default-machine-name-to-support-loongarch.patch new file mode 100644 index 0000000..f127fe0 --- /dev/null +++ b/0001-add-default-machine-name-to-support-loongarch.patch @@ -0,0 +1,30 @@ +From f492b34a694a4bf40e075a030c01f360eaa5500e Mon Sep 17 00:00:00 2001 +From: Wenlong Zhang <zhangwenlong@loongson.cn> +Date: Fri, 27 May 2022 09:41:38 +0800 +Subject: [PATCH] add default machine name to support loongarch + +--- + lib/rpmrc.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/lib/rpmrc.c b/lib/rpmrc.c +index 120777c..bd0dbca 100644 +--- a/lib/rpmrc.c ++++ b/lib/rpmrc.c +@@ -1242,6 +1242,13 @@ static void defaultMachine(rpmrcCtx ctx, const char ** arch, const char ** os) + } + # endif /* riscv */ + ++# if defined(__linux__) && defined(__loongarch__) ++ if (sizeof(long) == 4) ++ strcpy(un.machine, "loongarch32"); ++ else if (sizeof(long) == 8) ++ strcpy(un.machine, "loongarch64"); ++# endif /* loongarch */ ++ + # if defined(__GNUC__) && defined(__alpha__) + { + unsigned long amask, implver; +-- +2.27.0 + diff --git a/Add-digest-list-plugin.patch b/Add-digest-list-plugin.patch new file mode 100644 index 0000000..2256824 --- /dev/null +++ b/Add-digest-list-plugin.patch @@ -0,0 +1,586 @@ +From e49074a4e4bd0699d2c4a5bb3a0dc5ca45e19e12 Mon Sep 17 00:00:00 2001 +From: Roberto Sassu <roberto.sassu@huawei.com> +Date: Wed, 26 Feb 2020 15:54:24 +0100 +Subject: [PATCH 2/3] Add digest list plugin + +--- + macros.in | 1 + + plugins/Makefile.am | 4 + + plugins/digest_list.c | 498 ++++++++++++++++++++++++++++++++++++++++++ + rpmio/digest.h | 1 + + rpmio/rpmpgp.c | 3 + + 5 files changed, 507 insertions(+) + create mode 100644 plugins/digest_list.c + +diff --git a/macros.in b/macros.in +index 402749362..8619c1323 100644 +--- a/macros.in ++++ b/macros.in +@@ -1184,6 +1184,7 @@ package or when debugging this package.\ + %__transaction_prioreset %{__plugindir}/prioreset.so + %__transaction_audit %{__plugindir}/audit.so + %__transaction_dbus_announce %{__plugindir}/dbus_announce.so ++%__transaction_digest_list %{__plugindir}/digest_list.so + + #------------------------------------------------------------------------------ + # Macros for further automated spec %setup and patch application +diff --git a/plugins/Makefile.am b/plugins/Makefile.am +index d4ef039ed..07aa3585b 100644 +--- a/plugins/Makefile.am ++++ b/plugins/Makefile.am +@@ -48,3 +48,7 @@ audit_la_sources = audit.c + audit_la_LIBADD = $(top_builddir)/lib/librpm.la $(top_builddir)/rpmio/librpmio.la @WITH_AUDIT_LIB@ + plugins_LTLIBRARIES += audit.la + endif ++ ++digest_list_la_sources = digest_list.c ++digest_list_la_LIBADD = $(top_builddir)/lib/librpm.la $(top_builddir)/rpmio/librpmio.la ++plugins_LTLIBRARIES += digest_list.la +diff --git a/plugins/digest_list.c b/plugins/digest_list.c +new file mode 100644 +index 000000000..beb397309 +--- /dev/null ++++ b/plugins/digest_list.c +@@ -0,0 +1,499 @@ ++#include "system.h" ++#include "errno.h" ++ ++#include <fcntl.h> ++#include <rpm/rpmlog.h> ++#include <rpm/rpmts.h> ++#include <rpm/header.h> ++#include <rpmio/digest.h> ++#include <rpmio/rpmpgp.h> ++#include <rpm/rpmfileutil.h> ++#include "lib/rpmplugin.h" ++#include <netinet/in.h> ++#include <sys/stat.h> ++#include <openssl/sha.h> ++#include <sys/xattr.h> ++#include <linux/xattr.h> ++#include <asm/byteorder.h> ++#include <sys/wait.h> ++ ++#include "debug.h" ++ ++#define IMA_DIR "/sys/kernel/security/ima" ++#define DIGEST_LIST_DATA_PATH IMA_DIR "/digest_list_data" ++#define DIGEST_LIST_DATA_DEL_PATH IMA_DIR "/digest_list_data_del" ++#define DIGEST_LIST_COUNT IMA_DIR "/digests_count" ++#define DIGEST_LIST_DEFAULT_PATH "/etc/ima/digest_lists" ++#define RPM_PARSER "/usr/libexec/rpm_parser" ++ ++#define DIGEST_LIST_OP_ADD 0 ++#define DIGEST_LIST_OP_DEL 1 ++ ++enum hash_algo { ++ HASH_ALGO_MD4, ++ HASH_ALGO_MD5, ++ HASH_ALGO_SHA1, ++ HASH_ALGO_RIPE_MD_160, ++ HASH_ALGO_SHA256, ++ HASH_ALGO_SHA384, ++ HASH_ALGO_SHA512, ++ HASH_ALGO_SHA224, ++ HASH_ALGO_RIPE_MD_128, ++ HASH_ALGO_RIPE_MD_256, ++ HASH_ALGO_RIPE_MD_320, ++ HASH_ALGO_WP_256, ++ HASH_ALGO_WP_384, ++ HASH_ALGO_WP_512, ++ HASH_ALGO_TGR_128, ++ HASH_ALGO_TGR_160, ++ HASH_ALGO_TGR_192, ++ HASH_ALGO_SM3_256, ++ HASH_ALGO__LAST ++}; ++ ++#define PGPHASHALGO__LAST PGPHASHALGO_SHA224 + 1 ++enum hash_algo pgp_algo_mapping[PGPHASHALGO__LAST] = { ++ [PGPHASHALGO_MD5] = HASH_ALGO_MD5, ++ [PGPHASHALGO_SHA1] = HASH_ALGO_SHA1, ++ [PGPHASHALGO_SHA224] = HASH_ALGO_SHA224, ++ [PGPHASHALGO_SHA256] = HASH_ALGO_SHA256, ++ [PGPHASHALGO_SHA384] = HASH_ALGO_SHA384, ++ [PGPHASHALGO_SHA512] = HASH_ALGO_SHA512, ++}; ++ ++/* from integrity.h */ ++enum evm_ima_xattr_type { ++ IMA_XATTR_DIGEST = 0x01, ++ EVM_XATTR_HMAC, ++ EVM_IMA_XATTR_DIGSIG, ++ IMA_XATTR_DIGEST_NG, ++ EVM_XATTR_PORTABLE_DIGSIG, ++ EVM_IMA_XATTR_DIGEST_LIST, ++ IMA_XATTR_LAST ++}; ++ ++struct evm_ima_xattr_data { ++ uint8_t type; ++ uint8_t digest[SHA512_DIGEST_LENGTH + 1]; ++} __attribute__((packed)); ++ ++struct signature_v2_hdr { ++ uint8_t type; /* xattr type */ ++ uint8_t version; /* signature format version */ ++ uint8_t hash_algo; /* Digest algorithm [enum hash_algo] */ ++ __be32 keyid; /* IMA key identifier - not X509/PGP specific */ ++ __be16 sig_size; /* signature size */ ++ uint8_t sig[0]; /* signature payload */ ++} __attribute__((packed)); ++ ++static int upload_digest_list(char *path, int type, int digest_list_signed) ++{ ++ size_t size; ++ char buf[21]; ++ const char *ima_path = DIGEST_LIST_DATA_PATH; ++ struct stat st; ++ pid_t pid; ++ int ret = 0, fd; ++ ++ if (type == TR_REMOVED) ++ ima_path = DIGEST_LIST_DATA_DEL_PATH; ++ ++ if (stat(ima_path, &st) == -1) ++ return 0; ++ ++ /* First determine if kernel interface can accept new digest lists */ ++ fd = open(DIGEST_LIST_COUNT, O_RDONLY); ++ if (fd < 0) { ++ rpmlog(RPMLOG_ERR, "digest_list: could not open IMA interface " ++ "'%s': %s\n", DIGEST_LIST_COUNT, strerror(errno)); ++ return -EACCES; ++ } ++ ++ ret = read(fd, buf, sizeof(buf)); ++ close(fd); ++ ++ if (ret <= 0) { ++ rpmlog(RPMLOG_ERR, "digest_list: could not read from IMA " ++ "interface '%s': %s\n", DIGEST_LIST_COUNT, ++ strerror(errno)); ++ return -EACCES; ++ } ++ ++ /* Last character is newline */ ++ buf[ret - 1] = '\0'; ++ ++ rpmlog(RPMLOG_DEBUG, "digest_list: digests count %s\n", buf); ++ ++ if (*buf == '0') { ++ rpmlog(RPMLOG_DEBUG, "digest_list: not uploading '%s' to IMA " ++ "interface '%s'\n", path, ima_path); ++ return RPMRC_OK; ++ } ++ ++ /* If the digest list is not signed, execute the RPM parser */ ++ if (!digest_list_signed) { ++ if ((pid = fork()) == 0) { ++ execlp(RPM_PARSER, RPM_PARSER, (type == TR_ADDED) ? ++ "add" : "del", path, NULL); ++ _exit(EXIT_FAILURE); ++ } ++ ++ waitpid(pid, &ret, 0); ++ if (ret != 0) ++ rpmlog(RPMLOG_ERR, "digest_list: %s returned %d\n", ++ RPM_PARSER, ret); ++ return 0; ++ } ++ ++ fd = open(ima_path, O_WRONLY); ++ if (fd < 0) { ++ rpmlog(RPMLOG_ERR, "digest_list: could not open IMA interface " ++ "'%s': %s\n", ima_path, strerror(errno)); ++ return -EACCES; ++ } ++ ++ /* Write the path of the digest list to securityfs */ ++ size = write(fd, path, strlen(path)); ++ if (size != strlen(path)) { ++ rpmlog(RPMLOG_ERR, "digest_list: could not write '%s' to IMA " ++ "interface '%s': %s\n", path, ima_path, strerror(errno)); ++ ret = -EIO; ++ goto out; ++ } ++ ++ rpmlog(RPMLOG_DEBUG, "digest_list: written '%s' to '%s'\n", path, ++ ima_path); ++out: ++ close(fd); ++ return ret; ++} ++ ++static int write_rpm_digest_list(rpmte te, char *path) ++{ ++ FD_t fd; ++ ssize_t written; ++ Header rpm = rpmteHeader(te); ++ rpmtd immutable; ++ int ret = 0; ++ ++ immutable = rpmtdNew(); ++ headerGet(rpm, RPMTAG_HEADERIMMUTABLE, immutable, 0); ++ ++ fd = Fopen(path, "w.ufdio"); ++ if (fd == NULL || Ferror(fd)) { ++ ret = -EACCES; ++ goto out; ++ } ++ ++ written = Fwrite(rpm_header_magic, sizeof(uint8_t), ++ sizeof(rpm_header_magic), fd); ++ ++ if (written != sizeof(rpm_header_magic)) { ++ ret = -EIO; ++ goto out; ++ } ++ ++ written = Fwrite(immutable->data, sizeof(uint8_t), ++ immutable->count, fd); ++ if (written != immutable->count || Ferror(fd)) ++ ret = -EIO; ++out: ++ Fclose(fd); ++ rpmtdFree(immutable); ++ return ret; ++} ++ ++static int write_rpm_digest_list_ima_xattr(rpmte te, char *path) ++{ ++ rpmtd signature; ++ ssize_t written; ++ uint8_t sig[2048] = { 0 }; ++ pgpDigParams sigp = NULL; ++ struct signature_v2_hdr *sig_hdr = (struct signature_v2_hdr *)sig; ++ Header rpm = rpmteHeader(te); ++ FD_t fd; ++ int ret = 0, sig_size, sig_size_rounded; ++ ++ signature = rpmtdNew(); ++ headerGet(rpm, RPMTAG_RSAHEADER, signature, 0); ++ ret = pgpPrtParams(signature->data, signature->count, ++ PGPTAG_SIGNATURE, &sigp); ++ ++ if (ret) { ++ ret = -ENOENT; ++ goto out; ++ } ++ ++ fd = Fopen(path, "a.ufdio"); ++ if (fd == NULL || Ferror(fd)) { ++ ret = -EACCES; ++ goto out; ++ } ++ ++ written = Fwrite(sigp->hash, sizeof(uint8_t), ++ sigp->hashlen, fd); ++ if (written != sigp->hashlen || Ferror(fd)) { ++ ret = -EIO; ++ goto out; ++ } ++ ++ if (sigp->version == 4) { ++ /* V4 trailer is six octets long (rfc4880) */ ++ uint8_t trailer[6]; ++ uint32_t nb = sigp->hashlen; ++ nb = htonl(nb); ++ trailer[0] = sigp->version; ++ trailer[1] = 0xff; ++ memcpy(trailer+2, &nb, 4); ++ ++ written = Fwrite(trailer, sizeof(uint8_t), sizeof(trailer), fd); ++ if (written != sizeof(trailer) || Ferror(fd)) { ++ ret = -EIO; ++ goto out; ++ } ++ } ++ ++ Fclose(fd); ++ ++ sig_hdr->type = EVM_IMA_XATTR_DIGSIG; ++ sig_hdr->version = 2; ++ sig_hdr->hash_algo = pgp_algo_mapping[sigp->hash_algo]; ++ memcpy((void *)&sig_hdr->keyid, sigp->signid + sizeof(uint32_t), ++ sizeof(uint32_t)); ++ ++ sig_size = (pgpMpiBits(sigp->data) + 7) >> 3; ++ if (sizeof(sig_hdr) + sig_size > sizeof(sig)) { ++ rpmlog(RPMLOG_ERR, ++ "digest_list: signature in %s too big\n", path); ++ ret = -E2BIG; ++ goto out; ++ } ++ ++ sig_size_rounded = ((sig_size + 7) >> 3) * 8; ++ sig_hdr->sig_size = __cpu_to_be16(sig_size_rounded); ++ ++ memcpy(sig_hdr->sig + sig_size_rounded - sig_size, ++ (uint8_t *)sigp->data + 2, sig_size); ++ ++ ret = lsetxattr(path, XATTR_NAME_IMA, ++ sig, sizeof(*sig_hdr) + sig_size_rounded, 0); ++ if (ret < 0) ++ rpmlog(RPMLOG_ERR, "digest_list: could not apply security.ima " ++ "on '%s': %s\n", path, strerror(errno)); ++ else ++ rpmlog(RPMLOG_DEBUG, "digest_list: security.ima successfully " ++ "applied on '%s'\n", path); ++out: ++ pgpDigParamsFree(sigp); ++ rpmtdFree(signature); ++ return ret; ++} ++ ++static int write_digest_list_ima_xattr(rpmte te, char *path, char *path_sig) ++{ ++ rpmtd signature; ++ uint8_t sig[2048] = { 0 }; ++ pgpDigParams sigp = NULL; ++ struct signature_v2_hdr *sig_hdr = (struct signature_v2_hdr *)sig; ++ Header rpm = rpmteHeader(te); ++ FD_t fd; ++ struct stat st; ++ int ret = 0, sig_size; ++ ++ signature = rpmtdNew(); ++ headerGet(rpm, RPMTAG_RSAHEADER, signature, 0); ++ ret = pgpPrtParams(signature->data, signature->count, ++ PGPTAG_SIGNATURE, &sigp); ++ ++ if (ret) { ++ ret = -ENOENT; ++ goto out; ++ } ++ ++ sig_hdr->type = EVM_IMA_XATTR_DIGSIG; ++ sig_hdr->version = 2; ++ sig_hdr->hash_algo = HASH_ALGO_SHA256; ++ memcpy((void *)&sig_hdr->keyid, sigp->signid + sizeof(uint32_t), ++ sizeof(uint32_t)); ++ ++ if (stat(path_sig, &st) == -1) { ++ ret = -EACCES; ++ goto out; ++ } ++ ++ if (sizeof(sig_hdr) + st.st_size > sizeof(sig)) { ++ rpmlog(RPMLOG_ERR, "digest_list: signature in %s too big\n", ++ path); ++ ret = -E2BIG; ++ goto out; ++ } ++ ++ fd = Fopen(path_sig, "r.ufdio"); ++ if (fd < 0) { ++ rpmlog(RPMLOG_ERR, "digest_list: could not open '%s': %s\n", ++ path_sig, strerror(errno)); ++ ret = -EACCES; ++ goto out; ++ } ++ ++ sig_size = Fread(sig_hdr->sig, sizeof(uint8_t), st.st_size, fd); ++ if (sig_size != st.st_size || Ferror(fd)) { ++ rpmlog(RPMLOG_ERR, "digest_list: could not read '%s': %s\n", ++ path_sig, strerror(errno)); ++ Fclose(fd); ++ ret = -EIO; ++ goto out; ++ } ++ ++ sig_hdr->sig_size = __cpu_to_be16(sig_size); ++ ++ rpmlog(RPMLOG_DEBUG, ++ "digest_list: read signature of %d bytes from '%s'\n", ++ sig_size, path_sig); ++ ++ ret = lsetxattr(path, XATTR_NAME_IMA, ++ sig, sizeof(*sig_hdr) + sig_size, 0); ++ if (ret < 0) ++ rpmlog(RPMLOG_ERR, "digest_list: could not apply security.ima " ++ "on '%s': %s\n", path, strerror(errno)); ++ else ++ rpmlog(RPMLOG_DEBUG, "digest_list: security.ima successfully " ++ "applied on '%s'\n", path); ++out: ++ pgpDigParamsFree(sigp); ++ rpmtdFree(signature); ++ return ret; ++} ++ ++static int process_digest_list(rpmte te, int parser) ++{ ++ char *path = NULL, *path_sig = NULL; ++ int digest_list_signed = 0; ++ struct stat st; ++ ssize_t size; ++ rpmRC ret = RPMRC_OK; ++ ++ path = malloc(PATH_MAX); ++ if (!path) { ++ ret = RPMRC_FAIL; ++ goto out; ++ } ++ ++ path_sig = malloc(PATH_MAX); ++ if (!path_sig) { ++ ret = RPMRC_FAIL; ++ goto out; ++ } ++ ++ if (parser) ++ snprintf(path_sig, PATH_MAX, ++ "%s.sig/0-parser_list-compact-libexec.sig", ++ DIGEST_LIST_DEFAULT_PATH); ++ else ++ snprintf(path_sig, PATH_MAX, ++ "%s.sig/0-metadata_list-compact-%s-%s-%s.%s.sig", ++ DIGEST_LIST_DEFAULT_PATH, rpmteN(te), rpmteV(te), ++ rpmteR(te), rpmteA(te)); ++ ++ if (!stat(path_sig, &st)) ++ digest_list_signed = 1; ++ ++ if (parser && !digest_list_signed) ++ goto out; ++ ++ if (parser) ++ snprintf(path, PATH_MAX, "%s/0-parser_list-compact-libexec", ++ DIGEST_LIST_DEFAULT_PATH); ++ else ++ snprintf(path, PATH_MAX, ++ "%s/0-metadata_list-compact-%s-%s-%s.%s", ++ DIGEST_LIST_DEFAULT_PATH, rpmteN(te), rpmteV(te), ++ rpmteR(te), rpmteA(te)); ++ ++ if (stat(path, &st) == -1) ++ goto out; ++ ++ if (!parser && !digest_list_signed) ++ snprintf(path, PATH_MAX, "%s/0-metadata_list-rpm-%s-%s-%s.%s", ++ DIGEST_LIST_DEFAULT_PATH, rpmteN(te), rpmteV(te), ++ rpmteR(te), rpmteA(te)); ++ ++ size = lgetxattr(path, XATTR_NAME_IMA, NULL, 0); ++ ++ /* Don't upload again if digest list was already processed */ ++ if ((rpmteType(te) == TR_ADDED && size > 0) || ++ (rpmteType(te) == TR_REMOVED && size < 0)) { ++ rpmlog(RPMLOG_DEBUG, "digest_list: '%s' already processed, " ++ "nothing to do\n", path); ++ goto out; ++ } ++ ++ if (rpmteType(te) == TR_ADDED) { ++ if (!digest_list_signed) { ++ /* Write RPM header to the disk */ ++ ret = write_rpm_digest_list(te, path); ++ if (ret < 0) { ++ ret = RPMRC_FAIL; ++ goto out; ++ } ++ ++ /* Write RPM header sig to security.ima */ ++ ret = write_rpm_digest_list_ima_xattr(te, path); ++ } else { ++ ret = write_digest_list_ima_xattr(te, path, path_sig); ++ } ++ ++ if (ret < 0) { ++ ret = RPMRC_FAIL; ++ goto out; ++ } ++ } ++ ++ /* Upload digest list to securityfs */ ++ upload_digest_list(path, rpmteType(te), digest_list_signed); ++ ++ if (rpmteType(te) == TR_REMOVED) { ++ if (!digest_list_signed) { ++ unlink(path); ++ goto out; ++ } ++ ++ ret = lremovexattr(path, XATTR_NAME_IMA); ++ if (ret < 0) ++ rpmlog(RPMLOG_ERR, "digest_list: cannot remove " ++ "security.ima from '%s'\n", path); ++ else ++ rpmlog(RPMLOG_DEBUG, "digest_list: security.ima " ++ "successfully removed from '%s'\n", path); ++ } ++out: ++ free(path); ++ free(path_sig); ++ return ret; ++} ++ ++static rpmRC digest_list_psm_pre(rpmPlugin plugin, rpmte te) ++{ ++ process_digest_list(te, 0); ++ if (!strcmp(rpmteN(te), "digest-list-tools")) ++ process_digest_list(te, 1); ++ ++ return RPMRC_OK; ++} ++ ++static rpmRC digest_list_psm_post(rpmPlugin plugin, rpmte te, int res) ++{ ++ if (res != RPMRC_OK) ++ return RPMRC_OK; ++ ++ process_digest_list(te, 0); ++ if (!strcmp(rpmteN(te), "digest-list-tools")) ++ process_digest_list(te, 1); ++ ++ return RPMRC_OK; ++} ++ ++struct rpmPluginHooks_s digest_list_hooks = { ++ .psm_pre = digest_list_psm_pre, ++ .psm_post = digest_list_psm_post, ++}; +diff --git a/rpmio/digest.h b/rpmio/digest.h +index 9e0cde3b9..01ca10d92 100644 +--- a/rpmio/digest.h ++++ b/rpmio/digest.h +@@ -24,6 +24,7 @@ struct pgpDigAlg_s { + struct pgpDigParams_s { + char * userid; + uint8_t * hash; ++ const uint8_t * data; + uint8_t tag; + + uint8_t version; /*!< version number. */ +diff --git a/rpmio/rpmpgp.c b/rpmio/rpmpgp.c +index 46cd0f31a..3c6b18b53 100644 +--- a/rpmio/rpmpgp.c ++++ b/rpmio/rpmpgp.c +@@ -600,6 +600,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); + } break; + case 4: +@@ -658,6 +659,7 @@ static int pgpPrtSig(pgpTag tag, const uint8_t *h, size_t hlen, + if (p > hend) + return 1; + ++ _digp->data = p; + rc = pgpPrtSigParams(tag, v->pubkey_algo, v->sigtype, p, h, hlen, _digp); + } break; + default: +@@ -745,6 +747,7 @@ static int pgpPrtKey(pgpTag tag, const uint8_t *h, size_t hlen, + } + + p = ((uint8_t *)v) + sizeof(*v); ++ _digp->data = p; + rc = pgpPrtPubkeyParams(v->pubkey_algo, p, h, hlen, _digp); + } + } break; +-- +2.27.GIT + diff --git a/Add-license-to-digest_list.c.patch b/Add-license-to-digest_list.c.patch new file mode 100644 index 0000000..fe07b05 --- /dev/null +++ b/Add-license-to-digest_list.c.patch @@ -0,0 +1,34 @@ +From 676cd4c0b90043b745a39b43446e42e80948c643 Mon Sep 17 00:00:00 2001 +From: Roberto Sassu <roberto.sassu@huawei.com> +Date: Fri, 12 Mar 2021 10:57:24 +0100 +Subject: [PATCH 5/5] Add license to digest_list.c + +--- + plugins/digest_list.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/plugins/digest_list.c b/plugins/digest_list.c +index cfde5cd1d..992a7e81a 100644 +--- a/plugins/digest_list.c ++++ b/plugins/digest_list.c +@@ -1,3 +1,17 @@ ++/* ++ * Copyright (C) 2020-2021 Huawei Technologies Duesseldorf GmbH ++ * ++ * Author: Roberto Sassu <roberto.sassu@huawei.com> ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation, version 2 of the ++ * License. ++ * ++ * File: digest_list.c ++ * Plugin to load digest lists in the Linux kernel. ++ */ ++ + #include "system.h" + #include "errno.h" + +-- +2.26.2 + diff --git a/Add-loongarch-architecture-support.patch b/Add-loongarch-architecture-support.patch new file mode 100644 index 0000000..80c9c41 --- /dev/null +++ b/Add-loongarch-architecture-support.patch @@ -0,0 +1,99 @@ +From 3100da59abd272fc3f301a30ebabedf86b0b4a00 Mon Sep 17 00:00:00 2001 +From: Sun Haiyong <sunhaiyong@loongson.cn> +Date: Tue, 21 Dec 2021 20:40:27 +0800 +Subject: [PATCH] Add loongarch architecture support. + +--- + installplatform | 12 ++++++++++++ + rpmrc.in | 17 +++++++++++++++++ + 2 files changed, 29 insertions(+) + +diff --git a/installplatform b/installplatform +index 12339fc..74c50a2 100755 +--- a/installplatform ++++ b/installplatform +@@ -168,6 +168,18 @@ for ARCH in noarch `grep ^arch_canon $RPMRC | cut -d: -f2`; do + CANONARCH=mips64r6el + CANONCOLOR=3 + ;; ++ loongarch32) ++ ISANAME=loongarch ++ ISABITS=32 ++ CANONARCH=loongarch32 ++ CANONCOLOR=0 ++ ;; ++ loongarch64) ++ ISANAME=loongarch ++ ISABITS=64 ++ CANONARCH=loongarch64 ++ CANONCOLOR=3 ++ ;; + m68k) + ISANAME=m68k + ISABITS=32 +diff --git a/rpmrc.in b/rpmrc.in +index 5bd9ba3..fc2932a 100644 +--- a/rpmrc.in ++++ b/rpmrc.in +@@ -67,6 +67,8 @@ optflags: mipsr6el -O2 -g + optflags: mips64r6 -O2 -g + optflags: mips64r6el -O2 -g + ++optflags: loongarch64 -O2 -g ++ + optflags: armv3l -O2 -g -march=armv3 + optflags: armv4b -O2 -g -march=armv4 + optflags: armv4l -O2 -g -march=armv4 +@@ -137,6 +139,9 @@ archcolor: mipsr6el 1 + archcolor: mips64r6 2 + archcolor: mips64r6el 2 + ++archcolor: loongarch32 1 ++archcolor: loongarch64 2 ++ + archcolor: m68k 1 + + archcolor: m68kmint 1 +@@ -257,6 +262,9 @@ arch_canon: mips64r6el: mips64r6el 21 + arch_canon: riscv: riscv64 22 + arch_canon: riscv64: riscv64 22 + ++arch_canon: loongarch32: loongarch32 25 ++arch_canon: loongarch64: loongarch64 26 ++ + ############################################################# + # Canonical OS names and numbers + +@@ -360,6 +368,9 @@ buildarchtranslate: mipsr6el: mipsr6el + buildarchtranslate: mips64r6: mips64r6 + buildarchtranslate: mips64r6el: mips64r6el + ++buildarchtranslate: loongarch32: loongarch32 ++buildarchtranslate: loongarch64: loongarch64 ++ + buildarchtranslate: m68k: m68k + + buildarchtranslate: atarist: m68kmint +@@ -449,6 +460,9 @@ arch_compat: mipsr6el: noarch + arch_compat: mips64r6: mipsr6 + arch_compat: mips64r6el: mipsr6el + ++arch_compat: loongarch32: noarch ++arch_compat: loongarch64: loongarch32 ++ + arch_compat: hppa2.0: hppa1.2 + arch_compat: hppa1.2: hppa1.1 + arch_compat: hppa1.1: hppa1.0 +@@ -586,6 +600,9 @@ buildarch_compat: mipsr6el: noarch + buildarch_compat: mips64r6: noarch + buildarch_compat: mips64r6el: noarch + ++buildarch_compat: loongarch32: noarch ++buildarch_compat: loongarch64: noarch ++ + buildarch_compat: armv4b: noarch + buildarch_compat: armv8l: armv7l + buildarch_compat: armv7l: armv6l +-- +2.30.0 + diff --git a/Avoid-generating-digest-lists-if-they-are-already-pa.patch b/Avoid-generating-digest-lists-if-they-are-already-pa.patch new file mode 100644 index 0000000..ecfedb9 --- /dev/null +++ b/Avoid-generating-digest-lists-if-they-are-already-pa.patch @@ -0,0 +1,50 @@ +From d0b01bb4366ca467bfd1386820fe17ae58aa3c8c Mon Sep 17 00:00:00 2001 +From: Roberto Sassu <roberto.sassu@huawei.com> +Date: Wed, 17 Mar 2021 17:25:46 +0100 +Subject: [PATCH] Avoid generating digest lists if they are already packaged + +--- + build/files.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/build/files.c b/build/files.c +index d5c83a094..a30828e1c 100644 +--- a/build/files.c ++++ b/build/files.c +@@ -51,6 +51,7 @@ + #define DEBUG_ID_DIR "/usr/lib/debug/.build-id" + #define DEBUG_DWZ_DIR "/usr/lib/debug/.dwz" + #define DIGEST_LIST_DIR "/.digest_lists" ++#define DEST_DIGEST_LIST_DIR "/etc/ima/digest_lists" + + #undef HASHTYPE + #undef HTKEYTYPE +@@ -993,7 +994,7 @@ static void genDigestListInput(FileList fl, Package pkg, int isSrc) + char buf[BUFSIZ]; + char file_info[BUFSIZ]; + char file_digest[128 * 2 + 1]; +- int i; ++ int i, gen_digest_lists = 1; + uint32_t defaultalgo = PGPHASHALGO_MD5, digestalgo; + Header h = pkg->header; /* just a shortcut */ + +@@ -1100,9 +1101,15 @@ static void genDigestListInput(FileList fl, Package pkg, int isSrc) + strlen(flp->caps) ? flp->caps : ""); + appendStringBuf(check_fileList_bin_pkg, file_info); + } ++ ++ if (S_ISREG(flp->fl_mode) && ++ !strncmp(flp->cpioPath, DEST_DIGEST_LIST_DIR, ++ sizeof(DEST_DIGEST_LIST_DIR) - 1)) ++ gen_digest_lists = 0; + } + +- if (genDigestList(pkg->header, fl, check_fileList_bin_pkg) > 0) ++ if (gen_digest_lists && ++ genDigestList(pkg->header, fl, check_fileList_bin_pkg) > 0) + fl->processingFailed = 1; + } + +-- +2.26.2 + diff --git a/Check-rpm-parser.patch b/Check-rpm-parser.patch new file mode 100644 index 0000000..43052a2 --- /dev/null +++ b/Check-rpm-parser.patch @@ -0,0 +1,29 @@ +From 18df7feaf512cf4d7548121e1f04d4e7066fb324 Mon Sep 17 00:00:00 2001 +From: Roberto Sassu <roberto.sassu@huawei.com> +Date: Wed, 10 Mar 2021 12:23:32 +0100 +Subject: [PATCH 2/5] Check rpm parser + +--- + plugins/digest_list.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/plugins/digest_list.c b/plugins/digest_list.c +index bb778c57f..c62f8c22f 100644 +--- a/plugins/digest_list.c ++++ b/plugins/digest_list.c +@@ -131,6 +131,12 @@ static int upload_digest_list(char *path, int type, int digest_list_signed) + + /* If the digest list is not signed, execute the RPM parser */ + if (!digest_list_signed) { ++ if (stat(RPM_PARSER, &st) == -1) { ++ rpmlog(RPMLOG_DEBUG, "digest_list: %s not found, " ++ "not uploading digest list\n", RPM_PARSER); ++ return 0; ++ } ++ + if ((pid = fork()) == 0) { + execlp(RPM_PARSER, RPM_PARSER, (type == TR_ADDED) ? + "add" : "del", path, NULL); +-- +2.26.2 + diff --git a/Don-t-add-dist-to-release-if-it-is-already-there.patch b/Don-t-add-dist-to-release-if-it-is-already-there.patch new file mode 100644 index 0000000..8820ef2 --- /dev/null +++ b/Don-t-add-dist-to-release-if-it-is-already-there.patch @@ -0,0 +1,26 @@ +From 90b01a63c7c3312c25d2c3b74508a98b51e703fa Mon Sep 17 00:00:00 2001 +From: Roberto Sassu <roberto.sassu@huawei.com> +Date: Wed, 22 Jul 2020 17:24:58 +0200 +Subject: [PATCH 3/3] Don't add dist to release if it is already there + +--- + build/parsePreamble.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/build/parsePreamble.c b/build/parsePreamble.c +index 147059bb5..c3d898b4c 100644 +--- a/build/parsePreamble.c ++++ b/build/parsePreamble.c +@@ -810,7 +810,8 @@ static rpmRC handlePreambleTag(rpmSpec spec, Package pkg, rpmTagVal tag, + SINGLE_TOKEN_ONLY; + if (tag == RPMTAG_RELEASE) { + char *dist = rpmExpand("%{?dist}",NULL); +- rasprintf(&field,"%s%s",field,dist); ++ rasprintf(&field,"%s%s",field, ++ (dist && strstr(field, dist)) ? "" : dist); + free(dist); + } + if (rpmCharCheck(spec, field, ALLOWED_CHARS_VERREL)) +-- +2.27.GIT + diff --git a/Fix-digest_list_counter.patch b/Fix-digest_list_counter.patch new file mode 100644 index 0000000..b9a3cd9 --- /dev/null +++ b/Fix-digest_list_counter.patch @@ -0,0 +1,81 @@ +From 8ecd5fc6884ae165e38e16b900cc4da90665b9db Mon Sep 17 00:00:00 2001 +From: Roberto Sassu <roberto.sassu@huawei.com> +Date: Wed, 10 Mar 2021 12:22:39 +0100 +Subject: [PATCH 1/5] Fix digest_list_counter + +--- + plugins/digest_list.c | 38 +++++++++++++++++++++++--------------- + 1 file changed, 23 insertions(+), 15 deletions(-) + +diff --git a/plugins/digest_list.c b/plugins/digest_list.c +index 2dfa21e35..bb778c57f 100644 +--- a/plugins/digest_list.c ++++ b/plugins/digest_list.c +@@ -477,8 +477,8 @@ int digest_list_counter; + static rpmRC digest_list_psm_pre(rpmPlugin plugin, rpmte te) + { + Header rpm = rpmteHeader(te); +- rpmtd dirnames; +- int i; ++ rpmtd dirnames, dirindexes; ++ int i = -1; + + digest_list_counter = 0; + +@@ -487,13 +487,26 @@ static rpmRC digest_list_psm_pre(rpmPlugin plugin, rpmte te) + + while ((i = rpmtdNext(dirnames)) >= 0) { + char *dirname = (char *) rpmtdGetString(dirnames); ++ + if (!strncmp(dirname, DIGEST_LIST_DEFAULT_PATH, +- sizeof(DIGEST_LIST_DEFAULT_PATH) - 1)) +- digest_list_counter++; ++ sizeof(DIGEST_LIST_DEFAULT_PATH) - 1) && ++ dirname[sizeof(DIGEST_LIST_DEFAULT_PATH) - 1] == '/') ++ break; + } + + rpmtdFree(dirnames); + ++ if (i == -1) ++ return RPMRC_OK; ++ ++ dirindexes = rpmtdNew(); ++ headerGet(rpm, RPMTAG_DIRINDEXES, dirindexes, 0); ++ while (rpmtdNext(dirindexes) >= 0) ++ if (rpmtdGetNumber(dirindexes) == i) ++ digest_list_counter++; ++ ++ rpmtdFree(dirindexes); ++ + cur_te = te; + return RPMRC_OK; + } +@@ -517,18 +530,13 @@ static rpmRC digest_list_file_common(rpmPlugin plugin, rpmfi fi, + (!pre && action != FA_CREATE)) + return RPMRC_OK; + +- if (digest_list_counter) { +- if (!pre) { +- if (!strncmp(path, DIGEST_LIST_DEFAULT_PATH, +- sizeof(DIGEST_LIST_DEFAULT_PATH) - 1)) +- digest_list_counter--; +- } else { +- digest_list_counter = 0; +- } ++ if (strncmp(path, DIGEST_LIST_DEFAULT_PATH, ++ sizeof(DIGEST_LIST_DEFAULT_PATH) - 1) || ++ path[sizeof(DIGEST_LIST_DEFAULT_PATH) - 1] != '/') ++ return RPMRC_OK; + +- if (digest_list_counter) +- return RPMRC_OK; +- } ++ if (!pre && --digest_list_counter) ++ return RPMRC_OK; + + process_digest_list(cur_te, 0); + if (!strcmp(rpmteN(cur_te), "digest-list-tools")) +-- +2.26.2 + diff --git a/Generate-digest-lists-before-calling-genCpioListAndH.patch b/Generate-digest-lists-before-calling-genCpioListAndH.patch new file mode 100644 index 0000000..bc85a01 --- /dev/null +++ b/Generate-digest-lists-before-calling-genCpioListAndH.patch @@ -0,0 +1,255 @@ +From 2b0cab0ed63e77582b047f723b69a0e3dd647566 Mon Sep 17 00:00:00 2001 +From: Roberto Sassu <roberto.sassu@huawei.com> +Date: Wed, 12 Aug 2020 18:23:42 +0200 +Subject: [PATCH] Generate digest lists before calling genCpioListAndHeader() + +Signed-off-by: luhuaxin <luhuaxin1@huawei.com> +--- + build/files.c | 182 ++++++++++++++++++++++++++++++++++++++++---------- + 1 file changed, 147 insertions(+), 35 deletions(-) + +diff --git a/build/files.c b/build/files.c +index d1e56c0..5358ead 100644 +--- a/build/files.c ++++ b/build/files.c +@@ -1000,20 +1000,149 @@ static int seenHardLink(FileRecords files, FileListRec flp, rpm_ino_t *fileid) + * @param pkg (sub) package + * @param isSrc pass 1 for source packages 0 otherwise + */ +-static void genCpioListAndHeader(FileList fl, Package pkg, int isSrc) ++static void genDigestListInput(FileList fl, Package pkg, int isSrc) + { + FileListRec flp; + char buf[BUFSIZ]; + char file_info[BUFSIZ]; + char file_digest[128 * 2 + 1]; ++ int i; ++ uint32_t defaultalgo = PGPHASHALGO_MD5, digestalgo; ++ Header h = pkg->header; /* just a shortcut */ ++ ++ /* ++ * See if non-md5 file digest algorithm is requested. If not ++ * specified, quietly assume md5. Otherwise check if supported type. ++ */ ++ digestalgo = rpmExpandNumeric(isSrc ? "%{_source_filedigest_algorithm}" : ++ "%{_binary_filedigest_algorithm}"); ++ if (digestalgo == 0) { ++ digestalgo = defaultalgo; ++ } ++ ++ if (rpmDigestLength(digestalgo) == 0) { ++ rpmlog(RPMLOG_WARNING, ++ _("Unknown file digest algorithm %u, falling back to MD5\n"), ++ digestalgo); ++ digestalgo = defaultalgo; ++ } ++ ++ /* Sort the big list */ ++ if (fl->files.recs) { ++ qsort(fl->files.recs, fl->files.used, ++ sizeof(*(fl->files.recs)), compareFileListRecs); ++ } ++ ++ /* Generate the header. */ ++ for (i = 0, flp = fl->files.recs; i < fl->files.used; i++, flp++) { ++ /* Merge duplicate entries. */ ++ while (i < (fl->files.used - 1) && ++ rstreq(flp->cpioPath, flp[1].cpioPath)) { ++ ++ /* Two entries for the same file found, merge the entries. */ ++ /* Note that an %exclude is a duplication of a file reference */ ++ ++ /* file flags */ ++ flp[1].flags |= flp->flags; ++ ++ if (!(flp[1].flags & RPMFILE_EXCLUDE)) ++ rpmlog(RPMLOG_WARNING, _("File listed twice: %s\n"), ++ flp->cpioPath); ++ ++ /* file mode */ ++ if (S_ISDIR(flp->fl_mode)) { ++ if ((flp[1].specdFlags & (SPECD_DIRMODE | SPECD_DEFDIRMODE)) < ++ (flp->specdFlags & (SPECD_DIRMODE | SPECD_DEFDIRMODE))) ++ flp[1].fl_mode = flp->fl_mode; ++ } else { ++ if ((flp[1].specdFlags & (SPECD_FILEMODE | SPECD_DEFFILEMODE)) < ++ (flp->specdFlags & (SPECD_FILEMODE | SPECD_DEFFILEMODE))) ++ flp[1].fl_mode = flp->fl_mode; ++ } ++ ++ /* uid */ ++ if ((flp[1].specdFlags & (SPECD_UID | SPECD_DEFUID)) < ++ (flp->specdFlags & (SPECD_UID | SPECD_DEFUID))) ++ { ++ flp[1].fl_uid = flp->fl_uid; ++ flp[1].uname = flp->uname; ++ } ++ ++ /* gid */ ++ if ((flp[1].specdFlags & (SPECD_GID | SPECD_DEFGID)) < ++ (flp->specdFlags & (SPECD_GID | SPECD_DEFGID))) ++ { ++ flp[1].fl_gid = flp->fl_gid; ++ flp[1].gname = flp->gname; ++ } ++ ++ /* verify flags */ ++ if ((flp[1].specdFlags & (SPECD_VERIFY | SPECD_DEFVERIFY)) < ++ (flp->specdFlags & (SPECD_VERIFY | SPECD_DEFVERIFY))) ++ flp[1].verifyFlags = flp->verifyFlags; ++ ++ /* XXX to-do: language */ ++ ++ flp++; i++; ++ } ++ ++ /* Skip files that were marked with %exclude. */ ++ if (flp->flags & RPMFILE_EXCLUDE) ++ { ++ argvAdd(&pkg->fileExcludeList, flp->cpioPath); ++ continue; ++ } ++ ++ buf[0] = '\0'; ++ if (S_ISREG(flp->fl_mode) && !(flp->flags & RPMFILE_GHOST)) ++ (void) rpmDoDigest(digestalgo, flp->diskPath, 1, ++ (unsigned char *)buf); ++ headerPutString(h, RPMTAG_FILEDIGESTS, buf); ++ snprintf(file_digest, sizeof(file_digest), "%s", buf); ++ ++ if (check_fileList_bin_pkg && S_ISREG(flp->fl_mode) && ++ !(flp->flags & RPMFILE_GHOST)) { ++ appendStringBuf(check_fileList_bin_pkg, "path="); ++ appendStringBuf(check_fileList_bin_pkg, flp->diskPath); ++ snprintf(file_info, sizeof(file_info), ++ "|digestalgopgp=%d|digest=%s|mode=%d" ++ "|uname=%s|gname=%s|caps=%s\n", ++ digestalgo, file_digest, flp->fl_mode, ++ rpmstrPoolStr(fl->pool, flp->uname), ++ rpmstrPoolStr(fl->pool, flp->gname), flp->caps && ++ strlen(flp->caps) ? flp->caps : ""); ++ appendStringBuf(check_fileList_bin_pkg, file_info); ++ } ++ } ++ ++ if (genDigestList(pkg->header, fl, check_fileList_bin_pkg) > 0) ++ fl->processingFailed = 1; ++} ++ ++/** ++ * Add file entries to header. ++ * @todo Should directories have %doc/%config attributes? (#14531) ++ * @todo Remove RPMTAG_OLDFILENAMES, add dirname/basename instead. ++ * @param fl package file tree walk data ++ * @param pkg (sub) package ++ * @param isSrc pass 1 for source packages 0 otherwise ++ */ ++static void genCpioListAndHeader(FileList fl, Package pkg, int isSrc) ++{ ++ FileListRec flp; ++ char buf[BUFSIZ]; + int i, npaths = 0; + int fail_on_dupes = rpmExpandNumeric("%{?_duplicate_files_terminate_build}") > 0; + uint32_t defaultalgo = PGPHASHALGO_MD5, digestalgo; + rpm_loff_t totalFileSize = 0; + Header h = pkg->header; /* just a shortcut */ +- int processed = 0; + time_t source_date_epoch = 0; + char *srcdate = getenv("SOURCE_DATE_EPOCH"); ++ struct rpmtd_s oldfiledigests; ++ ++ headerGet(h, RPMTAG_FILEDIGESTS, &oldfiledigests, HEADERGET_ALLOC); ++ headerDel(h, RPMTAG_FILEDIGESTS); ++ rpmtdInit(&oldfiledigests); + + /* Limit the maximum date to SOURCE_DATE_EPOCH if defined + * similar to the tar --clamp-mtime option +@@ -1080,9 +1209,8 @@ static void genCpioListAndHeader(FileList fl, Package pkg, int isSrc) + + pkg->dpaths = xmalloc((fl->files.used + 1) * sizeof(*pkg->dpaths)); + +-process_files: + /* Generate the header. */ +- for (i = processed, flp = fl->files.recs + processed; i < fl->files.used; i++, flp++) { ++ for (i = 0, flp = fl->files.recs; i < fl->files.used; i++, flp++) { + rpm_ino_t fileid = flp - fl->files.recs; + + /* Merge duplicate entries. */ +@@ -1212,13 +1340,17 @@ process_files: + if (fl->haveCaps) { + headerPutString(h, RPMTAG_FILECAPS, flp->caps); + } +- ++ + buf[0] = '\0'; +- if (S_ISREG(flp->fl_mode) && !(flp->flags & RPMFILE_GHOST)) +- (void) rpmDoDigest(digestalgo, flp->diskPath, 1, +- (unsigned char *)buf); +- headerPutString(h, RPMTAG_FILEDIGESTS, buf); +- snprintf(file_digest, sizeof(file_digest), "%s", buf); ++ if (strstr(flp->diskPath, DIGEST_LIST_DIR) || !oldfiledigests.count) { ++ if (S_ISREG(flp->fl_mode) && !(flp->flags & RPMFILE_GHOST)) ++ (void) rpmDoDigest(digestalgo, flp->diskPath, 1, ++ (unsigned char *)buf); ++ headerPutString(h, RPMTAG_FILEDIGESTS, buf); ++ } else { ++ headerPutString(h, RPMTAG_FILEDIGESTS, ++ rpmtdNextString(&oldfiledigests)); ++ } + + buf[0] = '\0'; + if (S_ISLNK(flp->fl_mode)) { +@@ -1259,31 +1391,6 @@ process_files: + flp->flags &= PARSEATTR_MASK; + + headerPutUint32(h, RPMTAG_FILEFLAGS, &(flp->flags) ,1); +- +- if (!processed && check_fileList_bin_pkg && S_ISREG(flp->fl_mode) && +- !(flp->flags & RPMFILE_GHOST)) { +- appendStringBuf(check_fileList_bin_pkg, "path="); +- appendStringBuf(check_fileList_bin_pkg, flp->diskPath); +- snprintf(file_info, sizeof(file_info), +- "|digestalgopgp=%d|digest=%s|mode=%d" +- "|uname=%s|gname=%s|caps=%s\n", +- digestalgo, file_digest, flp->fl_mode, +- rpmstrPoolStr(fl->pool, flp->uname), +- rpmstrPoolStr(fl->pool, flp->gname), flp->caps && +- strlen(flp->caps) ? flp->caps : ""); +- appendStringBuf(check_fileList_bin_pkg, file_info); +- } +- } +- +- if (!processed) { +- if (genDigestList(pkg->header, fl, check_fileList_bin_pkg) > 0) { +- fl->processingFailed = 1; +- } else if (i < fl->files.used) { +- pkg->dpaths = xrealloc(pkg->dpaths, +- (fl->files.used + 1) * sizeof(*pkg->dpaths)); +- processed = i; +- goto process_files; +- } + } + + pkg->dpaths[npaths] = NULL; +@@ -1324,6 +1431,7 @@ process_files: + /* Binary packages with dirNames cannot be installed by legacy rpm. */ + (void) rpmlibNeedsFeature(pkg, "CompressedFileNames", "3.0.4-1"); + } ++ rpmtdFreeData(&oldfiledigests); + } + + static FileRecords FileRecordsFree(FileRecords files) +@@ -2808,6 +2916,10 @@ static rpmRC processPackageFiles(rpmSpec spec, rpmBuildPkgFlags pkgFlags, + if (checkHardLinks(&fl.files)) + (void) rpmlibNeedsFeature(pkg, "PartialHardlinkSets", "4.0.4-1"); + ++ genDigestListInput(&fl, pkg, 0); ++ if (fl.processingFailed) ++ goto exit; ++ + genCpioListAndHeader(&fl, pkg, 0); + + exit: +-- +2.33.0 + diff --git a/Generate-digest-lists.patch b/Generate-digest-lists.patch new file mode 100644 index 0000000..7fbac1c --- /dev/null +++ b/Generate-digest-lists.patch @@ -0,0 +1,323 @@ +From 4d1801825c754171962050ee9c36c2d69c630ece Mon Sep 17 00:00:00 2001 +From: Roberto Sassu <roberto.sassu@huawei.com> +Date: Thu, 12 Mar 2020 17:29:55 +0100 +Subject: [PATCH 1/3] Generate digest lists + +--- + build/files.c | 176 ++++++++++++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 169 insertions(+), 7 deletions(-) + +diff --git a/build/files.c b/build/files.c +index 6dfd801c8..ab6938d8c 100644 +--- a/build/files.c ++++ b/build/files.c +@@ -50,6 +50,7 @@ + #define DEBUG_LIB_PREFIX "/usr/lib/debug/" + #define DEBUG_ID_DIR "/usr/lib/debug/.build-id" + #define DEBUG_DWZ_DIR "/usr/lib/debug/.dwz" ++#define DIGEST_LIST_DIR "/.digest_lists" + + #undef HASHTYPE + #undef HTKEYTYPE +@@ -129,6 +130,8 @@ typedef struct AttrRec_s { + + /* list of files */ + static StringBuf check_fileList = NULL; ++/* list of files per binary package */ ++static StringBuf check_fileList_bin_pkg = NULL; + + typedef struct FileEntry_s { + rpmfileAttrs attrFlags; +@@ -193,6 +196,10 @@ typedef struct FileList_s { + struct FileEntry_s cur; + } * FileList; + ++static char *digest_list_dir; ++ ++static int genDigestList(Header header, FileList fl, StringBuf fileList); ++ + static void nullAttrRec(AttrRec ar) + { + memset(ar, 0, sizeof(*ar)); +@@ -997,11 +997,14 @@ static void genCpioListAndHeader(FileList fl, Package pkg, int isSrc) + { + FileListRec flp; + char buf[BUFSIZ]; ++ char file_info[BUFSIZ]; ++ char file_digest[128 * 2 + 1]; + int i, npaths = 0; + int fail_on_dupes = rpmExpandNumeric("%{?_duplicate_files_terminate_build}") > 0; + uint32_t defaultalgo = PGPHASHALGO_MD5, digestalgo; + rpm_loff_t totalFileSize = 0; + Header h = pkg->header; /* just a shortcut */ ++ int processed = 0; + time_t source_date_epoch = 0; + char *srcdate = getenv("SOURCE_DATE_EPOCH"); + +@@ -1058,8 +1067,9 @@ static void genCpioListAndHeader(FileList fl, Package pkg, int isSrc) + + pkg->dpaths = xmalloc((fl->files.used + 1) * sizeof(*pkg->dpaths)); + ++process_files: + /* Generate the header. */ +- for (i = 0, flp = fl->files.recs; i < fl->files.used; i++, flp++) { ++ for (i = processed, flp = fl->files.recs + processed; i < fl->files.used; i++, flp++) { + rpm_ino_t fileid = flp - fl->files.recs; + + /* Merge duplicate entries. */ +@@ -1190,7 +1200,8 @@ static void genCpioListAndHeader(FileList fl, Package pkg, int isSrc) + (void) rpmDoDigest(digestalgo, flp->diskPath, 1, + (unsigned char *)buf); + headerPutString(h, RPMTAG_FILEDIGESTS, buf); +- ++ snprintf(file_digest, sizeof(file_digest), "%s", buf); ++ + buf[0] = '\0'; + if (S_ISLNK(flp->fl_mode)) { + ssize_t llen = readlink(flp->diskPath, buf, BUFSIZ-1); +@@ -1230,7 +1241,33 @@ static void genCpioListAndHeader(FileList fl, Package pkg, int isSrc) + flp->flags &= PARSEATTR_MASK; + + headerPutUint32(h, RPMTAG_FILEFLAGS, &(flp->flags) ,1); ++ ++ if (!processed && check_fileList_bin_pkg && S_ISREG(flp->fl_mode) && ++ !(flp->flags & RPMFILE_GHOST)) { ++ appendStringBuf(check_fileList_bin_pkg, "path="); ++ appendStringBuf(check_fileList_bin_pkg, flp->diskPath); ++ snprintf(file_info, sizeof(file_info), ++ "|digestalgopgp=%d|digest=%s|mode=%d" ++ "|uname=%s|gname=%s|caps=%s\n", ++ digestalgo, file_digest, flp->fl_mode, ++ rpmstrPoolStr(fl->pool, flp->uname), ++ rpmstrPoolStr(fl->pool, flp->gname), flp->caps && ++ strlen(flp->caps) ? flp->caps : ""); ++ appendStringBuf(check_fileList_bin_pkg, file_info); ++ } ++ } ++ ++ if (!processed) { ++ if (genDigestList(pkg->header, fl, check_fileList_bin_pkg) > 0) { ++ fl->processingFailed = 1; ++ } else if (i < fl->files.used) { ++ pkg->dpaths = xrealloc(pkg->dpaths, ++ (fl->files.used + 1) * sizeof(*pkg->dpaths)); ++ processed = i; ++ goto process_files; ++ } + } ++ + pkg->dpaths[npaths] = NULL; + + if (totalFileSize < UINT32_MAX) { +@@ -1343,8 +1380,8 @@ static int validFilename(const char *fn) + * @param statp file stat (possibly NULL) + * @return RPMRC_OK on success + */ +-static rpmRC addFile(FileList fl, const char * diskPath, +- struct stat * statp) ++static rpmRC addFile_common(FileList fl, const char * diskPath, ++ struct stat * statp, int digest_list) + { + size_t plen = strlen(diskPath); + char buf[plen + 1]; +@@ -1355,6 +1392,10 @@ static rpmRC addFile(FileList fl, const char * diskPath, + gid_t fileGid; + const char *fileUname; + const char *fileGname; ++ char realPath[PATH_MAX]; ++ int digest_list_prefix = 0; ++ struct stat st; ++ int exclude = 0; + rpmRC rc = RPMRC_FAIL; /* assume failure */ + + /* Strip trailing slash. The special case of '/' path is handled below. */ +@@ -1390,6 +1431,33 @@ static rpmRC addFile(FileList fl, const char * diskPath, + if (*cpioPath == '\0') + cpioPath = "/"; + ++ snprintf(realPath, sizeof(realPath), "%s", diskPath); ++ rpmCleanPath(realPath); ++ ++ digest_list_prefix = (!strncmp(realPath, digest_list_dir, ++ strlen(digest_list_dir))); ++ ++ if ((!digest_list && digest_list_prefix) || ++ (digest_list && !digest_list_prefix)) { ++ rc = RPMRC_OK; ++ goto exit; ++ } ++ ++ if (digest_list) { ++ if (strncmp(cpioPath, DIGEST_LIST_DIR, sizeof(DIGEST_LIST_DIR) - 1)) { ++ rc = RPMRC_OK; ++ goto exit; ++ } ++ ++ cpioPath += sizeof(DIGEST_LIST_DIR) - 1; ++ ++ snprintf(realPath, sizeof(realPath), "%.*s%s", ++ (int)(strlen(digest_list_dir) - sizeof(DIGEST_LIST_DIR) + 1), ++ digest_list_dir, cpioPath); ++ if (!stat(realPath, &st)) ++ exclude = 1; ++ } ++ + /* + * Unless recursing, we dont have stat() info at hand. Handle the + * various cases, preserving historical behavior wrt %dev(): +@@ -1527,6 +1595,8 @@ static rpmRC addFile(FileList fl, const char * diskPath, + } + + flp->flags = fl->cur.attrFlags; ++ if (exclude) ++ flp->flags |= RPMFILE_EXCLUDE; + flp->specdFlags = fl->cur.specdFlags; + flp->verifyFlags = fl->cur.verifyFlags; + +@@ -1547,6 +1617,32 @@ exit: + return rc; + } + ++/** ++ * Add a file to the package manifest. ++ * @param fl package file tree walk data ++ * @param diskPath path to file ++ * @param statp file stat (possibly NULL) ++ * @return RPMRC_OK on success ++ */ ++static rpmRC addFile(FileList fl, const char * diskPath, ++ struct stat * statp) ++{ ++ return addFile_common(fl, diskPath, statp, 0); ++} ++ ++/** ++ * Add a digest list to the package manifest. ++ * @param fl package file tree walk data ++ * @param diskPath path to digest list ++ * @param statp file stat (possibly NULL) ++ * @return RPMRC_OK on success ++ */ ++static rpmRC addDigestList(FileList fl, const char * diskPath, ++ struct stat * statp) ++{ ++ return addFile_common(fl, diskPath, statp, 1); ++} ++ + /** + * Add directory (and all of its files) to the package manifest. + * @param fl package file tree walk data +@@ -2556,6 +2652,58 @@ static void addPackageFileList (struct FileList_s *fl, Package pkg, + argvFree(fileNames); + } + ++/** ++ * Generate digest lists list for current binary package. ++ * @header package header ++ * @fl file list ++ * @param fileList packaged file list ++ * @return -1 if skipped, 0 on OK, 1 on error ++ */ ++static int genDigestList(Header header, FileList fl, StringBuf fileList) ++{ ++ const char *errorString; ++ char *binFormat = rpmGetPath("%{_rpmfilename}", NULL); ++ char *binRpm = headerFormat(header, binFormat, &errorString); ++ static char * av_brp[] = { "%{?__brp_digest_list}", DIGEST_LIST_DIR + 1, NULL, NULL }; ++ StringBuf sb_stdout = NULL; ++ int rc = -1; ++ char * s = rpmExpand(av_brp[0], NULL); ++ ++ if (!(s && *s)) ++ goto exit; ++ ++ av_brp[2] = strchr(binRpm, '/') + 1; ++ rpmlog(RPMLOG_NOTICE, _("Generating digest list: %s\n"), s); ++ ++ rc = rpmfcExec(av_brp, fileList, &sb_stdout, 0, binRpm); ++ if (sb_stdout && getStringBuf(sb_stdout)) { ++ const char * t = getStringBuf(sb_stdout), *ptr; ++ char *digest_list_path; ++ ++ while((ptr = strchr(t, '\n'))) { ++ digest_list_path = strndup(t, ptr - t); ++ if (!digest_list_path) { ++ rc = -1; ++ goto exit; ++ } ++ FileEntryFree(&fl->cur); ++ resetPackageFilesDefaults(fl, fl->pkgFlags); ++ rc = addDigestList(fl, digest_list_path, NULL); ++ free(digest_list_path); ++ if (rc != RPMRC_OK) ++ break; ++ ++ t = ptr + 1; ++ } ++ } ++exit: ++ free(binFormat); ++ free(binRpm); ++ free(s); ++ freeStringBuf(sb_stdout); ++ return rc; ++} ++ + static rpmRC processPackageFiles(rpmSpec spec, rpmBuildPkgFlags pkgFlags, + Package pkg, int didInstall, int test) + { +@@ -2569,6 +2717,10 @@ static rpmRC processPackageFiles(rpmSpec spec, rpmBuildPkgFlags pkgFlags, + if (readFilesManifest(spec, pkg, *fp)) + return RPMRC_FAIL; + } ++ ++ /* Init the buffer containing the list of packaged files */ ++ check_fileList_bin_pkg = newStringBuf(); ++ + /* Init the file list structure */ + memset(&fl, 0, sizeof(fl)); + +@@ -2630,6 +2782,7 @@ exit: + FileListFree(&fl); + specialDirFree(specialDoc); + specialDirFree(specialLic); ++ freeStringBuf(check_fileList_bin_pkg); + return fl.processingFailed ? RPMRC_FAIL : RPMRC_OK; + } + +@@ -3092,6 +3245,7 @@ static void addPackageDeps(Package from, Package to, enum rpmTag_e tag) + rpmRC processBinaryFiles(rpmSpec spec, rpmBuildPkgFlags pkgFlags, + int didInstall, int test) + { ++ struct stat st; + Package pkg; + rpmRC rc = RPMRC_OK; + char *buildroot; +@@ -3108,7 +3262,14 @@ rpmRC processBinaryFiles(rpmSpec spec, rpmBuildPkgFlags pkgFlags, + check_fileList = newStringBuf(); + genSourceRpmName(spec); + buildroot = rpmGenPath(spec->rootDir, spec->buildRoot, NULL); +- ++ ++ digest_list_dir = rpmGenPath(buildroot, DIGEST_LIST_DIR, NULL); ++ if (!digest_list_dir) ++ goto exit; ++ ++ if (!stat(digest_list_dir, &st)) ++ rpmlog(RPMLOG_NOTICE, _("Ignoring files in: %s\n"), digest_list_dir); ++ + if (rpmExpandNumeric("%{?_debuginfo_subpackages}")) { + maindbg = findDebuginfoPackage(spec); + if (maindbg) { +@@ -3214,6 +3375,7 @@ exit: + check_fileList = freeStringBuf(check_fileList); + _free(buildroot); + _free(uniquearch); +- ++ _free(digest_list_dir); ++ + return rc; + } +-- +2.27.GIT + diff --git a/Remove-digest-list-from-the-kernel-during-package-re.patch b/Remove-digest-list-from-the-kernel-during-package-re.patch new file mode 100644 index 0000000..2bd6caa --- /dev/null +++ b/Remove-digest-list-from-the-kernel-during-package-re.patch @@ -0,0 +1,106 @@ +From 0f088c5c9efa8ab877455bc273d7e536c763f824 Mon Sep 17 00:00:00 2001 +From: Roberto Sassu <roberto.sassu@huawei.com> +Date: Thu, 11 Mar 2021 11:59:45 +0100 +Subject: [PATCH] Remove digest list from the kernel during package + reinstallation + +Signed-off-by: luhuaxin <luhuaxin1@huawei.com> +--- + plugins/digest_list.c | 36 +++++++++++++++++------------------- + 1 file changed, 17 insertions(+), 19 deletions(-) + +diff --git a/plugins/digest_list.c b/plugins/digest_list.c +index ca77282..63f8f1c 100644 +--- a/plugins/digest_list.c ++++ b/plugins/digest_list.c +@@ -27,9 +27,6 @@ + #define DIGEST_LIST_DEFAULT_PATH "/etc/ima/digest_lists" + #define RPM_PARSER "/usr/libexec/rpm_parser" + +-#define DIGEST_LIST_OP_ADD 0 +-#define DIGEST_LIST_OP_DEL 1 +- + enum hash_algo { + HASH_ALGO_MD4, + HASH_ALGO_MD5, +@@ -372,12 +369,13 @@ out: + return ret; + } + +-static int process_digest_list(rpmte te, int parser) ++static int process_digest_list(rpmte te, int parser, int pre) + { + char *path = NULL, *path_sig = NULL; + int digest_list_signed = 0; + struct stat st; + ssize_t size; ++ int type = rpmteType(te); + struct __user_cap_header_struct cap_header_data; + cap_user_header_t cap_header = &cap_header_data; + struct __user_cap_data_struct cap_data_data; +@@ -431,15 +429,7 @@ static int process_digest_list(rpmte te, int parser) + + size = lgetxattr(path, XATTR_NAME_IMA, NULL, 0); + +- /* Don't upload again if digest list was already processed */ +- if ((rpmteType(te) == TR_ADDED && size > 0) || +- (rpmteType(te) == TR_REMOVED && size < 0)) { +- rpmlog(RPMLOG_DEBUG, "digest_list: '%s' already processed, " +- "nothing to do\n", path); +- goto out; +- } +- +- if (rpmteType(te) == TR_ADDED) { ++ if (type == TR_ADDED && !pre && size < 0) { + if (!digest_list_signed) { + /* Write RPM header to the disk */ + ret = write_rpm_digest_list(te, path); +@@ -472,12 +462,18 @@ static int process_digest_list(rpmte te, int parser) + ret = RPMRC_FAIL; + goto out; + } ++ } else if (type == TR_ADDED && pre) { ++ if (size < 0) ++ goto out; ++ ++ /* rpm is overwriting the digest list, remove from the kernel */ ++ type = TR_REMOVED; + } + + /* Upload digest list to securityfs */ +- upload_digest_list(path, rpmteType(te), digest_list_signed); ++ upload_digest_list(path, type, digest_list_signed); + +- if (rpmteType(te) == TR_REMOVED) { ++ if (type == TR_REMOVED) { + if (!digest_list_signed) { + unlink(path); + goto out; +@@ -552,8 +548,10 @@ static rpmRC digest_list_file_common(rpmPlugin plugin, rpmfi fi, + if (!pre && res != RPMRC_OK) + return res; + +- if ((pre && action != FA_ERASE) || +- (!pre && action != FA_CREATE)) ++ if (!pre && rpmteType(cur_te) != TR_ADDED) ++ return RPMRC_OK; ++ ++ if (pre && action == FA_SKIP) + return RPMRC_OK; + + if (strncmp(path, DIGEST_LIST_DEFAULT_PATH, +@@ -564,9 +562,9 @@ static rpmRC digest_list_file_common(rpmPlugin plugin, rpmfi fi, + if (!pre && --digest_list_counter) + return RPMRC_OK; + +- process_digest_list(cur_te, 0); ++ process_digest_list(cur_te, 0, pre); + if (!strcmp(rpmteN(cur_te), "digest-list-tools")) +- process_digest_list(cur_te, 1); ++ process_digest_list(cur_te, 1, pre); + + return RPMRC_OK; + } +-- +2.33.0 + diff --git a/Unbundle-config-site-and-add-RPM-LD-FLAGS-macro.patch b/Unbundle-config-site-and-add-RPM-LD-FLAGS-macro.patch new file mode 100644 index 0000000..920a285 --- /dev/null +++ b/Unbundle-config-site-and-add-RPM-LD-FLAGS-macro.patch @@ -0,0 +1,38 @@ +From eee654b9652fb9387018f9653431a11401a354fd Mon Sep 17 00:00:00 2001 +From: openeuler-basic <shenyangyang4@huawei.com> +Date: Thu, 9 Jan 2020 19:16:58 +0800 +Subject: [PATCH] Unbundle config site and add RPM LD FLAGS macro + +--- + macros.in | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/macros.in b/macros.in +index fe9803a..4027493 100644 +--- a/macros.in ++++ b/macros.in +@@ -794,10 +794,11 @@ package or when debugging this package.\ + RPM_SOURCE_DIR=\"%{u2p:%{_sourcedir}}\"\ + RPM_BUILD_DIR=\"%{u2p:%{_builddir}}\"\ + RPM_OPT_FLAGS=\"%{optflags}\"\ ++ RPM_LD_FLAGS=\"%{?build_ldflags}\"\ + RPM_ARCH=\"%{_arch}\"\ + RPM_OS=\"%{_os}\"\ + RPM_BUILD_NCPUS=\"%{_smp_build_ncpus}\"\ +- export RPM_SOURCE_DIR RPM_BUILD_DIR RPM_OPT_FLAGS RPM_ARCH RPM_OS RPM_BUILD_NCPUS\ ++ export RPM_SOURCE_DIR RPM_BUILD_DIR RPM_OPT_FLAGS RPM_ARCH RPM_OS RPM_BUILD_NCPUS RPM_OPT_FLAGS\ + RPM_DOC_DIR=\"%{_docdir}\"\ + export RPM_DOC_DIR\ + RPM_PACKAGE_NAME=\"%{NAME}\"\ +@@ -813,6 +814,8 @@ package or when debugging this package.\ + export CLASSPATH}\ + PKG_CONFIG_PATH=\"${PKG_CONFIG_PATH}:%{_libdir}/pkgconfig:%{_datadir}/pkgconfig\"\ + export PKG_CONFIG_PATH\ ++ CONFIG_SITE=${CONFIG_SITE:-NONE}\ ++ export CONFIG_SITE\ + \ + %[%{verbose}?"set -x":""]\ + umask 022\ +-- +1.8.3.1 + diff --git a/add-dist-to-release-by-default.patch b/add-dist-to-release-by-default.patch new file mode 100644 index 0000000..36c8226 --- /dev/null +++ b/add-dist-to-release-by-default.patch @@ -0,0 +1,37 @@ +From af9a2347cd725a8dbb6045d7d3e9661d524af110 Mon Sep 17 00:00:00 2001 +From: openEuler Buildteam <buildteam@openeuler.org> +Date: Wed, 4 Mar 2020 16:12:58 +0800 +Subject: [PATCH] add dist to release by default + +--- + build/parsePreamble.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/build/parsePreamble.c b/build/parsePreamble.c +index b0a17c8..cac899a 100644 +--- a/build/parsePreamble.c ++++ b/build/parsePreamble.c +@@ -808,6 +808,11 @@ static rpmRC handlePreambleTag(rpmSpec spec, Package pkg, rpmTagVal tag, + case RPMTAG_VERSION: + case RPMTAG_RELEASE: + SINGLE_TOKEN_ONLY; ++ if (tag == RPMTAG_RELEASE) { ++ char *dist = rpmExpand("%{?dist}",NULL); ++ rasprintf(&field,"%s%s",field,dist); ++ free(dist); ++ } + if (rpmCharCheck(spec, field, ALLOWED_CHARS_VERREL)) + goto exit; + headerPutString(pkg->header, tag, field); +@@ -987,6 +992,8 @@ static rpmRC handlePreambleTag(rpmSpec spec, Package pkg, rpmTagVal tag, + } + rc = RPMRC_OK; + exit: ++ if (tag == RPMTAG_RELEASE) ++ free(field); + return rc; + } + +-- +1.8.3.1 + diff --git a/backport-Actually-return-an-error-in-parseScript-if-parsing-f.patch b/backport-Actually-return-an-error-in-parseScript-if-parsing-f.patch new file mode 100644 index 0000000..e6732d0 --- /dev/null +++ b/backport-Actually-return-an-error-in-parseScript-if-parsing-f.patch @@ -0,0 +1,48 @@ +From 911a4f253c7213a8570028a7dc2a20b045de8e9e Mon Sep 17 00:00:00 2001 +From: Fabian Vogt <fvogt@suse.de> +Date: Mon, 26 Jun 2023 16:28:07 +0200 +Subject: [PATCH] Actually return an error in parseScript if parsing fails + +The return value is stored in the "res" variable which is set to the return +value of parseLines early in the function. Past that point, any "goto exit;" +caused the function to return success. This was introduced by 52ce88851abb +("Port parseScript() to use parseLines(), no functional changes"). To fix it, +reintroduce the nextPart variable. +--- + build/parseScript.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/build/parseScript.c b/build/parseScript.c +index f8b693ac6..6f3dc2fe8 100644 +--- a/build/parseScript.c ++++ b/build/parseScript.c +@@ -95,7 +95,7 @@ int parseScript(rpmSpec spec, int parsePart) + int index; + char * reqargs = NULL; + +- int res = PART_ERROR; /* assume failure */ ++ int nextPart, res = PART_ERROR; /* assume failure */ + int rc, argc; + int arg; + const char **argv = NULL; +@@ -367,7 +367,7 @@ int parseScript(rpmSpec spec, int parsePart) + goto exit; + } + +- if ((res = parseLines(spec, STRIP_NOTHING, NULL, &sb)) == PART_ERROR) ++ if ((nextPart = parseLines(spec, STRIP_NOTHING, NULL, &sb)) == PART_ERROR) + goto exit; + + if (sb) { +@@ -479,6 +479,8 @@ int parseScript(rpmSpec spec, int parsePart) + } + } + ++ res = nextPart; ++ + exit: + free(reqargs); + freeStringBuf(sb); +-- +2.27.0 + 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 <demi@invisiblethingslab.com> +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-Add-a-test-for-special-device-node-installation.patch b/backport-Add-a-test-for-special-device-node-installation.patch new file mode 100644 index 0000000..8fd8ff9 --- /dev/null +++ b/backport-Add-a-test-for-special-device-node-installation.patch @@ -0,0 +1,79 @@ +From 5dcc399cd21f607f13eb092a3abfc8b8daa59d4c Mon Sep 17 00:00:00 2001 +From: Panu Matilainen <pmatilai@redhat.com> +Date: Fri, 13 Jan 2023 10:44:28 +0200 +Subject: [PATCH] Add a test for special device node installation + +This is a bit theoretical as it does not work for regular users or in +containers which are the typical scenarios for running the test-suite. +--- + tests/atlocal.in | 6 ++++++ + tests/data/SPECS/dev.spec | 14 ++++++++++++++ + tests/rpmi.at | 17 +++++++++++++++++ + 3 files changed, 37 insertions(+) + create mode 100644 tests/data/SPECS/dev.spec + +diff --git a/tests/atlocal.in b/tests/atlocal.in +index c3189d3..1fb08d4 100644 +--- a/tests/atlocal.in ++++ b/tests/atlocal.in +@@ -49,6 +49,12 @@ if grep -q '#define WITH_CAP 1' "${abs_top_builddir}/config.h"; then + else + CAP_DISABLED=true; + fi ++if mknod foodev c 123 123; then ++ MKNOD_DISABLED=false ++ rm -f foodev ++else ++ MKNOD_DISABLED=true ++fi + + function setup_env() + { +diff --git a/tests/data/SPECS/dev.spec b/tests/data/SPECS/dev.spec +new file mode 100644 +index 000000000..d784fe114 +--- /dev/null ++++ b/tests/data/SPECS/dev.spec +@@ -0,0 +1,14 @@ ++Name: dev ++Version: 1.0 ++Release: 1 ++Group: Testing ++License: GPL ++Summary: Testing dev behavior ++BuildArch: noarch ++ ++%description ++%{summary} ++ ++%files ++%dev(c 11 22) /test-char ++%dev(b 33 44) /test-block +diff --git a/tests/rpmi.at b/tests/rpmi.at +index a2389de..f439e46 100644 +--- a/tests/rpmi.at ++++ b/tests/rpmi.at +@@ -888,3 +888,20 @@ runroot rpm -Vv --nouser --nogroup fifo + ], + []) + AT_CLEANUP ++ ++AT_SETUP([rpm -U dev]) ++AT_KEYWORDS([install]) ++AT_SKIP_IF([$MKNOD_DISABLED]) ++AT_CHECK([ ++RPMDB_INIT ++ ++runroot rpmbuild -bb --quiet /data/SPECS/dev.spec ++runroot rpm -U --ignoreos /build/RPMS/noarch/dev-1.0-1.noarch.rpm ++runroot rpm -Vv --nouser --nogroup dev ++], ++[0], ++[......... /test-block ++......... /test-char ++], ++[]) ++AT_CLEANUP +-- +2.27.0 + diff --git a/backport-Add-optional-callback-on-directory-changes-during-rp.patch b/backport-Add-optional-callback-on-directory-changes-during-rp.patch new file mode 100644 index 0000000..53765d4 --- /dev/null +++ b/backport-Add-optional-callback-on-directory-changes-during-rp.patch @@ -0,0 +1,105 @@ +From fb13f7fd9eff012cb7b9dbf94ac5381c69404055 Mon Sep 17 00:00:00 2001 +From: Panu Matilainen <pmatilai@redhat.com> +Date: Wed, 9 Feb 2022 14:47:14 +0200 +Subject: [PATCH] Add optional callback on directory changes during rpmfi + iteration + +Internal only for now in case we need to fiddle with the API some more, +but no reason this couldn't be made public later. +--- + lib/rpmfi.c | 24 +++++++++++++++++++++++- + lib/rpmfi_internal.h | 17 +++++++++++++++++ + 2 files changed, 40 insertions(+), 1 deletion(-) + +diff --git a/lib/rpmfi.c b/lib/rpmfi.c +index 4673fbb..e8e7d08 100644 +--- a/lib/rpmfi.c ++++ b/lib/rpmfi.c +@@ -55,6 +55,9 @@ struct rpmfi_s { + int intervalStart; /*!< Start of iterating interval. */ + int intervalEnd; /*!< End of iterating interval. */ + ++ rpmfiChdirCb onChdir; /*!< Callback for directory changes */ ++ void *onChdirData; /*!< Caller private callback data */ ++ + rpmfiles files; /*!< File info set */ + rpmcpio_t archive; /*!< Archive with payload */ + unsigned char * found; /*!< Bit field of files found in the archive */ +@@ -312,6 +312,17 @@ int rpmfiDI(rpmfi fi) + } + #endif + ++int rpmfiSetOnChdir(rpmfi fi, rpmfiChdirCb cb, void *data) ++{ ++ int rc = -1; ++ if (fi != NULL) { ++ fi->onChdir = cb; ++ fi->onChdirData = data; ++ rc = 0; ++ } ++ return rc; ++} ++ + int rpmfiFX(rpmfi fi) + { + return (fi != NULL ? fi->i : -1); +@@ -313,9 +327,17 @@ int rpmfiSetFX(rpmfi fi, int fx) + int i = -1; + + if (fi != NULL && fx >= 0 && fx < rpmfilesFC(fi->files)) { ++ int dx = fi->j; ++ i = fi->i; + fi->i = fx; + fi->j = rpmfilesDI(fi->files, fi->i); + i = fi->i; ++ ++ if (fi->j != dx && fi->onChdir) { ++ int chrc = fi->onChdir(fi, fi->onChdirData); ++ if (chrc < 0) ++ i = chrc; ++ } + } + return i; + } +@@ -1780,9 +1802,9 @@ static rpmfi initIter(rpmfiles files, int itype, int link) + if (files && itype>=0 && itype<=RPMFILEITERMAX) { + fi = xcalloc(1, sizeof(*fi)); + fi->i = -1; ++ fi->j = -1; + fi->files = link ? rpmfilesLink(files) : files; + fi->next = nextfuncs[itype]; +- fi->i = -1; + if (itype == RPMFI_ITER_BACK) { + fi->i = rpmfilesFC(fi->files); + } else if (itype >=RPMFI_ITER_READ_ARCHIVE +diff --git a/lib/rpmfi_internal.h b/lib/rpmfi_internal.h +index dccc6ccb..37f1d45 100644 +--- a/lib/rpmfi_internal.h ++++ b/lib/rpmfi_internal.h +@@ -14,6 +14,23 @@ extern "C" { + #endif + + /** \ingroup rpmfi ++ * Callback on file iterator directory changes ++ * @param fi file info ++ * @param data caller private callback data ++ * @return 0 on success, < 0 on error (to stop iteration) ++ */ ++typedef int (*rpmfiChdirCb)(rpmfi fi, void *data); ++ ++/** \ingroup rpmfi ++ * Set a callback for directory changes during iteration. ++ * @param fi file info ++ * @param cb callback function ++ * @param data caller private callback data ++ * @return string pool handle (weak reference) ++ */ ++int rpmfiSetOnChdir(rpmfi fi, rpmfiChdirCb cb, void *data); ++ ++/** \ingroup rpmfi + * Return file info set string pool handle + * @param fi file info + * @return string pool handle (weak reference) +-- +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 <demi@invisiblethingslab.com> +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-reading-out-of-bounds-of-the-i18ntable.patch b/backport-Avoid-reading-out-of-bounds-of-the-i18ntable.patch new file mode 100644 index 0000000..d237fa5 --- /dev/null +++ b/backport-Avoid-reading-out-of-bounds-of-the-i18ntable.patch @@ -0,0 +1,29 @@ +From db8fc1057e38839adc04e263fe255ce86cab9fa7 Mon Sep 17 00:00:00 2001 +From: Demi Marie Obenour <demi@invisiblethingslab.com> +Date: Sat, 12 Feb 2022 13:46:28 -0500 +Subject: [PATCH] Avoid reading out of bounds of the i18ntable + +If the i18ntable was smaller than the i18nstring entry an out of bounds +read could result. This should not happen in a valid package, but even +if RPM rejected such packages during load, this situation could still +result as a result of usage of the RPM API. +--- + lib/header.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/header.c b/lib/header.c +index 098ea5d..c939006 100644 +--- a/lib/header.c ++++ b/lib/header.c +@@ -1311,7 +1311,7 @@ static int copyI18NEntry(Header h, indexEntry entry, rpmtd td, + + /* For each entry in the header ... */ + for (langNum = 0, t = table->data, ed = entry->data; +- langNum < entry->info.count; ++ langNum < entry->info.count && langNum < table->info.count; + langNum++, t += strlen(t) + 1, ed += strlen(ed) + 1) { + + int match = headerMatchLocale(t, l, le); +-- +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 <demi@invisiblethingslab.com> +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-Bury-rpmio-FD-use-to-fsmUnpack.patch b/backport-Bury-rpmio-FD-use-to-fsmUnpack.patch new file mode 100644 index 0000000..c735909 --- /dev/null +++ b/backport-Bury-rpmio-FD-use-to-fsmUnpack.patch @@ -0,0 +1,129 @@ +From bbc270d78fb361bd78eac9a9117070caeb537d4a Mon Sep 17 00:00:00 2001 +From: Panu Matilainen <pmatilai@redhat.com> +Date: Mon, 14 Feb 2022 12:35:58 +0200 +Subject: [PATCH] Bury rpmio FD use to fsmUnpack() + +fsmUnpack() is the only place in FSM that needs to deal with rpmio FD +types, everywhere else they are nothing but a hindrance that need to +be converted to OS level descriptors for use. Better deal with OS +level descriptors to begin with. +--- + lib/fsm.c | 37 ++++++++++++++++--------------------- + 1 file changed, 16 insertions(+), 21 deletions(-) + +diff --git a/lib/fsm.c b/lib/fsm.c +index 13b1142..b019f57 100644 +--- a/lib/fsm.c ++++ b/lib/fsm.c +@@ -110,14 +110,14 @@ static int fsmSetFCaps(const char *path, const char *captxt) + return rc; + } + +-static int fsmClose(FD_t *wfdp) ++static int fsmClose(int *wfdp) + { + int rc = 0; +- if (wfdp && *wfdp) { ++ if (wfdp && *wfdp >= 0) { + int myerrno = errno; + static int oneshot = 0; + static int flush_io = 0; +- int fdno = Fileno(*wfdp); ++ int fdno = *wfdp; + + if (!oneshot) { + flush_io = (rpmExpandNumeric("%{?_flush_io}") > 0); +@@ -126,61 +126,56 @@ static int fsmClose(FD_t *wfdp) + if (flush_io) { + fsync(fdno); + } +- if (Fclose(*wfdp)) ++ if (close(fdno)) + rc = RPMERR_CLOSE_FAILED; + + if (_fsm_debug) { + rpmlog(RPMLOG_DEBUG, " %8s ([%d]) %s\n", __func__, + fdno, (rc < 0 ? strerror(errno) : "")); + } +- *wfdp = NULL; ++ *wfdp = -1; + errno = myerrno; + } + return rc; + } + +-static int fsmOpen(FD_t *wfdp, int dirfd, const char *dest) ++static int fsmOpen(int *wfdp, int dirfd, const char *dest) + { + int rc = 0; + /* Create the file with 0200 permissions (write by owner). */ + int fd = openat(dirfd, dest, O_WRONLY|O_EXCL|O_CREAT, 0200); + +- if (fd >= 0) { +- *wfdp = fdDup(fd); +- close(fd); +- } +- +- if (fd < 0 || Ferror(*wfdp)) ++ if (fd < 0) + rc = RPMERR_OPEN_FAILED; + + if (_fsm_debug) { + rpmlog(RPMLOG_DEBUG, " %8s (%s [%d]) %s\n", __func__, +- dest, Fileno(*wfdp), (rc < 0 ? strerror(errno) : "")); ++ dest, fd, (rc < 0 ? strerror(errno) : "")); + } +- +- if (rc) +- fsmClose(wfdp); ++ *wfdp = fd; + + return rc; + } + +-static int fsmUnpack(rpmfi fi, FD_t fd, rpmpsm psm, int nodigest) ++static int fsmUnpack(rpmfi fi, int fdno, rpmpsm psm, int nodigest) + { ++ FD_t fd = fdDup(fdno); + int rc = rpmfiArchiveReadToFilePsm(fi, fd, nodigest, psm); + if (_fsm_debug) { + rpmlog(RPMLOG_DEBUG, " %8s (%s %" PRIu64 " bytes [%d]) %s\n", __func__, + rpmfiFN(fi), rpmfiFSize(fi), Fileno(fd), + (rc < 0 ? strerror(errno) : "")); + } ++ Fclose(fd); + return rc; + } + + static int fsmMkfile(int dirfd, rpmfi fi, struct filedata_s *fp, rpmfiles files, + rpmpsm psm, int nodigest, +- struct filedata_s ** firstlink, FD_t *firstlinkfile) ++ struct filedata_s ** firstlink, int *firstlinkfile) + { + int rc = 0; +- FD_t fd = NULL; ++ int fd = -1; + + if (*firstlink == NULL) { + /* First encounter, open file for writing */ +@@ -206,7 +201,7 @@ static int fsmMkfile(int dirfd, rpmfi fi, struct filedata_s *fp, rpmfiles files, + if (*firstlink) { + fp->setmeta = 1; + *firstlink = NULL; +- *firstlinkfile = NULL; ++ *firstlinkfile = -1; + } + } + +@@ -811,7 +806,7 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files, + int fc = rpmfilesFC(files); + int nodigest = (rpmtsFlags(ts) & RPMTRANS_FLAG_NOFILEDIGEST) ? 1 : 0; + int nofcaps = (rpmtsFlags(ts) & RPMTRANS_FLAG_NOCAPS) ? 1 : 0; +- FD_t firstlinkfile = NULL; ++ int firstlinkfile = -1; + char *tid = NULL; + struct filedata_s *fdata = xcalloc(fc, sizeof(*fdata)); + struct filedata_s *firstlink = NULL; +-- +1.8.3.1 + diff --git a/backport-CVE-2021-35937-CVE-2021-35939.patch b/backport-CVE-2021-35937-CVE-2021-35939.patch new file mode 100644 index 0000000..b5f994a --- /dev/null +++ b/backport-CVE-2021-35937-CVE-2021-35939.patch @@ -0,0 +1,281 @@ +From 96ec957e281220f8e137a2d5eb23b83a6377d556 Mon Sep 17 00:00:00 2001 +From: Panu Matilainen <pmatilai@redhat.com> +Date: Thu, 10 Feb 2022 14:32:43 +0200 +Subject: [PATCH] Validate intermediate symlinks during installation, + CVE-2021-35939 + +Whenever directory changes during unpacking, walk the entire tree from +starting from / and validate any symlinks crossed, fail the install +on invalid links. + +This is the first of step of many towards securing our file operations +against local tamperers and besides plugging that one CVE, paves the way +for the next step by adding the necessary directory fd tracking. +This also bumps the rpm OS requirements to a whole new level by requiring +the *at() family of calls from POSIX-1.2008. + +This necessarily does a whole lot of huffing and puffing we previously +did not do. It should be possible to cache secure (ie root-owned) +directory structures to avoid validating everything a million times +but for now, just keeping things simple. +--- + INSTALL | 2 + + configure.ac | 3 +- + lib/fsm.c | 144 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- + 3 files changed, 142 insertions(+), 7 deletions(-) + +diff --git a/INSTALL b/INSTALL +index 677ef88..961a160 100644 +--- a/INSTALL ++++ b/INSTALL +@@ -103,6 +103,8 @@ option to configure). For GCC, OpenMP 4.5 is fully supported since GCC 6.1, + which is available from + http://www.gnu.org/ + ++Rpm requires a POSIX.1-2008 level operating system. ++ + To compile RPM: + -------------- + +diff --git a/configure.ac b/configure.ac +index 3ee3407..0099e5f 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -580,7 +580,8 @@ AC_CHECK_FUNCS([secure_getenv __secure_getenv]) + + AC_CHECK_FUNCS( + [mkstemp getcwd basename dirname realpath setenv unsetenv regcomp lchown \ +- utimes getline localtime_r statvfs getaddrinfo ], ++ utimes getline localtime_r statvfs getaddrinfo \ ++ openat mkdirat fstatat ], + [], [AC_MSG_ERROR([function required by rpm])]) + + AC_LIBOBJ(fnmatch) +diff --git a/lib/fsm.c b/lib/fsm.c +index 9118983..b6b152a 100644 +--- a/lib/fsm.c ++++ b/lib/fsm.c +@@ -8,6 +8,7 @@ + #include <inttypes.h> + #include <utime.h> + #include <errno.h> ++#include <fcntl.h> + #if WITH_CAP + #include <sys/capability.h> + #endif +@@ -20,6 +21,7 @@ + #include "rpmio/rpmio_internal.h" /* fdInit/FiniDigest */ + #include "lib/fsm.h" + #include "lib/rpmte_internal.h" /* XXX rpmfs */ ++#include "lib/rpmfi_internal.h" /* rpmfiSetOnChdir */ + #include "lib/rpmplugins.h" /* rpm plugins hooks */ + #include "lib/rpmug.h" + +@@ -406,17 +408,118 @@ static int fsmRmdir(const char *path) + return rc; + } + +-static int fsmMkdir(const char *path, mode_t mode) ++static int fsmMkdir(int dirfd, const char *path, mode_t mode) + { +- int rc = mkdir(path, (mode & 07777)); ++ int rc = mkdirat(dirfd, path, (mode & 07777)); + if (_fsm_debug) +- rpmlog(RPMLOG_DEBUG, " %8s (%s, 0%04o) %s\n", __func__, +- path, (unsigned)(mode & 07777), ++ rpmlog(RPMLOG_DEBUG, " %8s (%d %s, 0%04o) %s\n", __func__, ++ dirfd, path, (unsigned)(mode & 07777), + (rc < 0 ? strerror(errno) : "")); + if (rc < 0) rc = RPMERR_MKDIR_FAILED; + return rc; + } + ++static int fsmOpenat(int dirfd, const char *path, int flags) ++{ ++ struct stat lsb, sb; ++ int sflags = flags | O_NOFOLLOW; ++ int fd = openat(dirfd, path, sflags); ++ ++ /* ++ * Only ever follow symlinks by root or target owner. Since we can't ++ * open the symlink itself, the order matters: we stat the link *after* ++ * opening the target, and if the link ownership changed between the calls ++ * it could've only been the link owner or root. ++ */ ++ if (fd < 0 && errno == ELOOP && flags != sflags) { ++ int ffd = openat(dirfd, path, flags); ++ if (ffd >= 0 && fstatat(dirfd, path, &lsb, AT_SYMLINK_NOFOLLOW) == 0) { ++ if (fstat(ffd, &sb) == 0) { ++ if (lsb.st_uid == 0 || lsb.st_uid == sb.st_uid) { ++ fd = ffd; ++ } else { ++ close(ffd); ++ } ++ } ++ } ++ } ++ return fd; ++} ++ ++static int fsmDoMkDir(rpmPlugins plugins, int dirfd, const char *dn, ++ int owned, mode_t mode) ++{ ++ int rc; ++ rpmFsmOp op = (FA_CREATE); ++ if (!owned) ++ op |= FAF_UNOWNED; ++ ++ /* Run fsm file pre hook for all plugins */ ++ rc = rpmpluginsCallFsmFilePre(plugins, NULL, dn, mode, op); ++ ++ if (!rc) ++ rc = fsmMkdir(dirfd, dn, mode); ++ ++ if (!rc) { ++ rc = rpmpluginsCallFsmFilePrepare(plugins, NULL, dn, dn, mode, op); ++ } ++ ++ /* Run fsm file post hook for all plugins */ ++ rpmpluginsCallFsmFilePost(plugins, NULL, dn, mode, op, rc); ++ ++ if (!rc) { ++ rpmlog(RPMLOG_DEBUG, ++ "%s directory created with perms %04o\n", ++ dn, (unsigned)(mode & 07777)); ++ } ++ ++ return rc; ++} ++ ++static int ensureDir(rpmPlugins plugins, const char *p, int owned, int create) ++{ ++ char *path = xstrdup(p); ++ char *dp = path; ++ char *sp = NULL, *bn; ++ int oflags = O_RDONLY; ++ ++ int dirfd = fsmOpenat(-1, "/", oflags); ++ int fd = dirfd; /* special case of "/" */ ++ ++ while ((bn = strtok_r(dp, "/", &sp)) != NULL) { ++ struct stat sb; ++ fd = fsmOpenat(dirfd, bn, oflags); ++ ++ if (fd < 0 && errno == ENOENT && create) { ++ mode_t mode = S_IFDIR | (_dirPerms & 07777); ++ if (fsmDoMkDir(plugins, dirfd, bn, owned, mode) == 0) { ++ fd = fsmOpenat(dirfd, bn, oflags|O_NOFOLLOW); ++ } ++ } ++ ++ if (fd >= 0 && fstat(fd, &sb) == 0 && !S_ISDIR(sb.st_mode)) { ++ close(fd); ++ errno = ENOTDIR; ++ fd = -1; ++ } ++ ++ close(dirfd); ++ if (fd >= 0) { ++ dirfd = fd; ++ } else { ++ dirfd = -1; ++ rpmlog(RPMLOG_ERR, _("failed to open dir %s of %s: %s\n"), ++ bn, p, strerror(errno)); ++ break; ++ } ++ ++ dp = NULL; ++ } ++ ++ free(path); ++ return dirfd; ++} ++ + static int fsmMkfifo(const char *path, mode_t mode) + { + int rc = mkfifo(path, (mode & 07777)); +@@ -507,7 +610,7 @@ static int fsmMkdirs(rpmfiles files, rpmfs fs, rpmPlugins plugins) + rc = rpmpluginsCallFsmFilePre(plugins, NULL, dn, mode, op); + + if (!rc) +- rc = fsmMkdir(dn, mode); ++ rc = fsmMkdir(-1, dn, mode); + + if (!rc) { + rc = rpmpluginsCallFsmFilePrepare(plugins, NULL, dn, dn, +@@ -874,6 +977,21 @@ static void setFileState(rpmfs fs, int i) + } + } + ++struct diriter_s { ++ int dirfd; ++}; ++ ++static int onChdir(rpmfi fi, void *data) ++{ ++ struct diriter_s *di = data; ++ ++ if (di->dirfd >= 0) { ++ close(di->dirfd); ++ di->dirfd = -1; ++ } ++ return 0; ++} ++ + int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files, + rpmpsm psm, char ** failedFile) + { +@@ -890,6 +1008,7 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files, + char *tid = NULL; + struct filedata_s *fdata = xcalloc(fc, sizeof(*fdata)); + struct filedata_s *firstlink = NULL; ++ struct diriter_s di = { -1 }; + + /* transaction id used for temporary path suffix while installing */ + rasprintf(&tid, ";%08x", (unsigned)rpmtsGetTid(ts)); +@@ -932,6 +1051,7 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files, + rc = RPMERR_BAD_MAGIC; + goto exit; + } ++ rpmfiSetOnChdir(fi, onChdir, &di); + + /* Detect and create directories not explicitly in package. */ + if (!rc) +@@ -1063,6 +1063,16 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files, + if (!fp->suffix) { + rc = fsmBackup(fi, fp->action); + } ++ ++ if (di.dirfd == -1) { ++ di.dirfd = ensureDir(plugins, rpmfiDN(fi), 0, ++ (fp->action == FA_CREATE)); ++ if (di.dirfd == -1) { ++ rc = RPMERR_OPEN_FAILED; ++ break; ++ } ++ } ++ + /* Assume file does't exist when tmp suffix is in use */ + if (!fp->suffix) { + rc = fsmVerify(fp->fpath, fi); +@@ -980,7 +1110,7 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files, + mode_t mode = fp->sb.st_mode; + mode &= ~07777; + mode |= 00700; +- rc = fsmMkdir(fp->fpath, mode); ++ rc = fsmMkdir(di.dirfd, fp->fpath, mode); + } + } else if (S_ISLNK(fp->sb.st_mode)) { + if (rc == RPMERR_ENOENT) { +@@ -1022,6 +1152,8 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files, + fp->stage = FILE_UNPACK; + } + fi = rpmfiFree(fi); ++ close(di.dirfd); ++ di.dirfd = -1; + + if (!rc && fx < 0 && fx != RPMERR_ITER_END) + rc = fx; +-- +1.8.3.1 + diff --git a/backport-CVE-2021-35938.patch b/backport-CVE-2021-35938.patch new file mode 100644 index 0000000..4e5b3d4 --- /dev/null +++ b/backport-CVE-2021-35938.patch @@ -0,0 +1,40 @@ +From 25a435e90844ea98fe5eb7bef22c1aecf3a9c033 Mon Sep 17 00:00:00 2001 +From: Panu Matilainen <pmatilai@redhat.com> +Date: Mon, 14 Feb 2022 14:29:33 +0200 +Subject: [PATCH] Set file metadata via fd-based ops for everything but + symlinks + +Regular file ops are fd-based already, for the rest we need to open them +manually. Files with temporary suffix must never be followed, for +directories (and pre-existing FA_TOUCHed files) use the rpm symlink +"root or target owner allowed" rule wrt following. + +This mostly fixes CVE-2021-35938, but as we're not yet using dirfd-based +operatiosn for everything there are corner cases left undone. And then +there's the plugin API which needs updating for all this. +--- + lib/fsm.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/lib/fsm.c b/lib/fsm.c +index 913e9de..6f781c6 100644 +--- a/lib/fsm.c ++++ b/lib/fsm.c +@@ -1133,6 +1133,14 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files, + rc = RPMERR_UNKNOWN_FILETYPE; + } + ++ if (!rc && fd == -1 && !S_ISLNK(fp->sb.st_mode)) { ++ /* Only follow safe symlinks, and never on temporary files */ ++ fd = fsmOpenat(di.dirfd, fp->fpath, ++ fp->suffix ? AT_SYMLINK_NOFOLLOW : 0); ++ if (fd < 0) ++ rc = RPMERR_OPEN_FAILED; ++ } ++ + if (fd != firstlinkfile) + fsmClose(&fd); + } +-- +1.8.3.1 + 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 <ffesti@redhat.com> +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-Check-inside-root-when-querying-for-files.patch b/backport-Check-inside-root-when-querying-for-files.patch new file mode 100644 index 0000000..3759486 --- /dev/null +++ b/backport-Check-inside-root-when-querying-for-files.patch @@ -0,0 +1,38 @@ +From 3e820eaa4c8cb94a63338366cbf014dc5264eba2 Mon Sep 17 00:00:00 2001 +From: Florian Festi <ffesti@redhat.com> +Date: Tue, 25 Jul 2023 12:08:42 +0200 +Subject: [PATCH] Check inside --root when querying for files + +rpm -qf checks if the argument actually exists if it can't be found in +the rpmdb and gives different messages based on that. + +This was done without taking the root dir into account leading to wrong +messages if the file only exists in the root dir but not outside. + +Resolves: #2576 +--- + lib/query.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/lib/query.c b/lib/query.c +index e816241b7..dc2dc910b 100644 +--- a/lib/query.c ++++ b/lib/query.c +@@ -470,11 +470,13 @@ static rpmdbMatchIterator initQueryIterator(QVA_t qva, rpmts ts, const char * ar + + if (mi == NULL) { + struct stat sb; +- if (lstat(fn, &sb) != 0) ++ char * full_fn = rpmGetPath(rpmtsRootDir(ts), fn, NULL); ++ if (lstat(full_fn, &sb) != 0) + rpmlog(RPMLOG_ERR, _("file %s: %s\n"), fn, strerror(errno)); + else + rpmlog(RPMLOG_NOTICE, + _("file %s is not owned by any package\n"), fn); ++ free(full_fn); + } + + free(fn); +-- +2.27.0 + diff --git a/backport-Check-that-the-CRC-length-is-correct.patch b/backport-Check-that-the-CRC-length-is-correct.patch new file mode 100644 index 0000000..8506a45 --- /dev/null +++ b/backport-Check-that-the-CRC-length-is-correct.patch @@ -0,0 +1,27 @@ +From 1f03aba8b2881a5717af97065038fb056e02a2b3 Mon Sep 17 00:00:00 2001 +From: Demi Marie Obenour <demi@invisiblethingslab.com> +Date: Thu, 3 Feb 2022 20:42:02 -0500 +Subject: [PATCH] Check that the CRC length is correct + +Also fix a memory leak in an error path. +--- + rpmio/rpmpgp.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/rpmio/rpmpgp.c b/rpmio/rpmpgp.c +index 015c15a..d1966d3 100644 +--- a/rpmio/rpmpgp.c ++++ b/rpmio/rpmpgp.c +@@ -1444,7 +1444,8 @@ static pgpArmor decodePkts(uint8_t *b, uint8_t **pkt, size_t *pktlen) + + crcdec = NULL; + crclen = 0; +- if (rpmBase64Decode(crcenc, (void **)&crcdec, &crclen) != 0) { ++ if (rpmBase64Decode(crcenc, (void **)&crcdec, &crclen) != 0 || crclen != 3) { ++ crcdec = _free(crcdec); + ec = PGPARMOR_ERR_CRC_DECODE; + goto exit; + } +-- +1.8.3.1 + diff --git a/backport-Close-file-before-replacing-signed.patch b/backport-Close-file-before-replacing-signed.patch new file mode 100644 index 0000000..33fd5a3 --- /dev/null +++ b/backport-Close-file-before-replacing-signed.patch @@ -0,0 +1,27 @@ +From 9b4c50dd67c337f2d3c927cdd01ae4433bb08b61 Mon Sep 17 00:00:00 2001 +From: Evgeniy Taishev <e.taishev@omp.ru> +Date: Mon, 17 Jan 2022 22:07:13 +0300 +Subject: [PATCH] Close file before replacing signed + +--- + sign/rpmgensig.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/sign/rpmgensig.c b/sign/rpmgensig.c +index e88f9b7..b8c68ce 100644 +--- a/sign/rpmgensig.c ++++ b/sign/rpmgensig.c +@@ -695,6 +695,10 @@ static int rpmSign(const char *rpm, int deleting, int flags) + if (copyFile(&fd, rpm, &ofd, trpm) == 0) { + struct stat st; + ++ /* File must be closed before deletion due to different file locking in some file systems*/ ++ if (fd) (void) closeFile(&fd); ++ if (ofd) (void) closeFile(&ofd); ++ + /* Move final target into place, restore file permissions. */ + if (stat(rpm, &st) == 0 && unlink(rpm) == 0 && + rename(trpm, rpm) == 0 && chmod(rpm, st.st_mode) == 0) { +-- +1.8.3.1 + diff --git a/backport-Consolidate-skipped-hardlink-with-content-case-with-.patch b/backport-Consolidate-skipped-hardlink-with-content-case-with-.patch new file mode 100644 index 0000000..e992dca --- /dev/null +++ b/backport-Consolidate-skipped-hardlink-with-content-case-with-.patch @@ -0,0 +1,56 @@ +From cc22fc694d30a64862f0b16d137deaab5416382d Mon Sep 17 00:00:00 2001 +From: Panu Matilainen <pmatilai@redhat.com> +Date: Fri, 11 Feb 2022 13:05:45 +0200 +Subject: [PATCH] Consolidate skipped hardlink with content case with the + others + +Handling this in a separate clause makes the logic much clearer and +(in theory at least) lets us handle hardlinks to any content, not +just regular files. +--- + lib/fsm.c | 20 ++++++++++---------- + 1 file changed, 10 insertions(+), 10 deletions(-) + +diff --git a/lib/fsm.c b/lib/fsm.c +index ec6ee2c..82610c7 100644 +--- a/lib/fsm.c ++++ b/lib/fsm.c +@@ -832,9 +832,18 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files, + while (!rc && (fx = rpmfiNext(fi)) >= 0) { + struct filedata_s *fp = &fdata[fx]; + ++ /* ++ * Tricksy case: this file is a being skipped, but it's part of ++ * a hardlinked set and has the actual content linked with it. ++ * Write the content to the first non-skipped file of the set ++ * instead. ++ */ ++ if (fp->skip && firstlink && rpmfiArchiveHasContent(fi)) ++ fp = firstlink; ++ + if (!fp->skip) { + /* Directories replacing something need early backup */ +- if (!fp->suffix) { ++ if (!fp->suffix && fp != firstlink) { + rc = fsmBackup(fi, fp->action); + } + +@@ -904,15 +913,6 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files, + if (!IS_DEV_LOG(fp->fpath)) + rc = RPMERR_UNKNOWN_FILETYPE; + } +- } else if (firstlink && rpmfiArchiveHasContent(fi)) { +- /* +- * Tricksy case: this file is a being skipped, but it's part of +- * a hardlinked set and has the actual content linked with it. +- * Write the content to the first non-skipped file of the set +- * instead. +- */ +- rc = fsmMkfile(fi, firstlink, files, psm, nodigest, +- &firstlink, &firstlinkfile); + } + + /* Notify on success. */ +-- +1.8.3.1 + diff --git a/backport-Convert-the-file-creation-steps-the-at-family-of-cal.patch b/backport-Convert-the-file-creation-steps-the-at-family-of-cal.patch new file mode 100644 index 0000000..1b4de6f --- /dev/null +++ b/backport-Convert-the-file-creation-steps-the-at-family-of-cal.patch @@ -0,0 +1,189 @@ +From b599e28112ce5cee98b9ffa7bd96886ec5155e9c Mon Sep 17 00:00:00 2001 +From: Panu Matilainen <pmatilai@redhat.com> +Date: Fri, 11 Feb 2022 15:35:16 +0200 +Subject: [PATCH] Convert the file creation steps the *at() family of calls + +Supposedly no functional changes here, we just need all these things +converted before we can swap over to relative paths. +--- + configure.ac | 2 +- + lib/fsm.c | 59 ++++++++++++++++++++++++++++++----------------------------- + 2 files changed, 31 insertions(+), 30 deletions(-) + +diff --git a/configure.ac b/configure.ac +index 0099e5f..ac90037 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -581,7 +581,7 @@ AC_CHECK_FUNCS([secure_getenv __secure_getenv]) + AC_CHECK_FUNCS( + [mkstemp getcwd basename dirname realpath setenv unsetenv regcomp lchown \ + utimes getline localtime_r statvfs getaddrinfo \ +- openat mkdirat fstatat ], ++ openat mkdirat fstatat linkat symlinkat mkfifoat mknodat ], + [], [AC_MSG_ERROR([function required by rpm])]) + + AC_LIBOBJ(fnmatch) +diff --git a/lib/fsm.c b/lib/fsm.c +index ae1bd3f..8443954 100644 +--- a/lib/fsm.c ++++ b/lib/fsm.c +@@ -214,13 +214,13 @@ const char * dnlNextIterator(DNLI_t dnli) + return dn; + } + +-static int fsmLink(const char *opath, const char *path) ++static int fsmLink(int odirfd, const char *opath, int dirfd, const char *path) + { +- int rc = link(opath, path); ++ int rc = linkat(odirfd, opath, dirfd, path, 0); + + if (_fsm_debug) { +- rpmlog(RPMLOG_DEBUG, " %8s (%s, %s) %s\n", __func__, +- opath, path, (rc < 0 ? strerror(errno) : "")); ++ rpmlog(RPMLOG_DEBUG, " %8s (%d %s, %d %s) %s\n", __func__, ++ odirfd, opath, dirfd, path, (rc < 0 ? strerror(errno) : "")); + } + + if (rc < 0) +@@ -139,17 +139,18 @@ static int fsmClose(FD_t *wfdp) + return rc; + } + +-static int fsmOpen(FD_t *wfdp, const char *dest) ++static int fsmOpen(FD_t *wfdp, int dirfd, const char *dest) + { + int rc = 0; + /* Create the file with 0200 permissions (write by owner). */ +- { +- mode_t old_umask = umask(0577); +- *wfdp = Fopen(dest, "wx.ufdio"); +- umask(old_umask); ++ int fd = openat(dirfd, dest, O_WRONLY|O_EXCL|O_CREAT, 0200); ++ ++ if (fd >= 0) { ++ *wfdp = fdDup(fd); ++ close(fd); + } + +- if (Ferror(*wfdp)) ++ if (fd < 0 || Ferror(*wfdp)) + rc = RPMERR_OPEN_FAILED; + + if (_fsm_debug) { +@@ -174,7 +175,7 @@ static int fsmUnpack(rpmfi fi, FD_t fd, rpmpsm psm, int nodigest) + return rc; + } + +-static int fsmMkfile(rpmfi fi, struct filedata_s *fp, rpmfiles files, ++static int fsmMkfile(int dirfd, rpmfi fi, struct filedata_s *fp, rpmfiles files, + rpmpsm psm, int nodigest, + struct filedata_s ** firstlink, FD_t *firstlinkfile) + { +@@ -183,7 +184,7 @@ static int fsmMkfile(rpmfi fi, struct filedata_s *fp, rpmfiles files, + + if (*firstlink == NULL) { + /* First encounter, open file for writing */ +- rc = fsmOpen(&fd, fp->fpath); ++ rc = fsmOpen(&fd, dirfd, fp->fpath); + /* If it's a part of a hardlinked set, the content may come later */ + if (fp->sb.st_nlink > 1) { + *firstlink = fp; +@@ -192,7 +193,7 @@ static int fsmMkfile(rpmfi fi, struct filedata_s *fp, rpmfiles files, + } else { + /* Create hard links for others and avoid redundant metadata setting */ + if (*firstlink != fp) { +- rc = fsmLink((*firstlink)->fpath, fp->fpath); ++ rc = fsmLink(dirfd, (*firstlink)->fpath, dirfd, fp->fpath); + } + fd = *firstlinkfile; + } +@@ -382,13 +383,13 @@ static int ensureDir(rpmPlugins plugins, const char *p, int owned, int create) + return dirfd; + } + +-static int fsmMkfifo(const char *path, mode_t mode) ++static int fsmMkfifo(int dirfd, const char *path, mode_t mode) + { +- int rc = mkfifo(path, (mode & 07777)); ++ int rc = mkfifoat(dirfd, path, (mode & 07777)); + + if (_fsm_debug) { +- rpmlog(RPMLOG_DEBUG, " %8s (%s, 0%04o) %s\n", +- __func__, path, (unsigned)(mode & 07777), ++ rpmlog(RPMLOG_DEBUG, " %8s (%d %s, 0%04o) %s\n", ++ __func__, dirfd, path, (unsigned)(mode & 07777), + (rc < 0 ? strerror(errno) : "")); + } + +@@ -398,14 +399,14 @@ static int fsmMkfifo(const char *path, mode_t mode) + return rc; + } + +-static int fsmMknod(const char *path, mode_t mode, dev_t dev) ++static int fsmMknod(int dirfd, const char *path, mode_t mode, dev_t dev) + { + /* FIX: check S_IFIFO or dev != 0 */ +- int rc = mknod(path, (mode & ~07777), dev); ++ int rc = mknodat(dirfd, path, (mode & ~07777), dev); + + if (_fsm_debug) { +- rpmlog(RPMLOG_DEBUG, " %8s (%s, 0%o, 0x%x) %s\n", +- __func__, path, (unsigned)(mode & ~07777), ++ rpmlog(RPMLOG_DEBUG, " %8s (%d %s, 0%o, 0x%x) %s\n", ++ __func__, dirfd, path, (unsigned)(mode & ~07777), + (unsigned)dev, (rc < 0 ? strerror(errno) : "")); + } + +@@ -440,13 +441,13 @@ static void fsmDebug(const char *fpath, rpmFileAction action, + (fpath ? fpath : "")); + } + +-static int fsmSymlink(const char *opath, const char *path) ++static int fsmSymlink(const char *opath, int dirfd, const char *path) + { +- int rc = symlink(opath, path); ++ int rc = symlinkat(opath, dirfd, path); + + if (_fsm_debug) { +- rpmlog(RPMLOG_DEBUG, " %8s (%s, %s) %s\n", __func__, +- opath, path, (rc < 0 ? strerror(errno) : "")); ++ rpmlog(RPMLOG_DEBUG, " %8s (%s, %d %s) %s\n", __func__, ++ opath, dirfd, path, (rc < 0 ? strerror(errno) : "")); + } + + if (rc < 0) +@@ -884,7 +885,7 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files, + + if (S_ISREG(fp->sb.st_mode)) { + if (rc == RPMERR_ENOENT) { +- rc = fsmMkfile(fi, fp, files, psm, nodigest, ++ rc = fsmMkfile(di.dirfd, fi, fp, files, psm, nodigest, + &firstlink, &firstlinkfile); + } + } else if (S_ISDIR(fp->sb.st_mode)) { +@@ -896,19 +897,19 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files, + } + } else if (S_ISLNK(fp->sb.st_mode)) { + if (rc == RPMERR_ENOENT) { +- rc = fsmSymlink(rpmfiFLink(fi), fp->fpath); ++ rc = fsmSymlink(rpmfiFLink(fi), di.dirfd, fp->fpath); + } + } else if (S_ISFIFO(fp->sb.st_mode)) { + /* This mimics cpio S_ISSOCK() behavior but probably isn't right */ + if (rc == RPMERR_ENOENT) { +- rc = fsmMkfifo(fp->fpath, 0000); ++ rc = fsmMkfifo(di.dirfd, fp->fpath, 0000); + } + } else if (S_ISCHR(fp->sb.st_mode) || + S_ISBLK(fp->sb.st_mode) || + S_ISSOCK(fp->sb.st_mode)) + { + if (rc == RPMERR_ENOENT) { +- rc = fsmMknod(fp->fpath, fp->sb.st_mode, fp->sb.st_rdev); ++ rc = fsmMknod(di.dirfd, fp->fpath, fp->sb.st_mode, fp->sb.st_rdev); + } + } else { + /* XXX Special case /dev/log, which shouldn't be packaged anyways */ +-- +1.8.3.1 + diff --git a/backport-Fix-BANames-leak-in-handlePreambleTag.patch b/backport-Fix-BANames-leak-in-handlePreambleTag.patch new file mode 100644 index 0000000..417980f --- /dev/null +++ b/backport-Fix-BANames-leak-in-handlePreambleTag.patch @@ -0,0 +1,26 @@ +From 7fcdfd3b40f69af6a1d4980683859eef05f39b4e Mon Sep 17 00:00:00 2001 +From: xujing <xujing125@huawei.com> +Date: Fri, 25 Nov 2022 16:48:34 +0800 +Subject: [PATCH 1/5] Fix BANames leak in handlePreambleTag + +The "BANames" is alloced from popParseArgvString but not freed +when spec->packages != pkg. Fix it. +--- + build/parsePreamble.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/build/parsePreamble.c b/build/parsePreamble.c +index 119551cf6..c4d137cf7 100644 +--- a/build/parsePreamble.c ++++ b/build/parsePreamble.c +@@ -961,6 +961,7 @@ static rpmRC handlePreambleTag(rpmSpec spec, Package pkg, rpmTagVal tag, + BANames = _free(BANames); + goto exit; + } ++ BANames = _free(BANames); + headerPutString(pkg->header, RPMTAG_ARCH, "noarch"); + } + if (!BACount) +-- +2.27.0 + diff --git a/backport-Fix-Header-leak-when-running-rpm2cpio.patch b/backport-Fix-Header-leak-when-running-rpm2cpio.patch new file mode 100644 index 0000000..395234f --- /dev/null +++ b/backport-Fix-Header-leak-when-running-rpm2cpio.patch @@ -0,0 +1,29 @@ +From cf27c6f4963dcf27302d0f4fa39d7787dd03f942 Mon Sep 17 00:00:00 2001 +From: xujing <xujing125@huawei.com> +Date: Fri, 25 Nov 2022 17:18:33 +0800 +Subject: [PATCH] Fix Header leak when running rpm2cpio + +Header "h" is alloced in rpmReadPackageFile but not freed when +running rpm2cpio. Fix it. Remove redundant whitespace between +the Fclose()'s too while at it for logical cleanup grouping. +--- + rpm2cpio.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/rpm2cpio.c b/rpm2cpio.c +index fcc3b3079..940d6ce38 100644 +--- a/rpm2cpio.c ++++ b/rpm2cpio.c +@@ -96,8 +96,8 @@ int main(int argc, char *argv[]) + */ + rc = (ufdCopy(gzdi, fdo) >= payload_size) ? EXIT_SUCCESS : EXIT_FAILURE; + ++ headerFree(h); + Fclose(fdo); +- + Fclose(gzdi); /* XXX gzdi == fdi */ + + return rc; +-- +2.33.0 + 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 <demi@invisiblethingslab.com> +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-__cplusplus-misspelled-as-_cplusplus.patch b/backport-Fix-__cplusplus-misspelled-as-_cplusplus.patch new file mode 100644 index 0000000..26e5cb8 --- /dev/null +++ b/backport-Fix-__cplusplus-misspelled-as-_cplusplus.patch @@ -0,0 +1,39 @@ +From 989d7c593c7ab12e17ea8f486856bafac6a1ae37 Mon Sep 17 00:00:00 2001 +From: Peter Pentchev <roam@ringlet.net> +Date: Sat, 27 Nov 2021 00:43:41 +0200 +Subject: [PATCH] Fix __cplusplus misspelled as _cplusplus. + +--- + sign/rpmsignfiles.h | 2 +- + sign/rpmsignverity.h | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/sign/rpmsignfiles.h b/sign/rpmsignfiles.h +index 2ff623c..a21a006 100644 +--- a/sign/rpmsignfiles.h ++++ b/sign/rpmsignfiles.h +@@ -19,7 +19,7 @@ extern "C" { + RPM_GNUC_INTERNAL + rpmRC rpmSignFiles(Header sigh, Header h, const char *key, char *keypass); + +-#ifdef _cplusplus ++#ifdef __cplusplus + } + #endif + +diff --git a/sign/rpmsignverity.h b/sign/rpmsignverity.h +index d869e8d..16e6c98 100644 +--- a/sign/rpmsignverity.h ++++ b/sign/rpmsignverity.h +@@ -29,7 +29,7 @@ RPM_GNUC_INTERNAL + rpmRC rpmSignVerity(FD_t fd, Header sigh, Header h, char *key, + char *keypass, char *cert, uint16_t algo); + +-#ifdef _cplusplus ++#ifdef __cplusplus + } + #endif + +-- +1.8.3.1 + diff --git a/backport-Fix-a-copy-paste-help-description-of-whatconflicts-R.patch b/backport-Fix-a-copy-paste-help-description-of-whatconflicts-R.patch new file mode 100644 index 0000000..ad4d1e7 --- /dev/null +++ b/backport-Fix-a-copy-paste-help-description-of-whatconflicts-R.patch @@ -0,0 +1,26 @@ +From 03525592c944957f3b7b200b7daeb9f615cdcde7 Mon Sep 17 00:00:00 2001 +From: Panu Matilainen <pmatilai@redhat.com> +Date: Tue, 23 May 2023 12:46:22 +0300 +Subject: [PATCH] Fix a copy-paste --help description of --whatconflicts + (RhBug:2208661) + +--- + lib/poptQV.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/poptQV.c b/lib/poptQV.c +index ac8e8975d..8bd91c652 100644 +--- a/lib/poptQV.c ++++ b/lib/poptQV.c +@@ -108,7 +108,7 @@ struct poptOption rpmQVSourcePoptTable[] = { + { "verify", 'V', POPT_ARGFLAG_DOC_HIDDEN, NULL, 'V', + N_("rpm verify mode"), NULL }, + { "whatconflicts", '\0', 0, 0, POPT_WHATCONFLICTS, +- N_("query/verify the package(s) which require a dependency"), "CAPABILITY" }, ++ N_("query/verify the package(s) which conflict with a dependency"), "CAPABILITY" }, + { "whatrequires", '\0', 0, 0, POPT_WHATREQUIRES, + N_("query/verify the package(s) which require a dependency"), "CAPABILITY" }, + { "whatobsoletes", '\0', 0, 0, POPT_WHATOBSOLETES, +-- +2.27.0 + 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 <pmatilai@redhat.com> +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-a-segfault-on-a-non-stringable-argument-to-macro.patch b/backport-Fix-a-segfault-on-a-non-stringable-argument-to-macro.patch new file mode 100644 index 0000000..541c6c3 --- /dev/null +++ b/backport-Fix-a-segfault-on-a-non-stringable-argument-to-macro.patch @@ -0,0 +1,58 @@ +From 856ddc334174fd37fe4ce81bc9f9f11a08cf6c81 Mon Sep 17 00:00:00 2001 +From: Panu Matilainen <pmatilai@redhat.com> +Date: Fri, 17 Mar 2023 12:53:42 +0200 +Subject: [PATCH] Fix a segfault on a non-stringable argument to macro call + from Lua + +When natively calling a parametric macro from Lua, with the arguments +inside a table, we can't assume lua_tostring() always succeeds as it +can fail eg on a table. Report the error instead of crashing in argvAdd(), +and add a test as well. +--- + rpmio/rpmlua.c | 9 +++++++-- + tests/rpmmacro.at | 9 +++++++++ + 2 files changed, 16 insertions(+), 2 deletions(-) + +diff --git a/rpmio/rpmlua.c b/rpmio/rpmlua.c +index 6c42af792..0e3685713 100644 +--- a/rpmio/rpmlua.c ++++ b/rpmio/rpmlua.c +@@ -1178,8 +1178,13 @@ static int mc_call(lua_State *L) + + for (int i = 1; i <= nitem; i++) { + lua_rawgeti(L, 1, i); +- argvAdd(&argv, lua_tostring(L, -1)); +- lua_pop(L, 1); ++ const char *s= lua_tostring(L, -1); ++ if (s) { ++ argvAdd(&argv, s); ++ lua_pop(L, 1); ++ } else { ++ luaL_argerror(L, i, "cannot convert to string"); ++ } + } + + if (rpmExpandThisMacro(*mc, name, argv, &buf, 0) >= 0) { +diff --git a/tests/rpmmacro.at b/tests/rpmmacro.at +index 55b7d5fa5..22d873e81 100644 +--- a/tests/rpmmacro.at ++++ b/tests/rpmmacro.at +@@ -713,6 +713,15 @@ nil + 1:%{?aaa} 2:%{yyy} + that + ]) ++ ++AT_CHECK([[ ++runroot rpm \ ++ --eval "%{lua:macros.defined({1,2,{}})}" ++]], ++[1], ++[], ++[[error: lua script failed: [string "<lua>"]:1: bad argument #3 to 'defined' (cannot convert to string) ++]]) + AT_CLEANUP + + AT_SETUP([lua macros recursion]) +-- +2.27.0 + 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 <pmatilai@redhat.com> +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-eiu-sourceURL-info-leak-in-rpmInstall.patch b/backport-Fix-eiu-sourceURL-info-leak-in-rpmInstall.patch new file mode 100644 index 0000000..bcddb75 --- /dev/null +++ b/backport-Fix-eiu-sourceURL-info-leak-in-rpmInstall.patch @@ -0,0 +1,31 @@ +From 084c64d5ea0e1a309d3b57dc95926eb1536d0a7a Mon Sep 17 00:00:00 2001 +From: xujing <xujing125@huawei.com> +Date: Thu, 24 Nov 2022 11:43:28 +0800 +Subject: [PATCH 1/3] Fix eiu->sourceURL info leak in rpmInstall() + +When installing source rpms, eiu->sourceURL info is leaked. +--- + lib/rpminstall.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/lib/rpminstall.c b/lib/rpminstall.c +index 097599681..eb68deb4d 100644 +--- a/lib/rpminstall.c ++++ b/lib/rpminstall.c +@@ -672,8 +672,13 @@ exit: + eiu->pkgURL[i] = _free(eiu->pkgURL[i]); + } + } ++ if (eiu->sourceURL != NULL) { ++ for (i = 0; i < eiu->numSRPMS; i++) ++ eiu->sourceURL[i] = _free(eiu->sourceURL[i]); ++ } + eiu->pkgState = _free(eiu->pkgState); + eiu->pkgURL = _free(eiu->pkgURL); ++ eiu->sourceURL = _free(eiu->sourceURL); + eiu->argv = _free(eiu->argv); + rc = eiu->numFailed; + free(eiu); +-- +2.33.0 + diff --git a/backport-Fix-elf-leak-in-getElfColor.patch b/backport-Fix-elf-leak-in-getElfColor.patch new file mode 100644 index 0000000..cf87488 --- /dev/null +++ b/backport-Fix-elf-leak-in-getElfColor.patch @@ -0,0 +1,28 @@ +From 01196e00beefc2ba6f7f0787350c5dd76891829a Mon Sep 17 00:00:00 2001 +From: xujing <xujing125@huawei.com> +Date: Fri, 25 Nov 2022 17:11:22 +0800 +Subject: [PATCH 3/5] Fix elf leak in getElfColor + +The "elf" is leaked in getElfColor when gelf_getehdr return fail. +--- + build/rpmfc.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/build/rpmfc.c b/build/rpmfc.c +index d35c148b9..06205469c 100644 +--- a/build/rpmfc.c ++++ b/build/rpmfc.c +@@ -1145,8 +1145,9 @@ static uint32_t getElfColor(const char *fn) + color = RPMFC_ELF32; + break; + } +- elf_end(elf); + } ++ if (elf) ++ elf_end(elf); + close(fd); + } + #endif +-- +2.27.0 + diff --git a/backport-Fix-file-leak-when-src-rpm-in-URL-format-is-used-for.patch b/backport-Fix-file-leak-when-src-rpm-in-URL-format-is-used-for.patch new file mode 100644 index 0000000..de7f89f --- /dev/null +++ b/backport-Fix-file-leak-when-src-rpm-in-URL-format-is-used-for.patch @@ -0,0 +1,33 @@ +From 0b34438ccc3fdcbdaa6226d2398df88cc7439603 Mon Sep 17 00:00:00 2001 +From: xujing <xujing125@huawei.com> +Date: Thu, 24 Nov 2022 17:16:46 +0800 +Subject: [PATCH 2/3] Fix file leak when src rpm in URL format is used for + installation + +%{_tmppath}/rpm-tmp.* is created by rpmMkTempFile() when src rpm in +URL format is used for installation, which is leaked. +--- + lib/rpminstall.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/lib/rpminstall.c b/lib/rpminstall.c +index eb68deb4d..b392cf1c3 100644 +--- a/lib/rpminstall.c ++++ b/lib/rpminstall.c +@@ -673,8 +673,12 @@ exit: + } + } + if (eiu->sourceURL != NULL) { +- for (i = 0; i < eiu->numSRPMS; i++) ++ for (i = 0; i < eiu->numSRPMS; i++) { ++ if (eiu->sourceURL[i] == NULL) continue; ++ if (eiu->pkgState[i] == 1) ++ (void) unlink(eiu->sourceURL[i]); + eiu->sourceURL[i] = _free(eiu->sourceURL[i]); ++ } + } + eiu->pkgState = _free(eiu->pkgState); + eiu->pkgURL = _free(eiu->pkgURL); +-- +2.33.0 + diff --git a/backport-Fix-fileleak-and-memleak-in-rpmInstall.patch b/backport-Fix-fileleak-and-memleak-in-rpmInstall.patch new file mode 100644 index 0000000..fdf3c56 --- /dev/null +++ b/backport-Fix-fileleak-and-memleak-in-rpmInstall.patch @@ -0,0 +1,63 @@ +From f0f983b145583eeed618cf3cbc5d39bedd8af5a5 Mon Sep 17 00:00:00 2001 +From: xujing <xujing125@huawei.com> +Date: Mon, 28 Nov 2022 11:19:20 +0800 +Subject: [PATCH 2/3] Fix fileleak and memleak in rpmInstall + +The "*eiu->fnp" from "eiu->pkgURL[eiu->pkgx]" which is alloced. when +Fopen or rpmReadPackageFile fails in tryReadHeader, "*eiu->fnp" is +set to NULL but not freed. In addition, if "eiu->pkgState[eiu->pkgx]" +is set, the file is leaked too. Fix it. + +Only resource free is added, no other logic change. +--- + lib/rpminstall.c | 12 +++++++++--- + 1 file changed, 9 insertions(+), 3 deletions(-) + +diff --git a/lib/rpminstall.c b/lib/rpminstall.c +index b392cf1c3..90474fabf 100644 +--- a/lib/rpminstall.c ++++ b/lib/rpminstall.c +@@ -355,7 +355,6 @@ static int tryReadHeader(rpmts ts, struct rpmEIU * eiu, Header * hdrp) + fd = NULL; + } + eiu->numFailed++; +- *eiu->fnp = NULL; + return RPMRC_FAIL; + } + +@@ -371,7 +370,6 @@ static int tryReadHeader(rpmts ts, struct rpmEIU * eiu, Header * hdrp) + if (eiu->rpmrc == RPMRC_FAIL) { + rpmlog(RPMLOG_ERR, _("%s cannot be installed\n"), *eiu->fnp); + eiu->numFailed++; +- *eiu->fnp = NULL; + } + + return RPMRC_OK; +@@ -554,8 +552,12 @@ restart: + rpmlog(RPMLOG_DEBUG, "============== %s\n", *eiu->fnp); + (void) urlPath(*eiu->fnp, &fileName); + +- if (tryReadHeader(ts, eiu, &h) == RPMRC_FAIL) ++ if (tryReadHeader(ts, eiu, &h) == RPMRC_FAIL) { ++ if (eiu->pkgState[eiu->fnp - eiu->pkgURL] == 1) ++ (void) unlink(*eiu->fnp); ++ *eiu->fnp = _free(*eiu->fnp); + continue; ++ } + + if (eiu->rpmrc == RPMRC_NOTFOUND) { + rc = tryReadManifest(eiu); +@@ -564,6 +566,10 @@ restart: + headerFree(h); + goto restart; + } ++ } else if (eiu->rpmrc == RPMRC_FAIL) { ++ if (eiu->pkgState[eiu->fnp - eiu->pkgURL] == 1) ++ (void) unlink(*eiu->fnp); ++ *eiu->fnp = _free(*eiu->fnp); + } + + if (headerIsSource(h)) { +-- +2.27.0 + diff --git a/backport-Fix-fileleak-when-urlGetFile-fails-in-rpmInstall.patch b/backport-Fix-fileleak-when-urlGetFile-fails-in-rpmInstall.patch new file mode 100644 index 0000000..7b5bb6e --- /dev/null +++ b/backport-Fix-fileleak-when-urlGetFile-fails-in-rpmInstall.patch @@ -0,0 +1,30 @@ +From af81c95114bc2c01f005f15f17646a5188b5855d Mon Sep 17 00:00:00 2001 +From: xujing <xujing125@huawei.com> +Date: Mon, 28 Nov 2022 11:34:24 +0800 +Subject: [PATCH 3/3] Fix fileleak when urlGetFile fails in rpmInstall + +The "tfn" is created by calling rpmMkTempFile but not unlinked when +urlGetFile fails in rpmInstall. Fix it. +--- + lib/rpminstall.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/lib/rpminstall.c b/lib/rpminstall.c +index 90474fabf..c89ca30b5 100644 +--- a/lib/rpminstall.c ++++ b/lib/rpminstall.c +@@ -520,7 +520,10 @@ restart: + _("skipping %s - transfer failed\n"), fileURL); + eiu->numFailed++; + eiu->pkgURL[eiu->pkgx] = NULL; +- tfn = _free(tfn); ++ if (tfn) { ++ (void) unlink(tfn); ++ tfn = _free(tfn); ++ } + break; + } + eiu->pkgState[eiu->pkgx] = 1; +-- +2.27.0 + diff --git a/backport-Fix-h-blob-leak-when-installing-source-rpms.patch b/backport-Fix-h-blob-leak-when-installing-source-rpms.patch new file mode 100644 index 0000000..a29f84e --- /dev/null +++ b/backport-Fix-h-blob-leak-when-installing-source-rpms.patch @@ -0,0 +1,28 @@ +From 86c1d9738de58eb8f8844c5345baeb578ace9485 Mon Sep 17 00:00:00 2001 +From: xujing <xujing125@huawei.com> +Date: Thu, 24 Nov 2022 17:33:53 +0800 +Subject: [PATCH 3/3] Fix h->blob leak when installing source rpms + +When installing source rpms, "ei" is malloced and is saved in +blob->ei by rpmReadPackageFile->rpmpkgRead->hdrblobRead, and then +blob->ei is saved in h->blob by rpmReadPackageFile->hdrblobImport, +which is leaked during installation. +--- + lib/header.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/lib/header.c b/lib/header.c +index 31d2fca30..004102dd2 100644 +--- a/lib/header.c ++++ b/lib/header.c +@@ -241,6 +241,7 @@ Header headerFree(Header h) + } + h->index = _free(h->index); + } ++ h->blob = _free(h->blob); + + h = _free(h); + return NULL; +-- +2.33.0 + 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 <justus@sequoia-pgp.org> +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 <justus@sequoia-pgp.org> +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-header-leak-in-rpmInstall.patch b/backport-Fix-header-leak-in-rpmInstall.patch new file mode 100644 index 0000000..67dc581 --- /dev/null +++ b/backport-Fix-header-leak-in-rpmInstall.patch @@ -0,0 +1,42 @@ +From 15a0c73f4698bc58fa2a633d46527c7813150f3a Mon Sep 17 00:00:00 2001 +From: xujing <xujing125@huawei.com> +Date: Thu, 24 Nov 2022 10:43:11 +0800 +Subject: [PATCH] Fix header leak in rpmInstall() + +When rpm installs a package, the header from tryReadHeader() +in rpmInstall() is leaked in some cases. +--- + lib/rpminstall.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/lib/rpminstall.c b/lib/rpminstall.c +index 9167dbdde..097599681 100644 +--- a/lib/rpminstall.c ++++ b/lib/rpminstall.c +@@ -561,13 +561,14 @@ restart: + rc = tryReadManifest(eiu); + if (rc == RPMRC_OK) { + eiu->prevx++; ++ headerFree(h); + goto restart; + } + } + + if (headerIsSource(h)) { ++ headerFree(h); + if (ia->installInterfaceFlags & INSTALL_FRESHEN) { +- headerFree(h); + continue; + } + rpmlog(RPMLOG_DEBUG, "\tadded source package [%d]\n", +@@ -592,6 +593,7 @@ restart: + rpmlog(RPMLOG_ERR, _("package %s is not relocatable\n"), + headerGetString(h, RPMTAG_NAME)); + eiu->numFailed++; ++ headerFree(h); + goto exit; + } + } +-- +2.33.0 + diff --git a/backport-Fix-install-of-block-and-character-special-files-219.patch b/backport-Fix-install-of-block-and-character-special-files-219.patch new file mode 100644 index 0000000..047b6d1 --- /dev/null +++ b/backport-Fix-install-of-block-and-character-special-files-219.patch @@ -0,0 +1,110 @@ +From 28c92fd54c93371c3062664d8a938438a2be88d6 Mon Sep 17 00:00:00 2001 +From: Panu Matilainen <pmatilai@redhat.com> +Date: Fri, 13 Jan 2023 08:57:27 +0200 +Subject: [PATCH] Fix install of block and character special files (#2195, + #2275) + +While it's possible to open special files, they are, well, special and +have "side-effects" also known as, ahem, semantics. Opening a device +file in Unix means accessing that *device*, and FIFOs have their own +semantics. In other words, for rpm's purposes, we should never EVER +open these files as a part of the install / permission setting etc. +Fix this major brainfart in 25a435e90844ea98fe5eb7bef22c1aecf3a9c033. + +OTOH this forces us back to the less secure path based operations for +these files, which is what we were trying to avoid in the first place. +There always was a tiny race between create + open for these (because +there's no atomic way to create + open anything but regular files) but +this opens up the window quite a bit. +Nobody should be placing device nodes in user-owned directories but +FIFO's may be a different story. + +We haven't had tests for device nodes because it requires privileges the +test-suite usually doesn't have, not testing FIFOs I have no excuse for. +Add that test now. + +Fixes: #2195, #2275 +--- + lib/fsm.c | 4 +++- + tests/data/SPECS/fifo.spec | 16 ++++++++++++++++ + tests/Makefile.am | 2 +- + tests/rpmi.at | 15 +++++++++++++++ + 4 files changed, 35 insertions(+), 2 deletions(-) + create mode 100644 tests/data/SPECS/fifo.spec + +diff --git a/lib/fsm.c b/lib/fsm.c +index e38155df7..052416641 100644 +--- a/lib/fsm.c ++++ b/lib/fsm.c +@@ -1014,7 +1014,9 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files, + rc = RPMERR_UNKNOWN_FILETYPE; + } + +- if (!rc && fd == -1 && !S_ISLNK(fp->sb.st_mode)) { ++ /* Special files require path-based ops */ ++ int mayopen = S_ISREG(fp->sb.st_mode) || S_ISDIR(fp->sb.st_mode); ++ if (!rc && fd == -1 && mayopen) { + /* Only follow safe symlinks, and never on temporary files */ + fd = fsmOpenat(di.dirfd, fp->fpath, + fp->suffix ? AT_SYMLINK_NOFOLLOW : 0); +diff --git a/tests/data/SPECS/fifo.spec b/tests/data/SPECS/fifo.spec +new file mode 100644 +index 000000000..20b30b243 +--- /dev/null ++++ b/tests/data/SPECS/fifo.spec +@@ -0,0 +1,16 @@ ++Name: fifo ++Version: 1.0 ++Release: 1 ++Group: Testing ++License: GPL ++Summary: Testing fifo behavior ++BuildArch: noarch ++ ++%description ++%{summary} ++ ++%install ++mknod ${RPM_BUILD_ROOT}/test-fifo p ++ ++%files ++/test-fifo +diff --git a/tests/Makefile.am b/tests/Makefile.am +index 04fa1e5..1b12148 100644 +--- a/tests/Makefile.am ++++ b/tests/Makefile.am +@@ -174,7 +174,7 @@ populate_testing: + for d in dev etc magic tmp var; do if [ ! -d testing/$${d} ]; then mkdir testing/$${d}; fi; done + for node in urandom stdin stderr stdout null full; do ln -s /dev/$${node} testing/dev/$${node}; done + for cf in hosts resolv.conf passwd shadow group gshadow mtab ; do [ -f /etc/$${cf} ] && ln -s /etc/$${cf} testing/etc/$${cf}; done +- for prog in gzip cat patch tar sh ln chmod rm mkdir uname grep sed find file ionice mktemp nice cut sort diff touch install wc coreutils xargs; do p=`which $${prog}`; if [ "$${p}" != "" ]; then ln -s $${p} testing/$(bindir)/; fi; done ++ for prog in gzip cat patch tar sh ln chmod rm mkdir uname grep sed find file ionice mktemp nice cut sort diff touch install wc coreutils xargs mknod; do p=`which $${prog}`; if [ "$${p}" != "" ]; then ln -s $${p} testing/$(bindir)/; fi; done + for d in /proc /sys /selinux /etc/selinux; do if [ -d $${d} ]; then ln -s $${d} testing/$${d}; fi; done + (cd testing/magic && file -C) + chmod -R u-w testing/ +diff --git a/tests/rpmi.at b/tests/rpmi.at +index ee35bdc..a2389de 100644 +--- a/tests/rpmi.at ++++ b/tests/rpmi.at +@@ -873,3 +873,18 @@ runroot rpm -e hlinktest + ], + []) + AT_CLEANUP ++ ++AT_SETUP([rpm -U fifo]) ++AT_KEYWORDS([install]) ++AT_CHECK([ ++RPMDB_INIT ++ ++runroot rpmbuild -bb --quiet /data/SPECS/fifo.spec ++runroot rpm -U --ignoreos /build/RPMS/noarch/fifo-1.0-1.noarch.rpm ++runroot rpm -Vv --nouser --nogroup fifo ++], ++[0], ++[......... /test-fifo ++], ++[]) ++AT_CLEANUP +-- +2.27.0 + diff --git a/backport-Fix-memleak-when-fsmRename-failed-in-fsmCommit.patch b/backport-Fix-memleak-when-fsmRename-failed-in-fsmCommit.patch new file mode 100644 index 0000000..889cf6e --- /dev/null +++ b/backport-Fix-memleak-when-fsmRename-failed-in-fsmCommit.patch @@ -0,0 +1,28 @@ +From 688c4ad34d197055eb8f58fb4e45065af881598c Mon Sep 17 00:00:00 2001 +From: xujing <xujing125@huawei.com> +Date: Mon, 28 Nov 2022 11:10:19 +0800 +Subject: [PATCH 1/3] Fix memleak when fsmRename failed in fsmCommit + +The "dest" is alloced in fsmFsPath but not freed when fsmRename failed +in fsmCommit. Fix it. +--- + lib/fsm.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/lib/fsm.c b/lib/fsm.c +index 7987abbc9..e38155df7 100644 +--- a/lib/fsm.c ++++ b/lib/fsm.c +@@ -782,7 +782,8 @@ static int fsmCommit(int dirfd, char **path, rpmfi fi, rpmFileAction action, con + } + free(*path); + *path = dest; +- } ++ } else ++ free(dest); + } + } + +-- +2.27.0 + diff --git a/backport-Fix-memleak-when-running-generate_buildrequires.patch b/backport-Fix-memleak-when-running-generate_buildrequires.patch new file mode 100644 index 0000000..131cd7d --- /dev/null +++ b/backport-Fix-memleak-when-running-generate_buildrequires.patch @@ -0,0 +1,27 @@ +From 3b0b9d491f5828a40c15b76b4a19ca00006cf81e Mon Sep 17 00:00:00 2001 +From: xujing <xujing125@huawei.com> +Date: Mon, 28 Nov 2022 11:02:47 +0800 +Subject: [PATCH 5/5] Fix memleak when running %generate_buildrequires + +The "output[i]" is alloced in argvSplit but not freed when running +%generate_buildrequires. Fix it. +--- + build/build.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/build/build.c b/build/build.c +index 4437f6c9c..34e01d5be 100644 +--- a/build/build.c ++++ b/build/build.c +@@ -279,7 +279,7 @@ static int doBuildRequires(rpmSpec spec, int test) + + exit: + freeStringBuf(sb_stdout); +- free(output); ++ argvFree(output); + return rc; + } + +-- +2.27.0 + 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 <demi@invisiblethingslab.com> +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-memory-leak-in-pgpPrtParams.patch b/backport-Fix-memory-leak-in-pgpPrtParams.patch new file mode 100644 index 0000000..72db05c --- /dev/null +++ b/backport-Fix-memory-leak-in-pgpPrtParams.patch @@ -0,0 +1,38 @@ +From b6dffb6dc5ffa2ddc389743f0507876cab341315 Mon Sep 17 00:00:00 2001 +From: Michal Domonkos <mdomonko@redhat.com> +Date: Fri, 7 Jan 2022 16:10:26 +0100 +Subject: [PATCH] Fix memory leak in pgpPrtParams() + +Make sure selfsig is freed in case we break out of the loop in this +block. + +Note that the tests added with the binding validation commit bd36c5d do +not cover this code path so valgrind won't show this. +--- + rpmio/rpmpgp.c | 9 ++++----- + 1 file changed, 4 insertions(+), 5 deletions(-) + +diff --git a/rpmio/rpmpgp.c b/rpmio/rpmpgp.c +index 1e4f667..3560328 100644 +--- a/rpmio/rpmpgp.c ++++ b/rpmio/rpmpgp.c +@@ -1147,12 +1147,11 @@ int pgpPrtParams(const uint8_t * pkts, size_t pktlen, unsigned int pkttype, + + if (selfsig) { + /* subkeys must be followed by binding signature */ +- if (prevtag == PGPTAG_PUBLIC_SUBKEY) { +- if (selfsig->sigtype != PGPSIGTYPE_SUBKEY_BINDING) +- break; +- } ++ int xx = 1; /* assume failure */ + +- int xx = pgpVerifySelf(digp, selfsig, all, i); ++ if (!(prevtag == PGPTAG_PUBLIC_SUBKEY && ++ selfsig->sigtype != PGPSIGTYPE_SUBKEY_BINDING)) ++ xx = pgpVerifySelf(digp, selfsig, all, i); + + selfsig = pgpDigParamsFree(selfsig); + if (xx) +-- +1.8.3.1 + diff --git a/backport-Fix-old-Python-ts.check-argument-order-regression.patch b/backport-Fix-old-Python-ts.check-argument-order-regression.patch new file mode 100644 index 0000000..a9bcff6 --- /dev/null +++ b/backport-Fix-old-Python-ts.check-argument-order-regression.patch @@ -0,0 +1,32 @@ +From f0c158cbc8a50a776b44de2c0fe744c451155a41 Mon Sep 17 00:00:00 2001 +From: Panu Matilainen <pmatilai@redhat.com> +Date: Tue, 4 Jan 2022 15:57:10 +0200 +Subject: [PATCH] Fix old Python ts.check() argument order regression + +Commit fab2debfe440d677dbd072c3cd73d2c99876e7a5 managed to mess up the +order of the last two callback arguments, doh. + +Goes to show that nobody has missed this stuff in 12+ years, so it might +be more merciful to put this thing out of its misery... + +Fixes: #1871 +--- + python/rpm/transaction.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/python/rpm/transaction.py b/python/rpm/transaction.py +index 991fd9a..ba39881 100644 +--- a/python/rpm/transaction.py ++++ b/python/rpm/transaction.py +@@ -159,7 +159,7 @@ class TransactionSet(TransactionSetCore): + needver = "" + + res.append(((n, v, r), +- (needname, needver), needflags, sense, p.key)) ++ (needname, needver), needflags, p.key, sense)) + + return res + +-- +1.8.3.1 + diff --git a/backport-Fix-possible-NULL-pointer-dereference-in-rpmfcClassi.patch b/backport-Fix-possible-NULL-pointer-dereference-in-rpmfcClassi.patch new file mode 100644 index 0000000..cb718a4 --- /dev/null +++ b/backport-Fix-possible-NULL-pointer-dereference-in-rpmfcClassi.patch @@ -0,0 +1,39 @@ +From 1c15d748d3536a21b6edbbf9254db76fefb4b275 Mon Sep 17 00:00:00 2001 +From: Dmitry Gerasimov <d.gerasimov@omp.ru> +Date: Mon, 27 Dec 2021 12:27:57 +0300 +Subject: [PATCH] Fix possible NULL pointer dereference in rpmfcClassify + +Here is simplified overview of possible dereference: + + if (fc == NULL) { + rpmlog(RPMLOG_ERR, _("Empty file classifier\n")); + goto exit; + } + + // ... + + exit: + rpmstrPoolFreeze(fc->cdict, 0); + ~~~~~~~~~ + +This issue was found by Svace Static Analyzer. +--- + build/rpmfc.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/build/rpmfc.c b/build/rpmfc.c +index eb51a36..cf2c203 100644 +--- a/build/rpmfc.c ++++ b/build/rpmfc.c +@@ -1168,7 +1168,7 @@ rpmRC rpmfcClassify(rpmfc fc, ARGV_t argv, rpm_mode_t * fmode) + + if (fc == NULL) { + rpmlog(RPMLOG_ERR, _("Empty file classifier\n")); +- goto exit; ++ return RPMRC_FAIL; + } + + /* It is OK when we have no files to classify. */ +-- +1.8.3.1 + diff --git a/backport-Fix-possible-descriptor-leak-in-fsmOpenat.patch b/backport-Fix-possible-descriptor-leak-in-fsmOpenat.patch new file mode 100644 index 0000000..eca230e --- /dev/null +++ b/backport-Fix-possible-descriptor-leak-in-fsmOpenat.patch @@ -0,0 +1,45 @@ +From af08077fb4c60dee516948ce7bf9bed91de62119 Mon Sep 17 00:00:00 2001 +From: Panu Matilainen <pmatilai@redhat.com> +Date: Tue, 13 Sep 2022 10:26:05 +0300 +Subject: [PATCH] Fix possible descriptor leak in fsmOpenat() + +For the very unlikely case when openat() succeeded but fstatat() +doesn't, the directory descriptor may be leaved opened. Rearrange +the code a bit to ensure it'll always get closed when appropriate. + +Suggested-by: Pavel Kopylov <pkopylov@cloudlinux.com> +Suggested-by: Dmitry Antipov <dantipov@cloudlinux.com> +--- + lib/fsm.c | 14 ++++++++------ + 1 file changed, 8 insertions(+), 6 deletions(-) + +diff --git a/lib/fsm.c b/lib/fsm.c +index e4ec07e..c9ab3e1 100644 +--- a/lib/fsm.c ++++ b/lib/fsm.c +@@ -427,14 +427,16 @@ static int fsmOpenat(int dirfd, const char *path, int flags) + */ + if (fd < 0 && errno == ELOOP && flags != sflags) { + int ffd = openat(dirfd, path, flags); +- if (ffd >= 0 && fstatat(dirfd, path, &lsb, AT_SYMLINK_NOFOLLOW) == 0) { +- if (fstat(ffd, &sb) == 0) { +- if (lsb.st_uid == 0 || lsb.st_uid == sb.st_uid) { +- fd = ffd; +- } else { +- close(ffd); ++ if (ffd >= 0) { ++ if (fstatat(dirfd, path, &lsb, AT_SYMLINK_NOFOLLOW) == 0) { ++ if (fstat(ffd, &sb) == 0) { ++ if (lsb.st_uid == 0 || lsb.st_uid == sb.st_uid) { ++ fd = ffd; ++ } + } + } ++ if (ffd != fd) ++ close(ffd); + } + } + return fd; +-- +2.33.0 + diff --git a/backport-Fix-possible-null-pointer-reference-in-ndb.patch b/backport-Fix-possible-null-pointer-reference-in-ndb.patch new file mode 100644 index 0000000..b2aeb03 --- /dev/null +++ b/backport-Fix-possible-null-pointer-reference-in-ndb.patch @@ -0,0 +1,28 @@ +From 8ec9cfc81c3f8326a1c7ee5b795ef517cd48e6b4 Mon Sep 17 00:00:00 2001 +From: yuxiaojun <yuxiaojun1011@outlook.com> +Date: Wed, 14 Jun 2023 11:23:24 +0800 +Subject: [PATCH] Fix possible null pointer reference in ndb + +slot1 and slot2 may be NULL + +Signed-off-by: yuxiaojun <yuxiaojun1011@outlook.com> +--- + lib/backend/ndb/rpmxdb.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/backend/ndb/rpmxdb.c b/lib/backend/ndb/rpmxdb.c +index 2c1f29842..d9c373cb0 100644 +--- a/lib/backend/ndb/rpmxdb.c ++++ b/lib/backend/ndb/rpmxdb.c +@@ -755,7 +755,7 @@ static int moveblobstofront(rpmxdb xdb, struct xdb_slot *afterslot) + if (slot2 == xdb->slots) + slot2 = 0; + } +- if (slot1->pagecnt < slot2->pagecnt) { ++ if (slot1 && slot2 && slot1->pagecnt < slot2->pagecnt) { + struct xdb_slot *tmp = slot1; + slot1 = slot2; + slot2 = tmp; +-- +2.27.0 + diff --git a/backport-Fix-prog-leak-in-parseScript.patch b/backport-Fix-prog-leak-in-parseScript.patch new file mode 100644 index 0000000..fe0d786 --- /dev/null +++ b/backport-Fix-prog-leak-in-parseScript.patch @@ -0,0 +1,35 @@ +From c013821c0c9350b67d9f9a02848e1a7f87fa180b Mon Sep 17 00:00:00 2001 +From: xujing <xujing125@huawei.com> +Date: Fri, 25 Nov 2022 17:04:11 +0800 +Subject: [PATCH 2/5] Fix prog leak in parseScript + +The "prog" will be alloced when using "-p" options, which cause src +"proc" leak. Add "origproc" to point to src "proc" to fix it. +--- + build/parseScript.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/build/parseScript.c b/build/parseScript.c +index df7919238..f8b693ac6 100644 +--- a/build/parseScript.c ++++ b/build/parseScript.c +@@ -102,6 +102,7 @@ int parseScript(rpmSpec spec, int parsePart) + poptContext optCon = NULL; + char *name = NULL; + char *prog = xstrdup("/bin/sh"); ++ char *origprog = prog; + char *file = NULL; + int priority = 1000000; + struct poptOption optionsTable[] = { +@@ -482,6 +483,8 @@ exit: + free(reqargs); + freeStringBuf(sb); + free(progArgv); ++ if (origprog != prog) ++ free(origprog); + free(prog); + free(name); + free(file); +-- +2.27.0 + 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 <demi@invisiblethingslab.com> +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-rpm-lua-rpm_vercmp-error-message-if-second-argum.patch b/backport-Fix-rpm-lua-rpm_vercmp-error-message-if-second-argum.patch new file mode 100644 index 0000000..f2be2bc --- /dev/null +++ b/backport-Fix-rpm-lua-rpm_vercmp-error-message-if-second-argum.patch @@ -0,0 +1,26 @@ +From cf3150509ed7eb2407bdf1f5572cd613a30c2b86 Mon Sep 17 00:00:00 2001 +From: Vyacheslav Potoropin <vpotoropin@almalinux.org> +Date: Thu, 25 Aug 2022 23:08:09 +0200 +Subject: [PATCH] Fix rpm lua rpm_vercmp error message if second argument is + broken + +--- + rpmio/rpmlua.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/rpmio/rpmlua.c b/rpmio/rpmlua.c +index 3f0bdeb3f..615146fab 100644 +--- a/rpmio/rpmlua.c ++++ b/rpmio/rpmlua.c +@@ -491,7 +491,7 @@ static int rpm_vercmp(lua_State *L) + } else { + if (v1 == NULL) + luaL_argerror(L, 1, "invalid version "); +- if (v1 == NULL) ++ if (v2 == NULL) + luaL_argerror(L, 2, "invalid version "); + } + rpmverFree(v1); +-- +2.33.0 + diff --git a/backport-Fix-rpmDigestBundleFinal-and-Update-return-code-on-i.patch b/backport-Fix-rpmDigestBundleFinal-and-Update-return-code-on-i.patch new file mode 100644 index 0000000..b1dd56d --- /dev/null +++ b/backport-Fix-rpmDigestBundleFinal-and-Update-return-code-on-i.patch @@ -0,0 +1,40 @@ +From 3a50688558f18cfb250b2e70bc34464a8e089d32 Mon Sep 17 00:00:00 2001 +From: Panu Matilainen <pmatilai@redhat.com> +Date: Tue, 20 Jun 2023 09:34:47 +0300 +Subject: [PATCH] Fix rpmDigestBundleFinal() and Update() return code on + invalid arguments + +Discovered via #2548, these functions merrily return zero for success +when passed NULL data. In rpm nothing bothers to check for their return +codes but it doesn't mean it's the right thing to do +--- + rpmio/digest.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/rpmio/digest.c b/rpmio/digest.c +index 1975fe6b9..9c679d820 100644 +--- a/rpmio/digest.c ++++ b/rpmio/digest.c +@@ -77,8 +77,9 @@ int rpmDigestBundleAddID(rpmDigestBundle bundle, int algo, int id, + } + int rpmDigestBundleUpdate(rpmDigestBundle bundle, const void *data, size_t len) + { +- int rc = 0; ++ int rc = -1; + if (bundle && data && len > 0) { ++ rc = 0; + for (int i = 0; i <= bundle->index_max; i++) { + if (bundle->ids[i] > 0) + rc += rpmDigestUpdate(bundle->digests[i], data, len); +@@ -91,7 +92,7 @@ int rpmDigestBundleUpdate(rpmDigestBundle bundle, const void *data, size_t len) + int rpmDigestBundleFinal(rpmDigestBundle bundle, int id, + void ** datap, size_t * lenp, int asAscii) + { +- int rc = 0; ++ int rc = -1; + int ix = findID(bundle, id); + + if (ix >= 0) { +-- +2.27.0 + diff --git a/backport-Fix-sanitize-the-hardlink-metadata-setting-logic.patch b/backport-Fix-sanitize-the-hardlink-metadata-setting-logic.patch new file mode 100644 index 0000000..58bd285 --- /dev/null +++ b/backport-Fix-sanitize-the-hardlink-metadata-setting-logic.patch @@ -0,0 +1,67 @@ +From dce44771b2a3325b3dc1ebfe41027df9910a39fd Mon Sep 17 00:00:00 2001 +From: Panu Matilainen <pmatilai@redhat.com> +Date: Fri, 11 Feb 2022 13:18:11 +0200 +Subject: [PATCH] Fix + sanitize the hardlink metadata setting logic + +Fix the initial setmeta value to something meaningful: we will never +set metadata on skipped files, and hardlinks are handled with a special +logic during install. They'd need different kind of special logic on +FA_TOUCH so just play it safe and always apply metadata on those. + +Harlink metadata setting on install should happen on the *last* entry +of hardlinked set that gets installed (wrt various skip scenarios) +as otherwise creating those additional links affects the timestamp. +Note in particular the "last file of..." case in fsmMkfile() where we +the comment said just that, but set the metadata on the *first* file +which would then be NULL'ed away. + +This all gets current masked by the fact that we do the metadata setting on +a separate round, but that is about to change plus this makes the overall +logic clearer anyhow. +--- + lib/fsm.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/lib/fsm.c b/lib/fsm.c +index 82610c7..d9cfe6f 100644 +--- a/lib/fsm.c ++++ b/lib/fsm.c +@@ -193,7 +193,6 @@ static int fsmMkfile(rpmfi fi, struct filedata_s *fp, rpmfiles files, + /* Create hard links for others and avoid redundant metadata setting */ + if (*firstlink != fp) { + rc = fsmLink((*firstlink)->fpath, fp->fpath); +- fp->setmeta = 0; + } + fd = *firstlinkfile; + } +@@ -204,7 +203,7 @@ static int fsmMkfile(rpmfi fi, struct filedata_s *fp, rpmfiles files, + rc = fsmUnpack(fi, fd, psm, nodigest); + /* Last file of hardlink set, ensure metadata gets set */ + if (*firstlink) { +- (*firstlink)->setmeta = 1; ++ fp->setmeta = 1; + *firstlink = NULL; + *firstlinkfile = NULL; + } +@@ -797,7 +796,6 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files, + else + fp->action = rpmfsGetAction(fs, fx); + fp->skip = XFA_SKIPPING(fp->action); +- fp->setmeta = 1; + if (XFA_CREATING(fp->action) && !S_ISDIR(rpmfiFMode(fi))) + fp->suffix = tid; + fp->fpath = fsmFsPath(fi, fp->suffix); +@@ -805,6 +803,10 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files, + /* Remap file perms, owner, and group. */ + rc = rpmfiStat(fi, 1, &fp->sb); + ++ /* Hardlinks are tricky and handled elsewhere for install */ ++ fp->setmeta = (fp->skip == 0) && ++ (fp->sb.st_nlink == 1 || fp->action == FA_TOUCH); ++ + setFileState(fs, fx); + fsmDebug(fp->fpath, fp->action, &fp->sb); + +-- +1.8.3.1 + diff --git a/backport-Fix-sbp-leak-when-running-rpmbuild-with-quiet.patch b/backport-Fix-sbp-leak-when-running-rpmbuild-with-quiet.patch new file mode 100644 index 0000000..0c98b86 --- /dev/null +++ b/backport-Fix-sbp-leak-when-running-rpmbuild-with-quiet.patch @@ -0,0 +1,28 @@ +From 6130bd31038ff17a03fcac6ec7e41ac744163dde Mon Sep 17 00:00:00 2001 +From: xujing <xujing125@huawei.com> +Date: Sat, 26 Nov 2022 11:39:48 +0800 +Subject: [PATCH 4/5] Fix *sbp leak when running rpmbuild with --quiet + +When running rpmbuild with --quiet, the "*sbp" may be alloced many +times in buildSpec by calling doScript but only freed once. Fix it. +--- + build/build.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/build/build.c b/build/build.c +index 9cd569b83..4437f6c9c 100644 +--- a/build/build.c ++++ b/build/build.c +@@ -216,6 +216,9 @@ rpmRC doScript(rpmSpec spec, rpmBuildFlags what, const char *name, + buildCmd = rpmExpand(mCmd, " ", scriptName, NULL); + (void) poptParseArgvString(buildCmd, &argc, &argv); + ++ if (sb_stdoutp && *sb_stdoutp) ++ *sb_stdoutp = freeStringBuf(*sb_stdoutp); ++ + rpmlog(RPMLOG_NOTICE, _("Executing(%s): %s\n"), name, buildCmd); + if (rpmfcExec((ARGV_const_t)argv, NULL, sb_stdoutp, 1, + spec->buildSubdir)) { +-- +2.27.0 + 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 <mls@suse.de> +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-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 <pmatilai@redhat.com> +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-Fix-use-after-free-in-haveSignature.patch b/backport-Fix-use-after-free-in-haveSignature.patch new file mode 100644 index 0000000..869d0d3 --- /dev/null +++ b/backport-Fix-use-after-free-in-haveSignature.patch @@ -0,0 +1,33 @@ +From ae3d2d234ae47ff85229d3fce97a266fa1aa5a61 Mon Sep 17 00:00:00 2001 +From: Michal Domonkos <mdomonko@redhat.com> +Date: Fri, 7 Jan 2022 13:57:24 +0100 +Subject: [PATCH] Fix use-after-free in haveSignature() + +pgpPrtParams() may leave sig2 unchanged and if we're not in the very +first iteration of the while() loop, we could pass a freed pointer to +pgpDigParamsCmp(). Fix by setting it to NULL after freeing. + +Found by Coverity, after commit bd36c5d (subkey binding validation), +although note that the commit didn't introduce this bug; it just seems +to have been a false negative that got "fixed" by the changes in +pgpPrtParams() in that commit. +--- + sign/rpmgensig.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sign/rpmgensig.c b/sign/rpmgensig.c +index d8c84e9..e88f9b7 100644 +--- a/sign/rpmgensig.c ++++ b/sign/rpmgensig.c +@@ -364,7 +364,7 @@ static int haveSignature(rpmtd sigtd, Header h) + pgpPrtParams(oldtd.data, oldtd.count, PGPTAG_SIGNATURE, &sig2); + if (pgpDigParamsCmp(sig1, sig2) == 0) + rc = 1; +- pgpDigParamsFree(sig2); ++ sig2 = pgpDigParamsFree(sig2); + } + pgpDigParamsFree(sig1); + rpmtdFreeData(&oldtd); +-- +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 <demi@invisiblethingslab.com> +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 <rsa@rpm.org>) = 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-Make-pgpPubkeyFingerprint-do-something-meaningful-ag.patch b/backport-Make-pgpPubkeyFingerprint-do-something-meaningful-ag.patch new file mode 100644 index 0000000..8cac6e0 --- /dev/null +++ b/backport-Make-pgpPubkeyFingerprint-do-something-meaningful-ag.patch @@ -0,0 +1,64 @@ +From dc9e8169790eba18130fb96c13f56ecba6c9b346 Mon Sep 17 00:00:00 2001 +From: Panu Matilainen <pmatilai@redhat.com> +Date: Tue, 6 Sep 2022 09:28:10 +0300 +Subject: [PATCH] Make pgpPubkeyFingerprint() do something meaningful again + +Commit 4bbeec134aab33e24f960be28a7b2198359c1f67 "fixed" an old +terminology confusion about keyid vs fingerprint, but in the process +broke pgpPubkeyFingerprint() for any external callers, as it now only +feeds on decoded packets whereas before it did the decoding by itself. +Add the decoding step back to the public function to make it usable outside +rpmpgp_internal.c again, retrieving a fingerprint seems like an useful +(public) API to have. + +This is kind of a regression fix in that prior to commit +4bbeec134aab33e24f960be28a7b2198359c1f67 pgpPubkeyFingerprint() returned +meaningful data to the outside caller and afterwards it didn't, however +that commit broke the API anyhow so it's kinda complicated. +Maybe we should just call it a bugfix and be done with it. + +Related to #1549 +--- + rpmio/rpmpgp.c | 15 +++++++++++++-- + 1 file changed, 13 insertions(+), 2 deletions(-) + +diff --git a/rpmio/rpmpgp.c b/rpmio/rpmpgp.c +index d4dd4b89d..8d0d76869 100644 +--- a/rpmio/rpmpgp.c ++++ b/rpmio/rpmpgp.c +@@ -650,7 +650,7 @@ static int pgpPrtUserID(pgpTag tag, const uint8_t *h, size_t hlen, + return 0; + } + +-int pgpPubkeyFingerprint(const uint8_t *h, size_t hlen, ++static int getPubkeyFingerprint(const uint8_t *h, size_t hlen, + uint8_t **fp, size_t *fplen) + { + int rc = -1; /* assume failure */ +@@ -717,11 +717,22 @@ int pgpPubkeyFingerprint(const uint8_t *h, size_t hlen, + return rc; + } + ++int pgpPubkeyFingerprint(const uint8_t * pkt, size_t pktlen, ++ uint8_t **fp, size_t *fplen) ++{ ++ struct pgpPkt p; ++ ++ if (decodePkt(pkt, pktlen, &p)) ++ return -1; ++ ++ return getPubkeyFingerprint(p.body, p.blen, fp, fplen); ++} ++ + static int getKeyID(const uint8_t *h, size_t hlen, pgpKeyID_t keyid) + { + uint8_t *fp = NULL; + size_t fplen = 0; +- int rc = pgpPubkeyFingerprint(h, hlen, &fp, &fplen); ++ int rc = getPubkeyFingerprint(h, hlen, &fp, &fplen); + if (fp && fplen > 8) { + memcpy(keyid, (fp + (fplen-8)), 8); + free(fp); +-- +2.33.0 + diff --git a/backport-Make-rpmfiSetFX-return-code-meaningful.patch b/backport-Make-rpmfiSetFX-return-code-meaningful.patch new file mode 100644 index 0000000..e1e475b --- /dev/null +++ b/backport-Make-rpmfiSetFX-return-code-meaningful.patch @@ -0,0 +1,51 @@ +From 318efbaec80a90f1d9ac76d0cd433f6ea3c103fa Mon Sep 17 00:00:00 2001 +From: Panu Matilainen <pmatilai@redhat.com> +Date: Thu, 10 Feb 2022 10:07:06 +0200 +Subject: [PATCH] Make rpmfiSetFX() return code meaningful + +Up to now, rpmfiSetFX() has returned the previous file index on success, +and -1 on error. Which seems okay on the outset, but on a just +initialized iterator the file index is at -1 which means the returned +-1 sometimes indicates an error and sometimes success. This is so broken +that none of the callers even try to use it (grep for it). Which is +lucky in the sense that it means we can change it. + +Simply return the newly set index on success and -1 on error, it may +not be the greatest return code on earth but at least it's +non-ambiguous. +--- + lib/rpmfi.c | 2 +- + lib/rpmfi.h | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/lib/rpmfi.c b/lib/rpmfi.c +index 30e0738..4965aee 100644 +--- a/lib/rpmfi.c ++++ b/lib/rpmfi.c +@@ -314,9 +314,9 @@ int rpmfiSetFX(rpmfi fi, int fx) + int i = -1; + + if (fi != NULL && fx >= 0 && fx < rpmfilesFC(fi->files)) { +- i = fi->i; + fi->i = fx; + fi->j = rpmfilesDI(fi->files, fi->i); ++ i = fi->i; + } + return i; + } +diff --git a/lib/rpmfi.h b/lib/rpmfi.h +index 989582b..52310c6 100644 +--- a/lib/rpmfi.h ++++ b/lib/rpmfi.h +@@ -39,7 +39,7 @@ int rpmfiFX(rpmfi fi); + * Set current file index in file info set iterator. + * @param fi file info set iterator + * @param fx new file index +- * @return current file index ++ * @return new file index, -1 on error + */ + int rpmfiSetFX(rpmfi fi, int fx); + +-- +1.8.3.1 + diff --git a/backport-Move-file-metadata-setting-back-to-unpack-stage.patch b/backport-Move-file-metadata-setting-back-to-unpack-stage.patch new file mode 100644 index 0000000..ef9071e --- /dev/null +++ b/backport-Move-file-metadata-setting-back-to-unpack-stage.patch @@ -0,0 +1,69 @@ +From da79e3c3ae7da8719f0bf87a1a60e046597b8240 Mon Sep 17 00:00:00 2001 +From: Panu Matilainen <pmatilai@redhat.com> +Date: Fri, 11 Feb 2022 13:28:25 +0200 +Subject: [PATCH] Move file metadata setting back to unpack stage + +Commit a82251b44ee2d2802ee8aea1b3d89f88beee4bad moved metadata setting +to a separate step because there are potential benefits to doing so, but +the current downsides are worse: as long as we operate in potentially +untrusted directories, we'd need to somehow verify the content is what we +initially laid down to avoid possible privilege escalation from non-root +owned directories. + +This commit does not fix that vulnerability, only makes the window much +smaller and paves the way for the real fix(es) without introducing a +second round of directory tree validation chase to the picture. +--- + lib/fsm.c | 22 +++++++--------------- + 1 file changed, 7 insertions(+), 15 deletions(-) + +diff --git a/lib/fsm.c b/lib/fsm.c +index d9cfe6fa9..ae1bd3f48 100644 +--- a/lib/fsm.c ++++ b/lib/fsm.c +@@ -880,7 +880,7 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files, + + /* When touching we don't need any of this... */ + if (fp->action == FA_TOUCH) +- continue; ++ goto setmeta; + + if (S_ISREG(fp->sb.st_mode)) { + if (rc == RPMERR_ENOENT) { +@@ -1143,6 +1143,12 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files, + rc = RPMERR_OPEN_FAILED; + } + ++setmeta: ++ if (!rc && fp->setmeta) { ++ rc = fsmSetmeta(fp->fpath, fi, plugins, fp->action, ++ &fp->sb, nofcaps); ++ } ++ + if (fd != firstlinkfile) + fsmClose(&fd); + } +@@ -931,20 +937,6 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files, + if (!rc && fx < 0 && fx != RPMERR_ITER_END) + rc = fx; + +- /* Set permissions, timestamps etc for non-hardlink entries */ +- fi = rpmfilesIter(files, RPMFI_ITER_FWD); +- while (!rc && (fx = rpmfiNext(fi)) >= 0) { +- struct filedata_s *fp = &fdata[fx]; +- if (!fp->skip && fp->setmeta) { +- rc = fsmSetmeta(fp->fpath, fi, plugins, fp->action, +- &fp->sb, nofcaps); +- } +- if (rc) +- *failedFile = xstrdup(fp->fpath); +- fp->stage = FILE_PREP; +- } +- fi = rpmfiFree(fi); +- + /* If all went well, commit files to final destination */ + fi = rpmfilesIter(files, RPMFI_ITER_FWD); + while (!rc && (fx = rpmfiNext(fi)) >= 0) { +-- +2.27.0 + 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 <demi@invisiblethingslab.com> +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 <ludwig.nussel@suse.de> +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 <pmatilai@redhat.com> +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-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 <pmatilai@redhat.com> +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 <pmatilai@redhat.com> +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-Remove-obscure-check-for-package-build-time-from-reb.patch b/backport-Remove-obscure-check-for-package-build-time-from-reb.patch new file mode 100644 index 0000000..2bd4c62 --- /dev/null +++ b/backport-Remove-obscure-check-for-package-build-time-from-reb.patch @@ -0,0 +1,41 @@ +From 6caf2a5f586838f6188dd6667a4df6d9c6ec0163 Mon Sep 17 00:00:00 2001 +From: Panu Matilainen <pmatilai@redhat.com> +Date: Thu, 1 Jun 2023 09:45:01 +0300 +Subject: [PATCH] Remove obscure check for package build time from --rebuilddb + (#2527) + +Back in 1997, commit be0b90359bcd8156385178eb9b570c0538c0333f added a +sanity check for --rebuilddb operation, skipping headers which lack +some basic tags. Name, version and release are real requirements for +packages, but checking for buildtime is odd, and plain wrong. +Yes, we expect that to be present in packages built by rpm, but that's +not used for any processing and certainly is not required for a package +to be installable. And if it can be installed then it can't be +right to throw it away when rebuilding, leaving untrackable orphan +files in the process. + +It is also documented as informational and optional by LSB. While +severely outdated, it is right on this account. + +Fixes: #2527 +--- + lib/rpmdb.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/lib/rpmdb.c b/lib/rpmdb.c +index b51e9f09e..361f04150 100644 +--- a/lib/rpmdb.c ++++ b/lib/rpmdb.c +@@ -2470,8 +2470,7 @@ int rpmdbRebuild(const char * prefix, rpmts ts, + /* let's sanity check this record a bit, otherwise just skip it */ + if (!(headerIsEntry(h, RPMTAG_NAME) && + headerIsEntry(h, RPMTAG_VERSION) && +- headerIsEntry(h, RPMTAG_RELEASE) && +- headerIsEntry(h, RPMTAG_BUILDTIME))) ++ headerIsEntry(h, RPMTAG_RELEASE))) + { + rpmlog(RPMLOG_ERR, + _("header #%u in the database is bad -- skipping.\n"), +-- +2.27.0 + 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 <demi@invisiblethingslab.com> +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-Return-descriptor-of-created-file-from-fsmMkfile.patch b/backport-Return-descriptor-of-created-file-from-fsmMkfile.patch new file mode 100644 index 0000000..bb9bb16 --- /dev/null +++ b/backport-Return-descriptor-of-created-file-from-fsmMkfile.patch @@ -0,0 +1,65 @@ +From 693d828c035848585b500dfde6f4e58cfb8d4de4 Mon Sep 17 00:00:00 2001 +From: Panu Matilainen <pmatilai@redhat.com> +Date: Mon, 14 Feb 2022 12:44:42 +0200 +Subject: [PATCH] Return descriptor of created file from fsmMkfile() + +This will be needed for using fd-based metadata operations. +--- + lib/fsm.c | 13 ++++++++----- + 1 file changed, 8 insertions(+), 5 deletions(-) + +diff --git a/lib/fsm.c b/lib/fsm.c +index b019f57..7c4796f 100644 +--- a/lib/fsm.c ++++ b/lib/fsm.c +@@ -172,7 +172,8 @@ static int fsmUnpack(rpmfi fi, int fdno, rpmpsm psm, int nodigest) + + static int fsmMkfile(int dirfd, rpmfi fi, struct filedata_s *fp, rpmfiles files, + rpmpsm psm, int nodigest, +- struct filedata_s ** firstlink, int *firstlinkfile) ++ struct filedata_s ** firstlink, int *firstlinkfile, ++ int *fdp) + { + int rc = 0; + int fd = -1; +@@ -204,9 +205,7 @@ static int fsmMkfile(int dirfd, rpmfi fi, struct filedata_s *fp, rpmfiles files, + *firstlinkfile = -1; + } + } +- +- if (fd != *firstlinkfile) +- fsmClose(&fd); ++ *fdp = fd; + + return rc; + } +@@ -1065,6 +1065,7 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files, + fp = firstlink; + + if (!fp->skip) { ++ int fd = -1; + /* Directories replacing something need early backup */ + if (!fp->suffix && fp != firstlink) { + rc = fsmBackup(fi, fp->action); +@@ -910,7 +910,7 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files, + if (S_ISREG(fp->sb.st_mode)) { + if (rc == RPMERR_ENOENT) { + rc = fsmMkfile(di.dirfd, fi, fp, files, psm, nodigest, +- &firstlink, &firstlinkfile); ++ &firstlink, &firstlinkfile, &fd); + } + } else if (S_ISDIR(fp->sb.st_mode)) { + if (rc == RPMERR_ENOENT) { +@@ -1131,6 +1132,9 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files, + if (!IS_DEV_LOG(fp->fpath)) + rc = RPMERR_UNKNOWN_FILETYPE; + } ++ ++ if (fd != firstlinkfile) ++ fsmClose(&fd); + } + + /* Notify on success. */ +-- +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 <licunlong1@huawei.com> +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 <pmatilai@redhat.com> +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-Skip-recorded-symlinks-in-setperms-RhBug-1900662.patch b/backport-Skip-recorded-symlinks-in-setperms-RhBug-1900662.patch new file mode 100644 index 0000000..1d09f82 --- /dev/null +++ b/backport-Skip-recorded-symlinks-in-setperms-RhBug-1900662.patch @@ -0,0 +1,40 @@ +From ed07a187734addfa16be9ee922398e4ff9859f53 Mon Sep 17 00:00:00 2001 +From: Michal Domonkos <mdomonko@redhat.com> +Date: Tue, 7 Dec 2021 08:08:37 +0100 +Subject: [PATCH] Skip recorded symlinks in --setperms (RhBug:1900662) + +If a package contains a symlink in the buildroot which is declared as a +ghost or config file but is a regular file or directory on the system +where it's installed, a --setperms call will reset its permissions to +those of a symlink (777 on Linux), which almost certainly is not the +correct thing to do. + +To fix that, just skip files that were recorded as symlinks. + +This is a special case of a general issue in --setperms; since file +permission semantics may change depending on the file type, to stay on +the safe side, any (ghost or config) file whose type changes after +installation should probably be skipped. However, symlinks are the most +prominent case here, so let's just focus on that now and avoid adding +too much cleverness to a popt alias (this got us into trouble not too +long ago, see commits 38c2f6e and 0d83637). We may revisit this in the +eventual C implementation. +--- + rpmpopt.in | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/rpmpopt.in b/rpmpopt.in +index 27d2986..d5a6b14 100644 +--- a/rpmpopt.in ++++ b/rpmpopt.in +@@ -44,6 +44,7 @@ rpm alias --scripts --qf '\ + --POPTdesc=$"list install/erase scriptlets from package(s)" + + rpm alias --setperms -q --qf '[\[ -L %{FILENAMES:shescape} \] || \ ++ \[ -n %{FILELINKTOS:shescape} \] || \ + ( \[ $((%{FILEFLAGS} & 2#1001000)) != 0 \] && \[ ! -e %{FILENAMES:shescape} \] ) || \ + chmod %7{FILEMODES:octal} %{FILENAMES:shescape}\n]' \ + --pipe "grep -v \(none\) | grep '^. -L ' | sed 's/chmod .../chmod /' | sh" \ +-- +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 <mls@suse.de> +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-Use-fd-based-ops-for-metadata-in-FA_TOUCH-mode-too-w.patch b/backport-Use-fd-based-ops-for-metadata-in-FA_TOUCH-mode-too-w.patch new file mode 100644 index 0000000..c537632 --- /dev/null +++ b/backport-Use-fd-based-ops-for-metadata-in-FA_TOUCH-mode-too-w.patch @@ -0,0 +1,46 @@ +From 932013698149d43720cc321c8df2f99f51866e18 Mon Sep 17 00:00:00 2001 +From: Panu Matilainen <pmatilai@redhat.com> +Date: Fri, 13 Jan 2023 10:00:37 +0200 +Subject: [PATCH] Use fd-based ops for metadata in FA_TOUCH mode too, +when + possible + +Fixes another brainfart in commit 25a435e90844ea98fe5eb7bef22c1aecf3a9c033. +--- + lib/fsm.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/lib/fsm.c b/lib/fsm.c +index 54fea90..e6fac40 100644 +--- a/lib/fsm.c ++++ b/lib/fsm.c +@@ -1002,6 +1002,7 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files, + int nodigest = (rpmtsFlags(ts) & RPMTRANS_FLAG_NOFILEDIGEST) ? 1 : 0; + int nofcaps = (rpmtsFlags(ts) & RPMTRANS_FLAG_NOCAPS) ? 1 : 0; + int firstlinkfile = -1; ++ int mayopen = 0; + char *tid = NULL; + struct filedata_s *fdata = xcalloc(fc, sizeof(*fdata)); + struct filedata_s *firstlink = NULL; +@@ -1136,8 +1137,9 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files, + rc = RPMERR_UNKNOWN_FILETYPE; + } + ++setmeta: + /* Special files require path-based ops */ +- int mayopen = S_ISREG(fp->sb.st_mode) || S_ISDIR(fp->sb.st_mode); ++ mayopen = S_ISREG(fp->sb.st_mode) || S_ISDIR(fp->sb.st_mode); + if (!rc && fd == -1 && mayopen) { + /* Only follow safe symlinks, and never on temporary files */ + fd = fsmOpenat(di.dirfd, fp->fpath, +@@ -1146,7 +1148,6 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files, + rc = RPMERR_OPEN_FAILED; + } + +-setmeta: + if (!rc && fp->setmeta) { + rc = fsmSetmeta(fp->fpath, fi, plugins, fp->action, + &fp->sb, nofcaps); +-- +2.27.0 + diff --git a/backport-Use-proper-type-for-copyTagsFromMainDebug.patch b/backport-Use-proper-type-for-copyTagsFromMainDebug.patch new file mode 100644 index 0000000..d60e6fb --- /dev/null +++ b/backport-Use-proper-type-for-copyTagsFromMainDebug.patch @@ -0,0 +1,27 @@ +From 42694806bf73b07514554233d0d58d17a58cd863 Mon Sep 17 00:00:00 2001 +From: Panu Matilainen <pmatilai@redhat.com> +Date: Thu, 9 Feb 2023 13:05:24 +0200 +Subject: [PATCH] Use proper type for copyTagsFromMainDebug + +The array contains a non-enum value (0), this is why headerCopyTags() +uses rpmTagVal pointer, not rpmTag. +--- + build/files.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/build/files.c b/build/files.c +index 666c66651..24b4d80bf 100644 +--- a/build/files.c ++++ b/build/files.c +@@ -2858,7 +2858,7 @@ exit: + return rc; + } + +-static rpmTag copyTagsFromMainDebug[] = { ++static rpmTagVal copyTagsFromMainDebug[] = { + RPMTAG_ARCH, + RPMTAG_SUMMARY, + RPMTAG_DESCRIPTION, +-- +2.27.0 + diff --git a/backport-Use-root-as-default-UID_0_USER-and-UID_0_GROUP.patch b/backport-Use-root-as-default-UID_0_USER-and-UID_0_GROUP.patch new file mode 100644 index 0000000..80b8790 --- /dev/null +++ b/backport-Use-root-as-default-UID_0_USER-and-UID_0_GROUP.patch @@ -0,0 +1,29 @@ +From 7b3a3f004f96ed3cb9cc377f7e64bfc88195dfc2 Mon Dec 13 16:41:34 2021 +From: From: Florian Festi <ffesti@redhat.com> +Date: Mon, 13 Dec 2021 16:41:34 +0800 +Subject: [PATCH] Use root as default UID_0_USER and UID_0_GROUP + +If /etc/passwd or /etc/group was not available during building rpm itself +these ended up empty. This affects builds done later on using rpmbuild. + +Resolves: #1838 +--- + configure.ac | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/configure.ac b/configure.ac +index cdaf2b6..8656043 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -1050,6 +1050,8 @@ fi + + user_with_uid0=$(awk -F: '$3==0 {print $1;exit}' /etc/passwd) + group_with_gid0=$(awk -F: '$3==0 {print $1;exit}' /etc/group) ++if test -z "$user_with_uid0" ; then user_with_uid0=root ; fi ++if test -z "$group_with_gid0" ; then group_with_gid0=root ; fi + AC_DEFINE_UNQUOTED([UID_0_USER],["$user_with_uid0"],[Get the user name having userid 0]) + AC_DEFINE_UNQUOTED([GID_0_GROUP],["$group_with_gid0"],[Get the group name having groupid 0]) + +-- +1.8.3.1 + diff --git a/backport-Use-unsigned-integers-more-consistently-in-the-handl.patch b/backport-Use-unsigned-integers-more-consistently-in-the-handl.patch new file mode 100644 index 0000000..af8b4b1 --- /dev/null +++ b/backport-Use-unsigned-integers-more-consistently-in-the-handl.patch @@ -0,0 +1,63 @@ +From 8e6108a5964c7289f3db70f3d188293276416528 Mon Sep 17 00:00:00 2001 +From: Daniel Alley <dalley@redhat.com> +Date: Thu, 8 Dec 2022 09:40:00 -0500 +Subject: [PATCH] Use unsigned integers more consistently in the handling of + tag data + +Not a functional change, it just makes the code more clear and +self-consistent. +--- + lib/header.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +diff --git a/lib/header.c b/lib/header.c +index 004102dd2..72fb3d4fe 100644 +--- a/lib/header.c ++++ b/lib/header.c +@@ -568,7 +568,7 @@ static int regionSwab(indexEntry entry, int il, int dl, + } + } break; + case RPM_INT32_TYPE: +- { int32_t * it = ie.data; ++ { uint32_t * it = ie.data; + for (; ie.info.count > 0; ie.info.count--, it += 1) { + if (dataEnd && ((unsigned char *)it) >= dataEnd) + return -1; +@@ -576,7 +576,7 @@ static int regionSwab(indexEntry entry, int il, int dl, + } + } break; + case RPM_INT16_TYPE: +- { int16_t * it = ie.data; ++ { uint16_t * it = ie.data; + for (; ie.info.count > 0; ie.info.count--, it += 1) { + if (dataEnd && ((unsigned char *)it) >= dataEnd) + return -1; +@@ -772,9 +772,9 @@ static void * doExport(const struct indexEntry_s *hindex, int indexUsed, + count = entry->info.count; + src = entry->data; + while (count--) { +- *((int32_t *)te) = htonl(*((int32_t *)src)); +- te += sizeof(int32_t); +- src += sizeof(int32_t); ++ *((uint32_t *)te) = htonl(*((uint32_t *)src)); ++ te += sizeof(uint32_t); ++ src += sizeof(uint32_t); + } + break; + +@@ -782,9 +782,9 @@ static void * doExport(const struct indexEntry_s *hindex, int indexUsed, + count = entry->info.count; + src = entry->data; + while (count--) { +- *((int16_t *)te) = htons(*((int16_t *)src)); +- te += sizeof(int16_t); +- src += sizeof(int16_t); ++ *((uint16_t *)te) = htons(*((uint16_t *)src)); ++ te += sizeof(uint16_t); ++ src += sizeof(uint16_t); + } + break; + +-- +2.33.0 + 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 <pmatilai@redhat.com> +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) ++ ++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 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 <signed> 1]) +-- +1.8.3.1 + diff --git a/backport-bugfix-wrong-symlink-length-on-some-filesystems.patch b/backport-bugfix-wrong-symlink-length-on-some-filesystems.patch new file mode 100644 index 0000000..e2052e3 --- /dev/null +++ b/backport-bugfix-wrong-symlink-length-on-some-filesystems.patch @@ -0,0 +1,44 @@ +From 4c301883a5a94a9a186a1bb1d45d234db4db7c88 Mon Sep 17 00:00:00 2001 +From: Dominik Neudert-Schulz <dominikns@bachtechnology.com> +Date: Wed, 30 Jun 2021 14:13:46 +0200 +Subject: [PATCH] fix rpmbuild failure because of wrong symlink length on some + filesystems + +--- + build/files.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/build/files.c b/build/files.c +index f8153ad2b5..571b502e91 100644 +--- a/build/files.c ++++ b/build/files.c +@@ -1363,6 +1363,8 @@ static rpmRC addFile(FileList fl, const char * diskPath, + { + size_t plen = strlen(diskPath); + char buf[plen + 1]; ++ char linkPath[PATH_MAX]; ++ ssize_t linkLen; + const char *cpioPath; + struct stat statbuf; + mode_t fileMode; +@@ -1459,6 +1461,20 @@ static rpmRC addFile(FileList fl, const char * diskPath, + fileUid = statp->st_uid; + fileGid = statp->st_gid; + ++ if (S_ISLNK(fileMode)) { ++ /* stat's man page states that statp->st_size should equal the length of ++ the pointed-to path. On some filesystem a wrong size is reported. ++ So, explicitly get the length here. */ ++ linkLen = readlink(diskPath, linkPath, sizeof(linkPath)); ++ if ((linkLen < 0) || (linkLen >= sizeof(linkPath))) { ++ rpmlog(RPMLOG_ERR, ++ "Symbolic link too long or corrupt: %s\n", ++ diskPath); ++ goto exit; ++ } ++ statp->st_size = linkLen; ++ } ++ + /* Explicit %attr() always wins */ + if (fl->cur.ar.ar_fmodestr) { + if (S_ISLNK(fileMode)) {
\ No newline at end of file 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 <ffesti@redhat.com> +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/backport-rpm2cpio.sh-only-read-needed-bytes-of-file-magic.patch b/backport-rpm2cpio.sh-only-read-needed-bytes-of-file-magic.patch new file mode 100644 index 0000000..490ec44 --- /dev/null +++ b/backport-rpm2cpio.sh-only-read-needed-bytes-of-file-magic.patch @@ -0,0 +1,27 @@ +From 8f922eb38a096640e586ba0eda96adc093b74fc4 Mon Sep 17 00:00:00 2001 +From: Florian Festi <ffesti@redhat.com> +Date: Wed, 3 Aug 2022 17:19:02 +0200 +Subject: [PATCH] rpm2cpio.sh: only read needed bytes of file magic + +As we look at the first 4 bytes anyway there is no reason to read more. +Reading more also hits a bug in bash on aarch64 (rhbz#2115206). +--- + scripts/rpm2cpio.sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/scripts/rpm2cpio.sh b/scripts/rpm2cpio.sh +index 74aeed8..cea0da2 100755 +--- a/scripts/rpm2cpio.sh ++++ b/scripts/rpm2cpio.sh +@@ -43,7 +43,7 @@ calcsize() { + offset=$(($offset + $rsize)) + } + +-case "$(_dd 0 bs=8 count=1 | tr -d '\0')" in ++case "$(_dd 0 bs=4 count=1 | tr -d '\0')" in + "$(printf '\355\253\356\333')"*) ;; # '\xed\xab\xee\xdb' + *) fatal "File doesn't look like rpm: $pkg" ;; + esac +-- +1.8.3.1 + diff --git a/backport-rpm2cpio.sh-strip-null-bytes-with-tr.patch b/backport-rpm2cpio.sh-strip-null-bytes-with-tr.patch new file mode 100644 index 0000000..5cdef02 --- /dev/null +++ b/backport-rpm2cpio.sh-strip-null-bytes-with-tr.patch @@ -0,0 +1,35 @@ +From d499887c9261fdab4d03ea29316ea5e8fc646bd3 Mon Sep 17 00:00:00 2001 +From: Florian Festi <ffesti@redhat.com> +Date: Fri, 1 Jul 2022 14:49:09 +0200 +Subject: [PATCH] rpm2cpio.sh: strip null bytes with tr + +to avoid warnings +--- + scripts/rpm2cpio.sh | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/scripts/rpm2cpio.sh b/scripts/rpm2cpio.sh +index f77d5f8..59e8bc5 100755 +--- a/scripts/rpm2cpio.sh ++++ b/scripts/rpm2cpio.sh +@@ -43,7 +43,7 @@ calcsize() { + offset=$(($offset + $rsize)) + } + +-case "$(_dd 0 bs=8 count=1)" in ++case "$(_dd 0 bs=8 count=1 | tr -d '\0')" in + "$(printf '\355\253\356\333')"*) ;; # '\xed\xab\xee\xdb' + *) fatal "File doesn't look like rpm: $pkg" ;; + esac +@@ -54,7 +54,7 @@ sigsize=$rsize + calcsize $(($offset + (8 - ($sigsize % 8)) % 8)) + hdrsize=$rsize + +-case "$(_dd $offset bs=3 count=1)" in ++case "$(_dd $offset bs=3 count=1 | tr -d '\0')" in + "$(printf '\102\132')"*) _dd $offset | bunzip2 ;; # '\x42\x5a' + "$(printf '\037\213')"*) _dd $offset | gunzip ;; # '\x1f\x8b' + "$(printf '\375\067')"*) _dd $offset | xzcat ;; # '\xfd\x37' +-- +1.8.3.1 + diff --git a/backport-rpmkeys-exit-non-zero-on-I-O-errors.patch b/backport-rpmkeys-exit-non-zero-on-I-O-errors.patch new file mode 100644 index 0000000..ac18f35 --- /dev/null +++ b/backport-rpmkeys-exit-non-zero-on-I-O-errors.patch @@ -0,0 +1,53 @@ +From fc8386be36a32f8462a0d16a2dd3e5e18f7fbc2d Mon Sep 17 00:00:00 2001 +From: Demi Marie Obenour <demi@invisiblethingslab.com> +Date: Mon, 12 Apr 2021 11:30:51 -0400 +Subject: [PATCH] rpmkeys: exit non-zero on I/O errors + +If writing to stdout or stderr fails, rpmkeys should exit with a +non-zero status code. +--- + rpmkeys.c | 4 ++++ + tests/rpmsigdig.at | 13 +++++++++++++ + 2 files changed, 17 insertions(+) + +diff --git a/rpmkeys.c b/rpmkeys.c +index 542601c..2c304de 100644 +--- a/rpmkeys.c ++++ b/rpmkeys.c +@@ -86,5 +86,9 @@ int main(int argc, char *argv[]) + exit: + rpmtsFree(ts); + rpmcliFini(optCon); ++ fflush(stderr); ++ fflush(stdout); ++ if (ferror(stdout) || ferror(stderr)) ++ return 255; /* I/O error */ + return ec; + } +diff --git a/tests/rpmsigdig.at b/tests/rpmsigdig.at +index c8b9f13..429163e 100644 +--- a/tests/rpmsigdig.at ++++ b/tests/rpmsigdig.at +@@ -24,6 +24,19 @@ runroot rpmkeys -Kv /data/RPMS/hello-2.0-1.x86_64.rpm /data/RPMS/hello-1.0-1.i38 + []) + AT_CLEANUP + ++# ------------------------------ ++# Test rpmkeys write errors ++AT_SETUP([[rpmkeys -K no space left on stdout]]) ++AT_KEYWORDS([rpmkeys digest]) ++AT_CHECK([ ++RPMDB_INIT[ ++ ++runroot rpmkeys -Kv /data/RPMS/hello-2.0-1.x86_64.rpm /data/RPMS/hello-1.0-1.i386.rpm >/dev/full ++]],255,,[[Error writing to log: No space left on device ++]]) ++AT_CLEANUP ++ ++ + AT_SETUP([rpmkeys -Kv <reconstructed> 1]) + AT_KEYWORDS([rpmkeys digest]) + AT_CHECK([ +-- +1.8.3.1 + diff --git a/backport-support-for-POSIX-getopt-behaviour.patch b/backport-support-for-POSIX-getopt-behaviour.patch new file mode 100644 index 0000000..aa3c2c7 --- /dev/null +++ b/backport-support-for-POSIX-getopt-behaviour.patch @@ -0,0 +1,33 @@ +From 1f47b1cc0eddbb1921d81249a4bd604089c71495 Mon Sep 17 00:00:00 2001 +From: "(GalaxyMaster)" <galaxy4public@users.noreply.github.com> +Date: Tue, 31 Jan 2023 18:24:55 +1100 +Subject: [PATCH] support for POSIX getopt() behaviour + +[POSIX defines optarg only for options with arguments](https://pubs.opengroup.org/onlinepubs/000095399/functions/getopt.html) and callback() is expecting optarg to be NULL for options without arguments, however, at least on musl optarg will carry a pointer to the argument of the previous option with argument. This commit makes the behaviour deterministic and expected. +--- + rpmio/rgetopt.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/rpmio/rgetopt.c b/rpmio/rgetopt.c +index f789fa8fe..b14366a8a 100644 +--- a/rpmio/rgetopt.c ++++ b/rpmio/rgetopt.c +@@ -28,6 +28,7 @@ int rgetopt(int argc, char * const argv[], const char *opts, + optind = 0; + #else + optind = 1; ++ optarg = NULL; + #endif + + while ((c = getopt(argc, argv, opts)) != -1) { +@@ -39,6 +40,7 @@ int rgetopt(int argc, char * const argv[], const char *opts, + rc = -1; + break; + } ++ optarg = NULL; + } + return (rc < 0) ? -optopt : optind; + } +-- +2.27.0 + diff --git a/backport-treat-0-as-valid-file-descriptor.patch b/backport-treat-0-as-valid-file-descriptor.patch new file mode 100644 index 0000000..154e55a --- /dev/null +++ b/backport-treat-0-as-valid-file-descriptor.patch @@ -0,0 +1,27 @@ +From be64821b908fdb1ff3c12530430d1cf046839e60 Mon Sep 17 00:00:00 2001 +From: licunlong <licunlong1@huawei.com> +Date: Thu, 20 Jan 2022 19:59:44 +0800 +Subject: [PATCH] treat 0 as valid file descriptor The descriptor is openned in + rpmpkgOpen, and we treat 0 as valid file descriptor. Here we should do the + same or fail earlier. + +--- + lib/backend/ndb/rpmpkg.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/backend/ndb/rpmpkg.c b/lib/backend/ndb/rpmpkg.c +index 64d0493..0a041e4 100644 +--- a/lib/backend/ndb/rpmpkg.c ++++ b/lib/backend/ndb/rpmpkg.c +@@ -734,7 +734,7 @@ static int rpmpkgAddSlotPage(rpmpkgdb pkgdb) + + static int rpmpkgGetLock(rpmpkgdb pkgdb, int type) + { +- if (!pkgdb->fd) ++ if (pkgdb->fd < 0) + return RPMRC_FAIL; + if (flock(pkgdb->fd, type)) + return RPMRC_FAIL; +-- +1.8.3.1 + diff --git a/bugfix-rpm-4.11.3-add-aarch64_ilp32-arch.patch b/bugfix-rpm-4.11.3-add-aarch64_ilp32-arch.patch new file mode 100644 index 0000000..c598126 --- /dev/null +++ b/bugfix-rpm-4.11.3-add-aarch64_ilp32-arch.patch @@ -0,0 +1,80 @@ +diff -Nur rpm-4.14.2.old/installplatform rpm-4.14.2/installplatform +--- rpm-4.14.2.old/installplatform 2017-08-10 16:08:07.113108701 +0800 ++++ rpm-4.14.2/installplatform 2019-01-30 17:28:25.511000000 +0800 +@@ -180,6 +180,13 @@ + CANONARCH=riscv64 + CANONCOLOR=3 + ;; ++ aarch64_ilp32) ++ ISANAME=aarch ++ ISABITS=32 ++ CANONARCH=aarch64 ++ CANONCOLOR=0 ++ LIB=libilp32 ++ ;; + noarch) + CANONARCH=noarch + CANONCOLOR=0 +diff -Nur rpm-4.14.2.old/rpmrc.in rpm-4.14.2/rpmrc.in +--- rpm-4.14.2.old/rpmrc.in 2019-01-29 18:43:15.795000000 +0800 ++++ rpm-4.14.2/rpmrc.in 2019-01-30 20:30:17.916000000 +0800 +@@ -99,7 +99,7 @@ + optflags: sh4a -O2 -g -mieee + + optflags: aarch64 -O2 -g +- ++optflags: aarch64_ilp32 -O2 -g -mabi=ilp32 + optflags: riscv64 -O2 -g + + ############################################################# +@@ -149,7 +149,7 @@ + archcolor: sh4 1 + + archcolor: aarch64 2 +- ++archcolor: aarch64_ilp32 1 + archcolor: riscv64 2 + + ############################################################# +@@ -243,7 +243,7 @@ + arch_canon: sh4a: sh4a 17 + arch_canon: xtensa: xtensa 18 + arch_canon: aarch64: aarch64 19 +- ++arch_canon: aarch64_ilp32: aarch64 19 + arch_canon: mipsr6: mipsr6 20 + arch_canon: mipsr6el: mipsr6el 20 + arch_canon: mips64r6: mips64r6 21 +@@ -377,11 +377,11 @@ + buildarchtranslate: sh4a: sh4 + + buildarchtranslate: aarch64: aarch64 +- ++buildarchtranslate: aarch64_ilp32: aarch64_ilp32 + buildarchtranslate: riscv: riscv64 + buildarchtranslate: riscv64: riscv64 + +-############################################################# ++#########################################/#################### + # Architecture compatibility + + arch_compat: alphaev67: alphaev6 +@@ -485,7 +485,8 @@ + arch_compat: sh4: noarch + arch_compat: sh4a: sh4 + +-arch_compat: aarch64: noarch ++arch_compat: aarch64_ilp32: aarch64 noarch ++arch_compat: aarch64: aarch64_ilp32 noarch + + arch_compat: riscv: noarch + arch_compat: riscv64: noarch +@@ -522,7 +523,7 @@ + buildarch_compat: ia64: noarch + + buildarch_compat: aarch64: noarch +- ++buildarch_compat: aarch64_ilp32: noarch + buildarch_compat: riscv: noarch + buildarch_compat: riscv64: noarch + diff --git a/bugfix-rpm-4.14.2-wait-once-get-rpmlock-fail.patch b/bugfix-rpm-4.14.2-wait-once-get-rpmlock-fail.patch new file mode 100644 index 0000000..2379331 --- /dev/null +++ b/bugfix-rpm-4.14.2-wait-once-get-rpmlock-fail.patch @@ -0,0 +1,35 @@ +From c6699a7e90acfaa421830ce0fc12940335e40d7b Mon Sep 17 00:00:00 2001 +From: shanshishi <shanshishi@huawei.com> +Date: Sun, 19 May 2019 16:49:45 +0800 +Subject: [PATCH] rpm: wait once get rpmlock fail + +reason: When executing the rpm command concurrently, it will block some +times, because of lock is applied before. + +Signed-off-by: shanshishi <shanshishi@huawei.com> +--- + lib/rpmlock.c | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +diff --git a/lib/rpmlock.c b/lib/rpmlock.c +index d693c4b..86e07b3 100644 +--- a/lib/rpmlock.c ++++ b/lib/rpmlock.c +@@ -125,13 +125,10 @@ rpmlock rpmlockNew(const char *lock_path, const char *descr) + int rpmlockAcquire(rpmlock lock) + { + int locked = 0; /* assume failure */ +- int myerrno = errno; +- int maywait = isatty(STDIN_FILENO); /* dont wait within scriptlets */ +- errno = myerrno; + + if (lock) { + locked = rpmlock_acquire(lock, RPMLOCK_WRITE); +- if (!locked && (lock->openmode & RPMLOCK_WRITE) && maywait) { ++ if (!locked && (lock->openmode & RPMLOCK_WRITE)) { + rpmlog(RPMLOG_WARNING, _("waiting for %s lock on %s\n"), + lock->descr, lock->path); + locked = rpmlock_acquire(lock, (RPMLOCK_WRITE|RPMLOCK_WAIT)); +-- +1.7.12.4 + diff --git a/call-process_digest_list-after-files-are-added.patch b/call-process_digest_list-after-files-are-added.patch new file mode 100644 index 0000000..4809b58 --- /dev/null +++ b/call-process_digest_list-after-files-are-added.patch @@ -0,0 +1,115 @@ +From 641ec5a50cb5057e02c4cfe7bd537a32fafdd665 Mon Sep 17 00:00:00 2001 +From: Roberto Sassu <roberto.sassu@huawei.com> +Date: Mon, 26 Oct 2020 12:10:31 +0800 +Subject: [PATCH] call process_digest_list after files are added + +Signed-off-by: Anakin Zhang <benjamin93@163.com> +--- + plugins/digest_list.c | 78 ++++++++++++++++++++++++++++++++++++++----- + 1 file changed, 69 insertions(+), 9 deletions(-) + +diff --git a/plugins/digest_list.c b/plugins/digest_list.c +index 9fcb5c4..7213b41 100644 +--- a/plugins/digest_list.c ++++ b/plugins/digest_list.c +@@ -479,28 +479,88 @@ out: + return ret; + } + ++rpmte cur_te; ++int digest_list_counter; ++ + static rpmRC digest_list_psm_pre(rpmPlugin plugin, rpmte te) + { +- process_digest_list(te, 0); +- if (!strcmp(rpmteN(te), "digest-list-tools")) +- process_digest_list(te, 1); ++ Header rpm = rpmteHeader(te); ++ rpmtd dirnames; ++ int i; ++ ++ digest_list_counter = 0; ++ ++ dirnames = rpmtdNew(); ++ headerGet(rpm, RPMTAG_DIRNAMES, dirnames, 0); ++ ++ while ((i = rpmtdNext(dirnames)) >= 0) { ++ char *dirname = (char *) rpmtdGetString(dirnames); ++ if (!strncmp(dirname, DIGEST_LIST_DEFAULT_PATH, ++ sizeof(DIGEST_LIST_DEFAULT_PATH) - 1)) ++ digest_list_counter++; ++ } + ++ rpmtdFree(dirnames); ++ ++ cur_te = te; + return RPMRC_OK; + } + +-static rpmRC digest_list_psm_post(rpmPlugin plugin, rpmte te, int res) ++static rpmRC digest_list_file_common(rpmPlugin plugin, rpmfi fi, ++ const char* path, mode_t file_mode, ++ rpmFsmOp op, int pre, int res) + { +- if (res != RPMRC_OK) ++ rpmFileAction action = XFO_ACTION(op); ++ ++ if (!digest_list_counter) ++ return RPMRC_OK; ++ ++ if (!cur_te) ++ return RPMRC_OK; ++ ++ if (!pre && res != RPMRC_OK) ++ return res; ++ ++ if ((pre && action != FA_ERASE) || ++ (!pre && action != FA_CREATE)) + return RPMRC_OK; + +- process_digest_list(te, 0); +- if (!strcmp(rpmteN(te), "digest-list-tools")) +- process_digest_list(te, 1); ++ if (digest_list_counter) { ++ if (!pre) { ++ if (!strncmp(path, DIGEST_LIST_DEFAULT_PATH, ++ sizeof(DIGEST_LIST_DEFAULT_PATH) - 1)) ++ digest_list_counter--; ++ } else { ++ digest_list_counter = 0; ++ } ++ ++ if (digest_list_counter) ++ return RPMRC_OK; ++ } ++ ++ process_digest_list(cur_te, 0); ++ if (!strcmp(rpmteN(cur_te), "digest-list-tools")) ++ process_digest_list(cur_te, 1); + + return RPMRC_OK; + } + ++static rpmRC digest_list_file_pre(rpmPlugin plugin, rpmfi fi, ++ const char* path, mode_t file_mode, ++ rpmFsmOp op) ++{ ++ return digest_list_file_common(plugin, fi, path, file_mode, op, 1, 0); ++} ++ ++static rpmRC digest_list_file_post(rpmPlugin plugin, rpmfi fi, ++ const char* path, mode_t file_mode, ++ rpmFsmOp op, int res) ++{ ++ return digest_list_file_common(plugin, fi, path, file_mode, op, 0, res); ++} ++ + struct rpmPluginHooks_s digest_list_hooks = { + .psm_pre = digest_list_psm_pre, +- .psm_post = digest_list_psm_post, ++ .fsm_file_pre = digest_list_file_pre, ++ .fsm_file_post = digest_list_file_post, + }; +-- +2.23.0 + diff --git a/dont-remove-ima-xattr-of-parser-when-upgrading.patch b/dont-remove-ima-xattr-of-parser-when-upgrading.patch new file mode 100644 index 0000000..b2e0424 --- /dev/null +++ b/dont-remove-ima-xattr-of-parser-when-upgrading.patch @@ -0,0 +1,35 @@ +From 2c27c71952ce3ac61afeabd3ef4e1d182574e905 Mon Sep 17 00:00:00 2001 +From: luhuaxin <luhuaxin1@huawei.com> +Date: Tue, 15 Mar 2022 20:54:06 +0800 +Subject: [PATCH] dont remove ima xattr of parser when upgrading + +Signed-off-by: luhuaxin <luhuaxin1@huawei.com> +--- + plugins/digest_list.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/plugins/digest_list.c b/plugins/digest_list.c +index 0692b5b..1d7ef92 100644 +--- a/plugins/digest_list.c ++++ b/plugins/digest_list.c +@@ -576,9 +576,16 @@ static rpmRC digest_list_file_common(rpmPlugin plugin, rpmfi fi, + if (!pre && --digest_list_counter) + return RPMRC_OK; + ++ rpmlog(RPMLOG_DEBUG, "process ima digest, pre: %d, action: %d, teType: %d\n", ++ pre, action, rpmteType(cur_te)); + process_digest_list(cur_te, 0, pre); +- if (!strcmp(rpmteN(cur_te), "digest-list-tools")) ++ if (!strcmp(rpmteN(cur_te), "digest-list-tools")) { ++ if (pre && rpmteType(cur_te) == TR_REMOVED) ++ return RPMRC_OK; ++ ++ rpmlog(RPMLOG_DEBUG, "process parser digest\n"); + process_digest_list(cur_te, 1, pre); ++ } + + return RPMRC_OK; + } +-- +2.33.0 + diff --git a/fix-lsetxattr-error-in-container.patch b/fix-lsetxattr-error-in-container.patch new file mode 100644 index 0000000..c7cd4da --- /dev/null +++ b/fix-lsetxattr-error-in-container.patch @@ -0,0 +1,64 @@ +From 848cad38da6c727c91f0fcb8052f9402de598737 Mon Sep 17 00:00:00 2001 +From: Zhang Tianxing <zhangtianxing3@huawei.com> +Date: Mon, 13 Sep 2021 17:32:11 +0800 +Subject: [PATCH] fix lsetxattr error in container + +The digest list plugin in rpm will set security.ima xattr to IMA digest lists +when installing or updating an rpm package. However, in a container without +CAP_SYS_ADMIN, we'll get error messages when calling lsetxattr. + +This patch is to skip lsetxattr when CAP_SYS_ADMIN is missing. + +Signed-off-by: Zhang Tianxing <zhangtianxing3@huawei.com> +--- + plugins/digest_list.c | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +diff --git a/plugins/digest_list.c b/plugins/digest_list.c +index 6bc9415..2d14463 100644 +--- a/plugins/digest_list.c ++++ b/plugins/digest_list.c +@@ -12,6 +12,7 @@ + #include <sys/stat.h> + #include <openssl/sha.h> + #include <sys/xattr.h> ++#include <sys/capability.h> + #include <linux/xattr.h> + #include <asm/byteorder.h> + #include <sys/wait.h> +@@ -370,6 +371,10 @@ static int process_digest_list(rpmte te, int parser) + int digest_list_signed = 0; + struct stat st; + ssize_t size; ++ struct __user_cap_header_struct cap_header_data; ++ cap_user_header_t cap_header = &cap_header_data; ++ struct __user_cap_data_struct cap_data_data; ++ cap_user_data_t cap_data = &cap_data_data; + rpmRC ret = RPMRC_OK; + + path = malloc(PATH_MAX); +@@ -435,7 +440,21 @@ static int process_digest_list(rpmte te, int parser) + ret = RPMRC_FAIL; + goto out; + } ++ } + ++ /* don't call lsetxattr without CAP_SYS_ADMIN */ ++ cap_header->pid = getpid(); ++ cap_header->version = _LINUX_CAPABILITY_VERSION_1; ++ if (capget(cap_header, cap_data) < 0) { ++ ret = -ENOENT; ++ goto out; ++ } ++ if (!(cap_data->effective & CAP_TO_MASK(CAP_SYS_ADMIN))) { ++ ret = -EPERM; ++ goto out; ++ } ++ ++ if (!digest_list_signed) { + /* Write RPM header sig to security.ima */ + ret = write_rpm_digest_list_ima_xattr(te, path); + } else { +-- +2.27.0 + diff --git a/get-in-use-of-ndb.patch b/get-in-use-of-ndb.patch new file mode 100644 index 0000000..c3d31ff --- /dev/null +++ b/get-in-use-of-ndb.patch @@ -0,0 +1,42 @@ +From 8ba0780a26429bbb474e23112627ebbaeb9abfee Mon Sep 17 00:00:00 2001 +From: renmingshuai <renmingshuai@huawei.com> +Date: Mon, 29 Nov 2021 10:53:24 +0800 +Subject: [PATCH] get in use of ndb + +--- + configure.ac | 4 ++-- + macros.in | 2 +- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/configure.ac b/configure.ac +index 6b161dc..ab1c667 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -490,9 +490,9 @@ AM_CONDITIONAL([BDB_RO], [test "$enable_bdb_ro" = yes]) + # Check for SQLITE support + AC_ARG_ENABLE([sqlite], + [AS_HELP_STRING([--enable-sqlite=@<:@yes/no/auto@:>@)], +- [build with sqlite rpm database format support (default=yes)])], ++ [build with sqlite rpm database format support (default=auto)])], + [enable_sqlite="$enableval"], +- [enable_sqlite=yes]) ++ [enable_sqlite=auto]) + + AS_IF([test "x$enable_sqlite" != "xno"], [ + PKG_CHECK_MODULES([SQLITE], [sqlite3 >= 3.22.0], [have_sqlite=yes], [have_sqlite=no]) +diff --git a/macros.in b/macros.in +index 22f675c..3e81918 100644 +--- a/macros.in ++++ b/macros.in +@@ -602,7 +602,7 @@ package or when debugging this package.\ + # sqlite Sqlite database + # dummy dummy backend (no actual functionality) + # +-%_db_backend sqlite ++%_db_backend ndb + + #============================================================================== + # ---- GPG/PGP/PGP5 signature macros. +-- +1.8.3.1 + diff --git a/revert-always-execute-file-trigger-scriptlet-callbac.patch b/revert-always-execute-file-trigger-scriptlet-callbac.patch new file mode 100644 index 0000000..c8fd59c --- /dev/null +++ b/revert-always-execute-file-trigger-scriptlet-callbac.patch @@ -0,0 +1,26 @@ +From 9680c3f2f8ceeddced6e91048daeb9b93abf4c8d Mon Sep 17 00:00:00 2001 +From: openEuler Buildteam <buildteam@openeuler.org> +Date: Wed, 25 Mar 2020 16:57:29 +0800 +Subject: [PATCH] revert always execute file trigger scriptlet callbacks with + owning header + +--- + lib/rpmtriggers.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/rpmtriggers.c b/lib/rpmtriggers.c +index 285b2f0..b7c76e7 100644 +--- a/lib/rpmtriggers.c ++++ b/lib/rpmtriggers.c +@@ -437,7 +437,7 @@ static int runHandleTriggersInPkg(rpmts ts, rpmte te, Header h, + inputFunc = (char *(*)(void *)) matchFilesNext; + rpmScriptSetNextFileFunc(script, inputFunc, mfi); + +- nerrors += runScript(ts, NULL, h, installPrefixes.data, ++ nerrors += runScript(ts, te, h, installPrefixes.data, + script, 0, -1); + rpmtdFreeData(&installPrefixes); + rpmScriptFree(script); +-- +1.8.3.1 + diff --git a/rpm-4.12.0-rpm2cpio-hack.patch b/rpm-4.12.0-rpm2cpio-hack.patch new file mode 100644 index 0000000..38c7dbd --- /dev/null +++ b/rpm-4.12.0-rpm2cpio-hack.patch @@ -0,0 +1,18 @@ +diff --git a/rpm2cpio.c b/rpm2cpio.c +index 89ebdfa..ae999ff 100644 +--- a/rpm2cpio.c ++++ b/rpm2cpio.c +@@ -84,7 +84,12 @@ int main(int argc, char *argv[]) + exit(EXIT_FAILURE); + } + +- rc = (ufdCopy(gzdi, fdo) == payload_size) ? EXIT_SUCCESS : EXIT_FAILURE; ++ /* ++ * XXX HACK for #1142949: should be equality test, but archive size ++ * short by cpio trailer size in packages built with rpm 4.12.0 ++ * and its pre-releases. ++ */ ++ rc = (ufdCopy(gzdi, fdo) >= payload_size) ? EXIT_SUCCESS : EXIT_FAILURE; + + Fclose(fdo); + diff --git a/rpm-Add-sw64-architecture.patch b/rpm-Add-sw64-architecture.patch new file mode 100644 index 0000000..93b493b --- /dev/null +++ b/rpm-Add-sw64-architecture.patch @@ -0,0 +1,172 @@ +From 3c8ac8643a0d7c3c3ce972c0a0685d9d1c9de9bc Mon Sep 17 00:00:00 2001 +From: wzx <wuzx1226@qq.com> +Date: Thu, 27 Oct 2022 11:27:23 +0800 +Subject: [PATCH] Add sw64 architecture + +Add sw64 architecture in file config.guess config.sub installplatform lib/rpmrc.c macros.in rpmrc.in and tools/elfdeps.c to support sw64 architecture. + +Signed-off-by: wzx <wuzx1226@qq.com> +--- + build-aux/config.guess | 8 ++++++++ + build-aux/config.sub | 1 + + installplatform | 6 ++++++ + lib/rpmrc.c | 7 +++++++ + macros.in | 1 + + rpmrc.in | 15 +++++++++++++++ + tools/elfdeps.c | 1 + + 7 files changed, 39 insertions(+) + +diff --git a/build-aux/config.guess b/build-aux/config.guess +index b33c9e8..69e3005 100755 +--- a/build-aux/config.guess ++++ b/build-aux/config.guess +@@ -913,6 +913,14 @@ EOF + UNAME_MACHINE=aarch64_be + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; ++ sw_64:Linux:*:*) ++ case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in ++ sw) UNAME_MACHINE=sw_64 ;; ++ esac ++ objdump --private-headers /bin/sh | grep -q ld.so.1 ++ if test "$?" = 0 ; then LIBC=gnulibc1 ; fi ++ echo "$UNAME_MACHINE"-sunway-linux-"$LIBC" ++ exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; +diff --git a/build-aux/config.sub b/build-aux/config.sub +index b51fb8c..84a8688 100755 +--- a/build-aux/config.sub ++++ b/build-aux/config.sub +@@ -1155,6 +1155,7 @@ case $cpu-$vendor in + case $cpu in + 1750a | 580 \ + | a29k \ ++ | sw_64 \ + | aarch64 | aarch64_be \ + | abacus \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] \ +diff --git a/installplatform b/installplatform +index ca490e0..2700199 100755 +--- a/installplatform ++++ b/installplatform +@@ -108,6 +108,12 @@ for ARCH in noarch `grep ^arch_canon $RPMRC | cut -d: -f2`; do + CANONARCH=arm + CANONCOLOR=0 + ;; ++ sw_64*) ++ ISANAME=sw_64 ++ ISABITS=64 ++ CANONARCH=sw_64 ++ CANONCOLOR=0 ++ ;; + alpha*) + ISANAME=alpha + ISABITS=64 +diff --git a/lib/rpmrc.c b/lib/rpmrc.c +index 120777c..5d9507d 100644 +--- a/lib/rpmrc.c ++++ b/lib/rpmrc.c +@@ -1268,6 +1268,13 @@ static void defaultMachine(rpmrcCtx ctx, const char ** arch, const char ** os) + } + # endif + ++# if defined(__GNUC__) && defined(__sw_64__) ++ { ++ strcpy(un.machine, "sw_64sw6b"); ++ } ++# endif ++ ++ + # if defined(__linux__) && defined(__i386__) + { + char mclass = (char) (RPMClass() | '0'); +diff --git a/macros.in b/macros.in +index 4dbf5b6..6722a74 100644 +--- a/macros.in ++++ b/macros.in +@@ -1107,6 +1107,7 @@ package or when debugging this package.\ + #------------------------------------------------------------------------------ + # arch macro for all supported Alpha processors + %alpha alpha alphaev56 alphaev6 alphaev67 ++%sw_64 sw_64 sw_64sw6b + + #------------------------------------------------------------------------------ + # arch macro for all supported PowerPC 64 processors +diff --git a/rpmrc.in b/rpmrc.in +index 3a48af4..8d70f91 100644 +--- a/rpmrc.in ++++ b/rpmrc.in +@@ -25,6 +25,9 @@ optflags: x86_64 -O2 -g + optflags: amd64 -O2 -g + optflags: ia32e -O2 -g + ++optflags: sw_64 -O2 -g -mieee ++optflags: sw_64sw6b -O2 -g -mieee -mtune=sw6b ++ + optflags: alpha -O2 -g -mieee + optflags: alphaev5 -O2 -g -mieee -mtune=ev5 + optflags: alphaev56 -O2 -g -mieee -mtune=ev56 +@@ -112,6 +115,7 @@ optflags: riscv64 -O2 -g + archcolor: noarch 0 + archcolor: i386 1 + archcolor: alpha 2 ++archcolor: sw_64 2 + archcolor: sparc 1 + archcolor: sparc64 2 + archcolor: sparcv9 2 +@@ -176,6 +180,9 @@ arch_canon: amd64: amd64 1 + arch_canon: ia32e: ia32e 1 + arch_canon: em64t: em64t 1 + ++arch_canon: sw_64: sw_64 2 ++arch_canon: sw_64sw6b: sw_64sw6b 2 ++ + arch_canon: alpha: alpha 2 + arch_canon: alphaev5: alphaev5 2 + arch_canon: alphaev56: alphaev56 2 +@@ -315,6 +322,9 @@ buildarchtranslate: i586: i386 + buildarchtranslate: i486: i386 + buildarchtranslate: i386: i386 + ++buildarchtranslate: sw_64: sw_64 ++buildarchtranslate: sw_64sw6b: sw_64 ++ + buildarchtranslate: alphaev5: alpha + buildarchtranslate: alphaev56: alpha + buildarchtranslate: alphapca56: alpha +@@ -401,6 +411,8 @@ buildarchtranslate: riscv64: riscv64 + + #########################################/#################### + # Architecture compatibility ++arch_compat: sw_64sw6b: sw_64 ++arch_compat: sw_64: axp noarch + + arch_compat: alphaev67: alphaev6 + arch_compat: alphaev6: alphapca56 +@@ -570,6 +582,9 @@ buildarch_compat: sparcv9: sparcv8 + buildarch_compat: sparcv8: sparc + buildarch_compat: sparc: noarch + ++buildarch_compat: sw_64sw6b: sw_64 ++buildarch_compat: sw_64: noarch ++ + buildarch_compat: alphaev67: alphaev6 + buildarch_compat: alphaev6: alphapca56 + buildarch_compat: alphapca56: alphaev56 +diff --git a/tools/elfdeps.c b/tools/elfdeps.c +index d205935..590021b 100644 +--- a/tools/elfdeps.c ++++ b/tools/elfdeps.c +@@ -85,6 +85,7 @@ static const char *mkmarker(GElf_Ehdr *ehdr) + if (ehdr->e_ident[EI_CLASS] == ELFCLASS64) { + switch (ehdr->e_machine) { + case EM_ALPHA: ++ case EM_SW_64: + case EM_FAKE_ALPHA: + /* alpha doesn't traditionally have 64bit markers */ + break; +-- +2.33.0 + diff --git a/rpm-selinux-plugin-check-context-file-exist.patch b/rpm-selinux-plugin-check-context-file-exist.patch new file mode 100644 index 0000000..56d7982 --- /dev/null +++ b/rpm-selinux-plugin-check-context-file-exist.patch @@ -0,0 +1,26 @@ +From 55708fd5822a3e4bf5537002a648f32cb0a6e07e Mon Sep 17 00:00:00 2001 +From: luhuaxin <1539327763@qq.com> +Date: Tue, 26 Oct 2021 18:39:46 +0800 +Subject: [PATCH] rpm selinux plugin check context file exist + +--- + plugins/selinux.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/plugins/selinux.c b/plugins/selinux.c +index 1254517..fb8b7a2 100644 +--- a/plugins/selinux.c ++++ b/plugins/selinux.c +@@ -63,7 +63,8 @@ static rpmRC selinux_tsm_pre(rpmPlugin plugin, rpmts ts) + rpmRC rc = RPMRC_OK; + + /* If SELinux isn't enabled on the system, dont mess with it */ +- if (!is_selinux_enabled()) { ++ if (!is_selinux_enabled() || selinux_file_context_path() == NULL || ++ access(selinux_file_context_path(), F_OK)) { + rpmtsSetFlags(ts, (rpmtsFlags(ts) | RPMTRANS_FLAG_NOCONTEXTS)); + } + +-- +2.23.0 + diff --git a/rpm.spec b/rpm.spec new file mode 100644 index 0000000..a9f2f34 --- /dev/null +++ b/rpm.spec @@ -0,0 +1,733 @@ +Name: rpm +Version: 4.17.0 +Release: 30 +Summary: RPM Package Manager +License: GPLv2+ +URL: http://www.rpm.org/ +Source0: http://ftp.rpm.org/releases/rpm-4.17.x/%{name}-%{version}.tar.bz2 + +Patch1: Unbundle-config-site-and-add-RPM-LD-FLAGS-macro.patch +Patch2: rpm-4.12.0-rpm2cpio-hack.patch +Patch3: add-dist-to-release-by-default.patch +Patch4: revert-always-execute-file-trigger-scriptlet-callbac.patch +Patch5: bugfix-rpm-4.11.3-add-aarch64_ilp32-arch.patch +Patch6: bugfix-rpm-4.14.2-wait-once-get-rpmlock-fail.patch +Patch7: Generate-digest-lists.patch +Patch8: Add-digest-list-plugin.patch +Patch9: Don-t-add-dist-to-release-if-it-is-already-there.patch +Patch10: Generate-digest-lists-before-calling-genCpioListAndH.patch +Patch11: call-process_digest_list-after-files-are-added.patch +Patch12: fix-lsetxattr-error-in-container.patch +Patch13: rpm-selinux-plugin-check-context-file-exist.patch +Patch14: get-in-use-of-ndb.patch +Patch15: still-in-use-of-python-scripts-from-old-version.patch +Patch16: Add-loongarch-architecture-support.patch +Patch17: Fix-digest_list_counter.patch +Patch18: Check-rpm-parser.patch +Patch19: Remove-digest-list-from-the-kernel-during-package-re.patch +Patch20: Add-license-to-digest_list.c.patch +Patch21: Avoid-generating-digest-lists-if-they-are-already-pa.patch +Patch22: dont-remove-ima-xattr-of-parser-when-upgrading.patch +Patch23: rpm-Add-sw64-architecture.patch +Patch24: 0001-add-default-machine-name-to-support-loongarch.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 +Patch6012: backport-Fix-possible-NULL-pointer-dereference-in-rpmfcClassi.patch +Patch6013: backport-Fix-old-Python-ts.check-argument-order-regression.patch +Patch6014: backport-Fix-memory-leak-in-pgpPrtParams.patch +Patch6015: backport-Fix-use-after-free-in-haveSignature.patch +Patch6016: backport-Close-file-before-replacing-signed.patch +Patch6017: backport-Fix-__cplusplus-misspelled-as-_cplusplus.patch +Patch6018: backport-treat-0-as-valid-file-descriptor.patch +Patch6019: backport-Skip-recorded-symlinks-in-setperms-RhBug-1900662.patch +Patch6020: backport-Check-that-the-CRC-length-is-correct.patch +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 + +Patch6038: backport-Add-optional-callback-on-directory-changes-during-rp.patch +Patch6039: backport-CVE-2021-35937-CVE-2021-35939.patch +Patch6040: backport-Consolidate-skipped-hardlink-with-content-case-with-.patch +Patch6041: backport-Fix-sanitize-the-hardlink-metadata-setting-logic.patch +Patch6042: backport-Convert-the-file-creation-steps-the-at-family-of-cal.patch +Patch6043: backport-Bury-rpmio-FD-use-to-fsmUnpack.patch +Patch6044: backport-Return-descriptor-of-created-file-from-fsmMkfile.patch +Patch6045: backport-CVE-2021-35938.patch +Patch6046: backport-rpm2cpio.sh-strip-null-bytes-with-tr.patch +Patch6047: backport-rpm2cpio.sh-only-read-needed-bytes-of-file-magic.patch +Patch6048: backport-Fix-rpm-lua-rpm_vercmp-error-message-if-second-argum.patch +Patch6049: backport-Make-pgpPubkeyFingerprint-do-something-meaningful-ag.patch +Patch6050: backport-Fix-possible-descriptor-leak-in-fsmOpenat.patch +Patch6051: backport-Move-file-metadata-setting-back-to-unpack-stage.patch +Patch6052: backport-Fix-header-leak-in-rpmInstall.patch +Patch6053: backport-Fix-eiu-sourceURL-info-leak-in-rpmInstall.patch +Patch6054: backport-Fix-h-blob-leak-when-installing-source-rpms.patch +Patch6055: backport-Fix-Header-leak-when-running-rpm2cpio.patch +Patch6056: backport-Use-unsigned-integers-more-consistently-in-the-handl.patch +Patch6057: backport-Fix-file-leak-when-src-rpm-in-URL-format-is-used-for.patch +Patch6058: backport-Fix-BANames-leak-in-handlePreambleTag.patch +Patch6059: backport-Fix-prog-leak-in-parseScript.patch +Patch6060: backport-Fix-elf-leak-in-getElfColor.patch +Patch6061: backport-Fix-sbp-leak-when-running-rpmbuild-with-quiet.patch +Patch6062: backport-Fix-memleak-when-running-generate_buildrequires.patch +Patch6063: backport-Fix-memleak-when-fsmRename-failed-in-fsmCommit.patch +Patch6064: backport-Fix-fileleak-and-memleak-in-rpmInstall.patch +Patch6065: backport-Fix-fileleak-when-urlGetFile-fails-in-rpmInstall.patch + +Patch6066: backport-Fix-install-of-block-and-character-special-files-219.patch +Patch6067: backport-Use-fd-based-ops-for-metadata-in-FA_TOUCH-mode-too-w.patch +Patch6068: backport-Add-a-test-for-special-device-node-installation.patch +Patch6069: backport-support-for-POSIX-getopt-behaviour.patch +Patch6070: backport-Use-proper-type-for-copyTagsFromMainDebug.patch +Patch6071: backport-Fix-a-copy-paste-help-description-of-whatconflicts-R.patch +Patch6072: backport-Fix-a-segfault-on-a-non-stringable-argument-to-macro.patch + +Patch6073: backport-Remove-obscure-check-for-package-build-time-from-reb.patch +Patch6074: backport-Fix-possible-null-pointer-reference-in-ndb.patch +Patch6075: backport-Fix-rpmDigestBundleFinal-and-Update-return-code-on-i.patch +Patch6076: backport-Actually-return-an-error-in-parseScript-if-parsing-f.patch +Patch6077: backport-Check-inside-root-when-querying-for-files.patch +Patch6078: backport-bugfix-wrong-symlink-length-on-some-filesystems.patch + +BuildRequires: gcc autoconf automake libtool make gawk popt-devel openssl-devel readline-devel +BuildRequires: zlib-devel zstd-devel >= 1.3.8 xz-devel bzip2-devel libarchive-devel ima-evm-utils-devel +BuildRequires: dbus-devel fakechroot elfutils-devel elfutils-libelf-devel ima-evm-utils +BuildRequires: lua-devel libcap-devel libacl-devel libselinux-devel file-devel gettext-devel ncurses-devel +BuildRequires: system-rpm-config dwz gnupg2 debugedit +Requires: coreutils popt curl zstd >= 1.4.0 libcap crontabs logrotate +Obsoletes: %{name}-build-libs %{name}-sign-libs %{name}-sign %{name}-cron +Provides: %{name}-build-libs %{name}-sign-libs %{name}-sign %{name}-cron +Obsoletes: %{name}-plugin-selinux %{name}-plugin-syslog %{name}-plugin-systemd-inhibit < 4.15.1-28 %{name}-plugin-ima %{name}-plugin-prioreset +Provides: %{name}-plugin-selinux %{name}-plugin-syslog %{name}-plugin-ima %{name}-plugin-prioreset + +%description +The RPM Package Manager (RPM) is a powerful package management system capability as below + +-building computer software from source into easily distributable packages +-installing, updating and uninstalling packaged software +-querying detailed information about the packaged software, whether installed or not +-verifying integrity of packaged software and resulting software installation + +%package libs +Summary: Shared library of rpm 4.17 +Requires: %{name} = %{version}-%{release} + +%description libs +Shared library of rpm 4.17. + +%package build +Summary: Scripts and executable programs used to build packages +Requires: %{name} = %{version}-%{release} +Requires: elfutils binutils findutils sed grep gawk diffutils file patch +Requires: tar unzip gzip bzip2 cpio xz zstd pkgconfig system-rpm-config +Requires: gdb-headless debugedit + +%description build +This package provides scripts and executable programs that used to +build rpm packages. + +%package -n python3-%{name} +Summary: Python3 bindings for RPM user +BuildRequires: python3-devel +%{?python_provide:%python_provide python3-%{name}} +Requires: %{name} = %{version}-%{release} +Provides: %{name}-python3 = %{version}-%{release} +Obsoletes: %{name}-python3 < %{version}-%{release} + +%description -n python3-%{name} +This package contains a module that allow applications +written with Python3 to use the interface +supplied by RPM. + +%package devel +Summary: Development files for RPM handling +Requires: %{name} = %{version}-%{release} +Requires: popt-devel + +%description devel +%{summary}. + +%package plugin-systemd-inhibit +Summary: rpm plugin to get systemd-inhibit lock +Requires: %{name} = %{version}-%{release} + +%description plugin-systemd-inhibit +This package use systemd-inhibit to block systemd from entering +idle, sleep or shutdown while an rpm transcation is running. + +%package help +Summary: Man page for %{name} +BuildArch: noarch +Obsoletes: apidocs + +%description help +%{summary}. + +%prep +%autosetup -n %{name}-%{version} -p1 +%ifnarch sw_64 +%patch23 -R -p1 +%endif + +%build +CPPFLAGS="$CPPFLAGS -DLUA_COMPAT_APIINTCASTS" +CFLAGS="$RPM_OPT_FLAGS -DLUA_COMPAT_APIINTCASTS" +LDFLAGS="$LDFLAGS %{?__global_ldflags}" +export CPPFLAGS CFLAGS LDFLAGS + +autoreconf -i -f + +for i in $(find . -name ltmain.sh) ; do + %{__sed} -i.backup -e 's~compiler_flags=$~compiler_flags="%{_hardened_ldflags}"~' $i +done; + +./configure \ + --prefix=%{_usr} \ + --sysconfdir=%{_sysconfdir} \ + --localstatedir=%{_var} \ + --sharedstatedir=%{_var}/lib \ + --libdir=%{_libdir} \ + --build=%{_target_platform} \ + --host=%{_target_platform} \ + --with-vendor=%{_vendor} \ + --with-external-db \ + --with-lua \ + --with-selinux \ + --with-cap \ + --with-acl \ + --with-imaevm \ + --enable-zstd \ + --enable-python \ + --enable-bdb-ro \ + --enable-ndb \ + --enable-bdb=no \ + --enable-sqlite=no \ + --with-crypto=openssl \ + --with-fapolicyd=no \ + --with-fsverity=no + +%make_build + +pushd python +%{__python3} setup.py build +popd + +%install +%make_install + +pushd python +%{__python3} setup.py install --skip-build --root $RPM_BUILD_ROOT +popd + +mkdir -p ${RPM_BUILD_ROOT}%{_sysconfdir}/cron.daily +install -m 755 scripts/rpm.daily ${RPM_BUILD_ROOT}%{_sysconfdir}/cron.daily/rpm + +# During the upgrade of the major rpm version, the dynamic library may not be compatible. +# Therefore, ensure that no other rpm command is executed during the upgrade. A judgment +# is added to the RPM script of the scheduled task. If the dynamic library is not the +# dynamic library of the current version, exits directly. +pushd ${RPM_BUILD_ROOT}%{_libdir} +export SONAME=`ls librpm.so.*.*.*` +popd +sed -i "/bin\/sh/a \ +if [ ! -e %{_libdir}\/${SONAME} ]; then\n\ + exit 0\n\ +fi" ${RPM_BUILD_ROOT}%{_sysconfdir}/cron.daily/rpm +cp ${RPM_BUILD_ROOT}%{_sysconfdir}/cron.daily/rpm ${RPM_BUILD_ROOT}%{_rpmconfigdir}/rpm.daily + +mkdir -p ${RPM_BUILD_ROOT}%{_sysconfdir}/logrotate.d +install -m 644 scripts/rpm.log ${RPM_BUILD_ROOT}%{_sysconfdir}/logrotate.d/rpm + +install -m 755 build-aux/config.guess ${RPM_BUILD_ROOT}%{_rpmconfigdir}/ +install -m 755 build-aux/config.sub ${RPM_BUILD_ROOT}%{_rpmconfigdir}/ + +mkdir -p ${RPM_BUILD_ROOT}/usr/lib/tmpfiles.d +echo "r /var/lib/rpm/__db.*" > ${RPM_BUILD_ROOT}/usr/lib/tmpfiles.d/rpm.conf + +mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/rpm +mkdir -p $RPM_BUILD_ROOT%{_rpmconfigdir}/macros.d +mkdir -p $RPM_BUILD_ROOT/var/lib/rpm + +./rpmdb --define "_db_backend ndb" --dbpath=$(pwd)/ndb/ --initdb +cp -va ndb/. $RPM_BUILD_ROOT/var/lib/rpm/ + +%find_lang %{name} + +find $RPM_BUILD_ROOT -name "*.la"|xargs rm -f + +rm -f $RPM_BUILD_ROOT/%{_rpmconfigdir}/{perldeps.pl,perl.*,pythond*} +rm -f $RPM_BUILD_ROOT/%{_fileattrsdir}/{perl*,python*} +rm -f $RPM_BUILD_ROOT/%{_rpmconfigdir}/{tcl.req,osgideps.pl} +rm -f $RPM_BUILD_ROOT/%{_sysconfdir}/dbus-1/system.d/org.rpm.conf + +%check +%ifnarch loongarch64 +make check || (cat tests/rpmtests.log; exit 0) +%endif + +%post -p /sbin/ldconfig + +%postun -p /sbin/ldconfig + +%post libs -p /sbin/ldconfig + +%postun libs -p /sbin/ldconfig + +%posttrans +{ + set -e + disable_auto_rebuilddb=$(rpm -E 0%%{?_disable_auto_rebuilddb}) + if [ ${disable_auto_rebuilddb} -eq 0 ]; then + dbpath=$(rpm -E %{_dbpath}) + while [ -e ${dbpath}/Packages ] + do + date >> /var/log/rebuilddb.log 2>&1 + rpm -vvv --rebuilddb >> /var/log/rebuilddb.log 2>&1 + done + fi +} & + +%files -f %{name}.lang +%defattr(-,root,root) +%license COPYING +%doc CREDITS +/usr/lib/tmpfiles.d/rpm.conf +%{_sysconfdir}/cron.daily/rpm +%config(noreplace) %{_sysconfdir}/logrotate.d/rpm +%dir %{_sysconfdir}/rpm +%dir /var/lib/rpm +%attr(0644, root, root) %ghost %config(missingok,noreplace) /var/lib/rpm/* +%attr(0644, root, root) %ghost /var/lib/rpm/.*.lock +%lang(fr) %{_mandir}/fr/man[18]/*.[18]* +%lang(ko) %{_mandir}/ko/man[18]/*.[18]* +%lang(ja) %{_mandir}/ja/man[18]/*.[18]* +%lang(pl) %{_mandir}/pl/man[18]/*.[18]* +%lang(ru) %{_mandir}/ru/man[18]/*.[18]* +%lang(sk) %{_mandir}/sk/man[18]/*.[18]* + +%attr(0755, root, root) %dir %{_rpmconfigdir} +%{_rpmconfigdir}/macros +%{_rpmconfigdir}/macros.d +%{_rpmconfigdir}/rpmpopt* +%{_rpmconfigdir}/rpmrc +%{_rpmconfigdir}/rpmdb_* +%{_rpmconfigdir}/rpm.daily +%{_rpmconfigdir}/rpm.log +%{_rpmconfigdir}/rpm.supp +%{_rpmconfigdir}/rpm2cpio.sh +%{_rpmconfigdir}/tgpg +%{_rpmconfigdir}/platform +%{_libdir}/rpm-plugins/ +%exclude %{_libdir}/rpm-plugins/systemd_inhibit.so +%exclude %{_libdir}/rpm-plugins/fsverity.so +%exclude %{_libdir}/rpm-plugins/dbus_announce.so +%dir %{_rpmconfigdir}/fileattrs +%{_bindir}/rpm +%{_bindir}/rpm2archive +%{_bindir}/rpm2cpio +%{_bindir}/rpmdb +%{_bindir}/rpmkeys +%{_bindir}/rpmquery +%{_bindir}/rpmverify +%{_bindir}/rpmsign + +%files libs +%{_libdir}/librpm*.so.9* + +%files build +%defattr(-,root,root) +%{_bindir}/rpmbuild +%{_bindir}/gendiff +%{_bindir}/rpmspec + +%{_rpmconfigdir}/brp-* +%{_rpmconfigdir}/check-* +%{_rpmconfigdir}/find-lang.sh +%{_rpmconfigdir}/*provides* +%{_rpmconfigdir}/*requires* +%{_rpmconfigdir}/*deps* +%{_rpmconfigdir}/*.prov +%{_rpmconfigdir}/*.req +%{_rpmconfigdir}/mkinstalldirs +%{_rpmconfigdir}/fileattrs/* +%{_rpmconfigdir}/config.* + +%files -n python3-%{name} +%defattr(-,root,root) +%{python3_sitearch}/%{name}/ +%{python3_sitearch}/%{name}-%{version}*.egg-info + +%files devel +%defattr(-,root,root) +%{_bindir}/rpmgraph +%{_libdir}/librp*[a-z].so +%{_libdir}/pkgconfig/%{name}.pc +%{_includedir}/%{name}/ + +%files plugin-systemd-inhibit +%{_libdir}/rpm-plugins/systemd_inhibit.so +%{_mandir}/man8/rpm-plugin-systemd-inhibit.8* + +%files help +%defattr(-,root,root) +%doc docs/manual/[a-z]* +%doc docs/librpm/html/* +%{_mandir}/man8/rpm*.8* +%exclude %{_mandir}/man8/rpm-plugin-systemd-inhibit.8* +%exclude %{_mandir}/man8/rpm-plugin-dbus-announce.8* +%{_mandir}/man1/gendiff.1* + +%changelog +* Sun Sep 10 2023 chencheng<chenc136@chinaunicom.cn> - 4.17.0-31 +- add patch 6078 + +* Fri Sep 08 2023 renhongxun<renhongxun@h-partners.com> - 4.17.0-30 +- support _disable_auto_rebuilddb macro in posttrans + +* Tue Sep 05 2023 renhongxun<renhongxun@h-partners.com> - 4.17.0-29 +- Fix the coredump which may occur during upgrading of rpm + +* Tue Aug 29 2023 renhongxun<renhongxun@h-partners.com> - 4.17.0-28 +- Check inside --root when querying for files + +* Wed Aug 02 2023 renhongxun<renhongxun@h-partners.com> - 4.17.0-27 +- backport some patches from upstream + +* Fri Jun 16 2023 renhongxun<renhongxun@h-partners.com> - 4.17.0-26 +- Fix a segfault on a non-stringable argument to macro call from Lua + +* Tue Jun 13 2023 renhongxun<renhongxun@h-partners.com> - 4.17.0-25 +- Fix a copy-paste --help description of --whatconflicts + +* Tue Feb 28 2023 renhongxun<renhongxun@h-partners.com> - 4.17.0-24 +- bugfix with upstream patches about fifo + +* Mon Dec 26 2022 xujing<xujing125@huawei.com> - 4.17.0-23 +- backport patches from upstream to fix resource leak + +* Mon Dec 19 2022 xujing<xujing125@huawei.com> - 4.17.0-22 +- Fix file leak when src rpm in URL format is used for installation + +* Mon Dec 19 2022 xujing<xujing125@huawei.com> - 4.17.0-21 +- backport patches from upstream to fix memleak + +* Mon Nov 28 2022 renhongxun<renhongxun@h-partners.com> - 4.17.0-20 +- Move file metadata setting back to unpack stage + +* Wed Nov 16 2022 huajingyun<huajingyun@loongson.cn> - 4.17.0-19 +- add default machine name loongarch support +- disable test on loongarch + +* Tue Nov 8 2022 xujing<xujing125@huawei.com> - 4.17.0-18 +- rpm: fix rpm is blocked when open fifo file + +* Mon Nov 7 2022 wuzx<wuzx1226@qq.com> - 4.17.0-17 +- Add sw64 architecture + +* Thu Oct 27 2022 licunlong<licunlong1@huawei.com> - 4.17.0-16 +- sync patches from upstream + +* Fri Sep 09 2022 renhongxun<renhongxun@h-partners.com> - 4.17.0-15 +- sync patches from upstream + +* Wed Aug 31 2022 Hongxun Ren<renhongxun@h-partners.com> - 4.17.0-14 +- fix CVE-2021-35937 CVE-2021-35938 CVE-2021-35939 + +* Tue Aug 16 2022 Kou Wenqi<kouwenqi@kylinos.cn> - 4.17.0-13 +- Type:enhancement +- ID:NA +- SUG:NA +- DESC:requires zstd >= 1.4.0, requires zstd-devel >= 1.3.8 in build + +* Thu Aug 11 2022 renhongxun<renhongxun@h-partners.com> - 4.17.0-12 +- sync some patches from upstream + +* Thu Aug 11 2022 renhongxun<renhongxun@h-partners.com> - 4.17.0-11 +- sync some patches from upstream + +* Mon Aug 08 2022 renhongxun<renhongxun@h-partners.com> - 4.17.0-10 +- sync some patches from upstream + +* Thu Jun 23 2022 renhongxun<renhongxun@h-partners.com> - 4.17.0-9 +- Type:enhancement +- ID:NA +- SUG:NA +- DESC:requires zstd >= 1.5.0 + +* Wed Mar 16 2022 luhuaxin<luhuaxin1@huawei.com> - 4.17.0-8 +- Type:bugfix +- ID:NA +- SUG:NA +- DESC:fix issue of digest-list-tools upgrading + +* Tue Mar 15 2022 luhuaxin<luhuaxin1@huawei.com> - 4.17.0-7 +- Type:bugfix +- ID:NA +- SUG:NA +- DESC:backport IMA patches from 21.03 + +* Thu Feb 17 2022 renhongxun<renhongxun@h-partners.com> - 4.17.0-6 +- Type:bugfix +- ID:NA +- SUG:NA +- DESC:delete some libdb symbolic link + +* Tue Jan 11 2022 Sunhaiyong <sunhaiyong@loongson.cn> - 4.17.0-5 +- Add loongarch support. + +* Thu Jan 06 2022 renhongxun<renhongxun@huawei.com> - 4.17.0-4 +- Type:bugfix +- ID:NA +- SUG:NA +- DESC:delete new plugins' files + +* Tue Jan 04 2022 renhongxun<renhongxun@huawei.com> - 4.17.0-3 +- Type:bugfix +- ID:NA +- SUG:NA +- DESC:disable three new plugins + +* Wed Dec 29 2021 renhongxun<renhongxun@huawei.com> - 4.17.0-2 +- Type:bugfix +- ID:NA +- SUG:NA +- DESC:still in use of python scripts from old version + +* Mon Dec 13 2021 renhongxun<renhongxun@huawei.com> - 4.17.0-1 +- Type:requirement +- ID:NA +- SUG:NA +- DESC:upgrade to 4.17.0 + +* Fri Dec 3 2021 luhuaxin<1539327763@qq.com> - 4.15.1-32 +- Type:bugfix +- ID:NA +- SUG:NA +- DESC:rpm selinux plugin check context file exist + +* Wed Nov 03 2021 tianwei <tianwei12@huawei.com> - 4.15.1-31 +- Type:cve +- ID:NA +- SUG:NA +- DESC:fix CVE-2021-3521 + +* Mon Sep 13 2021 zhangtianxing<zhangtianxing3@huawei.com> - 4.15.1-30 +- Type:bugfix +- ID:NA +- SUG:NA +- DESC:fix lsetxattr error in container + +* Thu Jul 22 2021 liudabo<liudabo1@huawei.com> - 4.15.1-29 +- Type:bugfix +- ID:NA +- SUG:NA +- DESC:deleting gdb build dependency + +* Thu Jul 08 2021 shixuantong <shixuantong@huawei.com> - 4.15.1-28 +- Type:bugfix +- ID:NA +- SUG:NA +- DESC:split rpm-plugin-systemd-inhibit out of rpm. + +* Thu Jul 08 2021 shixuantong <shixuantong@huawei.com> - 4.15.1-27 +- Type:enhancement +- ID:NA +- SUG:NA +- DESC:remove unnecessary installation dependencies + +* Mon Jun 28 2021 shangyibin <shangyibin1@huawei.com> - 4.15.1-26 +- Type:bugfix +- ID:NA +- SUG:NA +- DESC:modify dependency + +* Wed Jun 09 2021 shixuantong <shixuantong@huawei.com> - 4.15.1-25 +- Type:bugfix +- ID:NA +- SUG:NA +- DESC:Fix data race in packageBinaries() function and prioritize large packages + +* Wed Jun 2 2021 guoxiaoqi<guoxiaoqi2@huawei.com> - 4.15.1-23 +- Type:cve +- ID:NA +- SUG:NA +- DESC:fix CVE-2021-20266 + +* Sat May 22 2021 liudabo<liudabo1@huawei.com> - 4.15.1-22 +- Type:bugfix +- ID:NA +- SUG:NA +- DESC:Optimize signature header merge a bit + +* Tue Apr 13 2021 liudabo<liudabo1@huawei.com> - 4.15.1-22 +- Type:enhancement +- ID:NA +- SUG:NA +- DESC:Fix CVE-2021-20271 + +* Mon Jan 11 2021 Liquor <lirui130@huawei.com> - 4.15.1-21 +- Type:enhancement +- ID:NA +- SUG:NA +- DESC:backport patches from upstream + +* Thu Dec 17 2020 Anakin Zhang <benjamin93@163.com> - 4.15.1-20 +- Type:bugfix +- ID:NA +- SUG:NA +- DESC:call process_digest_list before files are added + +* Thu Dec 17 2020 Anakin Zhang <benjamin93@163.com> - 4.15.1-19 +- Type:bugfix +- ID:NA +- SUG:NA +- DESC:use user.digest_list to avoid duplicate processing of the digest lists + +* Thu Oct 29 2020 Liquor <lirui130@huawei.com> - 4.15.1-18 +- Type:requirement +- ID:NA +- SUG:NA +- DESC:remove python2 + +* Tue Jul 14 2020 Roberto Sassu <roberto.sassu@huawei.com> - 4.15.1-17 +- Type:enhancement +- ID:NA +- SUG:NA +- DESC:add support for digest lists + +* Fri May 22 2020 openEuler Buildteam <buildteam@openeuler.org> - 4.15.1-16 +- Type:bugfix +- ID:NA +- SUG:NA +- DESC:solve the error of setexecfilecon + +* Wed May 13 2020 openEuler Buildteam <buildteam@openeuler.org> - 4.15.1-15 +- Type:bugfix +- ID:NA +- SUG:NA +- DESC:solve the failure of rpmsigdig.at test + +* Mon Mar 30 2020 openEuler Buildteam <buildteam@openeuler.org> - 4.15.1-14 +- Type:bugfix +- ID:NA +- SUG:NA +- DESC:add requires of some common build packages to rpm-build + +* Wed Mar 25 2020 openEuler Buildteam <buildteam@openeuler.org> - 4.15.1-13 +- Type:bugfix +- ID:NA +- SUG:NA +- DESC:revert always execute file trigger scriptlet callbacks with owning header + +* Fri Mar 6 2020 openEuler Buildteam <buildteam@openeuler.org> - 4.15.1-12 +- Type:bugfix +- ID:NA +- SUG:NA +- DESC:silence spurious error message from lsetfilecon() + +* Wed Mar 4 2020 openEuler Buildteam <buildteam@openeuler.org> - 4.15.1-11 +- Type:bugfix +- ID:NA +- SUG:NA +- DESC:add dist to release by default + +* Mon Mar 2 2020 openEuler Buildteam <buildteam@openeuler.org> - 4.15.1-10 +- Type:bugfix +- ID:NA +- SUG:NA +- DESC:revert last commit + +* Thu Feb 27 2020 openEuler Buildteam <buildteam@openeuler.org> - 4.15.1-9 +- Type:bugfix +- ID:NA +- SUG:NA +- DESC:add dist to the name of package + +* Fri Feb 14 2020 openEuler Buildteam <buildteam@openeuler.org> - 4.15.1-8 +- Type:bugfix +- ID:NA +- SUG:NA +- DESC:skip update the preference of gpg during make check + +* Mon Jan 20 2020 openEuler Buildteam <buildteam@openeuler.org> - 4.15.1-7 +- Type:bugfix +- ID:NA +- SUG:NA +- DESC:delete unneeded obsoletes + +* Sat Jan 18 2020 openEuler Buildteam <buildteam@openeuler.org> - 4.15.1-6 +- Type:bugfix +- ID:NA +- SUG:NA +- DESC:delete unneeded shared library + +* Tue Jan 14 2020 openEuler Buildteam <buildteam@openeuler.org> - 4.15.1-5 +- Type:bugfix +- ID:NA +- SUG:NA +- DESC:change requires to build requires + +* Tue Jan 14 2020 openEuler Buildteam <buildteam@openeuler.org> - 4.15.1-4 +- Type:bugfix +- ID:NA +- SUG:NA +- DESC:add build requires of ima-evm-utils and old shared library + +* Mon Jan 13 2020 openEuler Buildteam <buildteam@openeuler.org> - 4.15.1-3 +- Type:bugfix +- ID:NA +- SUG:NA +- DESC:add requires of shared library + +* Mon Jan 13 2020 openEuler Buildteam <buildteam@openeuler.org> - 4.15.1-2 +- Type:bugfix +- ID:NA +- SUG:NA +- DESC:add subpack of librpm8 and librpm9 to support update + +* Fri Jan 10 2020 openEuler Buildteam <buildteam@openeuler.org> - 4.15.1-1 +- Type:bugfix +- ID:NA +- SUG:NA +- DESC:update version to 4.15.1 + +* Tue Dec 24 2019 openEuler Buildteam <buildteam@openeuler.org> - 4.14.2-5 +- Type:bugfix +- ID:NA +- SUG:NA +- DESC:bugfix in files + +* Wed Nov 13 2019 hexiaowen<hexiaowen@huawei.com> - 4.14.2-4 +- add system-rpm-config buildrequires + +* Fri Sep 20 2019 openEuler Buildteam <buildteam@openeuler.org> - 4.14.2-3 +- Delete redundant information + +* Mon Sep 09 2019 openEuler Buildteam <buildteam@openeuler.org> - 4.14.2-2 +- Package init @@ -0,0 +1 @@ +ba23b5d2403fd2f9163dfd0dadce1820 rpm-4.17.0.tar.bz2 diff --git a/still-in-use-of-python-scripts-from-old-version.patch b/still-in-use-of-python-scripts-from-old-version.patch new file mode 100644 index 0000000..d9fee0b --- /dev/null +++ b/still-in-use-of-python-scripts-from-old-version.patch @@ -0,0 +1,210 @@ +From 4ec83c32024a8faf0a66a4275acbcd15751ee303 Mon Sep 17 00:00:00 2001 +From: renhongxun <renhongxun@huawei.com> +Date: Wed, 29 Dec 2021 16:37:45 +0800 +Subject: [PATCH] still in use of python scripts from old version + +--- + platform.in | 3 ++ + scripts/Makefile.am | 8 +-- + scripts/brp-python-bytecompile | 112 +++++++++++++++++++++++++++++++++++++++++ + scripts/brp-python-hardlink | 25 +++++++++ + 4 files changed, 144 insertions(+), 4 deletions(-) + create mode 100644 scripts/brp-python-bytecompile + create mode 100755 scripts/brp-python-hardlink + +diff --git a/platform.in b/platform.in +index 71496b8..748186e 100644 +--- a/platform.in ++++ b/platform.in +@@ -82,10 +82,13 @@ + # + + %__arch_install_post @ARCH_INSTALL_POST@ ++%_python_bytecompile_errors_terminate_build 0 ++%_python_bytecompile_extra 1 + + # Standard brp-macro naming: + # convert all '-' in basename to '_', add two leading underscores. + %__brp_compress %{_rpmconfigdir}/brp-compress %{?_prefix} ++%__brp_python_bytecompile %{_rpmconfigdir}/brp-python-bytecompile "" "%{?_python_bytecompile_errors_terminate_build}" "%{?_python_bytecompile_extra}" + %__brp_strip %{_rpmconfigdir}/brp-strip %{__strip} + %__brp_strip_comment_note %{_rpmconfigdir}/brp-strip-comment-note %{__strip} %{__objdump} + %__brp_strip_static_archive %{_rpmconfigdir}/brp-strip-static-archive %{__strip} +diff --git a/scripts/Makefile.am b/scripts/Makefile.am +index 4aed76b..5a1c494 100644 +--- a/scripts/Makefile.am ++++ b/scripts/Makefile.am +@@ -6,8 +6,8 @@ AM_CFLAGS = @RPMCFLAGS@ + CLEANFILES = + + EXTRA_DIST = \ +- brp-compress \ +- brp-strip brp-strip-comment-note \ ++ brp-compress brp-python-bytecompile \ ++ brp-strip brp-strip-comment-note brp-python-hardlink \ + brp-strip-static-archive brp-elfperms \ + brp-remove-la-files \ + check-files check-prereqs \ +@@ -23,8 +23,8 @@ EXTRA_DIST = \ + fontconfig.prov script.req + + rpmconfig_SCRIPTS = \ +- brp-compress \ +- brp-strip brp-strip-comment-note \ ++ brp-compress brp-python-bytecompile \ ++ brp-strip brp-strip-comment-note brp-python-hardlink \ + brp-strip-static-archive brp-elfperms \ + brp-remove-la-files \ + check-files check-prereqs \ +diff --git a/scripts/brp-python-bytecompile b/scripts/brp-python-bytecompile +new file mode 100644 +index 0000000..d9c4832 +--- /dev/null ++++ b/scripts/brp-python-bytecompile +@@ -0,0 +1,112 @@ ++#!/bin/bash ++errors_terminate=$2 ++extra=$3 ++ ++# If using normal root, avoid changing anything. ++if [ -z "$RPM_BUILD_ROOT" ] || [ "$RPM_BUILD_ROOT" = "/" ]; then ++ exit 0 ++fi ++ ++# Figure out how deep we need to descend. We could pick an insanely high ++# number and hope it's enough, but somewhere, somebody's sure to run into it. ++depth=`(find "$RPM_BUILD_ROOT" -type f -name "*.py" -print0 ; echo /) | \ ++ xargs -0 -n 1 dirname | sed 's,[^/],,g' | sort -u | tail -n 1 | wc -c` ++if [ -z "$depth" ] || [ "$depth" -le "1" ]; then ++ exit 0 ++fi ++ ++function python_bytecompile() ++{ ++ local options=$1 ++ local python_binary=$2 ++ local exclude=$3 ++ local python_libdir=$4 ++ local depth=$5 ++ local real_libdir=$6 ++ ++cat << EOF | $python_binary $options ++import compileall, sys, os, re ++ ++python_libdir = "$python_libdir" ++depth = $depth ++real_libdir = "$real_libdir" ++build_root = "$RPM_BUILD_ROOT" ++exclude = r"$exclude" ++ ++class Filter: ++ def search(self, path): ++ ret = not os.path.realpath(path).startswith(build_root) ++ if exclude: ++ ret = ret or re.search(exclude, path) ++ return ret ++ ++sys.exit(not compileall.compile_dir(python_libdir, depth, real_libdir, force=1, rx=Filter(), quiet=1)) ++EOF ++} ++ ++# .pyc/.pyo files embed a "magic" value, identifying the ABI version of Python ++# bytecode that they are for. ++# ++# The files below RPM_BUILD_ROOT could be targeting multiple versions of ++# python (e.g. a single build that emits several subpackages e.g. a ++# python26-foo subpackage, a python31-foo subpackage etc) ++# ++# Support this by assuming that below each /usr/lib/python$VERSION/, all ++# .pyc/.pyo files are to be compiled for /usr/bin/python$VERSION. ++# ++# For example, below /usr/lib/python2.6/, we're targeting /usr/bin/python2.6 ++# and below /usr/lib/python3.1/, we're targeting /usr/bin/python3.1 ++ ++shopt -s nullglob ++for python_libdir in `find "$RPM_BUILD_ROOT" -type d|grep -E "/usr/lib(64)?/python[0-9]\.[0-9]$"`; ++do ++ python_binary=/usr/bin/$(basename $python_libdir) ++ real_libdir=${python_libdir/$RPM_BUILD_ROOT/} ++ echo "Bytecompiling .py files below $python_libdir using $python_binary" ++ ++ # Generate normal (.pyc) byte-compiled files. ++ python_bytecompile "" "$python_binary" "" "$python_libdir" "$depth" "$real_libdir" ++ if [ $? -ne 0 ] && [ 0$errors_terminate -ne 0 ]; then ++ # One or more of the files had a syntax error ++ exit 1 ++ fi ++ ++ # Generate optimized (.pyo) byte-compiled files. ++ python_bytecompile "-O" "$python_binary" "" "$python_libdir" "$depth" "$real_libdir" ++ if [ $? -ne 0 ] && [ 0$errors_terminate -ne 0 ]; then ++ # One or more of the files had a syntax error ++ exit 1 ++ fi ++done ++ ++ ++# Handle other locations in the filesystem using the default python implementation ++# if extra is set to 0, don't do this ++if [ 0$extra -eq 0 ]; then ++ exit 0 ++fi ++ ++# If we don't have a default python interpreter, we cannot proceed ++default_python=${1:-/usr/bin/python} ++if [ ! -x "$default_python" ]; then ++ exit 0 ++fi ++ ++# Figure out if there are files to be bytecompiled with the default_python at all ++# this prevents unnecessary default_python invocation ++find "$RPM_BUILD_ROOT" -type f -name "*.py" | grep -Ev "/bin/|/sbin/|/usr/lib(64)?/python[0-9]\.[0-9]|/usr/share/doc" || exit 0 ++ ++# Generate normal (.pyc) byte-compiled files. ++python_bytecompile "" $default_python "/bin/|/sbin/|/usr/lib(64)?/python[0-9]\.[0-9]|/usr/share/doc" "$RPM_BUILD_ROOT" "$depth" "/" ++if [ $? -ne 0 ] && [ 0$errors_terminate -ne 0 ]; then ++ # One or more of the files had a syntax error ++ exit 1 ++fi ++ ++# Generate optimized (.pyo) byte-compiled files. ++python_bytecompile "-O" $default_python "/bin/|/sbin/|/usr/lib(64)?/python[0-9]\.[0-9]|/usr/share/doc" "$RPM_BUILD_ROOT" "$depth" "/" ++if [ $? -ne 0 ] && [ 0$errors_terminate -ne 0 ]; then ++ # One or more of the files had a syntax error ++ exit 1 ++fi ++exit 0 +diff --git a/scripts/brp-python-hardlink b/scripts/brp-python-hardlink +new file mode 100755 +index 0000000..5fd1b43 +--- /dev/null ++++ b/scripts/brp-python-hardlink +@@ -0,0 +1,25 @@ ++#!/bin/sh ++ ++# If using normal root, avoid changing anything. ++if [ -z "$RPM_BUILD_ROOT" ] || [ "$RPM_BUILD_ROOT" = "/" ]; then ++ exit 0 ++fi ++ ++hardlink_if_same() { ++ if cmp -s "$1" "$2" ; then ++ ln -f "$1" "$2" ++ return 0 ++ fi ++ return 1 ++} ++ ++# Hardlink identical *.pyc, *.pyo, and *.opt-[12].pyc. ++# Originally from PLD's rpm-build-macros ++find "$RPM_BUILD_ROOT" -type f -name "*.pyc" -not -name "*.opt-[12].pyc" | while read pyc ; do ++ hardlink_if_same "$pyc" "${pyc%c}o" ++ o1pyc="${pyc%pyc}opt-1.pyc" ++ hardlink_if_same "$pyc" "$o1pyc" ++ o2pyc="${pyc%pyc}opt-2.pyc" ++ hardlink_if_same "$pyc" "$o2pyc" || hardlink_if_same "$o1pyc" "$o2pyc" ++done ++exit 0 +-- +1.8.3.1 + |
