回退 'Pull Request !161 : rpm 升级至4.18.0'

This commit is contained in:
Monday 2022-10-27 02:00:37 +00:00 committed by Gitee
parent d37305278a
commit fcfe08e70b
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
73 changed files with 4677 additions and 1094 deletions

View File

@ -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

View File

@ -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

View File

@ -9,7 +9,7 @@ Subject: [PATCH] Add loongarch architecture support.
2 files changed, 29 insertions(+)
diff --git a/installplatform b/installplatform
index dd9effb..b8e6c33 100755
index 12339fc..74c50a2 100755
--- a/installplatform
+++ b/installplatform
@@ -168,6 +168,18 @@ for ARCH in noarch `grep ^arch_canon $RPMRC | cut -d: -f2`; do
@ -32,7 +32,7 @@ index dd9effb..b8e6c33 100755
ISANAME=m68k
ISABITS=32
diff --git a/rpmrc.in b/rpmrc.in
index f541b0e..9caa76c 100644
index 5bd9ba3..fc2932a 100644
--- a/rpmrc.in
+++ b/rpmrc.in
@@ -67,6 +67,8 @@ optflags: mipsr6el -O2 -g
@ -44,7 +44,7 @@ index f541b0e..9caa76c 100644
optflags: armv3l -O2 -g -march=armv3
optflags: armv4b -O2 -g -march=armv4
optflags: armv4l -O2 -g -march=armv4
@@ -139,6 +141,9 @@ archcolor: mipsr6el 1
@@ -137,6 +139,9 @@ archcolor: mipsr6el 1
archcolor: mips64r6 2
archcolor: mips64r6el 2
@ -54,9 +54,9 @@ index f541b0e..9caa76c 100644
archcolor: m68k 1
archcolor: m68kmint 1
@@ -265,6 +270,9 @@ arch_canon: riscv64: riscv64 22
arch_canon: loongarch64: loongarch64 23
@@ -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
@ -64,7 +64,7 @@ index f541b0e..9caa76c 100644
#############################################################
# Canonical OS names and numbers
@@ -368,6 +376,9 @@ buildarchtranslate: mipsr6el: mipsr6el
@@ -360,6 +368,9 @@ buildarchtranslate: mipsr6el: mipsr6el
buildarchtranslate: mips64r6: mips64r6
buildarchtranslate: mips64r6el: mips64r6el
@ -74,7 +74,7 @@ index f541b0e..9caa76c 100644
buildarchtranslate: m68k: m68k
buildarchtranslate: atarist: m68kmint
@@ -460,6 +471,9 @@ arch_compat: mipsr6el: noarch
@@ -449,6 +460,9 @@ arch_compat: mipsr6el: noarch
arch_compat: mips64r6: mipsr6
arch_compat: mips64r6el: mipsr6el
@ -84,7 +84,7 @@ index f541b0e..9caa76c 100644
arch_compat: hppa2.0: hppa1.2
arch_compat: hppa1.2: hppa1.1
arch_compat: hppa1.1: hppa1.0
@@ -602,6 +616,9 @@ buildarch_compat: mipsr6el: noarch
@@ -586,6 +600,9 @@ buildarch_compat: mipsr6el: noarch
buildarch_compat: mips64r6: noarch
buildarch_compat: mips64r6el: noarch
@ -95,5 +95,5 @@ index f541b0e..9caa76c 100644
buildarch_compat: armv8l: armv7l
buildarch_compat: armv7l: armv6l
--
2.26.2
2.30.0

View File

@ -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

29
Check-rpm-parser.patch Normal file
View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -8,10 +8,10 @@ Subject: [PATCH] Unbundle config site and add RPM LD FLAGS macro
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/macros.in b/macros.in
index 0e801ff..0f67b07 100644
index fe9803a..4027493 100644
--- a/macros.in
+++ b/macros.in
@@ -711,10 +711,11 @@ package or when debugging this package.\
@@ -794,10 +794,11 @@ package or when debugging this package.\
RPM_SOURCE_DIR=\"%{u2p:%{_sourcedir}}\"\
RPM_BUILD_DIR=\"%{u2p:%{_builddir}}\"\
RPM_OPT_FLAGS=\"%{optflags}\"\
@ -24,7 +24,7 @@ index 0e801ff..0f67b07 100644
RPM_DOC_DIR=\"%{_docdir}\"\
export RPM_DOC_DIR\
RPM_PACKAGE_NAME=\"%{NAME}\"\
@@ -730,6 +731,8 @@ package or when debugging this package.\
@@ -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\
@ -34,5 +34,5 @@ index 0e801ff..0f67b07 100644
%[%{verbose}?"set -x":""]\
umask 022\
--
2.26.2
1.8.3.1

