sync patches from upstream

This commit is contained in:
hugel 2024-12-02 14:44:13 +08:00
parent 8d61496310
commit 7c60678265
6 changed files with 394 additions and 1 deletions

View File

@ -0,0 +1,27 @@
From 2c20f9677eff989817148d236543191dec0d8059 Mon Sep 17 00:00:00 2001
From: Panu Matilainen <pmatilai@redhat.com>
Date: Tue, 14 Nov 2023 09:07:28 +0200
Subject: [PATCH] Allow version to be omitted in the replace test spec
Conflict:adapt context
Reference:https://github.com/rpm-software-management/rpm/commit/2c20f9677eff989817148d236543191dec0d8059
---
tests/data/SPECS/replacetest.spec | 1 +
1 file changed, 1 insertion(+)
diff --git a/tests/data/SPECS/replacetest.spec b/tests/data/SPECS/replacetest.spec
index 0f86ea628..4fb72b408 100644
--- a/tests/data/SPECS/replacetest.spec
+++ b/tests/data/SPECS/replacetest.spec
@@ -2,6 +2,7 @@
%{?fixit: %global havepretrans 1}
%{!?user: %global user root}
%{!?grp: %global grp root}
+%{!?ver: %global ver 1.0}
Name: replacetest%{?sub:-%{sub}}
Version: %{ver}
--
2.33.0

View File

@ -0,0 +1,47 @@
From 027ef640b33b38ca257bb301bb302e9c71d43c27 Mon Sep 17 00:00:00 2001
From: Panu Matilainen <pmatilai@redhat.com>
Date: Fri, 18 Oct 2024 14:50:35 +0300
Subject: [PATCH] Fix FA_TOUCH'ed files getting removed on failed update
Conflict:modify fsm.c instead of fsm.cc; don't modify testcode because
the test code differs greatly, it requires the root permission to run
chown. However, the current test code cannot implement chown. Manual
test cases will be used to guard test cases.
Reference:https://github.com/rpm-software-management/rpm/commit/027ef640b33b38ca257bb301bb302e9c71d43c27
On install/update, most files are laid down with a temporary suffix
and if the update fails, removing those at the end of the loop is
the right thing to do. However FA_TOUCH'ed files were already there,
we only update their metadata, and we better not remove them!
AFAICS this all versions since rpm >= 4.14 in one way or the other.
If %_minimize_writes is enabled then it affects way more than just
unmodified config files.
The test is a simplified version of pam update failing in the original
report. Technically, --nomtime should not be needed for the test
verification but we don't even try to restore the metadata on failure,
and fixing that is way out of scope here.
Fixes: RHEL-54386
Fixes: #3284
---
lib/fsm.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/fsm.c b/lib/fsm.c
index e3be219c3..ec0303400 100644
--- a/lib/fsm.c
+++ b/lib/fsm.c
@@ -1094,7 +1094,7 @@ setmeta:
if (ensureDir(NULL, rpmfiDN(fi), 0, 0, 1, &di.dirfd))
continue;
- if (fp->stage > FILE_NONE && !fp->skip) {
+ if (fp->stage > FILE_NONE && !fp->skip && fp->action != FA_TOUCH) {
(void) fsmRemove(di.dirfd, fp->fpath, fp->sb.st_mode);
}
}
--
2.33.0

View File