View File

@ -1,29 +1,29 @@
From 67f2f371822dde322047bcae05c433a91022f334 Mon Sep 17 00:00:00 2001
From: licihua <licihua@huawei.com>
Date: Thu, 20 Oct 2022 20:32:09 +0800
Subject: [PATCH 03/22] add dist to release by default
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 bd3da19..722d0ac 100644
index b0a17c8..cac899a 100644
--- a/build/parsePreamble.c
+++ b/build/parsePreamble.c
@@ -799,6 +799,11 @@ static rpmRC handlePreambleTag(rpmSpec spec, Package pkg, rpmTagVal tag,
@@ -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) {
+ if (tag == RPMTAG_RELEASE) {
+ char *dist = rpmExpand("%{?dist}",NULL);
+ rasprintf(&field,"%s%s",field,dist);
+ free(dist);
+ }
if (rpmCharCheck(spec, field, ALLOWED_CHARS_VERREL, NULL))
if (rpmCharCheck(spec, field, ALLOWED_CHARS_VERREL))
goto exit;
headerPutString(pkg->header, tag, field);
@@ -986,6 +991,8 @@ static rpmRC handlePreambleTag(rpmSpec spec, Package pkg, rpmTagVal tag,
@@ -987,6 +992,8 @@ static rpmRC handlePreambleTag(rpmSpec spec, Package pkg, rpmTagVal tag,
}
rc = RPMRC_OK;
exit:
@ -33,5 +33,5 @@ index bd3da19..722d0ac 100644
}
--
2.26.2
1.8.3.1

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -1,18 +1,7 @@
From c580bc45b40d7782754e14e11b79085acdb9be8d Mon Sep 17 00:00:00 2001
From: licihua <licihua@huawei.com>
Date: Thu, 20 Oct 2022 20:37:44 +0800
Subject: [PATCH 05/22] bugfix rpm 4.11.3 add aarch64_ilp32 arch
---
installplatform | 7 +++++++
rpmrc.in | 9 +++++++--
2 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/installplatform b/installplatform
index 4391691..dd9effb 100755
--- a/installplatform
+++ b/installplatform
@@ -180,6 +180,13 @@ for ARCH in noarch `grep ^arch_canon $RPMRC | cut -d: -f2`; do
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
;;
@ -23,14 +12,13 @@ index 4391691..dd9effb 100755
+ CANONCOLOR=0
+ LIB=libilp32
+ ;;
loongarch64)
ISANAME=loongarch64
ISABITS=64
diff --git a/rpmrc.in b/rpmrc.in
index 2975a3a..f541b0e 100644
--- a/rpmrc.in
+++ b/rpmrc.in
@@ -101,7 +101,7 @@ optflags: sh4 -O2 -g -mieee
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
@ -38,8 +26,8 @@ index 2975a3a..f541b0e 100644
+optflags: aarch64_ilp32 -O2 -g -mabi=ilp32
optflags: riscv64 -O2 -g
optflags: loongarch64 -O2 -g
@@ -154,7 +154,7 @@ archcolor: sh3 1
#############################################################
@@ -149,7 +149,7 @@
archcolor: sh4 1
archcolor: aarch64 2
@ -47,40 +35,46 @@ index 2975a3a..f541b0e 100644
+archcolor: aarch64_ilp32 1
archcolor: riscv64 2
@@ -253,6 +253,7 @@ arch_canon: sh4: sh4 17
#############################################################
@@ -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
@@ -391,6 +392,7 @@ buildarchtranslate: sh4: sh4
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
@@ -504,6 +506,8 @@ arch_compat: sh4: noarch
-#############################################################
+#########################################/####################
# 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: noarch
+arch_compat: aarch64_ilp32: aarch64 noarch
+arch_compat: aarch64: aarch64_ilp32 noarch
arch_compat: riscv: noarch
arch_compat: riscv64: noarch
@@ -542,6 +546,7 @@ arch_compat: loongarch64: 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
--
2.26.2

View File

@ -12,10 +12,10 @@ Signed-off-by: shanshishi <shanshishi@huawei.com>
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/lib/rpmlock.c b/lib/rpmlock.c
index b889e79..a546407 100644
index d693c4b..86e07b3 100644
--- a/lib/rpmlock.c
+++ b/lib/rpmlock.c
@@ -127,13 +127,10 @@ rpmlock rpmlockNew(const char *lock_path, const char *descr)
@@ -125,13 +125,10 @@ rpmlock rpmlockNew(const char *lock_path, const char *descr)
int rpmlockAcquire(rpmlock lock)
{
int locked = 0; /* assume failure */
@ -31,5 +31,5 @@ index b889e79..a546407 100644
lock->descr, lock->path);
locked = rpmlock_acquire(lock, (RPMLOCK_WRITE|RPMLOCK_WAIT));
--
2.26.2
1.7.12.4

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -5,13 +5,14 @@ Subject: [PATCH] get in use of ndb
---
configure.ac | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
macros.in | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/configure.ac b/configure.ac
index fbbfead..f0e6dd6 100644
index 6b161dc..ab1c667 100644
--- a/configure.ac
+++ b/configure.ac
@@ -523,9 +523,9 @@ AM_CONDITIONAL([BDB_RO], [test "$enable_bdb_ro" = yes])
@@ -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@:>@)],
@ -23,6 +24,19 @@ index fbbfead..f0e6dd6 100644
AS_IF([test "x$enable_sqlite" != "xno"], [
PKG_CHECK_MODULES([SQLITE], [sqlite3 >= 3.22.0], [have_sqlite=yes], [have_sqlite=no])
--
2.26.2
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

View File

@ -1,7 +1,7 @@
From 974dcb304c57fc5c1f4088f19856c4941c15c90a Mon Sep 17 00:00:00 2001
From: licihua <licihua@huawei.com>
Date: Thu, 20 Oct 2022 20:33:29 +0800
Subject: [PATCH 04/22] revert always execute file trigger scriptlet callbacks with
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
---
@ -9,10 +9,10 @@ Subject: [PATCH 04/22] revert always execute file trigger scriptlet callbacks wi
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/rpmtriggers.c b/lib/rpmtriggers.c
index 3f8fa22..f5c79ba 100644
index 285b2f0..b7c76e7 100644
--- a/lib/rpmtriggers.c
+++ b/lib/rpmtriggers.c
@@ -433,7 +433,7 @@ static int runHandleTriggersInPkg(rpmts ts, rpmte te, Header h,
@@ -437,7 +437,7 @@ static int runHandleTriggersInPkg(rpmts ts, rpmte te, Header h,
inputFunc = (char *(*)(void *)) matchFilesNext;
rpmScriptSetNextFileFunc(script, inputFunc, mfi);
@ -22,5 +22,5 @@ index 3f8fa22..f5c79ba 100644
rpmtdFreeData(&installPrefixes);
rpmScriptFree(script);
--
2.26.2
1.8.3.1

View File

@ -1,17 +1,8 @@
From 3b518bff7579647d2e9160e37dbbabc63c3d6792 Mon Sep 17 00:00:00 2001
From: licihua <licihua@huawei.com>
Date: Thu, 20 Oct 2022 20:28:48 +0800
Subject: [PATCH 02/22] rpm-4.12.0-rpm2cpio-hack
---
rpm2cpio.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/rpm2cpio.c b/rpm2cpio.c
index fcc3b30..5e650d5 100644
index 89ebdfa..ae999ff 100644
--- a/rpm2cpio.c
+++ b/rpm2cpio.c
@@ -94,7 +94,12 @@ int main(int argc, char *argv[])
@@ -84,7 +84,12 @@ int main(int argc, char *argv[])
exit(EXIT_FAILURE);
}
@ -25,6 +16,3 @@ index fcc3b30..5e650d5 100644
Fclose(fdo);
--
2.26.2

BIN
rpm-4.17.0.tar.bz2 Normal file

Binary file not shown.

Binary file not shown.

View File

@ -8,10 +8,10 @@ Subject: [PATCH] rpm selinux plugin check context file exist
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/plugins/selinux.c b/plugins/selinux.c
index 316ff88..ac1e354 100644
index 1254517..fb8b7a2 100644
--- a/plugins/selinux.c
+++ b/plugins/selinux.c
@@ -64,7 +64,8 @@ static rpmRC selinux_tsm_pre(rpmPlugin plugin, rpmts ts)
@@ -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 */
@ -22,5 +22,5 @@ index 316ff88..ac1e354 100644
}
--
2.26.2
2.23.0

View File

@ -1,22 +1,84 @@
Name: rpm
Version: 4.18.0
Release: 1
Version: 4.17.0
Release: 12
Summary: RPM Package Manager
License: GPLv2+
URL: http://www.rpm.org/
Source0: http://ftp.rpm.org/releases/rpm-4.18.x/%{name}-%{version}.tar.bz2
Source0: http://ftp.rpm.org/releases/rpm-4.17.x/%{name}-%{version}.tar.bz2
Patch0001: Unbundle-config-site-and-add-RPM-LD-FLAGS-macro.patch
Patch0002: rpm-4.12.0-rpm2cpio-hack.patch
Patch0003: add-dist-to-release-by-default.patch
Patch0004: revert-always-execute-file-trigger-scriptlet-callbac.patch
Patch0005: bugfix-rpm-4.11.3-add-aarch64_ilp32-arch.patch
Patch0006: bugfix-rpm-4.14.2-wait-once-get-rpmlock-fail.patch
Patch0007: rpm-selinux-plugin-check-context-file-exist.patch
Patch0008: get-in-use-of-ndb.patch
Patch0009: still-in-use-of-python-scripts-from-old-version.patch
Patch0010: Add-loongarch-architecture-support.patch
Patch0011: Generate-digest-lists.patch
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
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
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
@ -38,7 +100,7 @@ The RPM Package Manager (RPM) is a powerful package management system capability
-verifying integrity of packaged software and resulting software installation
%package libs
Summary: Shared library of rpm %{version}
Summary: Shared library of rpm 4.17
Requires: %{name} = %{version}-%{release}
%description libs
@ -247,7 +309,6 @@ make check || (cat tests/rpmtests.log; exit 0)
%{_bindir}/rpmbuild
%{_bindir}/gendiff
%{_bindir}/rpmspec
%{_bindir}/rpmlua
%{_rpmconfigdir}/brp-*
%{_rpmconfigdir}/check-*
@ -260,7 +321,6 @@ make check || (cat tests/rpmtests.log; exit 0)
%{_rpmconfigdir}/mkinstalldirs
%{_rpmconfigdir}/fileattrs/*
%{_rpmconfigdir}/config.*
%{_rpmconfigdir}/rpmuncompress
%files -n python3-%{name}
%defattr(-,root,root)
@ -288,9 +348,6 @@ make check || (cat tests/rpmtests.log; exit 0)
%{_mandir}/man1/gendiff.1*
%changelog
* Tue Oct 25 2022 licihua<licihua@huawei.com> - 4.18.0-1
- upgrade to 4.18
* Fri Sep 09 2022 renhongxun<renhongxun@h-partners.com> - 4.17.0-12
- sync patches from upstream

View File

@ -4,10 +4,10 @@ Date: Wed, 29 Dec 2021 16:37:45 +0800
Subject: [PATCH] still in use of python scripts from old version
---
platform.in | 3 +
platform.in | 3 ++
scripts/Makefile.am | 8 +--
scripts/brp-python-bytecompile | 112 +++++++++++++++++++++++++++++++++
scripts/brp-python-hardlink | 25 ++++++++
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
@ -31,7 +31,7 @@ index 71496b8..748186e 100644
%__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 5cbed80..a1608f9 100644
index 4aed76b..5a1c494 100644
--- a/scripts/Makefile.am
+++ b/scripts/Makefile.am
@@ -6,8 +6,8 @@ AM_CFLAGS = @RPMCFLAGS@
@ -45,7 +45,7 @@ index 5cbed80..a1608f9 100644
brp-strip-static-archive brp-elfperms \
brp-remove-la-files \
check-files check-prereqs \
@@ -24,8 +24,8 @@ EXTRA_DIST = \
@@ -23,8 +23,8 @@ EXTRA_DIST = \
fontconfig.prov script.req
rpmconfig_SCRIPTS = \
@ -58,7 +58,7 @@ index 5cbed80..a1608f9 100644
check-files check-prereqs \
diff --git a/scripts/brp-python-bytecompile b/scripts/brp-python-bytecompile
new file mode 100644
index 0000000..114a493
index 0000000..d9c4832
--- /dev/null
+++ b/scripts/brp-python-bytecompile
@@ -0,0 +1,112 @@
@ -206,5 +206,5 @@ index 0000000..5fd1b43
+done
+exit 0
--
2.26.2
1.8.3.1