@ -0,0 +1,49 @@
From 89ce4e7ca592f5abafc3f25aeaa07d36a7b43a61 Mon Sep 17 00:00:00 2001
From: Panu Matilainen <pmatilai@redhat.com>
Date: Tue, 14 Nov 2023 11:37:48 +0200
Subject: [PATCH] Fix wrong return code on O_DIRECTORY open of invalid symlink
Conflict:NA
Reference:https://github.com/rpm-software-management/rpm/commit/89ce4e7ca592f5abafc3f25aeaa07d36a7b43a61
The dir argument to fsmOpenpath() is supposed to be a rough O_DIRECTORY
equivalent, and if the path is actually a misowned symlink it should
return ENOTDIR instead of ELOOP. Makes the resulting error messages
at least a little more comprehensible.
---
lib/fsm.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/lib/fsm.c b/lib/fsm.c
index 51f439ef3..091e90554 100644
--- a/lib/fsm.c
+++ b/lib/fsm.c
@@ -304,6 +304,7 @@ static int fsmOpenat(int dirfd, const char *path, int flags, int dir)
struct stat lsb, sb;
int sflags = flags | O_NOFOLLOW;
int fd = openat(dirfd, path, sflags);
+ int ffd = fd;
/*
* Only ever follow symlinks by root or target owner. Since we can't
@@ -312,7 +313,7 @@ static int fsmOpenat(int dirfd, const char *path, int flags, int dir)
* it could've only been the link owner or root.
*/
if (fd < 0 && errno == ELOOP && flags != sflags) {
- int ffd = openat(dirfd, path, flags);
+ ffd = openat(dirfd, path, flags);
if (ffd >= 0) {
if (fstatat(dirfd, path, &lsb, AT_SYMLINK_NOFOLLOW) == 0) {
if (fstat(ffd, &sb) == 0) {
@@ -327,7 +328,7 @@ static int fsmOpenat(int dirfd, const char *path, int flags, int dir)
}
/* O_DIRECTORY equivalent */
- if (dir && fd >= 0 && fstat(fd, &sb) == 0 && !S_ISDIR(sb.st_mode)) {
+ if (dir && ((fd != ffd) || (fd >= 0 && fstat(fd, &sb) == 0 && !S_ISDIR(sb.st_mode)))) {
errno = ENOTDIR;
fsmClose(&fd);
}
--
2.33.0

View File

@ -0,0 +1,175 @@
From 14516542c113560dc0070df2f9102568a7a71b58 Mon Sep 17 00:00:00 2001
From: Panu Matilainen <pmatilai@redhat.com>
Date: Mon, 19 Aug 2024 11:03:10 +0300
Subject: [PATCH] Refactor fsmOpenat() return style for consistency within the
fsm
Conflict:adapt context; don't modify testcode because the test code differs
greatly, 0091214 requires the root permission to run chown. However, the
current test code cannot implement chown. Manual test cases will be used to
guard test cases.
Reference:https://github.com/rpm-software-management/rpm/commit/14516542c113560dc0070df2f9102568a7a71b58
Everything inside the fsm is returning a return code as the main
returned data and file descriptors as one of the arguments, except
for fsmOpenat() which I for some reason modeled after openat() instead.
This mismatch makes for some strange code in the callers.
The only visible change here is supposed to be the error message
changing slightly due to using rpmfileStrerror() instead of strerror().
Co-authored-by: Florian Festi <ffesti@redhat.com>
---
lib/fsm.c | 62 +++++++++++++++++++++++++--------------------------
1 file changed, 31 insertions(+), 31 deletions(-)
diff --git a/lib/fsm.c b/lib/fsm.c
index 20b270cf5..b5f8800a8 100644
--- a/lib/fsm.c
+++ b/lib/fsm.c
@@ -65,7 +65,7 @@ struct filedata_s {
* things around needlessly
*/
static const char * fileActionString(rpmFileAction a);
-static int fsmOpenat(int dirfd, const char *path, int flags, int dir);
+static int fsmOpenat(int *fdp, int dirfd, const char *path, int flags, int dir);
static int fsmClose(int *wfdp);
/** \ingroup payload
@@ -98,9 +98,9 @@ static int fsmLink(int odirfd, const char *opath, int dirfd, const char *path)
#if WITH_CAP
static int cap_set_fileat(int dirfd, const char *path, cap_t fcaps)
{
- int rc = -1;
- int fd = fsmOpenat(dirfd, path, O_RDONLY|O_NOFOLLOW, 0);
- if (fd >= 0) {
+ int fd = -1;
+ int rc = fsmOpenat(&fd, dirfd, path, O_RDONLY|O_NOFOLLOW, 0);
+ if (!rc) {
rc = cap_set_fd(fd, fcaps);
fsmClose(&fd);
}
@@ -299,12 +299,13 @@ static int fsmMkdir(int dirfd, const char *path, mode_t mode)
return rc;
}
-static int fsmOpenat(int dirfd, const char *path, int flags, int dir)
+static int fsmOpenat(int *wfdp, int dirfd, const char *path, int flags, int dir)
{
struct stat lsb, sb;
int sflags = flags | O_NOFOLLOW;
int fd = openat(dirfd, path, sflags);
int ffd = fd;
+ int rc = 0;
/*
* Only ever follow symlinks by root or target owner. Since we can't
@@ -328,11 +329,17 @@ static int fsmOpenat(int dirfd, const char *path, int flags, int dir)
}
/* O_DIRECTORY equivalent */
- if (dir && ((fd != ffd) || (fd >= 0 && fstat(fd, &sb) == 0 && !S_ISDIR(sb.st_mode)))) {
- errno = ENOTDIR;
+ if (!rc && dir && ((fd != ffd) || (fd >= 0 && fstat(fd, &sb) == 0 && !S_ISDIR(sb.st_mode))))
+ rc = RPMERR_ENOTDIR;
+
+ if (!rc && fd < 0)
+ rc = RPMERR_OPEN_FAILED;
+
+ if (rc)
fsmClose(&fd);
- }
- return fd;
+
+ *wfdp = fd;
+ return rc;
}
static int fsmDoMkDir(rpmPlugins plugins, int dirfd, const char *dn,
@@ -351,9 +358,7 @@ static int fsmDoMkDir(rpmPlugins plugins, int dirfd, const char *dn,
rc = fsmMkdir(dirfd, dn, mode);
if (!rc) {
- *fdp = fsmOpenat(dirfd, dn, O_RDONLY|O_NOFOLLOW, 1);
- if (*fdp == -1)
- rc = RPMERR_ENOTDIR;
+ rc = fsmOpenat(fdp, dirfd, dn, O_RDONLY|O_NOFOLLOW, 1);
}
if (!rc) {
@@ -378,47 +383,44 @@ static int ensureDir(rpmPlugins plugins, const char *p, int owned, int create,
char *sp = NULL, *bn;
char *apath = NULL;
int oflags = O_RDONLY;
- int rc = 0;
if (*dirfdp >= 0)
- return rc;
+ return 0;
- int dirfd = fsmOpenat(-1, "/", oflags, 1);
+ int dirfd = -1;
+ int rc = fsmOpenat(&dirfd, -1, "/", oflags, 1);
int fd = dirfd; /* special case of "/" */
char *path = xstrdup(p);
char *dp = path;
while ((bn = strtok_r(dp, "/", &sp)) != NULL) {
- fd = fsmOpenat(dirfd, bn, oflags, 1);
+ rc = fsmOpenat(&fd, dirfd, bn, oflags, 1);
/* assemble absolute path for plugins benefit, sigh */
apath = rstrscat(&apath, "/", bn, NULL);
- if (fd < 0 && errno == ENOENT && create) {
+ if (rc && errno == ENOENT && create) {
mode_t mode = S_IFDIR | (_dirPerms & 07777);
rc = fsmDoMkDir(plugins, dirfd, bn, apath, owned, mode, &fd);
}
fsmClose(&dirfd);
- if (fd >= 0) {
- dirfd = fd;
- } else {
- if (!quiet) {
- rpmlog(RPMLOG_ERR, _("failed to open dir %s of %s: %s\n"),
- bn, p, strerror(errno));
- }
- rc = RPMERR_OPEN_FAILED;
+ if (rc)
break;
- }
+ dirfd = fd;
dp = NULL;
}
if (rc) {
+ if (!quiet) {
+ char *msg = rpmfileStrerror(rc);
+ rpmlog(RPMLOG_ERR, _("failed to open dir %s of %s: %s\n"),
+ bn, p, msg);
+ free(msg);
+ }
fsmClose(&fd);
fsmClose(&dirfd);
- } else {
- rc = 0;
}
*dirfdp = dirfd;
@@ -1026,10 +1028,8 @@ setmeta:
/* Only follow safe symlinks, and never on temporary files */
if (fp->suffix)
flags |= AT_SYMLINK_NOFOLLOW;
- fd = fsmOpenat(di.dirfd, fp->fpath, flags,
+ rc = fsmOpenat(&fd, di.dirfd, fp->fpath, flags,
S_ISDIR(fp->sb.st_mode));
- if (fd < 0)
- rc = RPMERR_OPEN_FAILED;
}
if (!rc && fp->setmeta) {
--
2.33.0

View File

@ -0,0 +1,87 @@
From 535eacc96ae6fe5289a2917bb0af43e491b0f4f4 Mon Sep 17 00:00:00 2001
From: Panu Matilainen <pmatilai@redhat.com>
Date: Mon, 19 Aug 2024 11:43:33 +0300
Subject: [PATCH] Report unsafe symlinks during installation as a specific case
Conflict:don't modify testcode because the test code differs greatly, 0091214
requires the root permission to run chown. However, the current test code
cannot implement chown. Manual test cases will be used to guard test cases.
Reference:https://github.com/rpm-software-management/rpm/commit/535eacc96ae6fe5289a2917bb0af43e491b0f4f4
RPM refuses to follow non root owned symlinks pointing to files owned by
another user for security reasons. This case was lumped in with
O_DIRECTORY behavior, leading to confusing error message as the symlink
often indeed points at a directory. Emit a more meaningful error message
when encountering unsafe symlinks.
We already detect the error condition in the main if block here, might
as well set the error code right there and then so we don't need to
redetect later. We previously only tested for the unsafe link condition
when our O_DIRECTORY equivalent was set, but that seems wrong. Probably
doesn't matter with the existing callers, but we really must not
follow those unsafe symlinks no matter what.
Co-authored-by: Florian Festi <ffesti@redhat.com>
Resolves: #3100
---
lib/fsm.c | 10 ++++++----
lib/rpmfi.c | 2 +-
2 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/lib/fsm.c b/lib/fsm.c
index b5f8800a8..4c0968f73 100644
--- a/lib/fsm.c
+++ b/lib/fsm.c
@@ -304,7 +304,6 @@ static int fsmOpenat(int *wfdp, int dirfd, const char *path, int flags, int dir)
struct stat lsb, sb;
int sflags = flags | O_NOFOLLOW;
int fd = openat(dirfd, path, sflags);
- int ffd = fd;
int rc = 0;
/*
@@ -314,7 +313,7 @@ static int fsmOpenat(int *wfdp, int dirfd, const char *path, int flags, int dir)
* it could've only been the link owner or root.
*/
if (fd < 0 && errno == ELOOP && flags != sflags) {
- ffd = openat(dirfd, path, flags);
+ int ffd = openat(dirfd, path, flags);
if (ffd >= 0) {
if (fstatat(dirfd, path, &lsb, AT_SYMLINK_NOFOLLOW) == 0) {
if (fstat(ffd, &sb) == 0) {
@@ -323,13 +322,16 @@ static int fsmOpenat(int *wfdp, int dirfd, const char *path, int flags, int dir)
}
}
}
- if (ffd != fd)
+ /* Symlink with non-matching owners */
+ if (ffd != fd) {
close(ffd);
+ rc = RPMERR_INVALID_SYMLINK;
+ }
}
}
/* O_DIRECTORY equivalent */
- if (!rc && dir && ((fd != ffd) || (fd >= 0 && fstat(fd, &sb) == 0 && !S_ISDIR(sb.st_mode))))
+ if (!rc && dir && fd >= 0 && fstat(fd, &sb) == 0 && !S_ISDIR(sb.st_mode))
rc = RPMERR_ENOTDIR;
if (!rc && fd < 0)
diff --git a/lib/rpmfi.c b/lib/rpmfi.c
index a3d8ad470..d8dbb67c7 100644
--- a/lib/rpmfi.c
+++ b/lib/rpmfi.c
@@ -2426,7 +2426,7 @@ char * rpmfileStrerror(int rc)
case RPMERR_DIGEST_MISMATCH: s = _("Digest mismatch"); break;
case RPMERR_INTERNAL: s = _("Internal error"); break;
case RPMERR_UNMAPPED_FILE: s = _("Archive file not in header"); break;
- case RPMERR_INVALID_SYMLINK: s = _("Invalid symlink"); break;
+ case RPMERR_INVALID_SYMLINK: s = _("Unsafe symlink"); break;
case RPMERR_ENOTDIR: s = strerror(ENOTDIR); break;
case RPMERR_ENOENT: s = strerror(ENOENT); break;
case RPMERR_ENOTEMPTY: s = strerror(ENOTEMPTY); break;
--
2.33.0

View File

@ -1,6 +1,6 @@
Name: rpm Name: rpm
Version: 4.18.2 Version: 4.18.2
Release: 21 Release: 22
Summary: RPM Package Manager Summary: RPM Package Manager
License: GPL-2.0-or-later License: GPL-2.0-or-later
URL: https://rpm.org/ URL: https://rpm.org/
@ -52,6 +52,11 @@ Patch6029: backport-Fix-memleak-when-process-policies.patch
Patch6030: backport-Enforce-the-same-sanity-checks-on-db-add-and-rebuild.patch Patch6030: backport-Enforce-the-same-sanity-checks-on-db-add-and-rebuild.patch
Patch6031: backport-Fix-a-memory-leak-on-rpmdb-importdb.patch Patch6031: backport-Fix-a-memory-leak-on-rpmdb-importdb.patch
Patch6032: backport-Require-macro-filenames-to-end-in-alphanum-char.patch Patch6032: backport-Require-macro-filenames-to-end-in-alphanum-char.patch
Patch6033: backport-Allow-version-to-be-omitted-in-the-replace-test-spec.patch
Patch6034: backport-Fix-wrong-return-code-on-O_DIRECTORY-open-of-invalid.patch
Patch6035: backport-Refactor-fsmOpenat-return-style-for-consistency-with.patch
Patch6036: backport-Report-unsafe-symlinks-during-installation-as-a-spec.patch
Patch6037: backport-Fix-FA_TOUCH-ed-files-getting-removed-on-failed-upda.patch
Patch9000: Add-digest-list-plugin.patch Patch9000: Add-digest-list-plugin.patch
Patch9001: Add-IMA-digest-list-support.patch Patch9001: Add-IMA-digest-list-support.patch
@ -340,6 +345,9 @@ make clean
%exclude %{_mandir}/man8/rpmspec.8* %exclude %{_mandir}/man8/rpmspec.8*
%changelog %changelog
* Mon Dec 2 2024 hugel<gengqihu2@h-partners.com> - 4.18.2-22
- sync patches from upstream
* Wed Nov 27 2024 hugel<gengqihu2@h-partners.com> - 4.18.2-21 * Wed Nov 27 2024 hugel<gengqihu2@h-partners.com> - 4.18.2-21
- Require macro filenames to end in alphanum char - Require macro filenames to end in alphanum char