Compare commits

...

12 Commits

Author SHA1 Message Date
eabdullin c5e12412cf import UBI rpm-4.14.3-31.el8 2024-05-22 14:16:05 +00:00
eabdullin a5abd868a0 import UBI rpm-4.14.3-28.el8_9 2024-02-01 14:10:32 +00:00
CentOS Sources 801a95ca56 import rpm-4.14.3-26.el8 2023-05-16 06:33:19 +00:00
CentOS Sources a096a86a0e import rpm-4.14.3-24.el8_6 2022-11-08 10:57:04 +00:00
CentOS Sources 836001d6af import rpm-4.14.3-24.el8_6 2022-10-25 09:10:54 +00:00
CentOS Sources 56f20294c9 import rpm-4.14.3-23.el8 2022-05-10 11:47:11 +00:00
CentOS Sources 288ba0d69e import rpm-4.14.3-19.el8_5.2 2022-02-01 20:16:22 +00:00
CentOS Sources d9811c5e19 import rpm-4.14.3-19.el8 2021-12-08 12:33:30 +00:00
CentOS Sources fad1776797 import rpm-4.14.3-14.el8_4 2021-09-10 03:58:45 +00:00
CentOS Sources ecb531ab64 import rpm-4.14.3-13.el8 2021-09-10 03:58:42 +00:00
CentOS Sources d61db9f381 import rpm-4.14.3-4.el8 2021-09-10 03:58:39 +00:00
CentOS Sources 3e041157de import rpm-4.14.2-37.el8 2021-09-10 03:58:36 +00:00
79 changed files with 7655 additions and 951 deletions

2
.gitignore vendored
View File

@ -1 +1 @@
SOURCES/rpm-4.14.2.tar.bz2
SOURCES/rpm-4.14.3.tar.bz2

View File

@ -1 +1 @@
1ca664af796ab8d05ea3fccabe2b2e4767a97c74 SOURCES/rpm-4.14.2.tar.bz2
3f8c3ef08f93eaeef12008055a43f6872306f8a2 SOURCES/rpm-4.14.3.tar.bz2

View File

@ -77,7 +77,7 @@ Adjusted for rpm-4.14.2 in RHEL
eu-strip --remove-comment $r $g ${keep_remove_args} -f "$1" "$2" || exit
chmod 444 "$1" || exit
}
@@ -409,8 +426,12 @@
@@ -430,8 +430,12 @@
# libraries. Other executable ELF files (like kernel modules) don't need it.
if [ "$include_minidebug" = "true" -a "$strip_g" = "false" ]; then
skip_mini=true
@ -89,5 +89,5 @@ Adjusted for rpm-4.14.2 in RHEL
case "$(file -bi "$f")" in
- application/x-sharedlib*) skip_mini=false ;;
application/x-executable*) skip_mini=false ;;
application/x-pie-executable*) skip_mini=false ;;
esac
$skip_mini || add_minidebug "${debugfn}" "$f"

View File

@ -0,0 +1,44 @@
From f00bb5be9caa62220c6aeaf3f7264840d5c089e3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@redhat.com>
Date: Tue, 5 Feb 2019 18:15:47 +0100
Subject: [PATCH] Add limits to autopatch macro
Limits allow to apply only range of patches with given parameters.
Useful if something needs to be done between patch sets. Allows applying
of patches with different -pX parameter in one spec file.
Resolves: #626
Co-authored-by: Florian Festi <ffesti@redhat.com>
---
macros.in | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/macros.in b/macros.in
index 7b5b63020..912ad5997 100644
--- a/macros.in
+++ b/macros.in
@@ -1265,11 +1265,19 @@ else\
end}
# Automatically apply all patches
-%autopatch(vp:)\
+# -m<min> Apply patches with number >= min only
+# -M<max> Apply patches with number <= max only
+%autopatch(vp:m:M:)\
%{lua:\
local options = rpm.expand("%{!-v:-q} %{-p:-p%{-p*}} ")\
+local low_limit = tonumber(rpm.expand("%{-m:%{-m*}}"))\
+local high_limit = tonumber(rpm.expand("%{-M:%{-M*}}"))\
for i, p in ipairs(patches) do\
- print(rpm.expand("%apply_patch -m %{basename:"..p.."} "..options..p.." "..i.."\\n"))\
+ local inum = patch_nums[i]\
+ if ((not low_limit or inum>=low_limit) and (not high_limit or inum<=high_limit)) \
+ then\
+ print(rpm.expand("%apply_patch -m %{basename:"..p.."} "..options..p.." "..i.."\\n")) \
+ end\
end}
# One macro to (optionally) do it all.
--
2.26.2

View File

@ -0,0 +1,107 @@
From 186e0ab025b9ad92d900697f611633a6f6162f3b 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, 37 insertions(+), 4 deletions(-)
diff --git a/lib/rpmfi.c b/lib/rpmfi.c
index aec8220a3..6c631fdb5 100644
--- a/lib/rpmfi.c
+++ b/lib/rpmfi.c
@@ -53,6 +53,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 */
@@ -298,11 +301,16 @@ rpm_count_t rpmfiDC(rpmfi fi)
return (fi != NULL ? rpmfilesDC(fi->files) : 0);
}
-#ifdef NOTYET
-int rpmfiDI(rpmfi fi)
+int rpmfiSetOnChdir(rpmfi fi, rpmfiChdirCb cb, void *data)
{
+ int rc = -1;
+ if (fi != NULL) {
+ fi->onChdir = cb;
+ fi->onChdirData = data;
+ rc = 0;
+ }
+ return rc;
}
-#endif
int rpmfiFX(rpmfi fi)
{
@@ -314,9 +322,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;
}
@@ -1682,9 +1698,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 dccc6ccbe..37f1d45f5 100644
--- a/lib/rpmfi_internal.h
+++ b/lib/rpmfi_internal.h
@@ -13,6 +13,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
--
2.41.0

View File

@ -0,0 +1,32 @@
From 38c03ddb18e86c84d89af695f72442d8365eb64e Mon Sep 17 00:00:00 2001
From: Florian Festi <ffesti@redhat.com>
Date: Tue, 21 Jul 2020 10:45:20 +0200
Subject: [PATCH] Always close libelf handle (#1313)
Otherwise executables that are not proper elf files are leaking libelf
handles. This results in file being left open (mmap'ed) and fails the
build on NFS as those files can't be deleted properly there.
Resolves: rhbz#1840728
See also: https://bugzilla.redhat.com/show_bug.cgi?id=1840728
---
build/files.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/build/files.c b/build/files.c
index f675306f7..62489c07c 100644
--- a/build/files.c
+++ b/build/files.c
@@ -1935,8 +1935,8 @@ static int generateBuildIDs(FileList fl, ARGV_t *files)
if (terminate)
rc = 1;
}
- elf_end (elf);
}
+ elf_end (elf);
close (fd);
}
}
--
2.26.2

View File

@ -1,38 +0,0 @@
From ce11f04ed529cd84de8981b82c1185c0a30dfdcf Mon Sep 17 00:00:00 2001
From: Pavlina Moravcova Varekova <pmoravco@redhat.com>
Date: Thu, 14 Mar 2019 13:23:13 +0100
Subject: [PATCH] Correct rpm -ql exit value when optional -p is omitted
(RhBug:1680610)
---
lib/query.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/lib/query.c b/lib/query.c
index e47189ed0..e5408e211 100644
--- a/lib/query.c
+++ b/lib/query.c
@@ -568,16 +568,18 @@ int rpmcliArgIter(rpmts ts, QVA_t qva, ARGV_const_t argv)
break;
default:
for (ARGV_const_t arg = argv; arg && *arg; arg++) {
+ int ecLocal;
rpmdbMatchIterator mi = initQueryIterator(qva, ts, *arg);
- ec += rpmcliShowMatches(qva, ts, mi);
+ ecLocal = rpmcliShowMatches(qva, ts, mi);
if (mi == NULL && qva->qva_source == RPMQV_PACKAGE) {
size_t l = strlen(*arg);
if (l > 4 && !strcmp(*arg + l - 4, ".rpm")) {
rpmgi gi = rpmgiNew(ts, giFlags, argv);
- ec += rpmgiShowMatches(qva, ts, gi);
+ ecLocal = rpmgiShowMatches(qva, ts, gi);
rpmgiFree(gi);
}
}
+ ec += ecLocal;
rpmdbFreeIterator(mi);
}
break;
--
2.17.2

View File

@ -0,0 +1,30 @@
From 6c66abd34cccbb5b3c063f8f613e0c2faffc415f Mon Sep 17 00:00:00 2001
From: Panu Matilainen <pmatilai@redhat.com>
Date: Wed, 13 Dec 2023 11:57:50 +0200
Subject: [PATCH] Don't warn about missing user/group on skipped files
There's no reason to complain about missing user/group for entities
we don't create at all. It's cosmetical only, but "regressed" in the
4.17 fsm robustness rewrite.
Reported in https://issues.redhat.com/browse/RHEL-18037
---
lib/fsm.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/fsm.c b/lib/fsm.c
index 2189bd84c..a54e43bae 100644
--- a/lib/fsm.c
+++ b/lib/fsm.c
@@ -903,7 +903,7 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files,
fp->fpath = fsmFsPath(fi, fp->suffix);
/* Remap file perms, owner, and group. */
- rc = rpmfiStat(fi, 1, &fp->sb);
+ rc = rpmfiStat(fi, (fp->skip == 0), &fp->sb);
/* Hardlinks are tricky and handled elsewhere for install */
fp->setmeta = (fp->skip == 0) &&
--
2.43.0

View File

@ -0,0 +1,35 @@
From 0bc13d75b5883ccf4d6579f7a60fb1badd104649 Mon Sep 17 00:00:00 2001
From: Panu Matilainen <pmatilai@redhat.com>
Date: Thu, 10 Feb 2022 10:23:22 +0200
Subject: [PATCH] Eliminate code duplication from rpmfiNext()
Now that we can, let rpmfiSetFX() take care of the details.
---
lib/rpmfi.c | 11 ++---------
1 file changed, 2 insertions(+), 9 deletions(-)
diff --git a/lib/rpmfi.c b/lib/rpmfi.c
index 689ead2c5..aec8220a3 100644
--- a/lib/rpmfi.c
+++ b/lib/rpmfi.c
@@ -856,15 +856,8 @@ int rpmfiNext(rpmfi fi)
next = fi->next(fi);
} while (next == RPMERR_ITER_SKIP);
- if (next >= 0 && next < rpmfilesFC(fi->files)) {
- fi->i = next;
- fi->j = rpmfilesDI(fi->files, fi->i);
- } else {
- fi->i = -1;
- if (next >= 0) {
- next = -1;
- }
- }
+ if (next >= 0)
+ next = rpmfiSetFX(fi, next);
}
return next;
}
--
2.41.0

View File

@ -0,0 +1,66 @@
From c140768202e271b60910644c1e4bf848a50218d3 Mon Sep 17 00:00:00 2001
From: Panu Matilainen <pmatilai@redhat.com>
Date: Mon, 27 Nov 2023 11:52:34 +0200
Subject: [PATCH] Emit full paths for file disposition diagnostics on
--fsmdebug
The full path is visible in the actual file operations later, but the
pre-flight disposition diagnostics is unreadable without the full path.
This regressed in the switch to relative paths for the *at() API family
for the symlink CVE fixes.
---
lib/fsm.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/lib/fsm.c b/lib/fsm.c
index 091e90554..fcd764648 100644
--- a/lib/fsm.c
+++ b/lib/fsm.c
@@ -482,14 +482,14 @@ static void removeSBITS(int dirfd, const char *path)
}
}
-static void fsmDebug(const char *fpath, rpmFileAction action,
+static void fsmDebug(const char *dn, const char *fpath, rpmFileAction action,
const struct stat *st)
{
- rpmlog(RPMLOG_DEBUG, "%-10s %06o%3d (%4d,%4d)%6d %s\n",
+ rpmlog(RPMLOG_DEBUG, "%-10s %06o%3d (%4d,%4d)%6d %s%s\n",
fileActionString(action), (int)st->st_mode,
(int)st->st_nlink, (int)st->st_uid,
(int)st->st_gid, (int)st->st_size,
- (fpath ? fpath : ""));
+ (dn ? dn : ""), (fpath ? fpath : ""));
}
static int fsmSymlink(const char *opath, int dirfd, const char *path)
@@ -910,7 +910,7 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files,
(fp->sb.st_nlink == 1 || fp->action == FA_TOUCH);
setFileState(fs, fx);
- fsmDebug(fp->fpath, fp->action, &fp->sb);
+ fsmDebug(rpmfiDN(fi), fp->fpath, fp->action, &fp->sb);
fp->stage = FILE_PRE;
}
@@ -975,7 +975,7 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files,
rpmlog(RPMLOG_DEBUG, "file %s vanished unexpectedly\n",
fp->fpath);
fp->action = FA_CREATE;
- fsmDebug(fp->fpath, fp->action, &fp->sb);
+ fsmDebug(rpmfiDN(fi), fp->fpath, fp->action, &fp->sb);
}
/* When touching we don't need any of this... */
@@ -1138,7 +1138,7 @@ int rpmPackageFilesRemove(rpmts ts, rpmte te, rpmfiles files,
rc = fsmStat(di.dirfd, fp->fpath, 1, &fp->sb);
- fsmDebug(fp->fpath, fp->action, &fp->sb);
+ fsmDebug(rpmfiDN(fi), fp->fpath, fp->action, &fp->sb);
/* Run fsm file pre hook for all plugins */
rc = rpmpluginsCallFsmFilePre(plugins, fi, fp->fpath,
--
2.43.0

View File

@ -1,26 +0,0 @@
From 788935c9ea9d2f469f24be10a9fa998594046731 Mon Sep 17 00:00:00 2001
From: Panu Matilainen <pmatilai@redhat.com>
Date: Fri, 7 Sep 2018 11:52:33 +0300
Subject: [PATCH] Fix a blindingly obvious memleak in package verify step
Erm. Introduced in commit 765e2c72ae8be369ada41d4747b8999519a0e327,
but how on earth did this go unnoticed... *blush*
---
lib/transaction.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/lib/transaction.c b/lib/transaction.c
index 205c3f388..3969ad3fc 100644
--- a/lib/transaction.c
+++ b/lib/transaction.c
@@ -1261,6 +1261,7 @@ static int verifyPackageFiles(rpmts ts, rpm_loff_t total)
rpmteAddProblem(p, RPMPROB_VERIFY, NULL, vd.msg, 0);
vd.msg = _free(vd.msg);
+ rpmvsFree(vs);
}
rpmtsNotify(ts, NULL, RPMCALLBACK_VERIFY_STOP, total, total);
--
2.21.0

View File

@ -1,46 +0,0 @@
From 531dc8495cd3aabd3f659ecab604106fdbacbe98 Mon Sep 17 00:00:00 2001
Message-Id: <531dc8495cd3aabd3f659ecab604106fdbacbe98.1554974459.git.pmatilai@redhat.com>
From: Panu Matilainen <pmatilai@redhat.com>
Date: Wed, 3 Oct 2018 11:51:38 +0300
Subject: [PATCH] Fix ancient python GIL locking bug on callback
(RhBug:1632488)
Introduced in commit c7881d801745b4c156a8aa2afc17b95f97481e34 back in 2002,
synthesizing a python object for the callback occurs before retaking
the GIL lock, which is not allowed. Somehow this has managed to stay
latent all these years, and even now requires fairly specific conditions:
when the callback gets called without an associated key, such as erasures
or file trigger script start/stop events (in the case of RhBug:1632488),
when Python 3 is running in PYTHONMALLOC=debug mode,
it crashes with "Python memory allocator called without holding the GIL".
Simply retake the lock before any Python operations take place to fix.
---
python/rpmts-py.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/python/rpmts-py.c b/python/rpmts-py.c
index e4c5e1250..1ddfc9a1e 100644
--- a/python/rpmts-py.c
+++ b/python/rpmts-py.c
@@ -495,6 +495,8 @@ rpmtsCallback(const void * hd, const rpmCallbackType what,
if (cbInfo->cb == Py_None) return NULL;
+ PyEval_RestoreThread(cbInfo->_save);
+
/* Synthesize a python object for callback (if necessary). */
if (pkgObj == NULL) {
if (h) {
@@ -506,8 +508,6 @@ rpmtsCallback(const void * hd, const rpmCallbackType what,
} else
Py_INCREF(pkgObj);
- PyEval_RestoreThread(cbInfo->_save);
-
args = Py_BuildValue("(iLLOO)", what, amount, total, pkgObj, cbInfo->data);
result = PyEval_CallObject(cbInfo->cb, args);
Py_DECREF(args);
--
2.20.1

View File

@ -0,0 +1,41 @@
From 1fd84fa0cfa6e493d1c15edfb7d9f0bb05e4f920 Mon Sep 17 00:00:00 2001
From: Florian Festi <ffesti@redhat.com>
Date: Thu, 2 May 2019 17:17:56 +0200
Subject: [PATCH] Fix brp-strip-static-archive parallelism
The change made in fc2c986 can break for large values of %_smp_build_ncpus as
this many processes are able to overflow the following pipe.
Thanks to Denys Vlasenko for testing this.
This change solves this problem by running a whole processing pileline for each
parallel (file) process. This has also the benefit of running at least some
stip commands in parallel.
The -n param fro xargs was increased to 32 to further reduce the over head of
spawing the helpers as they are now needed for each run of the file command.
---
scripts/brp-strip-static-archive | 10 +++-------
1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/scripts/brp-strip-static-archive b/scripts/brp-strip-static-archive
index 4dc449061..13d9a098b 100755
--- a/scripts/brp-strip-static-archive
+++ b/scripts/brp-strip-static-archive
@@ -13,10 +13,6 @@ Darwin*) exit 0 ;;
esac
# Strip static libraries.
-for f in `find "$RPM_BUILD_ROOT" -type f | \
- grep -v "^${RPM_BUILD_ROOT}/\?usr/lib/debug" | \
- xargs -r -P$NCPUS -n16 file | sed 's/: */: /' | \
- grep 'current ar archive' | \
- sed -n -e 's/^\(.*\):[ ]*current ar archive/\1/p'`; do
- $STRIP -g "$f"
-done
+find "$RPM_BUILD_ROOT" -type f | \
+ grep -v "^${RPM_BUILD_ROOT}/\?usr/lib/debug" | \
+ xargs -r -P$NCPUS -n32 sh -c "file \"\$@\" | sed 's/: */: /' | grep 'current ar archive' | sed -n -e 's/^\(.*\):[ ]*current ar archive/\1/p' | xargs -I\{\} $STRIP -g \{\}" ARG0
--
2.21.0

View File

@ -1,30 +0,0 @@
From 5188a7b35eb3672c9b15e96433e033ee36f8e6a8 Mon Sep 17 00:00:00 2001
From: Panu Matilainen <pmatilai@redhat.com>
Date: Tue, 6 Aug 2019 13:06:16 +0300
Subject: [PATCH] Fix memleak during transaction verify step in the NOKEY case.
Found during RhBug:1714657 QA testing.
In addition, add a comment to clarify the fallthrough as intentional.
---
lib/transaction.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/lib/transaction.c b/lib/transaction.c
index 6e4d4be65..e51cff25a 100644
--- a/lib/transaction.c
+++ b/lib/transaction.c
@@ -1226,8 +1226,10 @@ static int vfyCb(struct rpmsinfo_s *sinfo, void *cbdata)
*/
if (!(vd->vfylevel & RPMSIG_SIGNATURE_TYPE))
sinfo->rc = RPMRC_OK;
+ /* fallthrough */
default:
- vd->msg = rpmsinfoMsg(sinfo);
+ if (sinfo->rc)
+ vd->msg = rpmsinfoMsg(sinfo);
break;
}
return (sinfo->rc == 0);
--
2.21.0

View File

@ -1,52 +0,0 @@
From 0d83637769b8a122b1e80f2e960ea1bbae8b4f10 Mon Sep 17 00:00:00 2001
Message-Id: <0d83637769b8a122b1e80f2e960ea1bbae8b4f10.1540199566.git.pmatilai@redhat.com>
From: Panu Matilainen <pmatilai@redhat.com>
Date: Mon, 22 Oct 2018 10:52:39 +0300
Subject: [PATCH] Fix nasty --setperms/--setugids regression in 4.14.2 (RhBug:
1640470)
Commit 38c2f6e160d5ed3e9c3a266139c7eb2632724c15 causes --setperms and
--setugids follow symlinks instead of skipping them.
In case of --setperms, all encountered symlinks will have their
target file/directory permissions set to the 0777 of the link itself
(so world writable etc but suid/sgid stripped), temporarily or permanently,
depending on whether the symlink occurs before or after it's target in the
package file list. When the link occurs before its target, there's a short
window where the target is world writable before having it's permissions
reset to original, making it particularly bad for suid/sgid binaries.
--setugids is similarly affected with link targets owner/group changing
to that of the symlink.
Add missing parentheses to the conditions introduced in commit
38c2f6e160d5ed3e9c3a266139c7eb2632724c15 to fix.
Reported by Karel Srot, patch by Pavlina Moravcova Varekova.
---
rpmpopt.in | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/rpmpopt.in b/rpmpopt.in
index 8aaa91f11..42d3416a3 100644
--- a/rpmpopt.in
+++ b/rpmpopt.in
@@ -44,14 +44,14 @@ rpm alias --scripts --qf '\
--POPTdesc=$"list install/erase scriptlets from package(s)"
rpm alias --setperms -q --qf '[\[ -L %{FILENAMES:shescape} \] || \
- \[ $((%{FILEFLAGS} & 2#1001000)) != 0 \] && \[ ! -e %{FILENAMES: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" \
--POPTdesc=$"set permissions of files in a package"
rpm alias --setugids -q --qf \
'[ch %{FILEUSERNAME:shescape} %{FILEGROUPNAME:shescape} %{FILENAMES:shescape} %{FILEFLAGS}\n]' \
- --pipe "(echo 'ch() { \[ $(($4 & 2#1001000)) != 0 \] && \[ ! -e \"$3\" \] || \
+ --pipe "(echo 'ch() { ( \[ $(($4 & 2#1001000)) != 0 \] && \[ ! -e \"$3\" \] ) || \
(chown -h -- \"$1\" \"$3\";chgrp -h -- \"$2\" \"$3\";) }'; \
grep '^ch '|grep -v \(none\))|sh" \
--POPTdesc=$"set user/group ownership of files in a package"
--
2.17.2

View File

@ -1,37 +0,0 @@
From e219c9548d16a3c18dd261f7043bb8d221b87c77 Mon Sep 17 00:00:00 2001
From: Panu Matilainen <pmatilai@redhat.com>
Date: Wed, 31 Jul 2019 11:56:26 +0300
Subject: [PATCH] Fix off-by-one in hdrblobGet() making last entry unreachable
(RhBug:1722921)
hdrblobGet() introduced in commits acfde0d0e812e9f8e153ab6be8c9f2682bdd4763
and 9821de18811db97238c34a564221e315f5f35b44 has an off-by-one thinko
(perhaps the idea was to skip the first, region tag) which causes
the last entry to be unreachable. In typical packages, that is
RPMSIG_PAYLOADSIZE which is not used at all in this context so it doesn't
matter, but in large packages use RPMSIG_LONGARCHIVESIZE which has a lower
tag number and leaves either RPMSIGTAG_MD5 or RPMSIGTAG_GPG last,
unreachable and thus unverifiable. Oops.
This fixes the regression introduced in rpm 4.14, affecting verification
of large packages (ie having RPMSIG_LONGARCHIVESIZE)
---
lib/header.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/header.c b/lib/header.c
index 33623884a..9ec7ed0e4 100644
--- a/lib/header.c
+++ b/lib/header.c
@@ -2015,7 +2015,7 @@ rpmRC hdrblobGet(hdrblob blob, uint32_t tag, rpmtd td)
memset(&einfo, 0, sizeof(einfo));
rpmtdReset(td);
- for (int i = 1; i < blob->il; i++, pe++) {
+ for (int i = 0; i < blob->il; i++, pe++) {
if (pe->tag != ntag)
continue;
ei2h(pe, &einfo);
--
2.21.0

View File

@ -1,39 +0,0 @@
From a144c29831a39ed303d6ea8d2ae91e1c36d64c84 Mon Sep 17 00:00:00 2001
Message-Id: <a144c29831a39ed303d6ea8d2ae91e1c36d64c84.1559799452.git.pmatilai@redhat.com>
From: Panu Matilainen <pmatilai@redhat.com>
Date: Wed, 15 May 2019 13:51:19 +0300
Subject: [PATCH] Fix packages getting erased on failed update with dnf
(RhBug:1620275)
When adding update elements, we set the erase element to depend on the
install element, but if an API user adds the same erasure manually
after adding the update, we know its a duplicate erasure and filter
it out, BUT we zero out the dependent element in the process. And
if installing the update now fails, we end up removing the whole package
due to that missing dependent element.
This never happens with rpm itself so we can't easily test it, but is
100% reproducable with dnf (at least dnf 3-4). Apparently it adds all
erasures by itself (which is kind of understandable I guess, perhaps
we should better allow this in the API)
---
lib/depends.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/lib/depends.c b/lib/depends.c
index 6e9866eae..f8a6084ab 100644
--- a/lib/depends.c
+++ b/lib/depends.c
@@ -121,7 +121,8 @@ static int removePackage(rpmts ts, Header h, rpmte depends)
/* Filter out duplicate erasures. */
if (packageHashGetEntry(tsmem->removedPackages, dboffset, &pp, NULL, NULL)) {
- rpmteSetDependsOn(pp[0], depends);
+ if (depends)
+ rpmteSetDependsOn(pp[0], depends);
return 0;
}
--
2.21.0

View File

@ -0,0 +1,102 @@
From 60066aba510b3ff4a7db092021aae71948e3f8be Mon Sep 17 00:00:00 2001
From: Panu Matilainen <pmatilai@redhat.com>
Date: Thu, 4 Jun 2020 11:18:01 +0300
Subject: [PATCH] Fix python ts.addErase() not raising exception on not-found
packages
The code would only raise an exception if TransactionSetCore.addErase()
returned an error, but the catch is that with many kinds of argument
types we'd silently skip the whole addition because no headers were found.
This looks to be a regression introduced some eleven years ago in
commit 9b20c706a4f93266450fae2f94007343b2e8fd9e.
As a special case, a match iterator argument will not raise an exception
if it doesn't actually match anything.
Fixes: #1214
---
python/rpm/transaction.py | 26 +++++++++++++++-----------
tests/rpmpython.at | 22 ++++++++++++++++++++++
2 files changed, 37 insertions(+), 11 deletions(-)
diff --git a/python/rpm/transaction.py b/python/rpm/transaction.py
index 7c4a551d3..3c9ddb207 100644
--- a/python/rpm/transaction.py
+++ b/python/rpm/transaction.py
@@ -91,14 +91,22 @@ class TransactionSet(TransactionSetCore):
def addErase(self, item):
hdrs = []
- if isinstance(item, rpm.hdr):
- hdrs = [item]
- elif isinstance(item, rpm.mi):
+ # match iterators are passed on as-is
+ if isinstance(item, rpm.mi):
hdrs = item
- elif isinstance(item, int):
- hdrs = self.dbMatch(rpm.RPMDBI_PACKAGES, item)
- elif isinstance(item, _string_types):
- hdrs = self.dbMatch(rpm.RPMDBI_LABEL, item)
+ elif isinstance(item, rpm.hdr):
+ hdrs.append(item)
+ elif isinstance(item, (int, _string_types)):
+ if isinstance(item, int):
+ dbi = rpm.RPMDBI_PACKAGES
+ else:
+ dbi = rpm.RPMDBI_LABEL
+
+ for h in self.dbMatch(dbi, item):
+ hdrs.append(h)
+
+ if not hdrs:
+ raise rpm.error("package not installed")
else:
raise TypeError("invalid type %s" % type(item))
@@ -106,10 +114,6 @@ class TransactionSet(TransactionSetCore):
if not TransactionSetCore.addErase(self, h):
raise rpm.error("package not installed")
- # garbage collection should take care but just in case...
- if isinstance(hdrs, rpm.mi):
- del hdrs
-
def run(self, callback, data):
rc = TransactionSetCore.run(self, callback, data, self._probFilter)
diff --git a/tests/rpmpython.at b/tests/rpmpython.at
index 3a7c251f1..de39c8417 100644
--- a/tests/rpmpython.at
+++ b/tests/rpmpython.at
@@ -201,6 +201,28 @@ for e in ts:
[foo-1.0-1.noarch]
)
+RPMPY_TEST([add erasure to transaction],[
+ts = rpm.ts()
+for i in ['foo', 1234]:
+ myprint('addErase %s' % i)
+ try:
+ ts.addErase(i)
+ except rpm.error as err:
+ myprint(err)
+myprint('addErase mi')
+mi = ts.dbMatch('name', 'foo')
+try:
+ ts.addErase(mi)
+except rpm.error as err:
+ myprint(err)
+],
+[addErase foo
+package not installed
+addErase 1234
+package not installed
+addErase mi]
+)
+
RPMPY_TEST([add bogus package to transaction 1],[
ts = rpm.ts()
h = rpm.hdr()
--
2.26.2

View File

@ -0,0 +1,50 @@
From ed6c5573c09611ff9522ed290ef9d1ba717d8019 Mon Sep 17 00:00:00 2001
Message-Id: <ed6c5573c09611ff9522ed290ef9d1ba717d8019.1574331915.git.pmatilai@redhat.com>
From: Panu Matilainen <pmatilai@redhat.com>
Date: Thu, 21 Nov 2019 12:22:45 +0200
Subject: [PATCH] Fix resource leaks on zstd open error paths
If zstd stream initialization fails, the opened fd and the stream
itself are leaked. Handle error exit in a central label.
---
rpmio/rpmio.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/rpmio/rpmio.c b/rpmio/rpmio.c
index 243942411..10ba20cd6 100644
--- a/rpmio/rpmio.c
+++ b/rpmio/rpmio.c
@@ -1128,13 +1128,13 @@ static rpmzstd rpmzstdNew(int fdno, const char *fmode)
if ((flags & O_ACCMODE) == O_RDONLY) { /* decompressing */
if ((_stream = (void *) ZSTD_createDStream()) == NULL
|| ZSTD_isError(ZSTD_initDStream(_stream))) {
- return NULL;
+ goto err;
}
nb = ZSTD_DStreamInSize();
} else { /* compressing */
if ((_stream = (void *) ZSTD_createCStream()) == NULL
|| ZSTD_isError(ZSTD_initCStream(_stream, level))) {
- return NULL;
+ goto err;
}
nb = ZSTD_CStreamOutSize();
}
@@ -1149,6 +1149,14 @@ static rpmzstd rpmzstdNew(int fdno, const char *fmode)
zstd->b = xmalloc(nb);
return zstd;
+
+err:
+ fclose(fp);
+ if ((flags & O_ACCMODE) == O_RDONLY)
+ ZSTD_freeDStream(_stream);
+ else
+ ZSTD_freeCStream(_stream);
+ return NULL;
}
static FD_t zstdFdopen(FD_t fd, int fdno, const char * fmode)
--
2.23.0

View File

@ -1,25 +0,0 @@
From 475af64f64cbc210c87588d425fa9a14cd9760b6 Mon Sep 17 00:00:00 2001
From: Panu Matilainen <pmatilai@redhat.com>
Date: Wed, 29 May 2019 11:38:53 +0300
Subject: [PATCH] Fix rpmfiles memory leak on %postuntrans file trigger
preparation
---
lib/rpmtriggers.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/lib/rpmtriggers.c b/lib/rpmtriggers.c
index cb2441c5a..b7c76e7fc 100644
--- a/lib/rpmtriggers.c
+++ b/lib/rpmtriggers.c
@@ -154,6 +154,7 @@ void rpmtriggersPrepPostUnTransFileTrigs(rpmts ts, rpmte te)
}
}
rpmdbFreeIterator(mi);
+ rpmfilesFree(files);
}
int runPostUnTransFileTrigs(rpmts ts)
--
2.21.0

View File

@ -1,60 +0,0 @@
From 050b392f8c11d111379e0d2bac52762beb97b3ae Mon Sep 17 00:00:00 2001
Message-Id: <050b392f8c11d111379e0d2bac52762beb97b3ae.1559645935.git.pmatilai@redhat.com>
From: Panu Matilainen <pmatilai@redhat.com>
Date: Tue, 2 Apr 2019 12:57:11 +0300
Subject: [PATCH] Fix segfault on fingerprinting symlink round (RhBug:1660232)
Both yum and dnf perform a test-transaction before the real thing,
and both neglet to check for an error code from the test-transaction
when there are no problem objects to return. Which can happen in
some special cases, such a using different vsflags between initial
package read and transaction (which is what both yum and dnf do),
which can cause the in-transaction package open fail on corrupt packages.
And when this failed transaction is fed back to rpmtsRun(), it
segfaults in fingerprinting as the second loop of symlink checking
doesn't check for NULL's element files like the first loop does.
Add the missing NULL check and remove bogus "can't happen" comment to fix.
FWIW, the scenario with different vsflags and corrupted packages doesn't
happen by default in rpm >= 4.14.2, the corrupt package gets caught
in the verify stage which does create problem objects and thus both
yum and dnf abort as they should.
---
lib/fprint.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/lib/fprint.c b/lib/fprint.c
index b810e4d2b..ab1891961 100644
--- a/lib/fprint.c
+++ b/lib/fprint.c
@@ -488,7 +488,7 @@ void fpCachePopulate(fingerPrintCache fpc, rpmts ts, int fileCount)
(void) rpmsqPoll();
if ((fi = rpmteFiles(p)) == NULL)
- continue; /* XXX can't happen */
+ continue;
(void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_FINGERPRINT), 0);
rpmfilesFpLookup(fi, fpc);
@@ -522,6 +522,9 @@ void fpCachePopulate(fingerPrintCache fpc, rpmts ts, int fileCount)
while ((p = rpmtsiNext(pi, 0)) != NULL) {
(void) rpmsqPoll();
+ if ((fi = rpmteFiles(p)) == NULL)
+ continue;
+
fs = rpmteGetFileStates(p);
fc = rpmfsFC(fs);
(void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_FINGERPRINT), 0);
@@ -531,6 +534,7 @@ void fpCachePopulate(fingerPrintCache fpc, rpmts ts, int fileCount)
fpLookupSubdir(symlinks, fpc, p, i);
}
(void) rpmswExit(rpmtsOp(ts, RPMTS_OP_FINGERPRINT), 0);
+ rpmfilesFree(fi);
}
rpmtsiFree(pi);
--
2.21.0

View File

@ -1,28 +0,0 @@
From 66e0c929b203d684a4f58135f42435fcc29cdd51 Mon Sep 17 00:00:00 2001
Message-Id: <66e0c929b203d684a4f58135f42435fcc29cdd51.1554982695.git.pmatilai@redhat.com>
From: Panu Matilainen <pmatilai@redhat.com>
Date: Wed, 10 Oct 2018 12:00:19 +0300
Subject: [PATCH] Fix testing for wrong variable in selinux plugin debug log
The strerror() case couldn't be reached as we were testing for the
wrong rc, spotted by covscan.
---
plugins/selinux.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/plugins/selinux.c b/plugins/selinux.c
index 3c9d9e4ab..accd47416 100644
--- a/plugins/selinux.c
+++ b/plugins/selinux.c
@@ -169,7 +169,7 @@ static rpmRC selinux_fsm_file_prepare(rpmPlugin plugin, rpmfi fi,
if (rpmIsDebug()) {
rpmlog(RPMLOG_DEBUG, "lsetfilecon: (%s, %s) %s\n",
- path, scon, (rc < 0 ? strerror(errno) : ""));
+ path, scon, (conrc < 0 ? strerror(errno) : ""));
}
if (conrc == 0 || (conrc < 0 && errno == EOPNOTSUPP))
--
2.20.1

View File

@ -0,0 +1,46 @@
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
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.43.0

View File

@ -1,47 +0,0 @@
From 74766d30b95f1575df8a42d185f2643caa235a8b Mon Sep 17 00:00:00 2001
Message-Id: <74766d30b95f1575df8a42d185f2643caa235a8b.1543835412.git.pmatilai@redhat.com>
From: Panu Matilainen <pmatilai@redhat.com>
Date: Fri, 23 Nov 2018 12:47:27 +0200
Subject: [PATCH] Handle unsupported digests the same as disabled ones
(RhBug:1652529)
A digest type unsupported by the underlying crypto library (whether
technically or by configuration) does not mean the digest is invalid,
it just cannot be used. Which for the purposes of verification is the
same as if that digest didn't exist at all, and that's exactly how we
handle digests and signatures disabled by configuration.
One particular case is FIPS mode which globally disables the use of MD5,
which we mishandled prior to this by showing it as OK in verification
despite actually not verifying it at all.
The exact place for handling this case is a bit subtle: the "obvious"
place for checking for supported type is in rpmvsInitRange() but this
doesn't work because of rpmDigestBundleAddID() return code semantics.
The other "obvious" place would be rpmvsVerify(), but by that point
we have even more funny cases to consider. So for now, it's actually
easiest to check for this in rpmvsFiniRange() even if it's not the
most obvious place for doing so. Might want to change the
rpmDigestBundleAddID() semantics later, but this makes for a nicer
backport (we'll need this in 4.14.x too).
---
lib/rpmvs.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/lib/rpmvs.c b/lib/rpmvs.c
index 7b5b86f8e..622e48011 100644
--- a/lib/rpmvs.c
+++ b/lib/rpmvs.c
@@ -388,6 +388,9 @@ void rpmvsFiniRange(struct rpmvs_s *sis, int range)
if (sinfo->range == range && sinfo->rc == RPMRC_OK) {
sinfo->ctx = rpmDigestBundleDupCtx(sis->bundle, sinfo->id);
+ /* Handle unsupported digests the same as disabled ones */
+ if (sinfo->ctx == NULL)
+ sinfo->rc = RPMRC_NOTFOUND;
rpmDigestBundleFinal(sis->bundle, sinfo->id, NULL, NULL, 0);
}
}
--
2.19.2

View File

@ -0,0 +1,53 @@
From 6b6c4d881dc6fc99f949dac4aaf9a513542f9956 Mon Sep 17 00:00:00 2001
Message-Id: <6b6c4d881dc6fc99f949dac4aaf9a513542f9956.1571920849.git.pmatilai@redhat.com>
From: Panu Matilainen <pmatilai@redhat.com>
Date: Wed, 3 Oct 2018 15:22:55 +0300
Subject: [PATCH 1/5] Honor PYTHON from configure when running tests
Pass PYTHON from configure down through all the nutty layers of make
to allow running test-suite with Python 3. In theory that is.
(cherry picked from commit dcd5ab67c40b543f22b07df8c1028c34b94a7929)
---
tests/Makefile.am | 1 +
tests/atlocal.in | 3 ++-
tests/local.at | 2 +-
3 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/tests/Makefile.am b/tests/Makefile.am
index eaf817cc2..21ca216a8 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -117,6 +117,7 @@ atlocal: atlocal.in Makefile
-e "s,[@]usrlibdir[@],$(libdir)," \
-e "s,[@]execprefix[@],$(exec_prefix)," \
-e "s,[@]RPMCONFIGDIR[@],$(rpmconfigdir)," \
+ -e "s,[@]PYTHON[@],$(PYTHON)," \
< $(srcdir)/atlocal.in > atlocal
DISTCLEANFILES = atlocal
EXTRA_DIST += atlocal.in
diff --git a/tests/atlocal.in b/tests/atlocal.in
index d7d837f45..3b1474b56 100644
--- rpm-4.14.3/tests/atlocal.in.orig 2020-04-28 14:19:26.866602968 +0200
+++ rpm-4.14.3/tests/atlocal.in 2020-04-28 14:21:07.977910054 +0200
@@ -3,7 +3,8 @@
PATH="${abs_builddir}/testing@rpmbindir@:${abs_builddir}/testing@usrbindir@:$PATH"
export PATH
-PYLIBDIR=`python2 -c "from distutils.sysconfig import get_python_lib; import sys; sys.stdout.write(get_python_lib(1,0,'@execprefix@'))"`
+PYTHON=@PYTHON@
+PYLIBDIR=$(${PYTHON} -c "from distutils.sysconfig import get_python_lib; import sys; sys.stdout.write(get_python_lib(1,0,'@execprefix@'))")
PYTHONPATH="${abs_builddir}/testing${PYLIBDIR}"
export PYTHONPATH
--- rpm-4.14.3/tests/local.at.orig 2020-04-28 14:28:33.106664317 +0200
+++ rpm-4.14.3/tests/local.at 2020-04-28 14:29:02.064038653 +0200
@@ -18,7 +18,7 @@
sys.stdout.write('%s\n' % msg)
$1
EOF
-python2 test.py
+${PYTHON} test.py test.py
]])
m4_define([RPMPY_CHECK],[

View File

@ -0,0 +1,63 @@
From 9ad4b813483f8cf6c641f56387248b33b6dfc570 Mon Sep 17 00:00:00 2001
From: Panu Matilainen <pmatilai@redhat.com>
Date: Wed, 20 Feb 2019 15:28:30 +0200
Subject: [PATCH] Introduce patch_nums and source_nums Lua variables in spec
context
The pre-existing patches and sources variables only contains patch and
source filenames, but for some purposes we need access to the associated
patch/source number too. We could use the number as the table key, but
that would make the table unsorted. That we could handle in our own
macros, but would break compatibility for anybody doing custom stuff
with these. So it seems best to just add parallel arrays sharing the
same array indexes so that both values are as easily accessible,
depending on the need.
Inspired by Pascal "Pixel" Rigaux's similar patch in Mageia, which differs
in that the number-arrays are indexed by the filename and is unordered.
Compared to patches/sources this seemed against principle of least
surprise, and is slightly more cumbersome int the case we want the number
directly, such as in PR #626. The variable names differ so there
is no incompatibility to that downstream patch introduced.
---
build/parsePreamble.c | 9 +++++++++
build/spec.c | 3 ++-
2 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/build/parsePreamble.c b/build/parsePreamble.c
index 812c41f9f..9520bac4b 100644
--- a/build/parsePreamble.c
+++ b/build/parsePreamble.c
@@ -322,6 +322,15 @@ static int addSource(rpmSpec spec, Package pkg, const char *field, rpmTagVal tag
rpmluaSetVar(lua, var);
rpmluavFree(var);
rpmluaPop(lua);
+
+ what = (flag & RPMBUILD_ISPATCH) ? "patch_nums" : "source_nums";
+ rpmluaPushTable(lua, what);
+ var = rpmluavNew();
+ rpmluavSetListMode(var, 1);
+ rpmluavSetValueNum(var, p->num);
+ rpmluaSetVar(lua, var);
+ rpmluavFree(var);
+ rpmluaPop(lua);
}
#endif
free(body);
diff --git a/build/spec.c b/build/spec.c
index 80eaca611..55095c6ce 100644
--- a/build/spec.c
+++ b/build/spec.c
@@ -305,7 +305,8 @@ rpmSpec newSpec(void)
#ifdef WITH_LUA
/* make sure patches and sources tables always exist */
rpmlua lua = NULL; /* global state */
- const char * luavars[] = { "patches", "sources", NULL, };
+ const char * luavars[] = { "patches", "sources",
+ "patch_nums", "source_nums", NULL, };
for (const char **vp = luavars; vp && *vp; vp++) {
rpmluaDelVar(lua, *vp);
rpmluaPushTable(lua, *vp);
--
2.26.2

View File

@ -0,0 +1,41 @@
From e811c7ec0b4d2685b63b61803e3952466b1a4ac6 Mon Sep 17 00:00:00 2001
Message-Id: <e811c7ec0b4d2685b63b61803e3952466b1a4ac6.1574335619.git.pmatilai@redhat.com>
From: marxin <mliska@suse.cz>
Date: Wed, 28 Nov 2018 10:52:01 +0100
Subject: [PATCH] Isolate %_smp_build_ncpus and use it for %_smp_mflags.
Refactor _smp_build_ncpus and use it in %_smp_mflags. Note that now
having a single CPU, %_smp_mflags is expanded to '-j1'.
XXX: hand-edited to remove double quotes as per upstream commit
9b6fdc65ef0507fff04a69c88e085a7a26711839 which isn't applicable
directly due to other changes
---
platform.in | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/platform.in b/platform.in
index 3eb67b55b..2dd951f87 100644
--- a/platform.in
+++ b/platform.in
@@ -50,11 +50,14 @@
# Maximum number of CPU's to use when building, 0 for unlimited.
#%_smp_ncpus_max 0
-%_smp_mflags %([ -z "$RPM_BUILD_NCPUS" ] \\\
+
+%_smp_build_ncpus %([ -z "$RPM_BUILD_NCPUS" ] \\\
&& RPM_BUILD_NCPUS="`/usr/bin/getconf _NPROCESSORS_ONLN`"; \\\
ncpus_max=%{?_smp_ncpus_max}; \\\
if [ -n "$ncpus_max" ] && [ "$ncpus_max" -gt 0 ] && [ "$RPM_BUILD_NCPUS" -gt "$ncpus_max" ]; then RPM_BUILD_NCPUS="$ncpus_max"; fi; \\\
- if [ "$RPM_BUILD_NCPUS" -gt 1 ]; then echo "-j$RPM_BUILD_NCPUS"; fi)
+ echo "$RPM_BUILD_NCPUS";)
+
+%_smp_mflags -j%{_smp_build_ncpus}
#==============================================================================
# ---- Build policy macros.
--
2.23.0

View File

@ -1,86 +0,0 @@
From 8cbe8baf9c3ff4754369bcd29441df14ecc6889d Mon Sep 17 00:00:00 2001
Message-Id: <8cbe8baf9c3ff4754369bcd29441df14ecc6889d.1554982512.git.pmatilai@redhat.com>
From: Panu Matilainen <pmatilai@redhat.com>
Date: Thu, 14 Feb 2019 13:12:49 +0200
Subject: [PATCH] Log RPMLOG_ERR level messages on actual errors in selinux
plugin, doh.
When there's an actual error, people will want to know without having
to rerun in verbose mode. Such as in RhBug:1641631 where configured
selinux policy differs from what is installed - the former message
error: Plugin selinux: hook tsm_pre failed
...is not particularly helpful to anybody, whereas this actually provides
some clues now:
error: selabel_open: (/etc/selinux/ponies/contexts/files/file_contexts) No such file or directory
error: Plugin selinux: hook tsm_pre failed
---
plugins/selinux.c | 19 +++++++++----------
1 file changed, 9 insertions(+), 10 deletions(-)
diff --git a/plugins/selinux.c b/plugins/selinux.c
index accd47416..f1caf257c 100644
--- a/plugins/selinux.c
+++ b/plugins/selinux.c
@@ -12,6 +12,11 @@
static struct selabel_handle * sehandle = NULL;
+static inline rpmlogLvl loglvl(int iserror)
+{
+ return iserror ? RPMLOG_ERR : RPMLOG_DEBUG;
+}
+
static void sehandle_fini(int close_status)
{
if (sehandle) {
@@ -47,7 +52,7 @@ static rpmRC sehandle_init(int open_status)
sehandle = selabel_open(SELABEL_CTX_FILE, opts, 1);
- rpmlog(RPMLOG_DEBUG, "selabel_open: (%s) %s\n",
+ rpmlog(loglvl(sehandle == NULL), "selabel_open: (%s) %s\n",
path, (sehandle == NULL ? strerror(errno) : ""));
return (sehandle != NULL) ? RPMRC_OK : RPMRC_FAIL;
@@ -125,10 +130,8 @@ static rpmRC selinux_scriptlet_fork_post(rpmPlugin plugin,
if ((xx = setexeccon(newcon)) == 0)
rc = RPMRC_OK;
- if (rpmIsDebug()) {
- rpmlog(RPMLOG_DEBUG, "setexeccon: (%s, %s) %s\n",
+ rpmlog(loglvl(xx < 0), "setexeccon: (%s, %s) %s\n",
path, newcon, (xx < 0 ? strerror(errno) : ""));
- }
exit:
context_free(con);
@@ -143,10 +146,8 @@ exit:
if ((xx = setexecfilecon(path, "rpm_script_t") == 0))
rc = RPMRC_OK;
- if (rpmIsDebug()) {
- rpmlog(RPMLOG_DEBUG, "setexecfilecon: (%s) %s\n",
+ rpmlog(loglvl(xx < 0), "setexecfilecon: (%s) %s\n",
path, (xx < 0 ? strerror(errno) : ""));
- }
#endif
/* If selinux is not enforcing, we don't care either */
if (rc && security_getenforce() < 1)
@@ -167,10 +168,8 @@ static rpmRC selinux_fsm_file_prepare(rpmPlugin plugin, rpmfi fi,
if (selabel_lookup_raw(sehandle, &scon, dest, file_mode) == 0) {
int conrc = lsetfilecon(path, scon);
- if (rpmIsDebug()) {
- rpmlog(RPMLOG_DEBUG, "lsetfilecon: (%s, %s) %s\n",
+ rpmlog(loglvl(conrc < 0), "lsetfilecon: (%s, %s) %s\n",
path, scon, (conrc < 0 ? strerror(errno) : ""));
- }
if (conrc == 0 || (conrc < 0 && errno == EOPNOTSUPP))
rc = RPMRC_OK;
--
2.20.1

View File

@ -0,0 +1,31 @@
From f23af97c4135013d3134a17c881014fb6e9589c8 Mon Sep 17 00:00:00 2001
From: Florian Festi <ffesti@redhat.com>
Date: Tue, 30 Apr 2019 17:12:35 +0200
Subject: [PATCH] Make check-buildroot check the build files in parallel
Thanks to Denys Vlasenko for pointing this out in rhbz#1704353
---
scripts/check-buildroot | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/scripts/check-buildroot b/scripts/check-buildroot
index 0cfb34f39..f91dc767b 100755
--- a/scripts/check-buildroot
+++ b/scripts/check-buildroot
@@ -24,11 +24,12 @@ fi
tmp=$(mktemp ${TMPDIR:-/tmp}/cbr.XXXXXX)
trap "rm -f $tmp" EXIT
+NCPUS=${RPM_BUILD_NCPUS:-1}
find "$RPM_BUILD_ROOT" \! \( \
-name '*.pyo' -o -name '*.pyc' -o -name '*.elc' -o -name '.packlist' \
\) -type f -print0 | \
- LANG=C xargs -0r grep -F "$RPM_BUILD_ROOT" >$tmp
+ LANG=C xargs -0r -P$NCPUS -n16 grep -F "$RPM_BUILD_ROOT" >>$tmp
test -s "$tmp" && {
cat "$tmp"
--
2.21.0

View File

@ -1,49 +0,0 @@
From 2ec0832287bd1443ebf336f8a98293f30bfa2036 Mon Sep 17 00:00:00 2001
Message-Id: <2ec0832287bd1443ebf336f8a98293f30bfa2036.1554983205.git.pmatilai@redhat.com>
From: Panu Matilainen <pmatilai@redhat.com>
Date: Mon, 18 Mar 2019 15:24:54 +0200
Subject: [PATCH 1/3] Make rpmsign exit values more consistent with our other
tools
rpmPkgSign*() return -1 for failure, which is not that helpful when
returned to shell and the way it was counted could easily wrap around
when signing multiple packages. Return number of failures similarly to
how rpm -q and frieds does, avoid overflows and xargs special value 255.
---
rpmsign.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/rpmsign.c b/rpmsign.c
index ae86f666d..1a5cd59c2 100644
--- a/rpmsign.c
+++ b/rpmsign.c
@@ -134,7 +134,8 @@ static int doSign(poptContext optCon, struct rpmSignArgs *sargs)
const char *arg;
rc = 0;
while ((arg = poptGetArg(optCon)) != NULL) {
- rc += rpmPkgSign(arg, sargs);
+ if (rpmPkgSign(arg, sargs) < 0)
+ rc++;
}
exit:
@@ -175,7 +176,8 @@ int main(int argc, char *argv[])
case MODE_DELSIGN:
ec = 0;
while ((arg = poptGetArg(optCon)) != NULL) {
- ec += rpmPkgDelSign(arg, &sargs);
+ if (rpmPkgDelSign(arg, &sargs) < 0)
+ ec++;
}
break;
case MODE_NONE:
@@ -188,5 +190,5 @@ int main(int argc, char *argv[])
exit:
rpmcliFini(optCon);
- return ec;
+ return RETVAL(ec);
}
--
2.20.1

View File

@ -1,89 +0,0 @@
From 13b0ebee7cdb1e4d200b3c40d0ec9440f198a1d4 Mon Sep 17 00:00:00 2001
Message-Id: <13b0ebee7cdb1e4d200b3c40d0ec9440f198a1d4.1554886141.git.pmatilai@redhat.com>
From: Panu Matilainen <pmatilai@redhat.com>
Date: Wed, 10 Apr 2019 11:24:44 +0300
Subject: [PATCH] Monkey-patch .decode() method to our strings as a temporary
compat crutch
As a temporary crutch to support faster deployment of the sane
string behavior on python3, monkey-patch a decode method into all
strings we return. This seems to be enough to fix practically all
API users who have already adapted to the long-standing broken API
on Python 3. API users compatible with both Python 2 and 3 never needed
this anyway. Issue a warning with pointer to the relevant bug when the
fake decode() method is used to alert users to the issue.
This is certainly an evil thing to do and will be removed as soon as
the critical users have been fixed to work with the new, corrected
behavior.
---
python/rpm/__init__.py | 3 +++
python/rpmmodule.c | 1 +
python/rpmsystem-py.h | 22 ++++++++++++++++++++--
3 files changed, 24 insertions(+), 2 deletions(-)
diff --git a/python/rpm/__init__.py b/python/rpm/__init__.py
index 54728bbd4..6d69eda7b 100644
--- a/python/rpm/__init__.py
+++ b/python/rpm/__init__.py
@@ -61,6 +61,9 @@ except ImportError:
# backwards compatibility + give the same class both ways
ts = TransactionSet
+def _fakedecode(self, encoding='utf-8', errors='strict'):
+ warnings.warn("decode() called on unicode string, see https://bugzilla.redhat.com/show_bug.cgi?id=1693751", UnicodeWarning, stacklevel=2)
+ return self
def headerLoad(*args, **kwds):
"""DEPRECATED! Use rpm.hdr() instead."""
diff --git a/python/rpmmodule.c b/python/rpmmodule.c
index 05032edc7..2a76cfbd0 100644
--- a/python/rpmmodule.c
+++ b/python/rpmmodule.c
@@ -28,6 +28,7 @@
*/
PyObject * pyrpmError;
+PyObject * fakedecode = NULL;
static PyObject * archScore(PyObject * self, PyObject * arg)
{
diff --git a/python/rpmsystem-py.h b/python/rpmsystem-py.h
index 25938464a..803da0fc1 100644
--- a/python/rpmsystem-py.h
+++ b/python/rpmsystem-py.h
@@ -19,12 +19,29 @@
#define PyInt_AsSsize_t PyLong_AsSsize_t
#endif
+PyObject * fakedecode;
+
static inline PyObject * utf8FromString(const char *s)
{
/* In Python 3, we return all strings as surrogate-escaped utf-8 */
#if PY_MAJOR_VERSION >= 3
- if (s != NULL)
- return PyUnicode_DecodeUTF8(s, strlen(s), "surrogateescape");
+ if (s != NULL) {
+ PyObject *o = PyUnicode_DecodeUTF8(s, strlen(s), "surrogateescape");
+ /* fish the fake decode function from python side if not done yet */
+ if (fakedecode == NULL) {
+ PyObject *n = PyUnicode_FromString("rpm");
+ PyObject *m = PyImport_Import(n);
+ PyObject *md = PyModule_GetDict(m);
+ fakedecode = PyDict_GetItemString(md, "_fakedecode");
+ Py_DECREF(m);
+ Py_DECREF(n);
+ }
+ if (fakedecode && o) {
+ /* monkey-patch it into the string object as "decode" */
+ PyDict_SetItemString(Py_TYPE(o)->tp_dict, "decode", fakedecode);
+ }
+ return o;
+ }
#else
if (s != NULL)
return PyBytes_FromString(s);
--
2.20.1

View File

@ -61,20 +61,16 @@ index 622e48011..0d475af86 100644
static int sinfoCmp(const void *a, const void *b)
{
const struct rpmsinfo_s *sa = a;
diff --git a/lib/rpmvs.h b/lib/rpmvs.h
index b27d9a612..a836d5c94 100644
--- a/lib/rpmvs.h
+++ b/lib/rpmvs.h
@@ -75,6 +75,9 @@ void rpmvsInitRange(struct rpmvs_s *sis, int range);
RPM_GNUC_INTERNAL
--- rpm-4.14.3/lib/rpmvs.h.orig 2020-04-28 10:57:19.727347211 +0200
+++ rpm-4.14.3/lib/rpmvs.h 2020-04-28 10:57:43.622612015 +0200
@@ -66,6 +66,8 @@
void rpmvsFiniRange(struct rpmvs_s *sis, int range);
+RPM_GNUC_INTERNAL
+int rpmvsRange(struct rpmvs_s *vs);
+int rpmvsRange(struct rpmvs_s *vs);
+
RPM_GNUC_INTERNAL
int rpmvsVerify(struct rpmvs_s *sis, int type,
rpmsinfoCb cb, void *cbdata);
--
2.20.1

View File

@ -0,0 +1,27 @@
From d97d7b71de158660eb96b4f11d40b6626b85521a Mon Sep 17 00:00:00 2001
From: Florian Festi <ffesti@redhat.com>
Date: Tue, 16 Apr 2019 09:50:57 +0200
Subject: [PATCH] Pass RPM_BUILD_NCPUS to build scripts
Use %_smp_build_ncpus instead of the initial value
---
macros.in | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/macros.in b/macros.in
index fc587997d..a15e46f26 100644
--- a/macros.in
+++ b/macros.in
@@ -807,7 +807,8 @@ package or when debugging this package.\
RPM_OPT_FLAGS=\"%{optflags}\"\
RPM_ARCH=\"%{_arch}\"\
RPM_OS=\"%{_os}\"\
- export RPM_SOURCE_DIR RPM_BUILD_DIR RPM_OPT_FLAGS RPM_ARCH RPM_OS\
+ RPM_BUILD_NCPUS=\"%{_smp_build_ncpus}\"\
+ export RPM_SOURCE_DIR RPM_BUILD_DIR RPM_OPT_FLAGS RPM_ARCH RPM_OS RPM_BUILD_NCPUS\
RPM_DOC_DIR=\"%{_docdir}\"\
export RPM_DOC_DIR\
RPM_PACKAGE_NAME=\"%{NAME}\"\
--
2.21.0

View File

@ -0,0 +1,153 @@
From ac7b0dbd5a18d2c57a942ca14ac856b8047425ff Mon Sep 17 00:00:00 2001
From: Panu Matilainen <pmatilai@redhat.com>
Date: Tue, 15 Feb 2022 10:43:13 +0200
Subject: [PATCH] Pass file descriptor to file prepare plugin hook, use when
possible
Sadly the thing that allegedly makes things better mostly just makes
things more complicated as symlinks can't be opened, so we'll now have
to deal with both cases in plugins too. To make matters worse, most
APIs out there support either an fd or a path, but very few support
the *at() style dirfd + basename approach so plugins are stuck with
absolute paths for now.
This is of course a plugin API/ABI change too.
---
lib/rpmplugin.h | 2 +-
lib/rpmplugins.c | 4 ++--
lib/rpmplugins.h | 3 ++-
plugins/ima.c | 9 +++++++--
plugins/selinux.c | 13 ++++++++-----
5 files changed, 20 insertions(+), 11 deletions(-)
diff --git a/lib/rpmplugin.h b/lib/rpmplugin.h
index fd81aec8d..fab4b3e83 100644
--- a/lib/rpmplugin.h
+++ b/lib/rpmplugin.h
@@ -57,7 +57,7 @@ typedef rpmRC (*plugin_fsm_file_post_func)(rpmPlugin plugin, rpmfi fi,
const char* path, mode_t file_mode,
rpmFsmOp op, int res);
typedef rpmRC (*plugin_fsm_file_prepare_func)(rpmPlugin plugin, rpmfi fi,
- const char* path,
+ int fd, const char* path,
const char *dest,
mode_t file_mode, rpmFsmOp op);
diff --git a/lib/rpmplugins.c b/lib/rpmplugins.c
index 65e684e84..923084b78 100644
--- a/lib/rpmplugins.c
+++ b/lib/rpmplugins.c
@@ -384,7 +384,7 @@ rpmRC rpmpluginsCallFsmFilePost(rpmPlugins plugins, rpmfi fi, const char *path,
}
rpmRC rpmpluginsCallFsmFilePrepare(rpmPlugins plugins, rpmfi fi,
- const char *path, const char *dest,
+ int fd, const char *path, const char *dest,
mode_t file_mode, rpmFsmOp op)
{
plugin_fsm_file_prepare_func hookFunc;
@@ -394,7 +394,7 @@ rpmRC rpmpluginsCallFsmFilePrepare(rpmPlugins plugins, rpmfi fi,
for (i = 0; i < plugins->count; i++) {
rpmPlugin plugin = plugins->plugins[i];
RPMPLUGINS_SET_HOOK_FUNC(fsm_file_prepare);
- if (hookFunc && hookFunc(plugin, fi, path, dest, file_mode, op) == RPMRC_FAIL) {
+ if (hookFunc && hookFunc(plugin, fi, fd, path, dest, file_mode, op) == RPMRC_FAIL) {
rpmlog(RPMLOG_ERR, "Plugin %s: hook fsm_file_prepare failed\n", plugin->name);
rc = RPMRC_FAIL;
}
diff --git a/lib/rpmplugins.h b/lib/rpmplugins.h
index 39762c376..ddf5d7048 100644
--- a/lib/rpmplugins.h
+++ b/lib/rpmplugins.h
@@ -156,6 +156,7 @@ rpmRC rpmpluginsCallFsmFilePost(rpmPlugins plugins, rpmfi fi, const char* path,
* permissions etc, but before committing file to destination path.
* @param plugins plugins structure
* @param fi file info iterator (or NULL)
+ * @param fd file descriptor (or -1 if not available)
* @param path file object current path
* @param dest file object destination path
* @param mode file object mode
@@ -164,7 +165,7 @@ rpmRC rpmpluginsCallFsmFilePost(rpmPlugins plugins, rpmfi fi, const char* path,
*/
RPM_GNUC_INTERNAL
rpmRC rpmpluginsCallFsmFilePrepare(rpmPlugins plugins, rpmfi fi,
- const char *path, const char *dest,
+ int fd, const char *path, const char *dest,
mode_t mode, rpmFsmOp op);
#ifdef __cplusplus
diff --git a/plugins/fapolicyd.c b/plugins/fapolicyd.c
index 7ac44f0d0..1ff50c30f 100644
--- a/plugins/fapolicyd.c
+++ b/plugins/fapolicyd.c
@@ -145,7 +145,8 @@ static rpmRC fapolicyd_scriptlet_pre(rpmPlugin plugin, const char *s_name,
}
static rpmRC fapolicyd_fsm_file_prepare(rpmPlugin plugin, rpmfi fi,
- const char *path, const char *dest,
+ int fd, const char *path,
+ const char *dest,
mode_t file_mode, rpmFsmOp op)
{
/* not ready */
--- a/plugins/ima.c 2020-04-28 14:50:11.835399269 +0200
+++ b/plugins/ima.c 2023-12-13 11:19:58.835948660 +0100
@@ -39,7 +39,7 @@
return (memcmp(fsig, &zero_hdr, sizeof(zero_hdr)) == 0);
}
-static rpmRC ima_fsm_file_prepare(rpmPlugin plugin, rpmfi fi,
+static rpmRC ima_fsm_file_prepare(rpmPlugin plugin, rpmfi fi, int fd,
const char *path,
const char *dest,
mode_t file_mode, rpmFsmOp op)
@@ -63,8 +63,14 @@
fsig = rpmfiFSignature(fi, &len);
if (fsig && (check_zero_hdr(fsig, len) == 0)) {
- if (lsetxattr(path, XATTR_NAME_IMA, fsig, len, 0) < 0) {
- rpmlog(RPMLOG_ERR,
+ int xx;
+ if (fd >= 0)
+ xx = fsetxattr(fd, XATTR_NAME_IMA, fsig, len, 0);
+ else
+ xx = lsetxattr(path, XATTR_NAME_IMA, fsig, len, 0);
+ if (xx < 0) {
+ int is_err = errno != EOPNOTSUPP;
+ rpmlog(is_err?RPMLOG_ERR:RPMLOG_DEBUG,
"ima: could not apply signature on '%s': %s\n",
path, strerror(errno));
rc = RPMRC_FAIL;
--- a/plugins/selinux.c 2023-12-13 11:21:54.935009141 +0100
+++ b/plugins/selinux.c 2023-12-13 11:22:23.172510285 +0100
@@ -149,7 +149,7 @@
return rc;
}
-static rpmRC selinux_fsm_file_prepare(rpmPlugin plugin, rpmfi fi,
+static rpmRC selinux_fsm_file_prepare(rpmPlugin plugin, rpmfi fi, int fd,
const char *path, const char *dest,
mode_t file_mode, rpmFsmOp op)
{
@@ -159,14 +159,17 @@
if (sehandle && !XFA_SKIPPING(action)) {
security_context_t scon = NULL;
if (selabel_lookup_raw(sehandle, &scon, dest, file_mode) == 0) {
- int conrc = lsetfilecon(path, scon);
+ int conrc;
+ if (fd >= 0)
+ conrc = fsetfilecon(fd, scon);
+ else
+ conrc = lsetfilecon(path, scon);
if (conrc == 0 || (conrc < 0 && errno == EOPNOTSUPP))
rc = RPMRC_OK;
- rpmlog((rc != RPMRC_OK) ? RPMLOG_ERR : RPMLOG_DEBUG,
- "lsetfilecon: (%s, %s) %s\n",
- path, scon, (conrc < 0 ? strerror(errno) : ""));
+ rpmlog((rc != RPMRC_OK) ? RPMLOG_ERR : RPMLOG_DEBUG, "lsetfilecon: (%d %s, %s) %s\n",
+ fd, path, scon, (conrc < 0 ? strerror(errno) : ""));
freecon(scon);
} else {

View File

@ -0,0 +1,32 @@
From f1503ab6e898430b80017c0f8347860f3a74d5bb Mon Sep 17 00:00:00 2001
From: Florian Festi <ffesti@redhat.com>
Date: Mon, 11 Dec 2023 15:50:15 +0100
Subject: [PATCH] Print full path if file removal fails
For normal debug output the basename of the files are sufficient as when
debugging is enabled the directories are also printed. But here the
warning is given without a debug flag so we need the full context right
there.
---
lib/fsm.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/lib/fsm.c b/lib/fsm.c
index fcd764648..2189bd84c 100644
--- a/lib/fsm.c
+++ b/lib/fsm.c
@@ -1174,9 +1174,9 @@ int rpmPackageFilesRemove(rpmts ts, rpmte te, rpmfiles files,
if (rc) {
int lvl = strict_erasures ? RPMLOG_ERR : RPMLOG_WARNING;
- rpmlog(lvl, _("%s %s: remove failed: %s\n"),
+ rpmlog(lvl, _("%s %s%s: remove failed: %s\n"),
S_ISDIR(fp->sb.st_mode) ? _("directory") : _("file"),
- fp->fpath, strerror(errno));
+ rpmfiDN(fi), fp->fpath, strerror(errno));
}
}
--
2.43.0

View File

@ -1,49 +0,0 @@
From b4178c979fff344a1c5142a305f274dd9aff8f45 Mon Sep 17 00:00:00 2001
From: Markus Linnala <markus.linnala@gmail.com>
Date: Sun, 28 Oct 2018 14:59:52 +0200
Subject: [PATCH] Remove capabilities instead of setting empty caps via.
--setcaps
If a file in a package does not have any capabilities rpm --setcaps should
remove capabilities of the file. Prior to this patch capabilities of the file
were set as empty.
Empty capabilities mean more than no capabilities. A file with no capabilities
can inherit capabilities, but file with empty capabilities can not.
When ever package does not have any capabilities set %|FILECAPS? is false.
If some files have capabilities, %|FILECAPS? is true but %{FILECAPS} is ''
when the file does not have capabilities and '= <capstring>' when there is some.
Reported and patch created by Markus Linnala
Commit message edited by Pavlina Moravcova Varekova and Florian Festi.
Fixes #585
Fixes #586
---
rpmpopt.in | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/rpmpopt.in b/rpmpopt.in
index 42d3416a3..557050a24 100644
--- a/rpmpopt.in
+++ b/rpmpopt.in
@@ -57,8 +57,13 @@ rpm alias --setugids -q --qf \
--POPTdesc=$"set user/group ownership of files in a package"
rpm alias --setcaps -q --qf \
- "[\[ -f %{FILENAMES:shescape} -a ! -L %{FILENAMES:shescape} \] \
- && setcap %|FILECAPS?{%{FILECAPS:shescape}}:{''}| %{FILENAMES:shescape}\n]" \
+ "[if \[ -f %{FILENAMES:shescape} -a ! -L %{FILENAMES:shescape} \]; then\n\
+%|FILECAPS?{ if \[ -n %{FILECAPS:shescape} \]; then\n\
+ setcap %{FILECAPS:shescape} %{FILENAMES:shescape}\n\
+ el}:{ }|if \[ -n \"\$(getcap %{FILENAMES:shescape})\" \]; then\n\
+ setcap -r %{FILENAMES:shescape}\n\
+ fi\n\
+fi\n]" \
--pipe "sh" \
--POPTdesc=$"set capabilities of files in a package"
--
2.21.0

View File

@ -1,57 +0,0 @@
From 8dd8e37acc79da1ce0a36c3f86650defa474a6a9 Mon Sep 17 00:00:00 2001
From: Pavlina Moravcova Varekova <pmoravco@redhat.com>
Date: Thu, 14 Mar 2019 13:56:26 +0100
Subject: [PATCH] Show list of files only once when use rpm -ql and multiple
rpm files
---
lib/query.c | 3 ++-
tests/rpmquery.at | 18 ++++++++++++++++++
2 files changed, 20 insertions(+), 1 deletion(-)
diff --git a/lib/query.c b/lib/query.c
index e5408e211..7568f67aa 100644
--- a/lib/query.c
+++ b/lib/query.c
@@ -574,7 +574,8 @@ int rpmcliArgIter(rpmts ts, QVA_t qva, ARGV_const_t argv)
if (mi == NULL && qva->qva_source == RPMQV_PACKAGE) {
size_t l = strlen(*arg);
if (l > 4 && !strcmp(*arg + l - 4, ".rpm")) {
- rpmgi gi = rpmgiNew(ts, giFlags, argv);
+ char * const argFirst[2] = { arg[0], NULL };
+ rpmgi gi = rpmgiNew(ts, giFlags, argFirst);
ecLocal = rpmgiShowMatches(qva, ts, gi);
rpmgiFree(gi);
}
diff --git a/tests/rpmquery.at b/tests/rpmquery.at
index ab7bb3c46..0dc6d78b6 100644
--- a/tests/rpmquery.at
+++ b/tests/rpmquery.at
@@ -61,6 +61,24 @@ hello.spec
[ignore])
AT_CLEANUP
+# ------------------------------
+AT_SETUP([rpm -ql multiple *.rpm])
+AT_KEYWORDS([query])
+AT_CHECK([
+runroot rpm \
+ -ql \
+ /data/SRPMS/hello-1.0-1.src.rpm /data/RPMS/hello-1.0-1.i386.rpm
+],
+[0],
+[hello-1.0.tar.gz
+hello.spec
+/usr/local/bin/hello
+/usr/share/doc/hello-1.0
+/usr/share/doc/hello-1.0/FAQ
+],
+[ignore])
+AT_CLEANUP
+
# ------------------------------
AT_SETUP([rpmspec -q])
AT_KEYWORDS([query])
--
2.17.2

View File

@ -1,27 +0,0 @@
From 35b09eed946a7e2f2f327531b692c9f768bf9e3b Mon Sep 17 00:00:00 2001
From: Pavlina Moravcova Varekova <pmoravco@redhat.com>
Date: Sun, 7 Apr 2019 07:23:47 +0200
Subject: [PATCH] Sort list of hard linked files in find-debuginfo.sh
(RhBug:1421272)
It helps to make build results reproducible. Based on Mark Wielaard's idea.
---
scripts/find-debuginfo.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/find-debuginfo.sh b/scripts/find-debuginfo.sh
index c75d176ac..23286139e 100755
--- a/scripts/find-debuginfo.sh
+++ b/scripts/find-debuginfo.sh
@@ -350,7 +350,7 @@ trap 'rm -rf "$temp"' EXIT
touch "$temp/primary"
find "$RPM_BUILD_ROOT" ! -path "${debugdir}/*.debug" -type f \
\( -perm -0100 -or -perm -0010 -or -perm -0001 \) \
- -print |
+ -print | LC_ALL=C sort |
file -N -f - | sed -n -e 's/^\(.*\):[ ]*.*ELF.*, not stripped.*/\1/p' |
xargs --no-run-if-empty stat -c '%h %D_%i %n' |
while read nlinks inum f; do
--
2.17.2

View File

@ -0,0 +1,90 @@
From 6dd62720fe84f7e2ad902c915b952fc0b29e3dcd Mon Sep 17 00:00:00 2001
From: Panu Matilainen <pmatilai@redhat.com>
Date: Tue, 15 Feb 2022 11:34:37 +0200
Subject: [PATCH] Swap over to dirfd+basename based operation within the fsm
Within fsm this is just a matter of adjusting error messages to include
the directory... if it only wasn't for the plugins requiring absolute
paths for outside users. For the plugins, we need to assemble absolute
paths as needed, both in ensureDir() and plugin file slots.
---
lib/rpmplugins.c | 20 +++++++++++++++++---
2 files changed, 36 insertions(+), 14 deletions(-)
diff --git a/lib/rpmplugins.c b/lib/rpmplugins.c
index 703368c0d..f06fd7895 100644
--- a/lib/rpmplugins.c
+++ b/lib/rpmplugins.c
@@ -350,21 +350,31 @@ rpmRC rpmpluginsCallScriptletPost(rpmPlugins plugins, const char *s_name, int ty
return rc;
}
+static char *abspath(rpmfi fi, const char *path)
+{
+ if (*path == '/')
+ return xstrdup(path);
+ else
+ return rstrscat(NULL, rpmfiDN(fi), path, NULL);
+}
+
rpmRC rpmpluginsCallFsmFilePre(rpmPlugins plugins, rpmfi fi, const char *path,
mode_t file_mode, rpmFsmOp op)
{
plugin_fsm_file_pre_func hookFunc;
int i;
rpmRC rc = RPMRC_OK;
+ char *apath = abspath(fi, path);
for (i = 0; i < plugins->count; i++) {
rpmPlugin plugin = plugins->plugins[i];
RPMPLUGINS_SET_HOOK_FUNC(fsm_file_pre);
- if (hookFunc && hookFunc(plugin, fi, path, file_mode, op) == RPMRC_FAIL) {
+ if (hookFunc && hookFunc(plugin, fi, apath, file_mode, op) == RPMRC_FAIL) {
rpmlog(RPMLOG_ERR, "Plugin %s: hook fsm_file_pre failed\n", plugin->name);
rc = RPMRC_FAIL;
}
}
+ free(apath);
return rc;
}
@@ -375,14 +385,16 @@ rpmRC rpmpluginsCallFsmFilePost(rpmPlugins plugins, rpmfi fi, const char *path,
plugin_fsm_file_post_func hookFunc;
int i;
rpmRC rc = RPMRC_OK;
+ char *apath = abspath(fi, path);
for (i = 0; i < plugins->count; i++) {
rpmPlugin plugin = plugins->plugins[i];
RPMPLUGINS_SET_HOOK_FUNC(fsm_file_post);
- if (hookFunc && hookFunc(plugin, fi, path, file_mode, op, res) == RPMRC_FAIL) {
+ if (hookFunc && hookFunc(plugin, fi, apath, file_mode, op, res) == RPMRC_FAIL) {
rpmlog(RPMLOG_WARNING, "Plugin %s: hook fsm_file_post failed\n", plugin->name);
}
}
+ free(apath);
return rc;
}
@@ -394,15 +406,17 @@ rpmRC rpmpluginsCallFsmFilePrepare(rpmPlugins plugins, rpmfi fi,
plugin_fsm_file_prepare_func hookFunc;
int i;
rpmRC rc = RPMRC_OK;
+ char *apath = abspath(fi, path);
for (i = 0; i < plugins->count; i++) {
rpmPlugin plugin = plugins->plugins[i];
RPMPLUGINS_SET_HOOK_FUNC(fsm_file_prepare);
- if (hookFunc && hookFunc(plugin, fi, fd, path, dest, file_mode, op) == RPMRC_FAIL) {
+ if (hookFunc && hookFunc(plugin, fi, fd, apath, dest, file_mode, op) == RPMRC_FAIL) {
rpmlog(RPMLOG_ERR, "Plugin %s: hook fsm_file_prepare failed\n", plugin->name);
rc = RPMRC_FAIL;
}
}
+ free(apath);
return rc;
}
--
2.41.0

View File

@ -0,0 +1,37 @@
From cb6aa82dbc10d554f8d234e934ae7c77e39a3ce2 Mon Sep 17 00:00:00 2001
From: Panu Matilainen <pmatilai@redhat.com>
Date: Tue, 12 Jan 2021 13:35:23 +0200
Subject: [PATCH] Unblock signals in forked scriptlets
Since commit c5f82d3f6223ebd0c5cc0a07ea60393ae7284929 we've blocked
most signals during transactions, which makes sense to rpm itself but
the signal mask is inherited to childs and carried even across exec(),
so all scriptlets are executing with those signals blocked as well.
Which in turn does not make sense, the scriptlets could run stuff that
actually depends on signal delivery (such as SIGALARM in RhBug:1913765).
Unblock all signals for forked scriptlet execution (Lua scriptlets are
totally different as they execute in-process for now)
---
lib/rpmscript.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/lib/rpmscript.c b/lib/rpmscript.c
index 2ae3378f7..c69d29554 100644
--- a/lib/rpmscript.c
+++ b/lib/rpmscript.c
@@ -152,6 +152,11 @@ static void doScriptExec(ARGV_const_t argv, ARGV_const_t prefixes,
FD_t scriptFd, FD_t out)
{
int xx;
+ sigset_t set;
+
+ /* Unmask all signals, the scripts may need them */
+ sigfillset(&set);
+ sigprocmask(SIG_UNBLOCK, &set, NULL);
/* SIGPIPE is ignored in rpm, reset to default for the scriptlet */
(void) signal(SIGPIPE, SIG_DFL);
--
2.29.2

View File

@ -0,0 +1,58 @@
From fc2c986d8f5e4174885ae377750185339636f062 Mon Sep 17 00:00:00 2001
From: Florian Festi <ffesti@redhat.com>
Date: Mon, 15 Apr 2019 15:46:09 +0200
Subject: [PATCH] Use RPM_BUILD_NCPUS in brp-strip-static-archive
to speed the script up for large number of files to be looked at.
Use xargs -P instead of find -exec.
Add xargs to the test environment
Resolves rhbz1691822
---
scripts/brp-strip-static-archive | 8 +++++---
tests/Makefile.am | 2 +-
2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/scripts/brp-strip-static-archive b/scripts/brp-strip-static-archive
index ddd3b2422..4dc449061 100755
--- a/scripts/brp-strip-static-archive
+++ b/scripts/brp-strip-static-archive
@@ -5,6 +5,7 @@ if [ -z "$RPM_BUILD_ROOT" -o "$RPM_BUILD_ROOT" = "/" ]; then
fi
STRIP=${1:-strip}
+NCPUS=${RPM_BUILD_NCPUS:-1}
case `uname -a` in
Darwin*) exit 0 ;;
@@ -12,9 +13,10 @@ Darwin*) exit 0 ;;
esac
# Strip static libraries.
-for f in `find "$RPM_BUILD_ROOT" -type f -a -exec file {} \; | \
- grep -v "^${RPM_BUILD_ROOT}/\?usr/lib/debug" | \
+for f in `find "$RPM_BUILD_ROOT" -type f | \
+ grep -v "^${RPM_BUILD_ROOT}/\?usr/lib/debug" | \
+ xargs -r -P$NCPUS -n16 file | sed 's/: */: /' | \
grep 'current ar archive' | \
- sed -n -e 's/^\(.*\):[ ]*current ar archive/\1/p'`; do
+ sed -n -e 's/^\(.*\):[ ]*current ar archive/\1/p'`; do
$STRIP -g "$f"
done
diff --git a/tests/Makefile.am b/tests/Makefile.am
index e2d759d82..ad9549a68 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -144,7 +144,7 @@ populate_testing:
for d in dev etc magic tmp var; do if [ ! -d testing/$${d} ]; then mkdir testing/$${d}; fi; done
for node in urandom stdin stderr stdout null full; do ln -s /dev/$${node} testing/dev/$${node}; done
for cf in hosts resolv.conf passwd shadow group gshadow mtab ; do [ -f /etc/$${cf} ] && ln -s /etc/$${cf} testing/etc/$${cf}; done
- for prog in gzip cat patch tar sh ln chmod rm mkdir uname grep sed find file ionice mktemp nice cut sort diff touch install wc coreutils; do p=`which $${prog}`; if [ "$${p}" != "" ]; then ln -s $${p} testing/$(bindir)/; fi; done
+ for prog in gzip cat patch tar sh ln chmod rm mkdir uname grep sed find file ionice mktemp nice cut sort diff touch install wc coreutils xargs; do p=`which $${prog}`; if [ "$${p}" != "" ]; then ln -s $${p} testing/$(bindir)/; fi; done
for d in /proc /sys /selinux /etc/selinux; do if [ -d $${d} ]; then ln -s $${d} testing/$${d}; fi; done
(cd testing/magic && file -C)
HOME=$(abs_builddir)/testing gpg2 --import ${abs_srcdir}/data/keys/*.secret
--
2.21.0

View File

@ -1,29 +0,0 @@
From d313baf1d3a4756447e398ee55f8c6760f942d50 Mon Sep 17 00:00:00 2001
From: Pavlina Moravcova Varekova <pmoravco@redhat.com>
Date: Wed, 24 Apr 2019 10:29:14 +0200
Subject: [PATCH] Use --dpbath only with full path (RhBug:1696408)
Before the patch rpm treats the relative path as a full path.
The new behavior is similar to the "--root" option.
---
lib/poptALL.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/lib/poptALL.c b/lib/poptALL.c
index 9983c1e62..69fd49846 100644
--- a/lib/poptALL.c
+++ b/lib/poptALL.c
@@ -147,6 +147,10 @@ static void rpmcliAllArgCallback( poptContext con,
break;
case POPT_DBPATH:
rpmcliConfigured();
+ if (arg && arg[0] != '/') {
+ fprintf(stderr, _("arguments to --dbpath must begin with '/'\n"));
+ exit(EXIT_FAILURE);
+ }
rpmPushMacro(NULL, "_dbpath", NULL, arg, RMIL_CMDLINE);
break;
case POPT_SHOWVERSION:
--
2.21.0

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,26 @@
From 09d181d78c16e1751779586c606e85c11f360407 Mon Sep 17 00:00:00 2001
From: Florian Festi <ffesti@redhat.com>
Date: Tue, 25 Jun 2019 18:04:20 +0200
Subject: [PATCH] Use newline as a delimiter to avoid xargs messing up file
names with quotes
which is the default behaviour otherwise.
Fixes rhbz#1721348
---
scripts/brp-strip-static-archive | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/brp-strip-static-archive b/scripts/brp-strip-static-archive
index 13d9a098b..f7fb26b87 100755
--- a/scripts/brp-strip-static-archive
+++ b/scripts/brp-strip-static-archive
@@ -15,4 +15,4 @@ esac
# Strip static libraries.
find "$RPM_BUILD_ROOT" -type f | \
grep -v "^${RPM_BUILD_ROOT}/\?usr/lib/debug" | \
- xargs -r -P$NCPUS -n32 sh -c "file \"\$@\" | sed 's/: */: /' | grep 'current ar archive' | sed -n -e 's/^\(.*\):[ ]*current ar archive/\1/p' | xargs -I\{\} $STRIP -g \{\}" ARG0
+ xargs -d '\n' -r -P$NCPUS -n32 sh -c "file \"\$@\" | sed 's/: */: /' | grep 'current ar archive' | sed -n -e 's/^\(.*\):[ ]*current ar archive/\1/p' | xargs -d '\n' -I\{\} $STRIP -g \{\}" ARG0
--
2.21.0

View File

@ -0,0 +1,38 @@
From 9cbc1fe444b048c3f7cf5ea09ab650d1c146d54a Mon Sep 17 00:00:00 2001
From: Panu Matilainen <pmatilai@redhat.com>
Date: Wed, 20 Feb 2019 14:49:19 +0200
Subject: [PATCH] When doing the same thing more than once, use a loop...
No functional changes but this'll simplify the next commit quite a bit.
---
build/spec.c | 12 +++++-------
1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/build/spec.c b/build/spec.c
index e414e4102..80eaca611 100644
--- a/build/spec.c
+++ b/build/spec.c
@@ -303,15 +303,13 @@ rpmSpec newSpec(void)
spec->pool = rpmstrPoolCreate();
#ifdef WITH_LUA
- {
/* make sure patches and sources tables always exist */
rpmlua lua = NULL; /* global state */
- rpmluaDelVar(lua, "patches");
- rpmluaDelVar(lua, "sources");
- rpmluaPushTable(lua, "patches");
- rpmluaPushTable(lua, "sources");
- rpmluaPop(lua);
- rpmluaPop(lua);
+ const char * luavars[] = { "patches", "sources", NULL, };
+ for (const char **vp = luavars; vp && *vp; vp++) {
+ rpmluaDelVar(lua, *vp);
+ rpmluaPushTable(lua, *vp);
+ rpmluaPop(lua);
}
#endif
return spec;
--
2.26.2

View File

@ -0,0 +1,44 @@
From 8fefd2bd21b30996ad0748eab6baadf915610642 Mon Sep 17 00:00:00 2001
From: Panu Matilainen <pmatilai@redhat.com>
Date: Thu, 13 Aug 2020 13:29:10 +0300
Subject: [PATCH] Work around buggy signature region preventing resigning
(RhBug:1851508)
Various proprietary packages in the wild have subtly malformed data
in the signature header, in particular wrt the immutable region size,
presumably from using some in-house/3rd party signing tools which do
not understand the immutable region business at all. This can prevent
resigning and signature deletion on such packages due to the more
thorough checking that rpmsign does.
As the old wisdom goes, be liberal in what you accept... we can easily
work around the crud by just taking a fresh copy of the contents that
are legit as such (otherwise the package would be uninstallable).
Adjusted for 4.14.3
--- rpm-4.14.3/sign/rpmgensig.c.orig 2020-10-29 16:00:38.785229048 +0100
+++ rpm-4.14.3/sign/rpmgensig.c 2020-10-29 16:08:55.997791345 +0100
@@ -401,12 +401,19 @@
if (headerGet(*hdrp, tag, utd, HEADERGET_DEFAULT)) {
oh = headerCopyLoad(utd->data);
- nh = headerCopy(oh);
- headerFree(oh);
rpmtdFreeData(utd);
+ } else {
+ /* XXX should we warn if the immutable region is corrupt/missing? */
+ oh = headerLink(*hdrp);
+ }
+
+ if (oh) {
+ /* Perform a copy to eliminate crud from buggy signing tools etc */
+ nh = headerCopy(oh);
headerFree(*hdrp);
*hdrp = headerLink(nh);
headerFree(nh);
+ headerFree(oh);
}
}

View File

@ -0,0 +1,490 @@
From ce6e8556a8f93327d6de0446f21ac5e549861d82 Mon Sep 17 00:00:00 2001
Message-Id: <ce6e8556a8f93327d6de0446f21ac5e549861d82.1573552234.git.pmatilai@redhat.com>
From: Mark Wielaard <mark@klomp.org>
Date: Mon, 17 Jun 2019 11:23:24 +0200
Subject: [PATCH 1/3] debugedit: Refactor reading/writing of relocated values.
This refactors the reading and writing of relocated values into seperate
helper functions (setup_relbuf and update_rela_data). It will be easier
to reuse this code in case we want to read/write relocated values in other
sections than DEBUG_INFO. The only functional change is that we explicitly
track whether the relocation data is updated, and only explicitly update
and write out the relocation data if so. In the case there were no strp
or stmt updates, there will also not be any relocation updates, even if
there is relocation data available.
All new debugedit testcases pass before and after this refactoring.
---
tools/debugedit.c | 395 +++++++++++++++++++++++++---------------------
1 file changed, 216 insertions(+), 179 deletions(-)
diff --git a/tools/debugedit.c b/tools/debugedit.c
index 4be85b979..cf9cc3ca9 100644
--- a/tools/debugedit.c
+++ b/tools/debugedit.c
@@ -401,13 +401,18 @@ dwarf2_write_be32 (unsigned char *p, uint32_t v)
relend). Might just update the addend. So relocations need to be
updated at the end. */
+static bool rel_updated;
+
#define do_write_32_relocated(ptr,val) ({ \
if (relptr && relptr < relend && relptr->ptr == ptr) \
{ \
if (reltype == SHT_REL) \
do_write_32 (ptr, val - relptr->addend); \
else \
- relptr->addend = val; \
+ { \
+ relptr->addend = val; \
+ rel_updated = true; \
+ } \
} \
else \
do_write_32 (ptr,val); \
@@ -418,14 +423,18 @@ dwarf2_write_be32 (unsigned char *p, uint32_t v)
ptr += 4; \
})
-static struct
+typedef struct debug_section
{
const char *name;
unsigned char *data;
Elf_Data *elf_data;
size_t size;
int sec, relsec;
- } debug_sections[] =
+ REL *relbuf;
+ REL *relend;
+ } debug_section;
+
+static debug_section debug_sections[] =
{
#define DEBUG_INFO 0
#define DEBUG_ABBREV 1
@@ -458,6 +467,201 @@ static struct
{ NULL, NULL, NULL, 0, 0, 0 }
};
+static int
+rel_cmp (const void *a, const void *b)
+{
+ REL *rela = (REL *) a, *relb = (REL *) b;
+
+ if (rela->ptr < relb->ptr)
+ return -1;
+
+ if (rela->ptr > relb->ptr)
+ return 1;
+
+ return 0;
+}
+
+/* Returns a malloced REL array, or NULL when there are no relocations
+ for this section. When there are relocations, will setup relend,
+ as the last REL, and reltype, as SHT_REL or SHT_RELA. */
+static void
+setup_relbuf (DSO *dso, debug_section *sec, int *reltype)
+{
+ int ndx, maxndx;
+ GElf_Rel rel;
+ GElf_Rela rela;
+ GElf_Sym sym;
+ GElf_Addr base = dso->shdr[sec->sec].sh_addr;
+ Elf_Data *symdata = NULL;
+ int rtype;
+ REL *relbuf;
+ Elf_Scn *scn;
+ Elf_Data *data;
+ int i = sec->relsec;
+
+ /* No relocations, or did we do this already? */
+ if (i == 0 || sec->relbuf != NULL)
+ {
+ relptr = sec->relbuf;
+ relend = sec->relend;
+ return;
+ }
+
+ scn = dso->scn[i];
+ data = elf_getdata (scn, NULL);
+ assert (data != NULL && data->d_buf != NULL);
+ assert (elf_getdata (scn, data) == NULL);
+ assert (data->d_off == 0);
+ assert (data->d_size == dso->shdr[i].sh_size);
+ maxndx = dso->shdr[i].sh_size / dso->shdr[i].sh_entsize;
+ relbuf = malloc (maxndx * sizeof (REL));
+ *reltype = dso->shdr[i].sh_type;
+ if (relbuf == NULL)
+ error (1, errno, "%s: Could not allocate memory", dso->filename);
+
+ symdata = elf_getdata (dso->scn[dso->shdr[i].sh_link], NULL);
+ assert (symdata != NULL && symdata->d_buf != NULL);
+ assert (elf_getdata (dso->scn[dso->shdr[i].sh_link], symdata) == NULL);
+ assert (symdata->d_off == 0);
+ assert (symdata->d_size == dso->shdr[dso->shdr[i].sh_link].sh_size);
+
+ for (ndx = 0, relend = relbuf; ndx < maxndx; ++ndx)
+ {
+ if (dso->shdr[i].sh_type == SHT_REL)
+ {
+ gelf_getrel (data, ndx, &rel);
+ rela.r_offset = rel.r_offset;
+ rela.r_info = rel.r_info;
+ rela.r_addend = 0;
+ }
+ else
+ gelf_getrela (data, ndx, &rela);
+ gelf_getsym (symdata, ELF64_R_SYM (rela.r_info), &sym);
+ /* Relocations against section symbols are uninteresting in REL. */
+ if (dso->shdr[i].sh_type == SHT_REL && sym.st_value == 0)
+ continue;
+ /* Only consider relocations against .debug_str, .debug_line
+ and .debug_abbrev. */
+ if (sym.st_shndx != debug_sections[DEBUG_STR].sec
+ && sym.st_shndx != debug_sections[DEBUG_LINE].sec
+ && sym.st_shndx != debug_sections[DEBUG_ABBREV].sec)
+ continue;
+ rela.r_addend += sym.st_value;
+ rtype = ELF64_R_TYPE (rela.r_info);
+ switch (dso->ehdr.e_machine)
+ {
+ case EM_SPARC:
+ case EM_SPARC32PLUS:
+ case EM_SPARCV9:
+ if (rtype != R_SPARC_32 && rtype != R_SPARC_UA32)
+ goto fail;
+ break;
+ case EM_386:
+ if (rtype != R_386_32)
+ goto fail;
+ break;
+ case EM_PPC:
+ case EM_PPC64:
+ if (rtype != R_PPC_ADDR32 && rtype != R_PPC_UADDR32)
+ goto fail;
+ break;
+ case EM_S390:
+ if (rtype != R_390_32)
+ goto fail;
+ break;
+ case EM_IA_64:
+ if (rtype != R_IA64_SECREL32LSB)
+ goto fail;
+ break;
+ case EM_X86_64:
+ if (rtype != R_X86_64_32)
+ goto fail;
+ break;
+ case EM_ALPHA:
+ if (rtype != R_ALPHA_REFLONG)
+ goto fail;
+ break;
+#if defined(EM_AARCH64) && defined(R_AARCH64_ABS32)
+ case EM_AARCH64:
+ if (rtype != R_AARCH64_ABS32)
+ goto fail;
+ break;
+#endif
+ case EM_68K:
+ if (rtype != R_68K_32)
+ goto fail;
+ break;
+#if defined(EM_RISCV) && defined(R_RISCV_32)
+ case EM_RISCV:
+ if (rtype != R_RISCV_32)
+ goto fail;
+ break;
+#endif
+ default:
+ fail:
+ error (1, 0, "%s: Unhandled relocation %d in %s section",
+ dso->filename, rtype, sec->name);
+ }
+ relend->ptr = sec->data
+ + (rela.r_offset - base);
+ relend->addend = rela.r_addend;
+ relend->ndx = ndx;
+ ++(relend);
+ }
+ if (relbuf == relend)
+ {
+ free (relbuf);
+ relbuf = NULL;
+ relend = NULL;
+ }
+ else
+ qsort (relbuf, relend - relbuf, sizeof (REL), rel_cmp);
+
+ sec->relbuf = relbuf;
+ sec->relend = relend;
+ relptr = relbuf;
+}
+
+/* Updates SHT_RELA section associated with the given section based on
+ the relbuf data. The relbuf data is freed at the end. */
+static void
+update_rela_data (DSO *dso, struct debug_section *sec)
+{
+ Elf_Data *symdata;
+ int relsec_ndx = sec->relsec;
+ Elf_Data *data = elf_getdata (dso->scn[relsec_ndx], NULL);
+ symdata = elf_getdata (dso->scn[dso->shdr[relsec_ndx].sh_link],
+ NULL);
+
+ relptr = sec->relbuf;
+ relend = sec->relend;
+ while (relptr < relend)
+ {
+ GElf_Sym sym;
+ GElf_Rela rela;
+ int ndx = relptr->ndx;
+
+ if (gelf_getrela (data, ndx, &rela) == NULL)
+ error (1, 0, "Couldn't get relocation: %s",
+ elf_errmsg (-1));
+
+ if (gelf_getsym (symdata, GELF_R_SYM (rela.r_info),
+ &sym) == NULL)
+ error (1, 0, "Couldn't get symbol: %s", elf_errmsg (-1));
+
+ rela.r_addend = relptr->addend - sym.st_value;
+
+ if (gelf_update_rela (data, ndx, &rela) == 0)
+ error (1, 0, "Couldn't update relocations: %s",
+ elf_errmsg (-1));
+
+ ++relptr;
+ }
+ elf_flagdata (data, ELF_C_SET, ELF_F_DIRTY);
+
+ free (sec->relbuf);
+}
+
struct abbrev_attr
{
unsigned int attr;
@@ -1743,20 +1947,6 @@ edit_attributes (DSO *dso, unsigned char *ptr, struct abbrev_tag *t, int phase)
return ptr;
}
-static int
-rel_cmp (const void *a, const void *b)
-{
- REL *rela = (REL *) a, *relb = (REL *) b;
-
- if (rela->ptr < relb->ptr)
- return -1;
-
- if (rela->ptr > relb->ptr)
- return 1;
-
- return 0;
-}
-
static int
line_rel_cmp (const void *a, const void *b)
{
@@ -1871,132 +2061,7 @@ edit_dwarf2 (DSO *dso)
htab_t abbrev;
struct abbrev_tag tag, *t;
int phase;
- REL *relbuf = NULL;
-
- if (debug_sections[DEBUG_INFO].relsec)
- {
- int ndx, maxndx;
- GElf_Rel rel;
- GElf_Rela rela;
- GElf_Sym sym;
- GElf_Addr base = dso->shdr[debug_sections[DEBUG_INFO].sec].sh_addr;
- Elf_Data *symdata = NULL;
- int rtype;
-
- i = debug_sections[DEBUG_INFO].relsec;
- scn = dso->scn[i];
- data = elf_getdata (scn, NULL);
- assert (data != NULL && data->d_buf != NULL);
- assert (elf_getdata (scn, data) == NULL);
- assert (data->d_off == 0);
- assert (data->d_size == dso->shdr[i].sh_size);
- maxndx = dso->shdr[i].sh_size / dso->shdr[i].sh_entsize;
- relbuf = malloc (maxndx * sizeof (REL));
- reltype = dso->shdr[i].sh_type;
- if (relbuf == NULL)
- error (1, errno, "%s: Could not allocate memory", dso->filename);
-
- symdata = elf_getdata (dso->scn[dso->shdr[i].sh_link], NULL);
- assert (symdata != NULL && symdata->d_buf != NULL);
- assert (elf_getdata (dso->scn[dso->shdr[i].sh_link], symdata)
- == NULL);
- assert (symdata->d_off == 0);
- assert (symdata->d_size
- == dso->shdr[dso->shdr[i].sh_link].sh_size);
-
- for (ndx = 0, relend = relbuf; ndx < maxndx; ++ndx)
- {
- if (dso->shdr[i].sh_type == SHT_REL)
- {
- gelf_getrel (data, ndx, &rel);
- rela.r_offset = rel.r_offset;
- rela.r_info = rel.r_info;
- rela.r_addend = 0;
- }
- else
- gelf_getrela (data, ndx, &rela);
- gelf_getsym (symdata, ELF64_R_SYM (rela.r_info), &sym);
- /* Relocations against section symbols are uninteresting
- in REL. */
- if (dso->shdr[i].sh_type == SHT_REL && sym.st_value == 0)
- continue;
- /* Only consider relocations against .debug_str, .debug_line
- and .debug_abbrev. */
- if (sym.st_shndx != debug_sections[DEBUG_STR].sec
- && sym.st_shndx != debug_sections[DEBUG_LINE].sec
- && sym.st_shndx != debug_sections[DEBUG_ABBREV].sec)
- continue;
- rela.r_addend += sym.st_value;
- rtype = ELF64_R_TYPE (rela.r_info);
- switch (dso->ehdr.e_machine)
- {
- case EM_SPARC:
- case EM_SPARC32PLUS:
- case EM_SPARCV9:
- if (rtype != R_SPARC_32 && rtype != R_SPARC_UA32)
- goto fail;
- break;
- case EM_386:
- if (rtype != R_386_32)
- goto fail;
- break;
- case EM_PPC:
- case EM_PPC64:
- if (rtype != R_PPC_ADDR32 && rtype != R_PPC_UADDR32)
- goto fail;
- break;
- case EM_S390:
- if (rtype != R_390_32)
- goto fail;
- break;
- case EM_IA_64:
- if (rtype != R_IA64_SECREL32LSB)
- goto fail;
- break;
- case EM_X86_64:
- if (rtype != R_X86_64_32)
- goto fail;
- break;
- case EM_ALPHA:
- if (rtype != R_ALPHA_REFLONG)
- goto fail;
- break;
-#if defined(EM_AARCH64) && defined(R_AARCH64_ABS32)
- case EM_AARCH64:
- if (rtype != R_AARCH64_ABS32)
- goto fail;
- break;
-#endif
- case EM_68K:
- if (rtype != R_68K_32)
- goto fail;
- break;
-#if defined(EM_RISCV) && defined(R_RISCV_32)
- case EM_RISCV:
- if (rtype != R_RISCV_32)
- goto fail;
- break;
-#endif
- default:
- fail:
- error (1, 0, "%s: Unhandled relocation %d in .debug_info section",
- dso->filename, rtype);
- }
- relend->ptr = debug_sections[DEBUG_INFO].data
- + (rela.r_offset - base);
- relend->addend = rela.r_addend;
- relend->ndx = ndx;
- ++relend;
- }
- if (relbuf == relend)
- {
- free (relbuf);
- relbuf = NULL;
- relend = NULL;
- }
- else
- qsort (relbuf, relend - relbuf, sizeof (REL), rel_cmp);
- }
+ bool info_rel_updated = false;
for (phase = 0; phase < 2; phase++)
{
@@ -2008,7 +2073,8 @@ edit_dwarf2 (DSO *dso)
break;
ptr = debug_sections[DEBUG_INFO].data;
- relptr = relbuf;
+ setup_relbuf(dso, &debug_sections[DEBUG_INFO], &reltype);
+ rel_updated = false;
endsec = ptr + debug_sections[DEBUG_INFO].size;
while (ptr < endsec)
{
@@ -2096,6 +2162,10 @@ edit_dwarf2 (DSO *dso)
htab_delete (abbrev);
}
+ /* Remember whether any .debug_info relocations might need
+ to be updated. */
+ info_rel_updated = rel_updated;
+
/* We might have to recalculate/rewrite the debug_line
section. We need to do that before going into phase one
so we have all new offsets. We do this separately from
@@ -2240,41 +2310,8 @@ edit_dwarf2 (DSO *dso)
dirty_section (DEBUG_INFO);
/* Update any debug_info relocations addends we might have touched. */
- if (relbuf != NULL && reltype == SHT_RELA)
- {
- Elf_Data *symdata;
- int relsec_ndx = debug_sections[DEBUG_INFO].relsec;
- data = elf_getdata (dso->scn[relsec_ndx], NULL);
- symdata = elf_getdata (dso->scn[dso->shdr[relsec_ndx].sh_link],
- NULL);
-
- relptr = relbuf;
- while (relptr < relend)
- {
- GElf_Sym sym;
- GElf_Rela rela;
- int ndx = relptr->ndx;
-
- if (gelf_getrela (data, ndx, &rela) == NULL)
- error (1, 0, "Couldn't get relocation: %s",
- elf_errmsg (-1));
-
- if (gelf_getsym (symdata, GELF_R_SYM (rela.r_info),
- &sym) == NULL)
- error (1, 0, "Couldn't get symbol: %s", elf_errmsg (-1));
-
- rela.r_addend = relptr->addend - sym.st_value;
-
- if (gelf_update_rela (data, ndx, &rela) == 0)
- error (1, 0, "Couldn't update relocations: %s",
- elf_errmsg (-1));
-
- ++relptr;
- }
- elf_flagdata (data, ELF_C_SET, ELF_F_DIRTY);
- }
-
- free (relbuf);
+ if (info_rel_updated)
+ update_rela_data (dso, &debug_sections[DEBUG_INFO]);
}
return 0;
--
2.23.0

View File

@ -1,28 +0,0 @@
From be3347b5bff6142e86e533174fe0ec352405d159 Mon Sep 17 00:00:00 2001
From: Florian Festi <ffesti@redhat.com>
Date: Thu, 18 Jul 2019 07:45:53 +0200
Subject: [PATCH] rpmsign man page: Add line about rpmsign requiring a valid
checksum
and the limitations in FIPS mode
---
doc/rpmsign.8 | 3 +++
1 file changed, 3 insertions(+)
diff --git a/doc/rpmsign.8 b/doc/rpmsign.8
index 80ffb6a32..d895a3b8c 100644
--- a/doc/rpmsign.8
+++ b/doc/rpmsign.8
@@ -21,6 +21,9 @@ options generate and insert new signatures for each package
existing signatures. There are two options for historical reasons,
there is no difference in behavior currently.
+To create a signature rpm needs to verify the package's checksum. As a result
+packages with a MD5/SHA1 checksums cannot be signed in FIPS mode.
+
\fBrpm\fR \fB--delsign\fR \fB\fIPACKAGE_FILE\fB\fR\fI ...\fR
.PP
--
2.21.0

View File

@ -1,64 +0,0 @@
From 3fd79a5564df97d512be283c5c8a4da2e7ef8bce Mon Sep 17 00:00:00 2001
Message-Id: <3fd79a5564df97d512be283c5c8a4da2e7ef8bce.1554983206.git.pmatilai@redhat.com>
In-Reply-To: <2ec0832287bd1443ebf336f8a98293f30bfa2036.1554983205.git.pmatilai@redhat.com>
References: <2ec0832287bd1443ebf336f8a98293f30bfa2036.1554983205.git.pmatilai@redhat.com>
From: Panu Matilainen <pmatilai@redhat.com>
Date: Mon, 18 Mar 2019 15:29:18 +0200
Subject: [PATCH 2/3] Drop internal-only visibility on rpmvs-related API
Makes it possible to use rpmvs API from eg librpmsign which we'll
need in the next commit. We need to make select parts of this
actually public eventually but for now...
---
lib/rpmvs.h | 12 ------------
1 file changed, 12 deletions(-)
diff --git a/lib/rpmvs.h b/lib/rpmvs.h
index a836d5c94..025895500 100644
--- a/lib/rpmvs.h
+++ b/lib/rpmvs.h
@@ -48,41 +48,29 @@ typedef int (*rpmsinfoCb)(struct rpmsinfo_s *sinfo, void *cbdata);
extern "C" {
#endif
-RPM_GNUC_INTERNAL
const char *rpmsinfoDescr(struct rpmsinfo_s *sinfo);
-RPM_GNUC_INTERNAL
char *rpmsinfoMsg(struct rpmsinfo_s *sinfo);
-RPM_GNUC_INTERNAL
struct rpmvs_s *rpmvsCreate(int vfylevel, rpmVSFlags vsflags, rpmKeyring keyring);
-RPM_GNUC_INTERNAL
void rpmvsInit(struct rpmvs_s *vs, hdrblob blob, rpmDigestBundle bundle);
-RPM_GNUC_INTERNAL
rpmVSFlags rpmvsFlags(struct rpmvs_s *vs);
-RPM_GNUC_INTERNAL
struct rpmvs_s *rpmvsFree(struct rpmvs_s *sis);
-RPM_GNUC_INTERNAL
void rpmvsAppendTag(struct rpmvs_s *sis, hdrblob blob, rpmTagVal tag);
-RPM_GNUC_INTERNAL
void rpmvsInitRange(struct rpmvs_s *sis, int range);
-RPM_GNUC_INTERNAL
void rpmvsFiniRange(struct rpmvs_s *sis, int range);
-RPM_GNUC_INTERNAL
int rpmvsRange(struct rpmvs_s *vs);
-RPM_GNUC_INTERNAL
int rpmvsVerify(struct rpmvs_s *sis, int type,
rpmsinfoCb cb, void *cbdata);
-RPM_GNUC_INTERNAL
rpmRC rpmpkgRead(struct rpmvs_s *vs, FD_t fd,
hdrblob *sigblobp, hdrblob *blobp, char **emsg);
--
2.20.1

View File

@ -0,0 +1,304 @@
From 201a71ce18734b1cebc337225f345fd754a6414f Mon Sep 17 00:00:00 2001
Message-Id: <201a71ce18734b1cebc337225f345fd754a6414f.1573552234.git.pmatilai@redhat.com>
In-Reply-To: <ce6e8556a8f93327d6de0446f21ac5e549861d82.1573552234.git.pmatilai@redhat.com>
References: <ce6e8556a8f93327d6de0446f21ac5e549861d82.1573552234.git.pmatilai@redhat.com>
From: Mark Wielaard <mark@klomp.org>
Date: Mon, 17 Jun 2019 11:23:25 +0200
Subject: [PATCH 2/3] Handle .debug_macro in debugedit.
When compiling with -g3 gcc will generate a .debug_macro section
which has pointers to the .debug_str section. Since we might rewrite
the .debug_str section, we also need to update any .debug_macro
pointers.
Updated the debugedit.at testcase by building everything with -g
and add various checks to see the .debug_macro section looks OK
after running debugedit. Added a new rpmbuild.at testcase to check
handing of .debug_macro in the whole rpmbuild debuginfo pipeline
to double check the separate .debug file also contains the macros.
Original patch by Michael Schroeder <mls@suse.de>. Extended by
Mark Wielaard <mark@klomp.org> to deal with relocations and possible
multiple COMDAT .debug_macro sections.
---
tests/Makefile.am | 1 +
tests/data/SPECS/hello-g3.spec | 60 ++++++++++
tests/debugedit.at | 79 ++++++++++++-
tests/rpmbuild.at | 33 ++++++
tools/debugedit.c | 196 +++++++++++++++++++++++++++++++--
5 files changed, 356 insertions(+), 13 deletions(-)
create mode 100644 tests/data/SPECS/hello-g3.spec
[ test-suite part edited out, too painful to backport ]
diff --git a/tools/debugedit.c b/tools/debugedit.c
index cf9cc3ca9..84483ef5e 100644
--- a/tools/debugedit.c
+++ b/tools/debugedit.c
@@ -41,6 +41,7 @@
#include <gelf.h>
#include <dwarf.h>
+
/* Unfortunately strtab manipulation functions were only officially added
to elfutils libdw in 0.167. Before that there were internal unsupported
ebl variants. While libebl.h isn't supported we'll try to use it anyway
@@ -432,6 +433,7 @@ typedef struct debug_section
int sec, relsec;
REL *relbuf;
REL *relend;
+ struct debug_section *next; /* Only happens for COMDAT .debug_macro. */
} debug_section;
static debug_section debug_sections[] =
@@ -1989,11 +1991,35 @@ edit_dwarf2 (DSO *dso)
for (j = 0; debug_sections[j].name; ++j)
if (strcmp (name, debug_sections[j].name) == 0)
{
+ struct debug_section *debug_sec = &debug_sections[j];
if (debug_sections[j].data)
{
- error (0, 0, "%s: Found two copies of %s section",
- dso->filename, name);
- return 1;
+ if (j != DEBUG_MACRO)
+ {
+ error (0, 0, "%s: Found two copies of %s section",
+ dso->filename, name);
+ return 1;
+ }
+ else
+ {
+ /* In relocatable files .debug_macro might
+ appear multiple times as COMDAT
+ section. */
+ struct debug_section *sec;
+ sec = calloc (sizeof (struct debug_section), 1);
+ if (sec == NULL)
+ error (1, errno,
+ "%s: Could not allocate more macro sections",
+ dso->filename);
+ sec->name = ".debug_macro";
+
+ struct debug_section *macro_sec = debug_sec;
+ while (macro_sec->next != NULL)
+ macro_sec = macro_sec->next;
+
+ macro_sec->next = sec;
+ debug_sec = sec;
+ }
}
scn = dso->scn[i];
@@ -2002,10 +2028,10 @@ edit_dwarf2 (DSO *dso)
assert (elf_getdata (scn, data) == NULL);
assert (data->d_off == 0);
assert (data->d_size == dso->shdr[i].sh_size);
- debug_sections[j].data = data->d_buf;
- debug_sections[j].elf_data = data;
- debug_sections[j].size = data->d_size;
- debug_sections[j].sec = i;
+ debug_sec->data = data->d_buf;
+ debug_sec->elf_data = data;
+ debug_sec->size = data->d_size;
+ debug_sec->sec = i;
break;
}
@@ -2028,7 +2054,26 @@ edit_dwarf2 (DSO *dso)
+ (dso->shdr[i].sh_type == SHT_RELA),
debug_sections[j].name) == 0)
{
- debug_sections[j].relsec = i;
+ if (j == DEBUG_MACRO)
+ {
+ /* Pick the correct one. */
+ int rel_target = dso->shdr[i].sh_info;
+ struct debug_section *macro_sec = &debug_sections[j];
+ while (macro_sec != NULL)
+ {
+ if (macro_sec->sec == rel_target)
+ {
+ macro_sec->relsec = i;
+ break;
+ }
+ macro_sec = macro_sec->next;
+ }
+ if (macro_sec == NULL)
+ error (0, 1, "No .debug_macro reloc section: %s",
+ dso->filename);
+ }
+ else
+ debug_sections[j].relsec = i;
break;
}
}
@@ -2062,6 +2107,7 @@ edit_dwarf2 (DSO *dso)
struct abbrev_tag tag, *t;
int phase;
bool info_rel_updated = false;
+ bool macro_rel_updated = false;
for (phase = 0; phase < 2; phase++)
{
@@ -2279,6 +2325,113 @@ edit_dwarf2 (DSO *dso)
}
}
+ /* The .debug_macro section also contains offsets into the
+ .debug_str section and references to the .debug_line
+ tables, so we need to update those as well if we update
+ the strings or the stmts. */
+ if ((need_strp_update || need_stmt_update)
+ && debug_sections[DEBUG_MACRO].data)
+ {
+ /* There might be multiple (COMDAT) .debug_macro sections. */
+ struct debug_section *macro_sec = &debug_sections[DEBUG_MACRO];
+ while (macro_sec != NULL)
+ {
+ setup_relbuf(dso, macro_sec, &reltype);
+ rel_updated = false;
+
+ ptr = macro_sec->data;
+ endsec = ptr + macro_sec->size;
+ int op = 0, macro_version, macro_flags;
+ int offset_len = 4, line_offset = 0;
+
+ while (ptr < endsec)
+ {
+ if (!op)
+ {
+ macro_version = read_16 (ptr);
+ macro_flags = read_8 (ptr);
+ if (macro_version < 4 || macro_version > 5)
+ error (1, 0, "unhandled .debug_macro version: %d",
+ macro_version);
+ if ((macro_flags & ~2) != 0)
+ error (1, 0, "unhandled .debug_macro flags: 0x%x",
+ macro_flags);
+
+ offset_len = (macro_flags & 0x01) ? 8 : 4;
+ line_offset = (macro_flags & 0x02) ? 1 : 0;
+
+ if (offset_len != 4)
+ error (0, 1,
+ "Cannot handle 8 byte macro offsets: %s",
+ dso->filename);
+
+ /* Update the line_offset if it is there. */
+ if (line_offset)
+ {
+ if (phase == 0)
+ ptr += offset_len;
+ else
+ {
+ size_t idx, new_idx;
+ idx = do_read_32_relocated (ptr);
+ new_idx = find_new_list_offs (&dso->lines,
+ idx);
+ write_32_relocated (ptr, new_idx);
+ }
+ }
+ }
+
+ op = read_8 (ptr);
+ if (!op)
+ continue;
+ switch(op)
+ {
+ case DW_MACRO_GNU_define:
+ case DW_MACRO_GNU_undef:
+ read_uleb128 (ptr);
+ ptr = ((unsigned char *) strchr ((char *) ptr, '\0')
+ + 1);
+ break;
+ case DW_MACRO_GNU_start_file:
+ read_uleb128 (ptr);
+ read_uleb128 (ptr);
+ break;
+ case DW_MACRO_GNU_end_file:
+ break;
+ case DW_MACRO_GNU_define_indirect:
+ case DW_MACRO_GNU_undef_indirect:
+ read_uleb128 (ptr);
+ if (phase == 0)
+ {
+ size_t idx = read_32_relocated (ptr);
+ record_existing_string_entry_idx (&dso->strings,
+ idx);
+ }
+ else
+ {
+ struct stridxentry *entry;
+ size_t idx, new_idx;
+ idx = do_read_32_relocated (ptr);
+ entry = string_find_entry (&dso->strings, idx);
+ new_idx = strent_offset (entry->entry);
+ write_32_relocated (ptr, new_idx);
+ }
+ break;
+ case DW_MACRO_GNU_transparent_include:
+ ptr += offset_len;
+ break;
+ default:
+ error (1, 0, "Unhandled DW_MACRO op 0x%x", op);
+ break;
+ }
+ }
+
+ if (rel_updated)
+ macro_rel_updated = true;
+ macro_sec = macro_sec->next;
+ }
+ }
+
/* Same for the debug_str section. Make sure everything is
in place for phase 1 updating of debug_info
references. */
@@ -2308,10 +2461,24 @@ edit_dwarf2 (DSO *dso)
new strp, strings and/or linep offsets. */
if (need_strp_update || need_string_replacement || need_stmt_update)
dirty_section (DEBUG_INFO);
+ if (need_strp_update || need_stmt_update)
+ dirty_section (DEBUG_MACRO);
+ if (need_stmt_update)
+ dirty_section (DEBUG_LINE);
- /* Update any debug_info relocations addends we might have touched. */
+ /* Update any relocations addends we might have touched. */
if (info_rel_updated)
update_rela_data (dso, &debug_sections[DEBUG_INFO]);
+
+ if (macro_rel_updated)
+ {
+ struct debug_section *macro_sec = &debug_sections[DEBUG_MACRO];
+ while (macro_sec != NULL)
+ {
+ update_rela_data (dso, macro_sec);
+ macro_sec = macro_sec->next;
+ }
+ }
}
return 0;
@@ -2843,6 +3010,17 @@ main (int argc, char *argv[])
destroy_lines (&dso->lines);
free (dso);
+ /* In case there were multiple (COMDAT) .debug_macro sections,
+ free them. */
+ struct debug_section *macro_sec = &debug_sections[DEBUG_MACRO];
+ macro_sec = macro_sec->next;
+ while (macro_sec != NULL)
+ {
+ struct debug_section *next = macro_sec->next;
+ free (macro_sec);
+ macro_sec = next;
+ }
+
poptFreeContext (optCon);
return 0;
--
2.23.0

View File

@ -0,0 +1,77 @@
From 172e1f5ec0e37c8aab91a2ae35bd73ea594432cb Mon Sep 17 00:00:00 2001
Message-Id: <172e1f5ec0e37c8aab91a2ae35bd73ea594432cb.1571920849.git.pmatilai@redhat.com>
In-Reply-To: <6b6c4d881dc6fc99f949dac4aaf9a513542f9956.1571920849.git.pmatilai@redhat.com>
References: <6b6c4d881dc6fc99f949dac4aaf9a513542f9956.1571920849.git.pmatilai@redhat.com>
From: Panu Matilainen <pmatilai@redhat.com>
Date: Thu, 4 Oct 2018 13:36:09 +0300
Subject: [PATCH 2/5] Use Python 3 -compatible exception syntax in tests
Makes a few tests pass that failed before, and others now fail
a little bit later...
(cherry picked from commit 511eef19298765e3639bccbe98bc3a50023f45b2)
---
tests/rpmpython.at | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/tests/rpmpython.at b/tests/rpmpython.at
index 3a7c251f1..1daaf1216 100644
--- a/tests/rpmpython.at
+++ b/tests/rpmpython.at
@@ -96,7 +96,7 @@ for a in ['name', 'bugurl', '__class__', '__foo__', ]:
try:
x = getattr(h, a)
myprint(x)
- except AttributeError, exc:
+ except AttributeError as exc:
myprint(exc)
],
[testpkg-5:1.0-1.noarch
@@ -119,7 +119,7 @@ h2['dirindexes'] = [ 0, 0, 1 ]
for h in [h1, h2]:
try:
myprint(','.join(h['filenames']))
- except rpm.error, exc:
+ except rpm.error as exc:
myprint(exc)
],
[invalid header data
@@ -164,7 +164,7 @@ rpm.setLogFile(sink)
try:
h = ts.hdrFromFdno('${RPMDATA}/RPMS/hello-2.0-1.x86_64-signed.rpm')
myprint(h['arch'])
-except rpm.error, e:
+except rpm.error as e:
myprint(e)
],
[public key not available
@@ -183,7 +183,7 @@ ts.setKeyring(keyring)
try:
h = ts.hdrFromFdno('${RPMDATA}/RPMS/hello-2.0-1.x86_64-signed.rpm')
myprint(h['arch'])
-except rpm.error, e:
+except rpm.error as e:
myprint(e)
],
[x86_64]
@@ -207,7 +207,7 @@ h = rpm.hdr()
h['name'] = "foo"
try:
ts.addInstall(h, 'foo', 'u')
-except rpm.error, err:
+except rpm.error as err:
myprint(err)
for e in ts:
myprint(e.NEVRA())
@@ -228,7 +228,7 @@ h['dirnames'] = ['/opt' '/flopt']
h['dirindexes'] = [ 1, 2, 3 ]
try:
ts.addInstall(h, 'foo', 'u')
-except rpm.error, err:
+except rpm.error as err:
myprint(err)
for e in ts:
myprint(e.NEVRA())
--
2.21.0

View File

@ -0,0 +1,44 @@
From 6525a9bf1529944741f273cb9fde5619f006a673 Mon Sep 17 00:00:00 2001
Message-Id: <6525a9bf1529944741f273cb9fde5619f006a673.1571920849.git.pmatilai@redhat.com>
In-Reply-To: <6b6c4d881dc6fc99f949dac4aaf9a513542f9956.1571920849.git.pmatilai@redhat.com>
References: <6b6c4d881dc6fc99f949dac4aaf9a513542f9956.1571920849.git.pmatilai@redhat.com>
From: Panu Matilainen <pmatilai@redhat.com>
Date: Thu, 4 Oct 2018 17:41:19 +0300
Subject: [PATCH 3/5] Fix couple of bytes vs strings issues in Python tests
For the purposes of rpmio testing and importing public key, we're
dealing with bytes rather than encoded strings. In the carefree days
of Python 2 such details didn't matter, in Python 3 they cause failures.
The signed package test still fails after this one but it's due to
a more general issue.
(cherry picked from commit 86f7898dd6a7fa8718c02675f5a7ee04ff987422)
---
tests/rpmpython.at | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tests/rpmpython.at b/tests/rpmpython.at
index 1daaf1216..ae020ae95 100644
--- a/tests/rpmpython.at
+++ b/tests/rpmpython.at
@@ -33,7 +33,7 @@ prexp(mname)
[])
RPMPY_TEST([basic rpmio],[
-msg = 'Killroy was here\n'
+msg = b'Killroy was here\n'
data = msg * 10
# TODO: test other compression types too if built in
for iot in [ 'fpio', 'fdio', 'ufdio', 'gzdio' ]:
@@ -173,7 +173,7 @@ except rpm.error as e:
RPMPY_TEST([reading a signed package file 2],[
-keydata = open('${RPMDATA}/keys/rpm.org-rsa-2048-test.pub').read()
+keydata = open('${RPMDATA}/keys/rpm.org-rsa-2048-test.pub', 'rb').read()
pubkey = rpm.pubkey(keydata)
keyring = rpm.keyring()
keyring.addKey(pubkey)
--
2.21.0

View File

@ -0,0 +1,30 @@
From 00a0afd5e079a73ef6871f1538f34fa4e67892e6 Mon Sep 17 00:00:00 2001
Message-Id: <00a0afd5e079a73ef6871f1538f34fa4e67892e6.1573552234.git.pmatilai@redhat.com>
In-Reply-To: <ce6e8556a8f93327d6de0446f21ac5e549861d82.1573552234.git.pmatilai@redhat.com>
References: <ce6e8556a8f93327d6de0446f21ac5e549861d82.1573552234.git.pmatilai@redhat.com>
From: Mark Wielaard <mark@klomp.org>
Date: Mon, 17 Jun 2019 11:23:26 +0200
Subject: [PATCH 3/3] debugedit: Make sure .debug_line old/new idx start equal.
Found by running the debugedit tests under valgrind.
If the old and new .debug_line offset isn't changed then we might
write out an uninitialized new_idx.
---
tools/debugedit.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/tools/debugedit.c b/tools/debugedit.c
index 84483ef5e..9f8dcd0fb 100644
--- a/tools/debugedit.c
+++ b/tools/debugedit.c
@@ -1177,6 +1177,7 @@ get_line_table (DSO *dso, size_t off, struct line_table **table)
*table = NULL;
t->old_idx = off;
+ t->new_idx = off;
t->size_diff = 0;
t->replace_dirs = false;
t->replace_files = false;
--
2.23.0

View File

@ -0,0 +1,109 @@
From 0b1456ed4c00a021389acea4b6b10d475986b660 Mon Sep 17 00:00:00 2001
Message-Id: <0b1456ed4c00a021389acea4b6b10d475986b660.1571920849.git.pmatilai@redhat.com>
In-Reply-To: <6b6c4d881dc6fc99f949dac4aaf9a513542f9956.1571920849.git.pmatilai@redhat.com>
References: <6b6c4d881dc6fc99f949dac4aaf9a513542f9956.1571920849.git.pmatilai@redhat.com>
From: Panu Matilainen <pmatilai@redhat.com>
Date: Thu, 4 Oct 2018 18:05:37 +0300
Subject: [PATCH 4/5] Bump the minimum Python version requirement to 2.7
Older Python versions are long since past their EOL, we don't need to
support them either. Python 2.7 is also the least incompatible version
compared to Python 3, going forward. Nuke the now unnecessary compat
macros.
(cherry picked from commit 3f3cb3eabf7bb49dcc6e691601f89500b3487e06)
---
configure.ac | 2 +-
python/header-py.c | 4 ++--
python/rpmsystem-py.h | 33 ---------------------------------
python/spec-py.c | 2 +-
4 files changed, 4 insertions(+), 37 deletions(-)
diff --git a/configure.ac b/configure.ac
index 34ea85f9f..4d1a48e5f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -800,7 +800,7 @@ esac],
WITH_PYTHON_SUBPACKAGE=0
AS_IF([test "$enable_python" = yes],[
- AM_PATH_PYTHON([2.6],[
+ AM_PATH_PYTHON([2.7],[
PKG_CHECK_MODULES([PYTHON], [python-${PYTHON_VERSION}], [WITH_PYTHON_SUBPACKAGE=1])
AC_SUBST(PYTHON_CFLAGS)
AC_SUBST(PYTHON_LIB)
diff --git a/python/header-py.c b/python/header-py.c
index 628b48534..c9d54e869 100644
--- a/python/header-py.c
+++ b/python/header-py.c
@@ -376,8 +376,8 @@ static PyObject *hdr_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds)
if (obj == NULL) {
h = headerNew();
- } else if (CAPSULE_CHECK(obj)) {
- h = CAPSULE_EXTRACT(obj, "rpm._C_Header");
+ } else if (PyCapsule_CheckExact(obj)) {
+ h = PyCapsule_GetPointer(obj, "rpm._C_Header");
headerLink(h);
} else if (hdrObject_Check(obj)) {
h = headerCopy(((hdrObject*) obj)->h);
diff --git a/python/rpmsystem-py.h b/python/rpmsystem-py.h
index c8423e3dc..955d60cd3 100644
--- a/python/rpmsystem-py.h
+++ b/python/rpmsystem-py.h
@@ -9,39 +9,6 @@
#include <Python.h>
#include <structmember.h>
-#if ((PY_MAJOR_VERSION << 8) | (PY_MINOR_VERSION << 0)) < 0x0205
-typedef ssize_t Py_ssize_t;
-typedef Py_ssize_t (*lenfunc)(PyObject *);
-#endif
-
-/* Compatibility macros for Python < 2.6 */
-#ifndef PyVarObject_HEAD_INIT
-#define PyVarObject_HEAD_INIT(type, size) \
- PyObject_HEAD_INIT(type) size,
-#endif
-
-#ifndef Py_TYPE
-#define Py_TYPE(o) ((o)->ob_type)
-#endif
-
-#if ((PY_MAJOR_VERSION << 8) | (PY_MINOR_VERSION << 0)) < 0x0206
-#define PyBytes_Check PyString_Check
-#define PyBytes_FromString PyString_FromString
-#define PyBytes_FromStringAndSize PyString_FromStringAndSize
-#define PyBytes_Size PyString_Size
-#define PyBytes_AsString PyString_AsString
-#endif
-
-#if ((PY_MAJOR_VERSION << 8) | (PY_MINOR_VERSION << 0)) >= 0x0207
-#define CAPSULE_BUILD(ptr,name) PyCapsule_New(ptr, name, NULL)
-#define CAPSULE_CHECK(obj) PyCapsule_CheckExact(obj)
-#define CAPSULE_EXTRACT(obj,name) PyCapsule_GetPointer(obj, name)
-#else
-#define CAPSULE_BUILD(ptr,name) PyCObject_FromVoidPtr(ptr, NULL)
-#define CAPSULE_CHECK(obj) PyCObject_Check(obj)
-#define CAPSULE_EXTRACT(obj,name) PyCObject_AsVoidPtr(obj)
-#endif
-
/* For Python 3, use the PyLong type throughout in place of PyInt */
#if PY_MAJOR_VERSION >= 3
#define PyInt_Check PyLong_Check
diff --git a/python/spec-py.c b/python/spec-py.c
index fa7e58928..4efdbf4bf 100644
--- a/python/spec-py.c
+++ b/python/spec-py.c
@@ -34,7 +34,7 @@ static PyObject *makeHeader(Header h)
PyObject *rpmmod = PyImport_ImportModuleNoBlock("rpm");
if (rpmmod == NULL) return NULL;
- PyObject *ptr = CAPSULE_BUILD(h, "rpm._C_Header");
+ PyObject *ptr = PyCapsule_New(h, "rpm._C_Header", NULL);
PyObject *hdr = PyObject_CallMethod(rpmmod, "hdr", "(O)", ptr);
Py_XDECREF(ptr);
Py_XDECREF(rpmmod);
--
2.21.0

View File

@ -0,0 +1,41 @@
From 98470eccf09b80ed11528ac893852d649c50be72 Mon Sep 17 00:00:00 2001
Message-Id: <98470eccf09b80ed11528ac893852d649c50be72.1571920849.git.pmatilai@redhat.com>
In-Reply-To: <6b6c4d881dc6fc99f949dac4aaf9a513542f9956.1571920849.git.pmatilai@redhat.com>
References: <6b6c4d881dc6fc99f949dac4aaf9a513542f9956.1571920849.git.pmatilai@redhat.com>
From: Panu Matilainen <pmatilai@redhat.com>
Date: Fri, 5 Oct 2018 14:05:27 +0300
Subject: [PATCH 5/5] Drop an unnecessary Python 2 vs 3 incompatibility from
the test
Python 2 speaks about 'type' whereas 3 speaks about 'class', which from
our perspective is just unnecessary pain with no gain.
(cherry picked from commit ff3d8ac2e5cb4456ad1355f227f3ccef08e01972)
---
tests/rpmpython.at | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/tests/rpmpython.at b/tests/rpmpython.at
index ae020ae95..bc42e49e4 100644
--- a/tests/rpmpython.at
+++ b/tests/rpmpython.at
@@ -92,7 +92,7 @@ h['arch'] = 'noarch'
myprint(h['nevra'])
del h['epoch']
myprint(h['nevra'])
-for a in ['name', 'bugurl', '__class__', '__foo__', ]:
+for a in ['name', 'bugurl', '__foo__', ]:
try:
x = getattr(h, a)
myprint(x)
@@ -103,7 +103,6 @@ for a in ['name', 'bugurl', '__class__', '__foo__', ]:
testpkg-1.0-1.noarch
testpkg
None
-<type 'rpm.hdr'>
'rpm.hdr' object has no attribute '__foo__']
)
--
2.21.0

View File

@ -0,0 +1,46 @@
From acbf558c486ee3518aca74045504f05872da4a58 Mon Sep 17 00:00:00 2001
From: Lumir Balhar <lbalhar@redhat.com>
Date: Tue, 26 Sep 2023 13:14:44 +0200
Subject: [PATCH] brp-python-bytecompile compatibility with newer pythons
---
scripts/brp-python-bytecompile | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/scripts/brp-python-bytecompile b/scripts/brp-python-bytecompile
index 4a9b49e..472bf10 100644
--- a/scripts/brp-python-bytecompile
+++ b/scripts/brp-python-bytecompile
@@ -58,7 +58,7 @@ EOF
# and below /usr/lib/python3.1/, we're targeting /usr/bin/python3.1
shopt -s nullglob
-for python_libdir in `find "$RPM_BUILD_ROOT" -type d|grep -E "/usr/lib(64)?/python[0-9]\.[0-9]$"`;
+for python_libdir in `find "$RPM_BUILD_ROOT" -type d|grep -E "/usr/lib(64)?/python[0-9]\.[0-9]+$"`;
do
python_binary=/usr/bin/$(basename $python_libdir)
if [ "$python_binary" = "/usr/bin/python3.6" ]; then
@@ -97,17 +97,17 @@ fi
# Figure out if there are files to be bytecompiled with the default_python at all
# this prevents unnecessary default_python invocation
-find "$RPM_BUILD_ROOT" -type f -name "*.py" | grep -Ev "/bin/|/sbin/|/usr/lib(64)?/python[0-9]\.[0-9]|/usr/share/doc" || exit 0
+find "$RPM_BUILD_ROOT" -type f -name "*.py" | grep -Ev "/bin/|/sbin/|/usr/lib(64)?/python[0-9]\.[0-9]+|/usr/share/doc" || exit 0
# Generate normal (.pyc) byte-compiled files.
-python_bytecompile "" $default_python "/bin/|/sbin/|/usr/lib(64)?/python[0-9]\.[0-9]|/usr/share/doc" "$RPM_BUILD_ROOT" "$depth" "/"
+python_bytecompile "" $default_python "/bin/|/sbin/|/usr/lib(64)?/python[0-9]\.[0-9]+|/usr/share/doc" "$RPM_BUILD_ROOT" "$depth" "/"
if [ $? -ne 0 -a 0$errors_terminate -ne 0 ]; then
# One or more of the files had a syntax error
exit 1
fi
# Generate optimized (.pyo) byte-compiled files.
-python_bytecompile "-O" $default_python "/bin/|/sbin/|/usr/lib(64)?/python[0-9]\.[0-9]|/usr/share/doc" "$RPM_BUILD_ROOT" "$depth" "/"
+python_bytecompile "-O" $default_python "/bin/|/sbin/|/usr/lib(64)?/python[0-9]\.[0-9]+|/usr/share/doc" "$RPM_BUILD_ROOT" "$depth" "/"
if [ $? -ne 0 -a 0$errors_terminate -ne 0 ]; then
# One or more of the files had a syntax error
exit 1
--
2.41.0

View File

@ -0,0 +1,11 @@
--- rpm-4.14.3/plugins/selinux.c.orig 2020-05-11 16:07:22.873791795 +0200
+++ rpm-4.14.3/plugins/selinux.c 2020-05-11 16:10:11.701771157 +0200
@@ -47,7 +47,7 @@
sehandle = selabel_open(SELABEL_CTX_FILE, opts, 1);
- rpmlog(RPMLOG_DEBUG, "selabel_open: (%s) %s\n",
+ rpmlog((sehandle == NULL) ? RPMLOG_ERR : RPMLOG_DEBUG, "selabel_open: (%s) %s\n",
path, (sehandle == NULL ? strerror(errno) : ""));
return (sehandle != NULL) ? RPMRC_OK : RPMRC_FAIL;

View File

@ -1,15 +1,16 @@
diff -up rpm-4.9.1.1/macros.in.jx rpm-4.9.1.1/macros.in
--- rpm-4.9.1.1/macros.in.jx 2011-08-03 16:19:05.000000000 -0400
+++ rpm-4.9.1.1/macros.in 2011-08-08 09:41:52.981064316 -0400
@@ -674,9 +674,10 @@ print (t)\
@@ -674,10 +674,11 @@ print (t)\
RPM_SOURCE_DIR=\"%{u2p:%{_sourcedir}}\"\
RPM_BUILD_DIR=\"%{u2p:%{_builddir}}\"\
RPM_OPT_FLAGS=\"%{optflags}\"\
+ RPM_LD_FLAGS=\"%{?__global_ldflags}\"\
RPM_ARCH=\"%{_arch}\"\
RPM_OS=\"%{_os}\"\
- export RPM_SOURCE_DIR RPM_BUILD_DIR RPM_OPT_FLAGS RPM_ARCH RPM_OS\
+ export RPM_SOURCE_DIR RPM_BUILD_DIR RPM_OPT_FLAGS RPM_LD_FLAGS RPM_ARCH RPM_OS\
RPM_BUILD_NCPUS=\"%{_smp_build_ncpus}\"\
- export RPM_SOURCE_DIR RPM_BUILD_DIR RPM_OPT_FLAGS RPM_ARCH RPM_OS RPM_BUILD_NCPUS\
+ export RPM_SOURCE_DIR RPM_BUILD_DIR RPM_OPT_FLAGS RPM_LD_FLAGS RPM_ARCH RPM_OS RPM_BUILD_NCPUS\
RPM_DOC_DIR=\"%{_docdir}\"\
export RPM_DOC_DIR\
RPM_PACKAGE_NAME=\"%{NAME}\"\

View File

@ -0,0 +1,14 @@
diff -up rpm-4.14.3/scripts/brp-strip.orig rpm-4.14.3/scripts/brp-strip
--- rpm-4.14.3/scripts/brp-strip.orig 2021-02-09 14:43:35.393940550 +0100
+++ rpm-4.14.3/scripts/brp-strip 2021-02-09 14:43:49.459222054 +0100
@@ -12,9 +12,8 @@ Darwin*) exit 0 ;;
esac
# Strip ELF binaries
-for f in `find "$RPM_BUILD_ROOT" -type f \( -perm -0100 -or -perm -0010 -or -perm -0001 \) -exec file {} \; | \
+for f in `find "$RPM_BUILD_ROOT" -type f -exec file {} \; | \
grep -v "^${RPM_BUILD_ROOT}/\?usr/lib/debug" | \
- grep -v ' shared object,' | \
sed -n -e 's/^\(.*\):[ ]*ELF.*, not stripped.*/\1/p'`; do
$STRIP -g "$f" || :
done

View File

@ -0,0 +1,186 @@
diff -up rpm-4.14.3/sign/rpmgensig.c.orig rpm-4.14.3/sign/rpmgensig.c
--- rpm-4.14.3/sign/rpmgensig.c.orig 2020-06-26 15:57:43.781333983 +0200
+++ rpm-4.14.3/sign/rpmgensig.c 2020-06-26 15:58:29.819229616 +0200
@@ -8,7 +8,6 @@
#include <errno.h>
#include <sys/wait.h>
#include <popt.h>
-#include <libgen.h>
#include <rpm/rpmlib.h> /* RPMSIGTAG & related */
#include <rpm/rpmmacro.h>
@@ -33,68 +32,6 @@ typedef struct sigTarget_s {
rpm_loff_t size;
} *sigTarget;
-/*
- * There is no function for creating unique temporary fifos so create
- * unique temporary directory and then create fifo in it.
- */
-static char *mkTempFifo(void)
-{
- char *tmppath = NULL, *tmpdir = NULL, *fifofn = NULL;
- mode_t mode;
-
- tmppath = rpmExpand("%{_tmppath}", NULL);
- if (rpmioMkpath(tmppath, 0755, (uid_t) -1, (gid_t) -1))
- goto exit;
-
-
- tmpdir = rpmGetPath(tmppath, "/rpm-tmp.XXXXXX", NULL);
- mode = umask(0077);
- tmpdir = mkdtemp(tmpdir);
- umask(mode);
- if (tmpdir == NULL) {
- rpmlog(RPMLOG_ERR, _("error creating temp directory %s: %m\n"),
- tmpdir);
- tmpdir = _free(tmpdir);
- goto exit;
- }
-
- fifofn = rpmGetPath(tmpdir, "/fifo", NULL);
- if (mkfifo(fifofn, 0600) == -1) {
- rpmlog(RPMLOG_ERR, _("error creating fifo %s: %m\n"), fifofn);
- fifofn = _free(fifofn);
- }
-
-exit:
- if (fifofn == NULL && tmpdir != NULL)
- unlink(tmpdir);
-
- free(tmppath);
- free(tmpdir);
-
- return fifofn;
-}
-
-/* Delete fifo and then temporary directory in which it was located */
-static int rpmRmTempFifo(const char *fn)
-{
- int rc = 0;
- char *dfn = NULL, *dir = NULL;
-
- if ((rc = unlink(fn)) != 0) {
- rpmlog(RPMLOG_ERR, _("error delete fifo %s: %m\n"), fn);
- return rc;
- }
-
- dfn = xstrdup(fn);
- dir = dirname(dfn);
-
- if ((rc = rmdir(dir)) != 0)
- rpmlog(RPMLOG_ERR, _("error delete directory %s: %m\n"), dir);
- free(dfn);
-
- return rc;
-}
-
static int closeFile(FD_t *fdp)
{
if (fdp == NULL || *fdp == NULL)
@@ -241,27 +178,38 @@ exit:
static int runGPG(sigTarget sigt, const char *sigfile)
{
int pid = 0, status;
- FD_t fnamedPipe = NULL;
- char *namedPipeName = NULL;
+ int pipefd[2];
+ FILE *fpipe = NULL;
unsigned char buf[BUFSIZ];
ssize_t count;
ssize_t wantCount;
rpm_loff_t size;
int rc = 1; /* assume failure */
- namedPipeName = mkTempFifo();
+ if (pipe(pipefd) < 0) {
+ rpmlog(RPMLOG_ERR, _("Could not create pipe for signing: %m\n"));
+ goto exit;
+ }
- rpmPushMacro(NULL, "__plaintext_filename", NULL, namedPipeName, -1);
+ rpmPushMacro(NULL, "__plaintext_filename", NULL, "-", -1);
rpmPushMacro(NULL, "__signature_filename", NULL, sigfile, -1);
if (!(pid = fork())) {
char *const *av;
char *cmd = NULL;
- const char *gpg_path = rpmExpand("%{?_gpg_path}", NULL);
+ const char *tty = ttyname(STDIN_FILENO);
+ const char *gpg_path = NULL;
+
+ if (!getenv("GPG_TTY") && (!tty || setenv("GPG_TTY", tty, 0)))
+ rpmlog(RPMLOG_WARNING, _("Could not set GPG_TTY to stdin: %m\n"));
+ gpg_path = rpmExpand("%{?_gpg_path}", NULL);
if (gpg_path && *gpg_path != '\0')
(void) setenv("GNUPGHOME", gpg_path, 1);
+ dup2(pipefd[0], STDIN_FILENO);
+ close(pipefd[1]);
+
unsetenv("MALLOC_CHECK_");
cmd = rpmExpand("%{?__gpg_sign_cmd}", NULL);
rc = poptParseArgvString(cmd, NULL, (const char ***)&av);
@@ -276,9 +224,10 @@ static int runGPG(sigTarget sigt, const
rpmPopMacro(NULL, "__plaintext_filename");
rpmPopMacro(NULL, "__signature_filename");
- fnamedPipe = Fopen(namedPipeName, "w");
- if (!fnamedPipe) {
- rpmlog(RPMLOG_ERR, _("Fopen failed\n"));
+ close(pipefd[0]);
+ fpipe = fdopen(pipefd[1], "w");
+ if (!fpipe) {
+ rpmlog(RPMLOG_ERR, _("Could not open pipe for writing: %m\n"));
goto exit;
}
@@ -291,8 +240,8 @@ static int runGPG(sigTarget sigt, const
size = sigt->size;
wantCount = size < sizeof(buf) ? size : sizeof(buf);
while ((count = Fread(buf, sizeof(buf[0]), wantCount, sigt->fd)) > 0) {
- Fwrite(buf, sizeof(buf[0]), count, fnamedPipe);
- if (Ferror(fnamedPipe)) {
+ fwrite(buf, sizeof(buf[0]), count, fpipe);
+ if (ferror(fpipe)) {
rpmlog(RPMLOG_ERR, _("Could not write to pipe\n"));
goto exit;
}
@@ -304,8 +253,13 @@ static int runGPG(sigTarget sigt, const
sigt->fileName, Fstrerror(sigt->fd));
goto exit;
}
- Fclose(fnamedPipe);
- fnamedPipe = NULL;
+
+exit:
+
+ if (fpipe)
+ fclose(fpipe);
+ if (pipefd[1])
+ close(pipefd[1]);
(void) waitpid(pid, &status, 0);
pid = 0;
@@ -314,20 +268,6 @@ static int runGPG(sigTarget sigt, const
} else {
rc = 0;
}
-
-exit:
-
- if (fnamedPipe)
- Fclose(fnamedPipe);
-
- if (pid)
- waitpid(pid, &status, 0);
-
- if (namedPipeName) {
- rpmRmTempFifo(namedPipeName);
- free(namedPipeName);
- }
-
return rc;
}

View File

@ -0,0 +1,378 @@
From c33faabc2d09b9ad8c80b941b6114c1e4c2be80f Mon Sep 17 00:00:00 2001
Message-Id: <c33faabc2d09b9ad8c80b941b6114c1e4c2be80f.1612252390.git.pmatilai@redhat.com>
From: Radovan Sroka <rsroka@redhat.com>
Date: Tue, 27 Oct 2020 16:18:04 +0100
Subject: [PATCH] Added fapolicyd rpm plugin
Fapolicyd (File Access Policy Daemon) implements application whitelisting
to decide file access rights. Applications that are known via a reputation
source are allowed access while unknown applications are not.
The rpm plugin allows us to use rpm database as a source of trust.
We used dnf plugin since the beggining but it only provides notification
when transaction ends. With "integrity checking" requirement we need
a continual addition of files which are installed during the system
update. With fapolicyd rpm plugin we can allow using of recently
added/updated files in scriptlets during rpm transaction.
The fapolicyd plugin gathers metadata of currently installed files.
It sends the information about files and about ongoing rpm transaction
to the fapolicyd daemon. The information is written to Linux pipe which
is placed in /var/run/fapolicyd/fapolicyd.fifo.
The data format is "%s %lu %64s\n". [path, size, sha256]
The fapolicyd rpm plugin can be enabled with "--with-fapolicyd"
configure option.
Related PRs:
https://github.com/linux-application-whitelisting/fapolicyd/pull/105
https://github.com/linux-application-whitelisting/fapolicyd/pull/106
Signed-off-by: Radovan Sroka <rsroka@redhat.com>
(cherry picked from commit 39595ccee321497dc3b08c7cab8a10304345429c)
Backported from commit 39595ccee321497dc3b08c7cab8a10304345429c
---
Makefile.am | 1 +
configure.ac | 8 ++
doc/Makefile.am | 2 +-
doc/rpm-plugin-fapolicyd.8 | 21 +++++
macros.in | 1 +
plugins/Makefile.am | 6 ++
plugins/fapolicyd.c | 189 +++++++++++++++++++++++++++++++++++++
7 files changed, 227 insertions(+), 1 deletion(-)
create mode 100644 doc/rpm-plugin-fapolicyd.8
create mode 100644 plugins/fapolicyd.c
diff --git a/Makefile.am b/Makefile.am
index 1f20f05b7..8e92f0cde 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -16,6 +16,7 @@ DISTCHECK_CONFIGURE_FLAGS = \
--with-selinux \
--with-imaevm \
--with-crypto=openssl \
+ --with-fapolicyd \
--disable-dependency-tracking
include $(top_srcdir)/rpm.am
diff --git a/configure.ac b/configure.ac
index 3fcb3ff20..3d0e9ef91 100644
--- a/configure.ac
+++ b/configure.ac
@@ -983,6 +983,14 @@ AS_IF([test "$enable_inhibit_plugin" = yes],[
])
AM_CONDITIONAL(ENABLE_INHIBIT_PLUGIN,[test "$enable_inhibit_plugin" = yes])
+#=================
+# Check for fapolicyd support
+AC_ARG_WITH(fapolicyd,
+AS_HELP_STRING([--with-fapolicyd],[build with File Access Policy Daemon support]),
+with_fapolicyd=$withval,
+with_fapolicyd=auto)
+AM_CONDITIONAL(FAPOLICYD,[test "$with_fapolicyd" = yes])
+
with_dbus=no
AS_IF([test "$enable_plugins" != no],[
AS_IF([test "$enable_inhibit_plugin" != no],[
diff --git a/doc/Makefile.am b/doc/Makefile.am
index d2f520d64..535ad3ec3 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -9,7 +9,7 @@ EXTRA_DIST += $(man_man1_DATA)
man_man8dir = $(mandir)/man8
man_man8_DATA = rpm.8 rpm-misc.8 rpmbuild.8 rpmdeps.8 rpmgraph.8 rpm2cpio.8
man_man8_DATA += rpmdb.8 rpmkeys.8 rpmsign.8 rpmspec.8
-man_man8_DATA += rpm-plugin-systemd-inhibit.8
+man_man8_DATA += rpm-plugin-systemd-inhibit.8 rpm-plugin-fapolicyd.8
EXTRA_DIST += $(man_man8_DATA)
man_fr_man8dir = $(mandir)/fr/man8
diff --git a/doc/rpm-plugin-fapolicyd.8 b/doc/rpm-plugin-fapolicyd.8
new file mode 100644
index 000000000..fe7a8c78e
--- /dev/null
+++ b/doc/rpm-plugin-fapolicyd.8
@@ -0,0 +1,21 @@
+'\" t
+.TH "RPM-FAPOLICYD" "8" "28 Jan 2021" "Red Hat, Inc."
+.SH NAME
+rpm-plugin-fapolicyd \- Fapolicyd plugin for the RPM Package Manager
+
+.SH Description
+
+The plugin gathers metadata of currently installed files. It sends the
+information about files and about ongoing rpm transaction to the fapolicyd daemon.
+The information is written to Linux pipe which is placed in
+/var/run/fapolicyd/fapolicyd.fifo.
+
+.SH Configuration
+
+There are currently no options for this plugin in particular. See
+.BR rpm-plugins (8)
+on how to control plugins in general.
+
+.SH SEE ALSO
+.IR fapolicyd (8)
+.IR rpm-plugins (8)
diff --git a/macros.in b/macros.in
index a6069ee4d..2fbda64cc 100644
--- a/macros.in
+++ b/macros.in
@@ -1173,6 +1173,7 @@ package or when debugging this package.\
%__transaction_selinux %{__plugindir}/selinux.so
%__transaction_syslog %{__plugindir}/syslog.so
%__transaction_ima %{__plugindir}/ima.so
+%__transaction_fapolicyd %{__plugindir}/fapolicyd.so
%__transaction_prioreset %{__plugindir}/prioreset.so
#------------------------------------------------------------------------------
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
index ab4eee34f..cbfb81e19 100644
--- a/plugins/Makefile.am
+++ b/plugins/Makefile.am
@@ -42,3 +42,9 @@ ima_la_sources = ima.c
ima_la_LIBADD = $(top_builddir)/lib/librpm.la $(top_builddir)/rpmio/librpmio.la
plugins_LTLIBRARIES += ima.la
endif
+
+if FAPOLICYD
+fapolicyd_la_sources = fapolicyd.c
+fapolicyd_la_LIBADD = $(top_builddir)/lib/librpm.la $(top_builddir)/rpmio/librpmio.la
+plugins_LTLIBRARIES += fapolicyd.la
+endif
diff --git a/plugins/fapolicyd.c b/plugins/fapolicyd.c
new file mode 100644
index 000000000..50f50155c
--- /dev/null
+++ b/plugins/fapolicyd.c
@@ -0,0 +1,189 @@
+#include "system.h"
+
+#include <rpm/rpmts.h>
+#include <rpm/rpmlog.h>
+#include "lib/rpmplugin.h"
+
+#include <fcntl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/stat.h>
+
+struct fapolicyd_data {
+ int fd;
+ long changed_files;
+ const char * fifo_path;
+};
+
+static struct fapolicyd_data fapolicyd_state = {
+ .fd = -1,
+ .changed_files = 0,
+ .fifo_path = "/run/fapolicyd/fapolicyd.fifo",
+};
+
+static rpmRC open_fifo(struct fapolicyd_data* state)
+{
+ int fd = -1;
+ struct stat s;
+
+ fd = open(state->fifo_path, O_RDWR);
+ if (fd == -1) {
+ rpmlog(RPMLOG_DEBUG, "Open: %s -> %s\n", state->fifo_path, strerror(errno));
+ goto bad;
+ }
+
+ if (stat(state->fifo_path, &s) == -1) {
+ rpmlog(RPMLOG_DEBUG, "Stat: %s -> %s\n", state->fifo_path, strerror(errno));
+ goto bad;
+ }
+
+ if (!S_ISFIFO(s.st_mode)) {
+ rpmlog(RPMLOG_DEBUG, "File: %s exists but it is not a pipe!\n", state->fifo_path);
+ goto bad;
+ }
+
+ /* keep only file's permition bits */
+ mode_t mode = s.st_mode & ~S_IFMT;
+
+ /* we require pipe to have 0660 permission */
+ if (mode != 0660) {
+ rpmlog(RPMLOG_ERR, "File: %s has %o instead of 0660 \n",
+ state->fifo_path,
+ mode );
+ goto bad;
+ }
+
+ state->fd = fd;
+ /* considering success */
+ return RPMRC_OK;
+
+ bad:
+ if (fd > 0)
+ close(fd);
+ return RPMRC_FAIL;
+}
+
+static rpmRC write_fifo(struct fapolicyd_data* state, const char * str)
+{
+ ssize_t len = strlen(str);
+ ssize_t written = 0;
+ ssize_t n = 0;
+
+ while (written < len) {
+ if ((n = write(state->fd, str + written, len - written)) < 0) {
+ if (errno == EINTR || errno == EAGAIN)
+ continue;
+ rpmlog(RPMLOG_DEBUG, "Write: %s -> %s\n", state->fifo_path, strerror(errno));
+ goto bad;
+ }
+ written += n;
+ }
+
+ return RPMRC_OK;
+
+ bad:
+ return RPMRC_FAIL;
+}
+
+static rpmRC fapolicyd_init(rpmPlugin plugin, rpmts ts)
+{
+ if (rpmtsFlags(ts) & (RPMTRANS_FLAG_TEST|RPMTRANS_FLAG_BUILD_PROBS))
+ goto end;
+
+ if (!rstreq(rpmtsRootDir(ts), "/"))
+ goto end;
+
+ (void) open_fifo(&fapolicyd_state);
+
+ end:
+ return RPMRC_OK;
+}
+
+static void fapolicyd_cleanup(rpmPlugin plugin)
+{
+ if (fapolicyd_state.fd > 0)
+ (void) close(fapolicyd_state.fd);
+
+ fapolicyd_state.fd = -1;
+}
+
+static rpmRC fapolicyd_tsm_post(rpmPlugin plugin, rpmts ts, int res)
+{
+ if (rpmtsFlags(ts) & (RPMTRANS_FLAG_TEST|RPMTRANS_FLAG_BUILD_PROBS))
+ goto end;
+
+ /* we are ready */
+ if (fapolicyd_state.fd > 0) {
+ /* send a signal that transaction is over */
+ (void) write_fifo(&fapolicyd_state, "1\n");
+ /* flush cache */
+ (void) write_fifo(&fapolicyd_state, "2\n");
+ }
+
+ end:
+ return RPMRC_OK;
+}
+
+static rpmRC fapolicyd_scriptlet_pre(rpmPlugin plugin, const char *s_name,
+ int type)
+{
+ if (fapolicyd_state.fd == -1)
+ goto end;
+
+ if (fapolicyd_state.changed_files > 0) {
+ /* send signal to flush cache */
+ (void) write_fifo(&fapolicyd_state, "2\n");
+
+ /* optimize flushing */
+ /* flush only when there was an actual change */
+ fapolicyd_state.changed_files = 0;
+ }
+
+ end:
+ return RPMRC_OK;
+}
+
+static rpmRC fapolicyd_fsm_file_prepare(rpmPlugin plugin, rpmfi fi,
+ const char *path, const char *dest,
+ mode_t file_mode, rpmFsmOp op)
+{
+ /* not ready */
+ if (fapolicyd_state.fd == -1)
+ goto end;
+
+ rpmFileAction action = XFO_ACTION(op);
+
+ /* Ignore skipped files and unowned directories */
+ if (XFA_SKIPPING(action) || (op & FAF_UNOWNED)) {
+ rpmlog(RPMLOG_DEBUG, "fapolicyd skipping early: path %s dest %s\n",
+ path, dest);
+ goto end;
+ }
+
+ if (!S_ISREG(rpmfiFMode(fi))) {
+ rpmlog(RPMLOG_DEBUG, "fapolicyd skipping non regular: path %s dest %s\n",
+ path, dest);
+ goto end;
+ }
+
+ fapolicyd_state.changed_files++;
+
+ char buffer[4096];
+
+ rpm_loff_t size = rpmfiFSize(fi);
+ char * sha = rpmfiFDigestHex(fi, NULL);
+
+ snprintf(buffer, 4096, "%s %lu %64s\n", dest, size, sha);
+ (void) write_fifo(&fapolicyd_state, buffer);
+
+ end:
+ return RPMRC_OK;
+}
+
+struct rpmPluginHooks_s fapolicyd_hooks = {
+ .init = fapolicyd_init,
+ .cleanup = fapolicyd_cleanup,
+ .scriptlet_pre = fapolicyd_scriptlet_pre,
+ .tsm_post = fapolicyd_tsm_post,
+ .fsm_file_prepare = fapolicyd_fsm_file_prepare,
+};
--
2.29.2
commit c66cee32e74ce1e507c031605e3d7b2c1391a52c
Author: Radovan Sroka <rsroka@redhat.com>
Date: Wed Feb 10 17:04:55 2021 +0100
Fixed issues find by coverity
- enhance the check for the file descriptor fd because 0 is also a valid
descriptor
- added free() for sha so it doesn't leak memory for every file that is
processed
Signed-off-by: Radovan Sroka <rsroka@redhat.com>
diff --git a/plugins/fapolicyd.c b/plugins/fapolicyd.c
index 50f50155c..48f65ae11 100644
--- a/plugins/fapolicyd.c
+++ b/plugins/fapolicyd.c
@@ -58,7 +58,7 @@ static rpmRC open_fifo(struct fapolicyd_data* state)
return RPMRC_OK;
bad:
- if (fd > 0)
+ if (fd >= 0)
close(fd);
return RPMRC_FAIL;
}
@@ -176,6 +176,8 @@ static rpmRC fapolicyd_fsm_file_prepare(rpmPlugin plugin, rpmfi fi,
snprintf(buffer, 4096, "%s %lu %64s\n", dest, size, sha);
(void) write_fifo(&fapolicyd_state, buffer);
+ free(sha);
+
end:
return RPMRC_OK;
}

View File

@ -0,0 +1,197 @@
From 013cd4ba63c35fa75feeccde0022d56e68bc5845 Mon Sep 17 00:00:00 2001
From: Michal Domonkos <mdomonko@redhat.com>
Date: Mon, 16 Aug 2021 18:21:02 +0200
Subject: [PATCH] Add support for RPMDBI_BASENAMES on file queries
There are legitimate reasons (such as rhbz#1940895 or the included test)
for wanting the former behavior where all file states were considered in
file queries prior to commit 9ad57bda4a82b9847826daa766b4421d877bb3d9,
so celebrate the tenth anniversary of that commit by adding a CLI switch
(a new package selector --path), as contemplated back then.
Update the man page for --file to reflect it's current behavior and make
--path that more obvious.
Resolves: rhbz#1940895
Combined with:
d1aebda01033bc8ba0d748b49f6fad9a5c0caa3f
f62b6d27cd741406a52a7e9c5b1d6f581dbd3af8
Backported for 4.14.3.
---
doc/rpm.8 | 9 ++++++--
lib/poptQV.c | 6 +++++-
lib/query.c | 7 +++++--
lib/rpmcli.h | 1 +
tests/rpmquery.at | 52 +++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 70 insertions(+), 5 deletions(-)
diff --git a/doc/rpm.8 b/doc/rpm.8
index 15a3db25f..74604c8ec 100644
--- a/doc/rpm.8
+++ b/doc/rpm.8
@@ -57,7 +57,7 @@ rpm \- RPM Package Manager
.PP
[\fB\fIPACKAGE_NAME\fB\fR]
- [\fB-a,--all [\fISELECTOR\fR]\fR] [\fB-f,--file \fIFILE\fB\fR]
+ [\fB-a,--all [\fISELECTOR\fR]\fR] [\fB-f,--file \fIFILE\fB\fR] [\fB--path \fIPATH\fB\fR]
[\fB-g,--group \fIGROUP\fB\fR] {\fB-p,--package \fIPACKAGE_FILE\fB\fR]
[\fB--hdrid \fISHA1\fB\fR] [\fB--pkgid \fIMD5\fB\fR] [\fB--tid \fITID\fB\fR]
[\fB--querybynumber \fIHDRNUM\fB\fR] [\fB--triggeredby \fIPACKAGE_NAME\fB\fR]
@@ -555,7 +555,7 @@ starts with "b".
List duplicated packages.
.TP
\fB-f, --file \fIFILE\fB\fR
-Query package owning \fIFILE\fR.
+Query package owning installed \fIFILE\fR.
.TP
\fB--filecaps\fR
List file names with POSIX1.e capabilities.
@@ -598,6 +598,11 @@ that will be expanded to paths that are substituted in place of
the package manifest as additional \fIPACKAGE_FILE\fR
arguments to the query.
.TP
+\fB--path \fIPATH\fB\fR
+Query package(s) owning \fIPATH\fR, whether the file is installed or not.
+Multiple packages may own a \fIPATH\fR, but the file is only owned by the
+package installed last.
+.TP
\fB--pkgid \fIMD5\fB\fR
Query package that contains a given package identifier, i.e. the
\fIMD5\fR digest of the combined header and
diff --git a/lib/poptQV.c b/lib/poptQV.c
index 9021d7b3c..f752d8b82 100644
--- a/lib/poptQV.c
+++ b/lib/poptQV.c
@@ -27,6 +27,7 @@ struct rpmQVKArguments_s rpmQVKArgs;
#define POPT_WHATENHANCES -1014
#define POPT_WHATOBSOLETES -1015
#define POPT_WHATCONFLICTS -1016
+#define POPT_QUERYBYPATH -1017
/* ========== Query/Verify/Signature source args */
static void rpmQVSourceArgCallback( poptContext con,
@@ -58,6 +59,7 @@ static void rpmQVSourceArgCallback( poptContext con,
case POPT_WHATSUPPLEMENTS: qva->qva_source |= RPMQV_WHATSUPPLEMENTS; break;
case POPT_WHATENHANCES: qva->qva_source |= RPMQV_WHATENHANCES; break;
case POPT_TRIGGEREDBY: qva->qva_source |= RPMQV_TRIGGEREDBY; break;
+ case POPT_QUERYBYPATH: qva->qva_source |= RPMQV_PATH_ALL; break;
case POPT_QUERYBYPKGID: qva->qva_source |= RPMQV_PKGID; break;
case POPT_QUERYBYHDRID: qva->qva_source |= RPMQV_HDRID; break;
case POPT_QUERYBYTID: qva->qva_source |= RPMQV_TID; break;
@@ -80,7 +82,9 @@ struct poptOption rpmQVSourcePoptTable[] = {
{ "checksig", 'K', POPT_ARGFLAG_DOC_HIDDEN, NULL, 'K',
N_("rpm checksig mode"), NULL },
{ "file", 'f', 0, 0, 'f',
- N_("query/verify package(s) owning file"), "FILE" },
+ N_("query/verify package(s) owning installed file"), "FILE" },
+ { "path", '\0', 0, 0, POPT_QUERYBYPATH,
+ N_("query/verify package(s) owning path, installed or not"), "PATH" },
{ "group", 'g', 0, 0, 'g',
N_("query/verify package(s) in group"), "GROUP" },
{ "package", 'p', 0, 0, 'p',
diff --git a/lib/query.c b/lib/query.c
index 26cdecf10..e6ea1fa2d 100644
--- a/lib/query.c
+++ b/lib/query.c
@@ -440,6 +440,7 @@ static rpmdbMatchIterator initQueryIterator(QVA_t qva, rpmts ts, const char * ar
}
/* fallthrough on absolute and relative paths */
case RPMQV_PATH:
+ case RPMQV_PATH_ALL:
{ char * fn;
for (s = arg; *s != '\0'; s++)
@@ -458,8 +459,10 @@ static rpmdbMatchIterator initQueryIterator(QVA_t qva, rpmts ts, const char * ar
fn = xstrdup(arg);
(void) rpmCleanPath(fn);
- /* XXX Add a switch to enable former BASENAMES behavior? */
- mi = rpmtsInitIterator(ts, RPMDBI_INSTFILENAMES, fn, 0);
+ rpmDbiTagVal tag = RPMDBI_INSTFILENAMES;
+ if (qva->qva_source == RPMQV_PATH_ALL)
+ tag = RPMDBI_BASENAMES;
+ mi = rpmtsInitIterator(ts, tag, fn, 0);
if (mi == NULL)
mi = rpmtsInitIterator(ts, RPMDBI_PROVIDENAME, fn, 0);
diff --git a/lib/rpmcli.h b/lib/rpmcli.h
index 99af2585a..c0d07d137 100644
--- a/lib/rpmcli.h
+++ b/lib/rpmcli.h
@@ -102,6 +102,7 @@ enum rpmQVSources_e {
RPMQV_SPECBUILTRPMS, /*!< ... from pkgs which would be built from spec */
RPMQV_WHATOBSOLETES, /*!< ... from obsoletes db search. */
RPMQV_WHATCONFLICTS, /*!< ... from conflicts db search. */
+ RPMQV_PATH_ALL, /*!< ... from file path db search (all states). */
};
typedef rpmFlags rpmQVSources;
diff --git a/tests/rpmquery.at b/tests/rpmquery.at
index 36c62339a..ad580f664 100644
--- a/tests/rpmquery.at
+++ b/tests/rpmquery.at
@@ -194,6 +194,58 @@ runroot rpm \
AT_CLEANUP
+# ------------------------------
+# query a package by a file
+AT_SETUP([rpm -qf])
+AT_KEYWORDS([query])
+AT_CHECK([
+RPMDB_INIT
+runroot rpm \
+ --nodeps \
+ -i /data/RPMS/hello-1.0-1.i386.rpm
+runroot rpm \
+ -qf /usr/local/bin/hello
+],
+[0],
+[hello-1.0-1.i386
+],
+[])
+AT_CLEANUP
+
+AT_SETUP([rpm -qf on non-installed file])
+AT_KEYWORDS([query])
+AT_CHECK([
+RPMDB_INIT
+runroot rpm \
+ --nodeps \
+ --excludedocs \
+ -i /data/RPMS/hello-1.0-1.i386.rpm
+runroot rpm \
+ -qf /usr/share/doc/hello-1.0/FAQ
+],
+[1],
+[],
+[error: file /usr/share/doc/hello-1.0/FAQ: No such file or directory
+])
+AT_CLEANUP
+
+AT_SETUP([rpm -q --path on non-installed file])
+AT_KEYWORDS([query])
+AT_CHECK([
+RPMDB_INIT
+runroot rpm \
+ --nodeps \
+ --excludedocs \
+ -i /data/RPMS/hello-1.0-1.i386.rpm
+runroot rpm \
+ -q --path /usr/share/doc/hello-1.0/FAQ
+],
+[0],
+[hello-1.0-1.i386
+],
+[])
+AT_CLEANUP
+
# ------------------------------
AT_SETUP([integer array query])
AT_KEYWORDS([query])
--
2.35.1

View File

@ -0,0 +1,798 @@
From 34790c335fe6e5e1099c9320d7b3134398104120 Mon Sep 17 00:00:00 2001
Message-Id: <34790c335fe6e5e1099c9320d7b3134398104120.1624429665.git.pmatilai@redhat.com>
From: Panu Matilainen <pmatilai@redhat.com>
Date: Wed, 23 Jun 2021 08:24:44 +0300
Subject: [PATCH] Add read-only support for sqlite
Based on latest upstream sqlite backend version, chainsaw write support
out and adjust for the infra differences (which there are more than a
few) and add an error message instead.
---
configure.ac | 23 ++
lib/Makefile.am | 6 +
lib/backend/dbi.c | 14 +
lib/backend/dbi.h | 5 +
lib/backend/sqlite.c | 659 +++++++++++++++++++++++++++++++++++++++++++
macros.in | 1 +
6 files changed, 708 insertions(+)
create mode 100644 lib/backend/sqlite.c
diff --git a/configure.ac b/configure.ac
index 3fcb3ff20..e04aced68 100644
--- a/configure.ac
+++ b/configure.ac
@@ -589,6 +589,29 @@ AS_IF([test "$enable_ndb" = yes],[
])
AM_CONDITIONAL([NDB], [test "$enable_ndb" = yes])
+# Check for SQLITE support
+AC_ARG_ENABLE([sqlite],
+ [AS_HELP_STRING([--enable-sqlite=@<:@yes/no/auto@:>@)],
+ [build with sqlite rpm database format support (default=yes)])],
+ [enable_sqlite="$enableval"],
+ [enable_sqlite=yes])
+
+AS_IF([test "x$enable_sqlite" != "xno"], [
+ PKG_CHECK_MODULES([SQLITE], [sqlite3 >= 3.22.0], [have_sqlite=yes], [have_sqlite=no])
+ AS_IF([test "$enable_sqlite" = "yes"], [
+ if test "$have_sqlite" = "no"; then
+ AC_MSG_ERROR([--enable-sqlite specified, but not available])
+ fi
+ ])
+])
+
+if test "x$have_sqlite" = "xyes"; then
+ AC_DEFINE([WITH_SQLITE], [1], [Define if SQLITE is available])
+ SQLITE_REQUIRES=sqlite
+ AC_SUBST(SQLITE_REQUIRES)
+fi
+AM_CONDITIONAL([SQLITE], [test "x$have_sqlite" = "xyes"])
+
#=================
# Check for LMDB support
AC_ARG_ENABLE([lmdb],
diff --git a/lib/Makefile.am b/lib/Makefile.am
index baf3238ee..8a9fe77bd 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -76,6 +76,12 @@ librpm_la_SOURCES += \
backend/ndb/rpmxdb.h
endif
+if SQLITE
+AM_CPPFLAGS += $(SQLITE_CFLAGS)
+librpm_la_LIBADD += $(SQLITE_LIBS)
+librpm_la_SOURCES += backend/sqlite.c
+endif
+
if LMDB
AM_CPPFLAGS += $(LMDB_CFLAGS)
librpm_la_LIBADD += $(LMDB_LIBS)
diff --git a/lib/backend/dbi.c b/lib/backend/dbi.c
index e99a5f2b2..dc3587f58 100644
--- a/lib/backend/dbi.c
+++ b/lib/backend/dbi.c
@@ -48,6 +48,11 @@ dbDetectBackend(rpmdb rdb)
if (!strcmp(db_backend, "ndb")) {
rdb->db_ops = &ndb_dbops;
} else
+#endif
+#ifdef WITH_SQLITE
+ if (!strcmp(db_backend, "sqlite")) {
+ rdb->db_ops = &sqlite_dbops;
+ } else
#endif
{
rdb->db_ops = &db3_dbops;
@@ -75,6 +80,15 @@ dbDetectBackend(rpmdb rdb)
free(path);
#endif
+#ifdef WITH_SQLITE
+ path = rstrscat(NULL, dbhome, "/rpmdb.sqlite", NULL);
+ if (access(path, F_OK) == 0 && rdb->db_ops != &sqlite_dbops) {
+ rdb->db_ops = &sqlite_dbops;
+ rpmlog(RPMLOG_WARNING, _("Found SQLITE rpmdb.sqlite database while attempting %s backend: using sqlite backend.\n"), db_backend);
+ }
+ free(path);
+#endif
+
path = rstrscat(NULL, dbhome, "/Packages", NULL);
if (access(path, F_OK) == 0 && rdb->db_ops != &db3_dbops) {
rdb->db_ops = &db3_dbops;
diff --git a/lib/backend/dbi.h b/lib/backend/dbi.h
index 02f49c8fd..ff2b4f974 100644
--- a/lib/backend/dbi.h
+++ b/lib/backend/dbi.h
@@ -275,6 +275,11 @@ RPM_GNUC_INTERNAL
extern struct rpmdbOps_s lmdb_dbops;
#endif
+#if defined(WITH_SQLITE)
+RPM_GNUC_INTERNAL
+extern struct rpmdbOps_s sqlite_dbops;
+#endif
+
#ifdef __cplusplus
}
#endif
diff --git a/lib/backend/sqlite.c b/lib/backend/sqlite.c
new file mode 100644
index 000000000..3caeba5f0
--- /dev/null
+++ b/lib/backend/sqlite.c
@@ -0,0 +1,659 @@
+#include "system.h"
+
+#include <sqlite3.h>
+#include <fcntl.h>
+
+#include <rpm/rpmlog.h>
+#include <rpm/rpmfileutil.h>
+#include <rpm/rpmmacro.h>
+#include "lib/rpmdb_internal.h"
+
+#include "debug.h"
+
+static const int sleep_ms = 50;
+
+struct dbiCursor_s {
+ sqlite3 *sdb;
+ sqlite3_stmt *stmt;
+ const char *fmt;
+ int flags;
+ rpmTagVal tag;
+ int ctype;
+ struct dbiCursor_s *subc;
+
+ const void *key;
+ unsigned int keylen;
+};
+
+static int sqlexec(sqlite3 *sdb, const char *fmt, ...);
+
+static void rpm_match3(sqlite3_context *sctx, int argc, sqlite3_value **argv)
+{
+ int match = 0;
+ if (argc == 3) {
+ int b1len = sqlite3_value_bytes(argv[0]);
+ int b2len = sqlite3_value_bytes(argv[1]);
+ int n = sqlite3_value_int(argv[2]);
+ if (b1len >= n && b2len >= n) {
+ const char *b1 = sqlite3_value_blob(argv[0]);
+ const char *b2 = sqlite3_value_blob(argv[1]);
+ match = (memcmp(b1, b2, n) == 0);
+ }
+ }
+ sqlite3_result_int(sctx, match);
+}
+
+static void errCb(void *data, int err, const char *msg)
+{
+ rpmdb rdb = data;
+ rpmlog(RPMLOG_WARNING, "%s: %s: %s\n",
+ rdb->db_descr, sqlite3_errstr(err), msg);
+}
+
+static int dbiCursorReset(dbiCursor dbc)
+{
+ if (dbc->stmt) {
+ sqlite3_reset(dbc->stmt);
+ sqlite3_clear_bindings(dbc->stmt);
+ }
+ return 0;
+}
+
+static int dbiCursorResult(dbiCursor dbc)
+{
+ int rc = sqlite3_errcode(dbc->sdb);
+ int err = (rc != SQLITE_OK && rc != SQLITE_DONE && rc != SQLITE_ROW);
+ if (err) {
+ rpmlog(RPMLOG_ERR, "%s: %d: %s\n", sqlite3_sql(dbc->stmt),
+ sqlite3_errcode(dbc->sdb), sqlite3_errmsg(dbc->sdb));
+ }
+ return err ? RPMRC_FAIL : RPMRC_OK;
+}
+
+static int dbiCursorPrep(dbiCursor dbc, const char *fmt, ...)
+{
+ if (dbc->stmt == NULL) {
+ char *cmd = NULL;
+ va_list ap;
+
+ va_start(ap, fmt);
+ cmd = sqlite3_vmprintf(fmt, ap);
+ va_end(ap);
+
+ sqlite3_prepare_v2(dbc->sdb, cmd, -1, &dbc->stmt, NULL);
+ sqlite3_free(cmd);
+ } else {
+ dbiCursorReset(dbc);
+ }
+
+ return dbiCursorResult(dbc);
+}
+
+static int dbiCursorBindPkg(dbiCursor dbc, unsigned int hnum,
+ void *blob, unsigned int bloblen)
+{
+ int rc = 0;
+
+ if (hnum)
+ rc = sqlite3_bind_int(dbc->stmt, 1, hnum);
+ else
+ rc = sqlite3_bind_null(dbc->stmt, 1);
+
+ if (blob) {
+ if (!rc)
+ rc = sqlite3_bind_blob(dbc->stmt, 2, blob, bloblen, NULL);
+ }
+ return dbiCursorResult(dbc);
+}
+
+static int dbiCursorBindIdx(dbiCursor dbc, const void *key, int keylen,
+ dbiIndexItem rec)
+{
+ int rc;
+ if (dbc->ctype == SQLITE_TEXT) {
+ rc = sqlite3_bind_text(dbc->stmt, 1, key, keylen, NULL);
+ } else {
+ rc = sqlite3_bind_blob(dbc->stmt, 1, key, keylen, NULL);
+ }
+
+ if (rec) {
+ if (!rc)
+ rc = sqlite3_bind_int(dbc->stmt, 2, rec->hdrNum);
+ if (!rc)
+ rc = sqlite3_bind_int(dbc->stmt, 3, rec->tagNum);
+ }
+
+ return dbiCursorResult(dbc);
+}
+
+static int sqlite_init(rpmdb rdb, const char * dbhome)
+{
+ int rc = 0;
+ char *dbfile = NULL;
+
+ if (rdb->db_dbenv == NULL) {
+ dbfile = rpmGenPath(dbhome, "rpmdb.sqlite", NULL);
+ sqlite3 *sdb = NULL;
+ int xx, flags = 0;
+ int retry_open = 1;
+
+ free(rdb->db_descr);
+ rdb->db_descr = xstrdup("sqlite");
+
+ if ((rdb->db_mode & O_ACCMODE) == O_RDONLY)
+ flags |= SQLITE_OPEN_READONLY;
+ else {
+ rpmlog(RPMLOG_ERR,
+ _("unable to open sqlite database %s for writing, sqlite support is read-only\n"), dbfile);
+ rc = RPMRC_FAIL;
+ goto exit;
+ }
+
+ while (retry_open--) {
+ xx = sqlite3_open_v2(dbfile, &sdb, flags, NULL);
+ /* Attempt to create if missing, discarding OPEN_READONLY (!) */
+ if (xx == SQLITE_CANTOPEN && (flags & SQLITE_OPEN_READONLY)) {
+ /* Sqlite allocates resources even on failure to open (!) */
+ sqlite3_close(sdb);
+ flags &= ~SQLITE_OPEN_READONLY;
+ flags |= (SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE);
+ retry_open++;
+ }
+ }
+
+ if (xx != SQLITE_OK) {
+ rpmlog(RPMLOG_ERR, _("Unable to open sqlite database %s: %s\n"),
+ dbfile, sqlite3_errstr(xx));
+ rc = 1;
+ goto exit;
+ }
+
+ sqlite3_create_function(sdb, "match", 3,
+ (SQLITE_UTF8|SQLITE_DETERMINISTIC),
+ NULL, rpm_match3, NULL, NULL);
+
+ sqlite3_busy_timeout(sdb, sleep_ms);
+ sqlite3_config(SQLITE_CONFIG_LOG, errCb, rdb);
+
+ sqlexec(sdb, "PRAGMA secure_delete = OFF");
+ sqlexec(sdb, "PRAGMA case_sensitive_like = ON");
+
+ if (sqlite3_db_readonly(sdb, NULL) == 0) {
+ if (sqlexec(sdb, "PRAGMA journal_mode = WAL") == 0) {
+ int one = 1;
+ /* Annoying but necessary to support non-privileged readers */
+ sqlite3_file_control(sdb, NULL, SQLITE_FCNTL_PERSIST_WAL, &one);
+
+ if (!rpmExpandNumeric("%{?_flush_io}"))
+ sqlexec(sdb, "PRAGMA wal_autocheckpoint = 0");
+ }
+ }
+
+ rdb->db_dbenv = sdb;
+ }
+ rdb->db_opens++;
+
+exit:
+ free(dbfile);
+ return rc;
+}
+
+static int sqlite_fini(rpmdb rdb)
+{
+ int rc = 0;
+ if (rdb) {
+ sqlite3 *sdb = rdb->db_dbenv;
+ if (rdb->db_opens > 1) {
+ rdb->db_opens--;
+ } else {
+ if (sqlite3_db_readonly(sdb, NULL) == 0) {
+ sqlexec(sdb, "PRAGMA optimize");
+ sqlexec(sdb, "PRAGMA wal_checkpoint = TRUNCATE");
+ }
+ rdb->db_dbenv = NULL;
+ int xx = sqlite3_close(sdb);
+ rc = (xx != SQLITE_OK);
+ }
+ }
+
+ return rc;
+}
+
+static int sqlexec(sqlite3 *sdb, const char *fmt, ...)
+{
+ int rc = 0;
+ char *cmd = NULL;
+ char *err = NULL;
+ va_list ap;
+
+ va_start(ap, fmt);
+ cmd = sqlite3_vmprintf(fmt, ap);
+ va_end(ap);
+
+ /* sqlite3_exec() doesn't seeem to honor sqlite3_busy_timeout() */
+ while ((rc = sqlite3_exec(sdb, cmd, NULL, NULL, &err)) == SQLITE_BUSY) {
+ usleep(sleep_ms);
+ }
+
+ if (rc)
+ rpmlog(RPMLOG_ERR, "sqlite failure: %s: %s\n", cmd, err);
+ else
+ rpmlog(RPMLOG_DEBUG, "%s: %d\n", cmd, rc);
+
+ sqlite3_free(cmd);
+
+ return rc ? RPMRC_FAIL : RPMRC_OK;
+}
+
+static int dbiExists(dbiIndex dbi)
+{
+ const char *col = (dbi->dbi_type == DBI_PRIMARY) ? "hnum" : "key";
+ const char *tbl = dbi->dbi_file;
+ int rc = sqlite3_table_column_metadata(dbi->dbi_db, NULL, tbl, col,
+ NULL, NULL, NULL, NULL, NULL);
+ return (rc == 0);
+}
+
+static int init_table(dbiIndex dbi, rpmTagVal tag)
+{
+ int rc = 0;
+
+ if (dbiExists(dbi))
+ return 0;
+
+ if (dbi->dbi_type == DBI_PRIMARY) {
+ rc = sqlexec(dbi->dbi_db,
+ "CREATE TABLE IF NOT EXISTS '%q' ("
+ "hnum INTEGER PRIMARY KEY AUTOINCREMENT,"
+ "blob BLOB NOT NULL"
+ ")",
+ dbi->dbi_file);
+ } else {
+ const char *keytype = (rpmTagGetClass(tag) == RPM_STRING_CLASS) ?
+ "TEXT" : "BLOB";
+ rc = sqlexec(dbi->dbi_db,
+ "CREATE TABLE IF NOT EXISTS '%q' ("
+ "key '%q' NOT NULL, "
+ "hnum INTEGER NOT NULL, "
+ "idx INTEGER NOT NULL, "
+ "FOREIGN KEY (hnum) REFERENCES 'Packages'(hnum)"
+ ")",
+ dbi->dbi_file, keytype);
+ }
+ if (!rc)
+ dbi->dbi_flags |= DBI_CREATED;
+
+ return rc;
+}
+
+static int create_index(sqlite3 *sdb, const char *table, const char *col)
+{
+ return sqlexec(sdb,
+ "CREATE INDEX IF NOT EXISTS '%s_%s_idx' ON '%q'(%s ASC)",
+ table, col, table, col);
+}
+
+static int init_index(dbiIndex dbi, rpmTagVal tag)
+{
+ int rc = 0;
+
+ /* Can't create on readonly database, but things will still work */
+ if (sqlite3_db_readonly(dbi->dbi_db, NULL) == 1)
+ return 0;
+
+ if (dbi->dbi_type == DBI_SECONDARY) {
+ int string = (rpmTagGetClass(tag) == RPM_STRING_CLASS);
+ int array = (rpmTagGetReturnType(tag) == RPM_ARRAY_RETURN_TYPE);
+ if (!rc && string)
+ rc = create_index(dbi->dbi_db, dbi->dbi_file, "key");
+ if (!rc && array)
+ rc = create_index(dbi->dbi_db, dbi->dbi_file, "hnum");
+ }
+ return rc;
+}
+
+static int sqlite_Open(rpmdb rdb, rpmDbiTagVal rpmtag, dbiIndex * dbip, int flags)
+{
+ int rc = sqlite_init(rdb, rpmdbHome(rdb));
+
+ if (!rc) {
+ dbiIndex dbi = dbiNew(rdb, rpmtag);
+ dbi->dbi_db = rdb->db_dbenv;
+
+ rc = init_table(dbi, rpmtag);
+
+ if (!rc && !(rdb->db_flags & RPMDB_FLAG_REBUILD))
+ rc = init_index(dbi, rpmtag);
+
+ if (!rc && dbip)
+ *dbip = dbi;
+ else
+ dbiFree(dbi);
+ }
+
+ return rc;
+}
+
+static int sqlite_Close(dbiIndex dbi, unsigned int flags)
+{
+ rpmdb rdb = dbi->dbi_rpmdb;
+ int rc = 0;
+ if (rdb->db_flags & RPMDB_FLAG_REBUILD)
+ rc = init_index(dbi, rpmTagGetValue(dbi->dbi_file));
+ sqlite_fini(dbi->dbi_rpmdb);
+ dbiFree(dbi);
+ return rc;
+}
+
+static int sqlite_Verify(dbiIndex dbi, unsigned int flags)
+{
+ int errors = -1;
+ int key_errors = -1;
+ sqlite3_stmt *s = NULL;
+ const char *cmd = "PRAGMA integrity_check";
+
+ if (dbi->dbi_type == DBI_SECONDARY)
+ return RPMRC_OK;
+
+ if (sqlite3_prepare_v2(dbi->dbi_db, cmd, -1, &s, NULL) == SQLITE_OK) {
+ errors = 0;
+ while (sqlite3_step(s) == SQLITE_ROW) {
+ const char *txt = (const char *)sqlite3_column_text(s, 0);
+ if (!rstreq(txt, "ok")) {
+ errors++;
+ rpmlog(RPMLOG_ERR, "verify: %s\n", txt);
+ }
+ }
+ sqlite3_finalize(s);
+ } else {
+ rpmlog(RPMLOG_ERR, "%s: %s\n", cmd, sqlite3_errmsg(dbi->dbi_db));
+ }
+
+ /* No point checking higher-level errors if low-level errors exist */
+ if (errors)
+ goto exit;
+
+ cmd = "PRAGMA foreign_key_check";
+ if (sqlite3_prepare_v2(dbi->dbi_db, cmd, -1, &s, NULL) == SQLITE_OK) {
+ key_errors = 0;
+ while (sqlite3_step(s) == SQLITE_ROW) {
+ key_errors++;
+ rpmlog(RPMLOG_ERR, "verify key: %s[%lld]\n",
+ sqlite3_column_text(s, 0),
+ sqlite3_column_int64(s, 1));
+ }
+ sqlite3_finalize(s);
+ } else {
+ rpmlog(RPMLOG_ERR, "%s: %s\n", cmd, sqlite3_errmsg(dbi->dbi_db));
+ }
+
+exit:
+
+ return (errors == 0 && key_errors == 0) ? RPMRC_OK : RPMRC_FAIL;
+}
+
+static void sqlite_SetFSync(rpmdb rdb, int enable)
+{
+ if (rdb->db_dbenv) {
+ sqlexec(rdb->db_dbenv,
+ "PRAGMA synchronous = %s", enable ? "FULL" : "OFF");
+ }
+}
+
+static int sqlite_Ctrl(rpmdb rdb, dbCtrlOp ctrl)
+{
+ int rc = 0;
+
+ switch (ctrl) {
+ case DB_CTRL_LOCK_RW:
+ rc = sqlexec(rdb->db_dbenv, "SAVEPOINT 'rwlock'");
+ break;
+ case DB_CTRL_UNLOCK_RW:
+ rc = sqlexec(rdb->db_dbenv, "RELEASE 'rwlock'");
+ break;
+ default:
+ break;
+ }
+
+ return rc;
+}
+
+static dbiCursor sqlite_CursorInit(dbiIndex dbi, unsigned int flags)
+{
+ dbiCursor dbc = xcalloc(1, sizeof(*dbc));
+ dbc->sdb = dbi->dbi_db;
+ dbc->flags = flags;
+ dbc->tag = rpmTagGetValue(dbi->dbi_file);
+ if (rpmTagGetClass(dbc->tag) == RPM_STRING_CLASS) {
+ dbc->ctype = SQLITE_TEXT;
+ } else {
+ dbc->ctype = SQLITE_BLOB;
+ }
+ if (dbc->flags & DBC_WRITE)
+ sqlexec(dbc->sdb, "SAVEPOINT '%s'", dbi->dbi_file);
+ return dbc;
+}
+
+static dbiCursor sqlite_CursorFree(dbiIndex dbi, dbiCursor dbc)
+{
+ if (dbc) {
+ sqlite3_finalize(dbc->stmt);
+ if (dbc->subc)
+ dbiCursorFree(dbi, dbc->subc);
+ if (dbc->flags & DBC_WRITE)
+ sqlexec(dbc->sdb, "RELEASE '%s'", dbi->dbi_file);
+ free(dbc);
+ }
+ return NULL;
+}
+
+static rpmRC sqlite_pkgdbNew(dbiIndex dbi, dbiCursor dbc, unsigned int *hdrNum)
+{
+ return RPMRC_FAIL;
+}
+
+static rpmRC sqlite_pkgdbPut(dbiIndex dbi, dbiCursor dbc, unsigned int hdrNum, unsigned char *hdrBlob, unsigned int hdrLen)
+{
+ return RPMRC_FAIL;
+}
+
+static rpmRC sqlite_pkgdbDel(dbiIndex dbi, dbiCursor dbc, unsigned int hdrNum)
+{
+ return RPMRC_FAIL;
+}
+
+static rpmRC sqlite_stepPkg(dbiCursor dbc, unsigned char **hdrBlob, unsigned int *hdrLen)
+{
+ int rc = sqlite3_step(dbc->stmt);
+
+ if (rc == SQLITE_ROW) {
+ if (hdrLen)
+ *hdrLen = sqlite3_column_bytes(dbc->stmt, 1);
+ if (hdrBlob)
+ *hdrBlob = (void *) sqlite3_column_blob(dbc->stmt, 1);
+ }
+ return rc;
+}
+
+static rpmRC sqlite_pkgdbByKey(dbiIndex dbi, dbiCursor dbc, unsigned int hdrNum, unsigned char **hdrBlob, unsigned int *hdrLen)
+{
+ int rc = dbiCursorPrep(dbc, "SELECT hnum, blob FROM '%q' WHERE hnum=?",
+ dbi->dbi_file);
+
+ if (!rc)
+ rc = dbiCursorBindPkg(dbc, hdrNum, NULL, 0);
+
+ if (!rc)
+ rc = sqlite_stepPkg(dbc, hdrBlob, hdrLen);
+
+ return dbiCursorResult(dbc);
+}
+
+static rpmRC sqlite_pkgdbIter(dbiIndex dbi, dbiCursor dbc,
+ unsigned char **hdrBlob, unsigned int *hdrLen)
+{
+ int rc = RPMRC_OK;
+ if (dbc->stmt == NULL) {
+ rc = dbiCursorPrep(dbc, "SELECT hnum, blob FROM '%q'", dbi->dbi_file);
+ }
+
+ if (!rc)
+ rc = sqlite_stepPkg(dbc, hdrBlob, hdrLen);
+
+ if (rc == SQLITE_DONE) {
+ rc = RPMRC_NOTFOUND;
+ } else {
+ rc = dbiCursorResult(dbc);
+ }
+
+ return rc;
+}
+
+static rpmRC sqlite_pkgdbGet(dbiIndex dbi, dbiCursor dbc, unsigned int hdrNum, unsigned char **hdrBlob, unsigned int *hdrLen)
+{
+ int rc;
+
+ if (hdrNum) {
+ rc = sqlite_pkgdbByKey(dbi, dbc, hdrNum, hdrBlob, hdrLen);
+ } else {
+ rc = sqlite_pkgdbIter(dbi, dbc, hdrBlob, hdrLen);
+ }
+
+ return rc;
+}
+
+static unsigned int sqlite_pkgdbKey(dbiIndex dbi, dbiCursor dbc)
+{
+ return sqlite3_column_int(dbc->stmt, 0);
+}
+
+static rpmRC sqlite_idxdbByKey(dbiIndex dbi, dbiCursor dbc,
+ const char *keyp, size_t keylen, int searchType,
+ dbiIndexSet *set)
+{
+ int rc = RPMRC_NOTFOUND;
+
+ if (searchType == DBC_PREFIX_SEARCH) {
+ rc = dbiCursorPrep(dbc, "SELECT hnum, idx FROM '%q' "
+ "WHERE MATCH(key,'%q',%d) "
+ "ORDER BY key",
+ dbi->dbi_file, keyp, keylen);
+ } else {
+ rc = dbiCursorPrep(dbc, "SELECT hnum, idx FROM '%q' WHERE key=?",
+ dbi->dbi_file);
+ if (!rc)
+ rc = dbiCursorBindIdx(dbc, keyp, keylen, NULL);
+ }
+
+
+ if (!rc) {
+ while ((rc = sqlite3_step(dbc->stmt)) == SQLITE_ROW) {
+ unsigned int hnum = sqlite3_column_int(dbc->stmt, 0);
+ unsigned int tnum = sqlite3_column_int(dbc->stmt, 1);
+
+ if (*set == NULL)
+ *set = dbiIndexSetNew(5);
+ dbiIndexSetAppendOne(*set, hnum, tnum, 0);
+ }
+ }
+
+ if (rc == SQLITE_DONE) {
+ rc = (*set) ? RPMRC_OK : RPMRC_NOTFOUND;
+ } else {
+ rc = dbiCursorResult(dbc);
+ }
+
+ return rc;
+}
+
+static rpmRC sqlite_idxdbIter(dbiIndex dbi, dbiCursor dbc, dbiIndexSet *set)
+{
+ int rc = RPMRC_OK;
+
+ if (dbc->stmt == NULL) {
+ rc = dbiCursorPrep(dbc, "SELECT DISTINCT key FROM '%q' ORDER BY key",
+ dbi->dbi_file);
+ if (set)
+ dbc->subc = dbiCursorInit(dbi, 0);
+ }
+
+ if (!rc)
+ rc = sqlite3_step(dbc->stmt);
+
+ if (rc == SQLITE_ROW) {
+ if (dbc->ctype == SQLITE_TEXT) {
+ dbc->key = sqlite3_column_text(dbc->stmt, 0);
+ } else {
+ dbc->key = sqlite3_column_blob(dbc->stmt, 0);
+ }
+ dbc->keylen = sqlite3_column_bytes(dbc->stmt, 0);
+ if (dbc->subc) {
+ rc = sqlite_idxdbByKey(dbi, dbc->subc, dbc->key, dbc->keylen,
+ DBC_NORMAL_SEARCH, set);
+ } else {
+ rc = RPMRC_OK;
+ }
+ } else if (rc == SQLITE_DONE) {
+ rc = RPMRC_NOTFOUND;
+ } else {
+ rc = dbiCursorResult(dbc);
+ }
+
+ return rc;
+}
+
+static rpmRC sqlite_idxdbGet(dbiIndex dbi, dbiCursor dbc, const char *keyp, size_t keylen, dbiIndexSet *set, int searchType)
+{
+ int rc;
+ if (keyp) {
+ rc = sqlite_idxdbByKey(dbi, dbc, keyp, keylen, searchType, set);
+ } else {
+ rc = sqlite_idxdbIter(dbi, dbc, set);
+ }
+
+ return rc;
+}
+
+static rpmRC sqlite_idxdbPut(dbiIndex dbi, dbiCursor dbc, const char *keyp, size_t keylen, dbiIndexItem rec)
+{
+ return RPMRC_FAIL;
+}
+
+static rpmRC sqlite_idxdbDel(dbiIndex dbi, dbiCursor dbc, const char *keyp, size_t keylen, dbiIndexItem rec)
+{
+ return RPMRC_FAIL;
+}
+
+static const void * sqlite_idxdbKey(dbiIndex dbi, dbiCursor dbc, unsigned int *keylen)
+{
+ const void *key = NULL;
+ if (dbc) {
+ key = dbc->key;
+ if (key && keylen)
+ *keylen = dbc->keylen;
+ }
+ return key;
+}
+
+struct rpmdbOps_s sqlite_dbops = {
+ .open = sqlite_Open,
+ .close = sqlite_Close,
+ .verify = sqlite_Verify,
+ .setFSync = sqlite_SetFSync,
+ .ctrl = sqlite_Ctrl,
+
+ .cursorInit = sqlite_CursorInit,
+ .cursorFree = sqlite_CursorFree,
+
+ .pkgdbPut = sqlite_pkgdbPut,
+ .pkgdbDel = sqlite_pkgdbDel,
+ .pkgdbGet = sqlite_pkgdbGet,
+ .pkgdbKey = sqlite_pkgdbKey,
+ .pkgdbNew = sqlite_pkgdbNew,
+
+ .idxdbGet = sqlite_idxdbGet,
+ .idxdbPut = sqlite_idxdbPut,
+ .idxdbDel = sqlite_idxdbDel,
+ .idxdbKey = sqlite_idxdbKey
+};
+
diff --git a/macros.in b/macros.in
index a6069ee4d..9ad3d60ef 100644
--- a/macros.in
+++ b/macros.in
@@ -620,6 +620,7 @@ package or when debugging this package.\
# bdb Berkeley DB
# lmdb Lightning Memory-mapped Database
# ndb new data base format
+# sqlite Sqlite database (read-only in this version!)
#
%_db_backend bdb
--
2.31.1

View File

@ -0,0 +1,12 @@
diff -up rpm-4.14.3/lib/header.c.orig rpm-4.14.3/lib/header.c
--- rpm-4.14.3/lib/header.c.orig 2020-04-28 14:50:11.816399041 +0200
+++ rpm-4.14.3/lib/header.c 2021-02-03 16:47:23.567245743 +0100
@@ -1910,7 +1910,7 @@ rpmRC hdrblobRead(FD_t fd, int magic, in
if (regionTag == RPMTAG_HEADERSIGNATURES) {
il_max = 32;
- dl_max = 8192;
+ dl_max = 64 * 1024 * 1024;
}
memset(block, 0, sizeof(block));

View File

@ -0,0 +1,167 @@
From 534fd1f0c84b12ba6080a46e07c57ef913c77cba Mon Sep 17 00:00:00 2001
From: Radovan Sroka <rsroka@redhat.com>
Date: Thu, 25 Aug 2022 15:38:01 +0200
Subject: [PATCH] fapolicyd: Make write() nonblocking
- switch to read only and non blocking mode for pipe
- add 1 minute loop to wait for pipe to reappear
Sometimes during the system update/upgrade fapolicyd
get restarted e.g. when systemd gets updated.
That can lead to the situation where fapolicyd pipe
has been removed and created again.
In such cases rpm-plugin-fapolicyd gets stuck on
write() to the pipe which does not exist anymore.
After switching to non blocking file descriptor
we can try to reopen the pipe if there is an error
from write(). Assuming that a new pipe should appear
when fapolicyd daemon starts again.
If not then after 1 minute of waiting we expect
fapolicyd daemon to be not active and we let the
transaction continue.
Signed-off-by: Radovan Sroka <rsroka@redhat.com>
---
plugins/fapolicyd.c | 74 +++++++++++++++++++++++++++++++++++++++------
1 file changed, 65 insertions(+), 9 deletions(-)
diff --git a/plugins/fapolicyd.c b/plugins/fapolicyd.c
index 1ff50c30f..6c6322941 100644
--- a/plugins/fapolicyd.c
+++ b/plugins/fapolicyd.c
@@ -27,7 +27,7 @@ static rpmRC open_fifo(struct fapolicyd_data* state)
int fd = -1;
struct stat s;
- fd = open(state->fifo_path, O_RDWR);
+ fd = open(state->fifo_path, O_WRONLY|O_NONBLOCK);
if (fd == -1) {
rpmlog(RPMLOG_DEBUG, "Open: %s -> %s\n", state->fifo_path, strerror(errno));
goto bad;
@@ -55,15 +55,26 @@ static rpmRC open_fifo(struct fapolicyd_data* state)
}
state->fd = fd;
+
/* considering success */
return RPMRC_OK;
bad:
if (fd >= 0)
close(fd);
+
+ state->fd = -1;
return RPMRC_FAIL;
}
+static void close_fifo(struct fapolicyd_data* state)
+{
+ if (state->fd > 0)
+ (void) close(state->fd);
+
+ state->fd = -1;
+}
+
static rpmRC write_fifo(struct fapolicyd_data* state, const char * str)
{
ssize_t len = strlen(str);
@@ -86,6 +97,54 @@ static rpmRC write_fifo(struct fapolicyd_data* state, const char * str)
return RPMRC_FAIL;
}
+static void try_to_write_to_fifo(struct fapolicyd_data* state, const char * str)
+{
+ int reload = 0;
+ int printed = 0;
+
+ /* 1min/60s */
+ const int timeout = 60;
+
+ /* wait up to X seconds */
+ for (int i = 0; i < timeout; i++) {
+
+ if (reload) {
+ if (!printed) {
+ rpmlog(RPMLOG_WARNING, "rpm-plugin-fapolicyd: waiting for the service connection to resume, it can take up to %d seconds\n", timeout);
+ printed = 1;
+ }
+
+ (void) close_fifo(state);
+ (void) open_fifo(state);
+ }
+
+ if (state->fd >= 0) {
+ if (write_fifo(state, str) == RPMRC_OK) {
+
+ /* write was successful after few reopens */
+ if (reload)
+ rpmlog(RPMLOG_WARNING, "rpm-plugin-fapolicyd: the service connection has resumed\n");
+
+ break;
+ }
+ }
+
+ /* failed write or reopen */
+ reload = 1;
+ sleep(1);
+
+ /* the last iteration */
+ /* consider failure */
+ if (i == timeout-1) {
+ rpmlog(RPMLOG_WARNING, "rpm-plugin-fapolicyd: the service connection has not resumed\n");
+ rpmlog(RPMLOG_WARNING, "rpm-plugin-fapolicyd: continuing without the service\n");
+ }
+
+ }
+
+}
+
+
static rpmRC fapolicyd_init(rpmPlugin plugin, rpmts ts)
{
if (rpmtsFlags(ts) & (RPMTRANS_FLAG_TEST|RPMTRANS_FLAG_BUILD_PROBS))
@@ -102,10 +161,7 @@ static rpmRC fapolicyd_init(rpmPlugin plugin, rpmts ts)
static void fapolicyd_cleanup(rpmPlugin plugin)
{
- if (fapolicyd_state.fd > 0)
- (void) close(fapolicyd_state.fd);
-
- fapolicyd_state.fd = -1;
+ (void) close_fifo(&fapolicyd_state);
}
static rpmRC fapolicyd_tsm_post(rpmPlugin plugin, rpmts ts, int res)
@@ -116,9 +172,9 @@ static rpmRC fapolicyd_tsm_post(rpmPlugin plugin, rpmts ts, int res)
/* we are ready */
if (fapolicyd_state.fd > 0) {
/* send a signal that transaction is over */
- (void) write_fifo(&fapolicyd_state, "1\n");
+ (void) try_to_write_to_fifo(&fapolicyd_state, "1\n");
/* flush cache */
- (void) write_fifo(&fapolicyd_state, "2\n");
+ (void) try_to_write_to_fifo(&fapolicyd_state, "2\n");
}
end:
@@ -133,7 +189,7 @@ static rpmRC fapolicyd_scriptlet_pre(rpmPlugin plugin, const char *s_name,
if (fapolicyd_state.changed_files > 0) {
/* send signal to flush cache */
- (void) write_fifo(&fapolicyd_state, "2\n");
+ (void) try_to_write_to_fifo(&fapolicyd_state, "2\n");
/* optimize flushing */
/* flush only when there was an actual change */
@@ -176,7 +232,7 @@ static rpmRC fapolicyd_fsm_file_prepare(rpmPlugin plugin, rpmfi fi,
char * sha = rpmfiFDigestHex(fi, NULL);
snprintf(buffer, 4096, "%s %lu %64s\n", dest, size, sha);
- (void) write_fifo(&fapolicyd_state, buffer);
+ (void) try_to_write_to_fifo(&fapolicyd_state, buffer);
free(sha);
--
2.37.3

View File

@ -0,0 +1,101 @@
diff -up rpm-4.14.3/lib/rpmscript.c.orig rpm-4.14.3/lib/rpmscript.c
--- rpm-4.14.3/lib/rpmscript.c.orig 2021-02-08 14:07:44.527197946 +0100
+++ rpm-4.14.3/lib/rpmscript.c 2021-02-08 14:09:05.732749080 +0100
@@ -46,27 +46,27 @@ struct scriptInfo_s {
};
static const struct scriptInfo_s scriptInfo[] = {
- { RPMSCRIPT_PREIN, "%prein", 0,
+ { RPMSCRIPT_PREIN, "prein", 0,
RPMTAG_PREIN, RPMTAG_PREINPROG, RPMTAG_PREINFLAGS },
- { RPMSCRIPT_PREUN, "%preun", 0,
+ { RPMSCRIPT_PREUN, "preun", 0,
RPMTAG_PREUN, RPMTAG_PREUNPROG, RPMTAG_PREUNFLAGS },
- { RPMSCRIPT_POSTIN, "%post", 0,
+ { RPMSCRIPT_POSTIN, "post", 0,
RPMTAG_POSTIN, RPMTAG_POSTINPROG, RPMTAG_POSTINFLAGS },
- { RPMSCRIPT_POSTUN, "%postun", 0,
+ { RPMSCRIPT_POSTUN, "postun", 0,
RPMTAG_POSTUN, RPMTAG_POSTUNPROG, RPMTAG_POSTUNFLAGS },
- { RPMSCRIPT_PRETRANS, "%pretrans", 0,
+ { RPMSCRIPT_PRETRANS, "pretrans", 0,
RPMTAG_PRETRANS, RPMTAG_PRETRANSPROG, RPMTAG_PRETRANSFLAGS },
- { RPMSCRIPT_POSTTRANS, "%posttrans", 0,
+ { RPMSCRIPT_POSTTRANS, "posttrans", 0,
RPMTAG_POSTTRANS, RPMTAG_POSTTRANSPROG, RPMTAG_POSTTRANSFLAGS },
- { RPMSCRIPT_TRIGGERPREIN, "%triggerprein", RPMSENSE_TRIGGERPREIN,
+ { RPMSCRIPT_TRIGGERPREIN, "triggerprein", RPMSENSE_TRIGGERPREIN,
RPMTAG_TRIGGERPREIN, 0, 0 },
- { RPMSCRIPT_TRIGGERUN, "%triggerun", RPMSENSE_TRIGGERUN,
+ { RPMSCRIPT_TRIGGERUN, "triggerun", RPMSENSE_TRIGGERUN,
RPMTAG_TRIGGERUN, 0, 0 },
- { RPMSCRIPT_TRIGGERIN, "%triggerin", RPMSENSE_TRIGGERIN,
+ { RPMSCRIPT_TRIGGERIN, "triggerin", RPMSENSE_TRIGGERIN,
RPMTAG_TRIGGERIN, 0, 0 },
- { RPMSCRIPT_TRIGGERPOSTUN, "%triggerpostun", RPMSENSE_TRIGGERPOSTUN,
+ { RPMSCRIPT_TRIGGERPOSTUN, "triggerpostun", RPMSENSE_TRIGGERPOSTUN,
RPMTAG_TRIGGERPOSTUN, 0, 0 },
- { RPMSCRIPT_VERIFY, "%verify", 0,
+ { RPMSCRIPT_VERIFY, "verify", 0,
RPMTAG_VERIFYSCRIPT, RPMTAG_VERIFYSCRIPTPROG, RPMTAG_VERIFYSCRIPTFLAGS},
{ 0, "unknown", 0,
RPMTAG_NOT_FOUND, RPMTAG_NOT_FOUND, RPMTAG_NOT_FOUND }
@@ -457,7 +457,7 @@ static const char * tag2sln(rpmTagVal ta
}
static rpmScript rpmScriptNew(Header h, rpmTagVal tag, const char *body,
- rpmscriptFlags flags)
+ rpmscriptFlags flags, const char *prefix)
{
char *nevra = headerGetAsString(h, RPMTAG_NEVRA);
rpmScript script = xcalloc(1, sizeof(*script));
@@ -465,7 +465,7 @@ static rpmScript rpmScriptNew(Header h,
script->type = getScriptType(tag);
script->flags = flags;
script->body = (body != NULL) ? xstrdup(body) : NULL;
- rasprintf(&script->descr, "%s(%s)", tag2sln(tag), nevra);
+ rasprintf(&script->descr, "%%%s%s(%s)", prefix, tag2sln(tag), nevra);
/* macros need to be expanded before possible queryformat */
if (script->body && (script->flags & RPMSCRIPT_FLAG_EXPAND)) {
@@ -556,6 +556,7 @@ rpmScript rpmScriptFromTriggerTag(Header
rpmScript script = NULL;
struct rpmtd_s tscripts, tprogs, tflags;
headerGetFlags hgflags = HEADERGET_MINMEM;
+ const char *prefix = "";
switch (tm) {
case RPMSCRIPT_NORMALTRIGGER:
@@ -567,11 +568,13 @@ rpmScript rpmScriptFromTriggerTag(Header
headerGet(h, RPMTAG_FILETRIGGERSCRIPTS, &tscripts, hgflags);
headerGet(h, RPMTAG_FILETRIGGERSCRIPTPROG, &tprogs, hgflags);
headerGet(h, RPMTAG_FILETRIGGERSCRIPTFLAGS, &tflags, hgflags);
+ prefix = "file";
break;
case RPMSCRIPT_TRANSFILETRIGGER:
headerGet(h, RPMTAG_TRANSFILETRIGGERSCRIPTS, &tscripts, hgflags);
headerGet(h, RPMTAG_TRANSFILETRIGGERSCRIPTPROG, &tprogs, hgflags);
headerGet(h, RPMTAG_TRANSFILETRIGGERSCRIPTFLAGS, &tflags, hgflags);
+ prefix = "transfile";
break;
}
@@ -582,7 +585,8 @@ rpmScript rpmScriptFromTriggerTag(Header
if (rpmtdSetIndex(&tflags, ix) >= 0)
sflags = rpmtdGetNumber(&tflags);
- script = rpmScriptNew(h, triggerTag, rpmtdGetString(&tscripts), sflags);
+ script = rpmScriptNew(h, triggerTag,
+ rpmtdGetString(&tscripts), sflags, prefix);
/* hack up a hge-style NULL-terminated array */
script->args = xmalloc(2 * sizeof(*script->args) + strlen(prog) + 1);
@@ -608,7 +612,7 @@ rpmScript rpmScriptFromTag(Header h, rpm
script = rpmScriptNew(h, scriptTag,
headerGetString(h, scriptTag),
- headerGetNumber(h, getFlagTag(scriptTag)));
+ headerGetNumber(h, getFlagTag(scriptTag)), "");
if (headerGet(h, progTag, &prog, (HEADERGET_ALLOC|HEADERGET_ARGV))) {
script->args = prog.data;

View File

@ -0,0 +1,184 @@
From f17aa638649fb8de730fecdbc906dc869b626ba5 Mon Sep 17 00:00:00 2001
From: Panu Matilainen <pmatilai@redhat.com>
Date: Tue, 16 Nov 2021 11:49:18 +0200
Subject: [PATCH 1/2] Fix spurious %transfiletriggerpostun execution
(RhBug:2023311)
If a package has multiple %transfiletriggerpostun triggers, any one
of them matching would cause all of them to run, due to disconnect
in the intel gathering stage: we'd gather all the headers with matching
files into a lump, and then add any postun triggers found in them,
but this loses the triggering file information and causes all postuns
to run.
The triggers need to be added while looping over the file matches,
like runFileTriggers() does. Doing so actually simplifies the code.
These should really be unified to use the same code, but leaving
that exercise to another rainy day.
---
lib/rpmtriggers.c | 64 +++++++++++++++++++++++------------------------
1 file changed, 31 insertions(+), 33 deletions(-)
diff --git a/lib/rpmtriggers.c b/lib/rpmtriggers.c
index 0827af0c2..dc457f7cc 100644
--- a/lib/rpmtriggers.c
+++ b/lib/rpmtriggers.c
@@ -97,19 +97,37 @@ static void rpmtriggersSortAndUniq(rpmtriggers trigs)
}
}
+static void addTriggers(rpmts ts, Header trigH, rpmsenseFlags filter)
+{
+ int tix = 0;
+ rpmds ds;
+ rpmds triggers = rpmdsNew(trigH, RPMTAG_TRANSFILETRIGGERNAME, 0);
+
+ while ((ds = rpmdsFilterTi(triggers, tix))) {
+ if ((rpmdsNext(ds) >= 0) && (rpmdsFlags(ds) & filter)) {
+ struct rpmtd_s priorities;
+
+ if (headerGet(trigH, RPMTAG_TRANSFILETRIGGERPRIORITIES,
+ &priorities, HEADERGET_MINMEM)) {
+ rpmtdSetIndex(&priorities, tix);
+ rpmtriggersAdd(ts->trigs2run, headerGetInstance(trigH),
+ tix, *rpmtdGetUint32(&priorities));
+ }
+ }
+ rpmdsFree(ds);
+ tix++;
+ }
+ rpmdsFree(triggers);
+}
+
void rpmtriggersPrepPostUnTransFileTrigs(rpmts ts, rpmte te)
{
- rpmdbMatchIterator mi;
rpmdbIndexIterator ii;
- Header trigH;
const void *key;
size_t keylen;
rpmfiles files;
- rpmds rpmdsTriggers;
- rpmds rpmdsTrigger;
ii = rpmdbIndexIteratorInit(rpmtsGetRdb(ts), RPMDBI_TRANSFILETRIGGERNAME);
- mi = rpmdbNewIterator(rpmtsGetRdb(ts), RPMDBI_PACKAGES);
files = rpmteFiles(te);
/* Iterate over file triggers in rpmdb */
@@ -121,39 +139,19 @@ void rpmtriggersPrepPostUnTransFileTrigs(rpmts ts, rpmte te)
rpmfi fi = rpmfilesFindPrefix(files, pfx);
while (rpmfiNext(fi) >= 0) {
if (RPMFILE_IS_INSTALLED(rpmfiFState(fi))) {
- /* If yes then store it */
- rpmdbAppendIterator(mi, rpmdbIndexIteratorPkgOffsets(ii),
- rpmdbIndexIteratorNumPkgs(ii));
- break;
+ unsigned int npkg = rpmdbIndexIteratorNumPkgs(ii);
+ const unsigned int *offs = rpmdbIndexIteratorPkgOffsets(ii);
+ /* Save any matching postun triggers */
+ for (int i = 0; i < npkg; i++) {
+ Header h = rpmdbGetHeaderAt(rpmtsGetRdb(ts), offs[i]);
+ addTriggers(ts, h, RPMSENSE_TRIGGERPOSTUN);
+ headerFree(h);
+ }
}
}
rpmfiFree(fi);
}
rpmdbIndexIteratorFree(ii);
-
- if (rpmdbGetIteratorCount(mi)) {
- /* Filter triggers and save only trans postun triggers into ts */
- while ((trigH = rpmdbNextIterator(mi)) != NULL) {
- int tix = 0;
- rpmdsTriggers = rpmdsNew(trigH, RPMTAG_TRANSFILETRIGGERNAME, 0);
- while ((rpmdsTrigger = rpmdsFilterTi(rpmdsTriggers, tix))) {
- if ((rpmdsNext(rpmdsTrigger) >= 0) &&
- (rpmdsFlags(rpmdsTrigger) & RPMSENSE_TRIGGERPOSTUN)) {
- struct rpmtd_s priorities;
-
- headerGet(trigH, RPMTAG_TRANSFILETRIGGERPRIORITIES,
- &priorities, HEADERGET_MINMEM);
- rpmtdSetIndex(&priorities, tix);
- rpmtriggersAdd(ts->trigs2run, rpmdbGetIteratorOffset(mi),
- tix, *rpmtdGetUint32(&priorities));
- }
- rpmdsFree(rpmdsTrigger);
- tix++;
- }
- rpmdsFree(rpmdsTriggers);
- }
- }
- rpmdbFreeIterator(mi);
rpmfilesFree(files);
}
--
2.35.1
From e617e7c550d3523998707c55f96b37ede2c48c78 Mon Sep 17 00:00:00 2001
From: Panu Matilainen <pmatilai@redhat.com>
Date: Wed, 2 Feb 2022 13:46:23 +0200
Subject: [PATCH 2/2] Really fix spurious %transfiletriggerpostun execution
(RhBug:2023311)
Commit b3d672a5523dfec033160e5cc866432a0e808649 got the base reasoning
in the ballpark but the code all wrong, introducing a severe performance
regression without actually fixing what it claimed to.
The missing incredient is actually comparing the current prefix with the
triggers in matched package (trying to describe this makes my head
spin): a package may have multiple triggers on multiple prefixes and
we need to make sure we only execute triggers of this type, from this
prefix.
This stuff really needs more and better testcases.
Fixes: b3d672a5523dfec033160e5cc866432a0e808649
---
lib/rpmtriggers.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/lib/rpmtriggers.c b/lib/rpmtriggers.c
index dc457f7cc..c652981be 100644
--- a/lib/rpmtriggers.c
+++ b/lib/rpmtriggers.c
@@ -97,14 +97,16 @@ static void rpmtriggersSortAndUniq(rpmtriggers trigs)
}
}
-static void addTriggers(rpmts ts, Header trigH, rpmsenseFlags filter)
+static void addTriggers(rpmts ts, Header trigH, rpmsenseFlags filter,
+ const char *prefix)
{
int tix = 0;
rpmds ds;
rpmds triggers = rpmdsNew(trigH, RPMTAG_TRANSFILETRIGGERNAME, 0);
while ((ds = rpmdsFilterTi(triggers, tix))) {
- if ((rpmdsNext(ds) >= 0) && (rpmdsFlags(ds) & filter)) {
+ if ((rpmdsNext(ds) >= 0) && (rpmdsFlags(ds) & filter) &&
+ strcmp(prefix, rpmdsN(ds)) == 0) {
struct rpmtd_s priorities;
if (headerGet(trigH, RPMTAG_TRANSFILETRIGGERPRIORITIES,
@@ -141,12 +143,13 @@ void rpmtriggersPrepPostUnTransFileTrigs(rpmts ts, rpmte te)
if (RPMFILE_IS_INSTALLED(rpmfiFState(fi))) {
unsigned int npkg = rpmdbIndexIteratorNumPkgs(ii);
const unsigned int *offs = rpmdbIndexIteratorPkgOffsets(ii);
- /* Save any matching postun triggers */
+ /* Save any postun triggers matching this prefix */
for (int i = 0; i < npkg; i++) {
Header h = rpmdbGetHeaderAt(rpmtsGetRdb(ts), offs[i]);
- addTriggers(ts, h, RPMSENSE_TRIGGERPOSTUN);
+ addTriggers(ts, h, RPMSENSE_TRIGGERPOSTUN, pfx);
headerFree(h);
}
+ break;
}
}
rpmfiFree(fi);
--
2.35.1

View File

@ -0,0 +1,100 @@
commit 8f4b3c3cab8922a2022b9e47c71f1ecf906077ef
Author: Demi Marie Obenour <athena@invisiblethingslab.com>
Date: Mon Feb 8 16:05:01 2021 -0500
hdrblobInit() needs bounds checks too
Users can pass untrusted data to hdrblobInit() and it must be robust
against this.
diff --git a/lib/header.c b/lib/header.c
index ea39e679f..ebba9c2b0 100644
--- a/lib/header.c
+++ b/lib/header.c
@@ -11,6 +11,7 @@
#include "system.h"
#include <netdb.h>
#include <errno.h>
+#include <inttypes.h>
#include <rpm/rpmtypes.h>
#include <rpm/rpmstring.h>
#include "lib/header_internal.h"
@@ -1912,6 +1913,25 @@ hdrblob hdrblobFree(hdrblob blob)
return NULL;
}
+static rpmRC hdrblobVerifyLengths(rpmTagVal regionTag, uint32_t il, uint32_t dl,
+ char **emsg) {
+ uint32_t il_max = HEADER_TAGS_MAX;
+ uint32_t dl_max = HEADER_DATA_MAX;
+ if (regionTag == RPMTAG_HEADERSIGNATURES) {
+ il_max = 32;
+ dl_max = 64 * 1024 * 1024;
+ }
+ if (hdrchkRange(il_max, il)) {
+ rasprintf(emsg, _("hdr tags: BAD, no. of tags(%" PRIu32 ") out of range"), il);
+ return RPMRC_FAIL;
+ }
+ if (hdrchkRange(dl_max, dl)) {
+ rasprintf(emsg, _("hdr data: BAD, no. of bytes(%" PRIu32 ") out of range"), dl);
+ return RPMRC_FAIL;
+ }
+ return RPMRC_OK;
+}
+
rpmRC hdrblobRead(FD_t fd, int magic, int exact_size, rpmTagVal regionTag, hdrblob blob, char **emsg)
{
int32_t block[4];
@@ -1924,13 +1944,6 @@ rpmRC hdrblobRead(FD_t fd, int magic, int exact_size, rpmTagVal regionTag, hdrbl
size_t nb;
rpmRC rc = RPMRC_FAIL; /* assume failure */
int xx;
- int32_t il_max = HEADER_TAGS_MAX;
- int32_t dl_max = HEADER_DATA_MAX;
-
- if (regionTag == RPMTAG_HEADERSIGNATURES) {
- il_max = 32;
- dl_max = 64 * 1024 * 1024;
- }
memset(block, 0, sizeof(block));
if ((xx = Freadall(fd, bs, blen)) != blen) {
@@ -1943,15 +1956,9 @@ rpmRC hdrblobRead(FD_t fd, int magic, int exact_size, rpmTagVal regionTag, hdrbl
goto exit;
}
il = ntohl(block[2]);
- if (hdrchkRange(il_max, il)) {
- rasprintf(emsg, _("hdr tags: BAD, no. of tags(%d) out of range"), il);
- goto exit;
- }
dl = ntohl(block[3]);
- if (hdrchkRange(dl_max, dl)) {
- rasprintf(emsg, _("hdr data: BAD, no. of bytes(%d) out of range"), dl);
+ if (hdrblobVerifyLengths(regionTag, il, dl, emsg))
goto exit;
- }
nb = (il * sizeof(struct entryInfo_s)) + dl;
uc = sizeof(il) + sizeof(dl) + nb;
@@ -1995,11 +2002,18 @@ rpmRC hdrblobInit(const void *uh, size_t uc,
struct hdrblob_s *blob, char **emsg)
{
rpmRC rc = RPMRC_FAIL;
-
memset(blob, 0, sizeof(*blob));
+ if (uc && uc < 8) {
+ rasprintf(emsg, _("hdr length: BAD"));
+ goto exit;
+ }
+
blob->ei = (int32_t *) uh; /* discards const */
- blob->il = ntohl(blob->ei[0]);
- blob->dl = ntohl(blob->ei[1]);
+ blob->il = ntohl((uint32_t)(blob->ei[0]));
+ blob->dl = ntohl((uint32_t)(blob->ei[1]));
+ if (hdrblobVerifyLengths(regionTag, blob->il, blob->dl, emsg) != RPMRC_OK)
+ goto exit;
+
blob->pe = (entryInfo) &(blob->ei[2]);
blob->pvlen = sizeof(blob->il) + sizeof(blob->dl) +
(blob->il * sizeof(*blob->pe)) + blob->dl;

View File

@ -0,0 +1,327 @@
commit c7d7c5acd0c14d0450016887cba1d86483086794
Author: Michal Domonkos <mdomonko@redhat.com>
Date: Mon Jun 21 10:05:10 2021 +0200
Add quoting to literal curly brackets
These curly brackets are already treated as literals by the shell, so
let's make that explicit for clarity, and silence a ShellCheck warning
at the same time.
More info: https://github.com/koalaman/shellcheck/wiki/SC1083
Found by ShellCheck.
diff -up rpm-4.16.1.3/scripts/check-rpaths-worker.orig rpm-4.16.1.3/scripts/check-rpaths-worker
--- rpm-4.16.1.3/scripts/check-rpaths-worker.orig 2021-06-29 15:34:31.671003589 +0200
+++ rpm-4.16.1.3/scripts/check-rpaths-worker 2021-06-29 15:34:51.993414093 +0200
@@ -120,13 +120,13 @@ for i; do
(/lib64/*|/usr/lib64/*|/usr/X11R6/lib64/*|/usr/local/lib64/*)
badness=0;;
- (\$ORIGIN|\${ORIGINX}|\$ORIGIN/*|\${ORIGINX}/*)
+ (\$ORIGIN|\$\{ORIGINX\}|\$ORIGIN/*|\$\{ORIGINX\}/*)
test $allow_ORIGIN -eq 0 && badness=8 || {
badness=0
new_allow_ORIGIN=1
}
;;
- (/*\$PLATFORM*|/*\${PLATFORM}*|/*\$LIB*|/*\${LIB}*)
+ (/*\$PLATFORM*|/*\$\{PLATFORM\}*|/*\$LIB*|/*\$\{LIB\}*)
badness=0;;
(/lib|/usr/lib|/usr/X11R6/lib)
From d8dc4fd37b1d90cd97de7fcf484d449ec132c9b3 Mon Sep 17 00:00:00 2001
From: Michal Domonkos <mdomonko@redhat.com>
Date: Wed, 9 Jun 2021 21:31:40 +0200
Subject: [PATCH 1/7] Fix memory leak in sqlexec()
Callers are supposed to free the error strings themselves:
https://www.sqlite.org/capi3ref.html#sqlite3_exec
Found by Coverity.
---
lib/backend/sqlite.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/lib/backend/sqlite.c b/lib/backend/sqlite.c
index 7c2de45aa..dbefeb163 100644
--- a/lib/backend/sqlite.c
+++ b/lib/backend/sqlite.c
@@ -233,6 +233,7 @@ static int sqlexec(sqlite3 *sdb, const char *fmt, ...)
rpmlog(RPMLOG_DEBUG, "%s: %d\n", cmd, rc);
sqlite3_free(cmd);
+ sqlite3_free(err);
return rc ? RPMRC_FAIL : RPMRC_OK;
}
--
2.31.1
From 5baf73feb4951cc3b3f553a4b18d3b3599cbf87c Mon Sep 17 00:00:00 2001
From: Michal Domonkos <mdomonko@redhat.com>
Date: Fri, 25 Jun 2021 11:21:46 +0200
Subject: [PATCH 2/7] Always free the arg list passed to rpmGlob()
Even though the actual implementation of rpmGlob() does not allocate the
passed arg list (av) if the return code (rc) is non-zero or arg count
(ac) is 0, it's the responsibility of the caller (rpmInstall() here) to
free that memory, so make sure we do that irrespectively of the above
conditions.
Found by Coverity.
---
lib/rpminstall.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/lib/rpminstall.c b/lib/rpminstall.c
index 724126e94..302ec0ba1 100644
--- a/lib/rpminstall.c
+++ b/lib/rpminstall.c
@@ -461,6 +461,7 @@ int rpmInstall(rpmts ts, struct rpmInstallArguments_s * ia, ARGV_t fileArgv)
rpmlog(RPMLOG_ERR, _("File not found by glob: %s\n"), *eiu->fnp);
}
eiu->numFailed++;
+ argvFree(av);
continue;
}
--
2.31.1
From 3c8b01b67ec907afaaffe71691fa41b878578527 Mon Sep 17 00:00:00 2001
From: Michal Domonkos <mdomonko@redhat.com>
Date: Mon, 14 Jun 2021 10:21:25 +0200
Subject: [PATCH 3/7] Fix resource leak in Fts_children()
This function is not used anywhere within our codebase (and neither is
it part of the public API) so it's basically a no-op... Still, rather
than yanking it completely, let's just silence the Coverity error here.
Found by Coverity.
---
misc/fts.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/misc/fts.c b/misc/fts.c
index d3ebb2946..caf27495d 100644
--- a/misc/fts.c
+++ b/misc/fts.c
@@ -585,8 +585,10 @@ Fts_children(FTS * sp, int instr)
if ((fd = __open(".", O_RDONLY, 0)) < 0)
return (NULL);
sp->fts_child = fts_build(sp, instr);
- if (__fchdir(fd))
+ if (__fchdir(fd)) {
+ (void)__close(fd);
return (NULL);
+ }
(void)__close(fd);
return (sp->fts_child);
}
--
2.31.1
From 39b7bf8579e0522cf16347b3a7e332d3b6d742c6 Mon Sep 17 00:00:00 2001
From: Michal Domonkos <mdomonko@redhat.com>
Date: Mon, 14 Jun 2021 12:34:23 +0200
Subject: [PATCH 4/7] Fix memory leak in fts_build()
Turns out this leak is already fixed in glibc's current version of fts.c
(where our copy originates from), so let's just backport that.
Original commit in glibc:
https://sourceware.org/git/?p=glibc.git;\
a=commit;h=db67c2c98b89a5723af44df54f38b779de8d4a65
Found by Coverity.
---
misc/fts.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/misc/fts.c b/misc/fts.c
index caf27495d..f7fce0eaa 100644
--- a/misc/fts.c
+++ b/misc/fts.c
@@ -855,6 +855,7 @@ mem1: saved_errno = errno;
fts_safe_changedir(sp, cur->fts_parent, -1, ".."))) {
cur->fts_info = FTS_ERR;
SET(FTS_STOP);
+ fts_lfree(head);
return (NULL);
}
@@ -862,6 +863,7 @@ mem1: saved_errno = errno;
if (!nitems) {
if (type == BREAD)
cur->fts_info = FTS_DP;
+ fts_lfree(head);
return (NULL);
}
--
2.31.1
From 9c093c4f092dd6bd1e0c8d2b852a72b74db076c2 Mon Sep 17 00:00:00 2001
From: Michal Domonkos <mdomonko@redhat.com>
Date: Tue, 15 Jun 2021 13:34:21 +0200
Subject: [PATCH 5/7] Fix memory leak in decodePkts()
Found by Coverity.
---
rpmio/rpmpgp.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/rpmio/rpmpgp.c b/rpmio/rpmpgp.c
index c59185dce..ee5c81e24 100644
--- a/rpmio/rpmpgp.c
+++ b/rpmio/rpmpgp.c
@@ -1371,9 +1371,13 @@ static pgpArmor decodePkts(uint8_t *b, uint8_t **pkt, size_t *pktlen)
crc = pgpCRC(dec, declen);
if (crcpkt != crc) {
ec = PGPARMOR_ERR_CRC_CHECK;
+ _free(dec);
goto exit;
}
- if (pkt) *pkt = dec;
+ if (pkt)
+ *pkt = dec;
+ else
+ _free(dec);
if (pktlen) *pktlen = declen;
ec = PGPARMOR_PUBKEY; /* XXX ASCII Pubkeys only, please. */
goto exit;
--
2.31.1
From 590b2fc06252567eb7d57197dc361a8b459d62a3 Mon Sep 17 00:00:00 2001
From: Michal Domonkos <mdomonko@redhat.com>
Date: Mon, 21 Jun 2021 17:51:14 +0200
Subject: [PATCH 6/7] Fix memory leak with multiple %lang-s in one line
We permit two equivalent forms of specifying a list of languages per
file:
%lang(xx,yy,zz) /path/to/file
%lang(xx) %lang(yy) %lang(zz) /path/to/file
The leak was when parsing the second form.
Found by Coverity.
---
build/files.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/build/files.c b/build/files.c
index f8153ad2b..0c8859f6c 100644
--- a/build/files.c
+++ b/build/files.c
@@ -777,6 +777,8 @@ static rpmRC parseForLang(char * buf, FileEntry cur)
if (*pe == ',') pe++; /* skip , if present */
}
+
+ q = _free(q);
}
rc = RPMRC_OK;
--
2.31.1
From b7a1e996326ee29a163d67ceb1e6127fdc251c14 Mon Sep 17 00:00:00 2001
From: Michal Domonkos <mdomonko@redhat.com>
Date: Fri, 25 Jun 2021 15:15:08 +0200
Subject: [PATCH 7/7] Fix memory leaks in Lua rex extension
This covers the following usage:
expr = rex.newPOSIX(<regex>)
expr:match(<string>) # A leak occurred here
expr:gmatch(<string>, <func>) # A leak occurred here
Found by Coverity.
---
luaext/lrexlib.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/luaext/lrexlib.c b/luaext/lrexlib.c
index 09c5a6454..0f29b6371 100644
--- a/luaext/lrexlib.c
+++ b/luaext/lrexlib.c
@@ -80,6 +80,7 @@ static void rex_push_matches(lua_State *L, const char *text, regmatch_t *match,
static int rex_match(lua_State *L)
{
+ int rc = 0;
int res;
#ifdef REG_BASIC
size_t len;
@@ -109,9 +110,10 @@ static int rex_match(lua_State *L)
lua_pushstring(L, "n");
lua_pushnumber(L, ncapt);
lua_rawset(L, -3);
- return 3;
- } else
- return 0;
+ rc = 3;
+ }
+ free(match);
+ return rc;
}
static int rex_gmatch(lua_State *L)
@@ -158,6 +160,7 @@ static int rex_gmatch(lua_State *L)
break;
}
lua_pushnumber(L, nmatch);
+ free(match);
return 1;
}
--
2.31.1
commit 9747a6af016a3458d54fe060777c95e3900b5fa4
Author: Demi Marie Obenour <athena@invisiblethingslab.com>
Date: Tue Mar 2 12:47:29 2021 -0500
Fix a tiny memory leak
Found by fuzzing rpmReadPackageFile() with libfuzzer under ASAN.
diff --git a/lib/headerutil.c b/lib/headerutil.c
index 22e36c74d..fab210ff2 100644
--- a/lib/headerutil.c
+++ b/lib/headerutil.c
@@ -333,8 +333,10 @@ static void providePackageNVR(Header h)
rpmds hds, nvrds;
/* Generate provides for this package name-version-release. */
- if (!(name && pEVR))
+ if (!(name && pEVR)) {
+ free(pEVR);
return;
+ }
/*
* Rpm prior to 3.0.3 does not have versioned provides.
commit cb2ae4bdf2f60876fdc68e3f84938e9c37182fab
Author: Igor Gnatenko <i.gnatenko.brain@gmail.com>
Date: Tue Feb 6 14:50:27 2018 +0100
lua: fix memory leak in Pexec()
Signed-off-by: Igor Gnatenko <i.gnatenko.brain@gmail.com>
diff --git a/luaext/lposix.c b/luaext/lposix.c
index 5d7ad3c87..2730bcff7 100644
--- a/luaext/lposix.c
+++ b/luaext/lposix.c
@@ -348,6 +348,7 @@ static int Pexec(lua_State *L) /** exec(path,[args]) */
for (i=1; i<n; i++) argv[i] = (char*)luaL_checkstring(L, i+1);
argv[i] = NULL;
execvp(path,argv);
+ free(argv);
return pusherror(L, path);
}

View File

@ -0,0 +1,38 @@
From 77007d68782b66f2d00d7b200516731246876dca Mon Sep 17 00:00:00 2001
From: Panu Matilainen <pmatilai@redhat.com>
Date: Thu, 27 May 2021 13:58:58 +0300
Subject: [PATCH] Macroize find-debuginfo script location
Makes it easier to handle varying paths, mainly in preparation for the
next step.
Backported for 4.14.3.
---
macros.in | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/macros.in b/macros.in
index a6069ee4d..be28a3b28 100644
--- a/macros.in
+++ b/macros.in
@@ -82,6 +82,8 @@
%__remsh %{__rsh}
%__strip @__STRIP@
+%__find_debuginfo %{_rpmconfigdir}/find-debuginfo.sh
+
# XXX avoid failures if tools are not installed when rpm is built.
%__libtoolize libtoolize
%__aclocal aclocal
@@ -177,7 +179,7 @@
# the script. See the script for details.
#
%__debug_install_post \
- %{_rpmconfigdir}/find-debuginfo.sh \\\
+ %{__find_debuginfo} \\\
%{?_smp_mflags} \\\
%{?_missing_build_ids_terminate_build:--strict-build-id} \\\
%{?_no_recompute_build_ids:-n} \\\
--
2.33.1

View File

@ -0,0 +1,162 @@
commit d6a86b5e69e46cc283b1e06c92343319beb42e21
Author: Panu Matilainen <pmatilai@redhat.com>
Date: Thu Mar 4 13:21:19 2021 +0200
Be much more careful about copying data from the signature header
Only look for known tags, and ensure correct type and size where known
before copying over. Bump the old arbitrary 16k count limit to 16M limit
though, it's not inconceivable that a package could have that many files.
While at it, ensure none of these tags exist in the main header,
which would confuse us greatly.
This is optimized for backporting ease, upstream can remove redundancies
and further improve checking later.
Reported and initial patches by Demi Marie Obenour.
Fixes: RhBug:1935049, RhBug:1933867, RhBug:1935035, RhBug:1934125, ...
Fixes: CVE-2021-3421, CVE-2021-20271
Combined with e2f1f1931c5ccf3ecbe4e1e12cacb1e17a277776 and backported into
4.14.3
diff -up rpm-4.14.3/lib/package.c.orig rpm-4.14.3/lib/package.c
--- rpm-4.14.3/lib/package.c.orig 2021-05-31 12:32:49.970393976 +0200
+++ rpm-4.14.3/lib/package.c 2021-05-31 13:53:58.250673275 +0200
@@ -31,76 +31,72 @@ struct pkgdata_s {
rpmRC rc;
};
+struct taglate_s {
+ rpmTagVal stag;
+ rpmTagVal xtag;
+ rpm_count_t count;
+ int quirk;
+} const xlateTags[] = {
+ { RPMSIGTAG_SIZE, RPMTAG_SIGSIZE, 1, 0 },
+ { RPMSIGTAG_PGP, RPMTAG_SIGPGP, 0, 0 },
+ { RPMSIGTAG_MD5, RPMTAG_SIGMD5, 16, 0 },
+ { RPMSIGTAG_GPG, RPMTAG_SIGGPG, 0, 0 },
+ /* { RPMSIGTAG_PGP5, RPMTAG_SIGPGP5, 0, 0 }, */ /* long obsolete, dont use */
+ { RPMSIGTAG_PAYLOADSIZE, RPMTAG_ARCHIVESIZE, 1, 1 },
+ { RPMSIGTAG_SHA1, RPMTAG_SHA1HEADER, 1, 0 },
+ { RPMSIGTAG_SHA256, RPMTAG_SHA256HEADER, 1, 0 },
+ { RPMSIGTAG_DSA, RPMTAG_DSAHEADER, 0, 0 },
+ { RPMSIGTAG_RSA, RPMTAG_RSAHEADER, 0, 0 },
+ { RPMSIGTAG_LONGSIZE, RPMTAG_LONGSIGSIZE, 1, 0 },
+ { RPMSIGTAG_LONGARCHIVESIZE, RPMTAG_LONGARCHIVESIZE, 1, 0 },
+ { 0 }
+};
+
/** \ingroup header
* Translate and merge legacy signature tags into header.
* @param h header (dest)
* @param sigh signature header (src)
+ * @return failing tag number, 0 on success
*/
static
-void headerMergeLegacySigs(Header h, Header sigh)
+rpmTagVal headerMergeLegacySigs(Header h, Header sigh, char **msg)
{
- HeaderIterator hi;
+ const struct taglate_s *xl;
struct rpmtd_s td;
- hi = headerInitIterator(sigh);
- for (; headerNext(hi, &td); rpmtdFreeData(&td))
- {
- switch (td.tag) {
- /* XXX Translate legacy signature tag values. */
- case RPMSIGTAG_SIZE:
- td.tag = RPMTAG_SIGSIZE;
- break;
- case RPMSIGTAG_PGP:
- td.tag = RPMTAG_SIGPGP;
- break;
- case RPMSIGTAG_MD5:
- td.tag = RPMTAG_SIGMD5;
- break;
- case RPMSIGTAG_GPG:
- td.tag = RPMTAG_SIGGPG;
- break;
- case RPMSIGTAG_PGP5:
- td.tag = RPMTAG_SIGPGP5;
- break;
- case RPMSIGTAG_PAYLOADSIZE:
- td.tag = RPMTAG_ARCHIVESIZE;
- break;
- case RPMSIGTAG_SHA1:
- case RPMSIGTAG_SHA256:
- case RPMSIGTAG_DSA:
- case RPMSIGTAG_RSA:
- default:
- if (!(td.tag >= HEADER_SIGBASE && td.tag < HEADER_TAGBASE))
+ rpmtdReset(&td);
+ for (xl = xlateTags; xl->stag; xl++) {
+ /* There mustn't be one in the main header */
+ if (headerIsEntry(h, xl->xtag)) {
+ /* Some tags may exist in either header, but never both */
+ if (xl->quirk && !headerIsEntry(sigh, xl->stag))
continue;
break;
}
- if (!headerIsEntry(h, td.tag)) {
- switch (td.type) {
- case RPM_NULL_TYPE:
- continue;
+ if (headerGet(sigh, xl->stag, &td, HEADERGET_RAW|HEADERGET_MINMEM)) {
+ /* Translate legacy tags */
+ if (xl->stag != xl->xtag)
+ td.tag = xl->xtag;
+ /* Ensure type and tag size match expectations */
+ if (td.type != rpmTagGetTagType(td.tag))
break;
- case RPM_CHAR_TYPE:
- case RPM_INT8_TYPE:
- case RPM_INT16_TYPE:
- case RPM_INT32_TYPE:
- case RPM_INT64_TYPE:
- if (td.count != 1)
- continue;
+ if (td.count < 1 || td.count > 16*1024*1024)
break;
- case RPM_STRING_TYPE:
- case RPM_BIN_TYPE:
- if (td.count >= 16*1024)
- continue;
+ if (xl->count && td.count != xl->count)
break;
- case RPM_STRING_ARRAY_TYPE:
- case RPM_I18NSTRING_TYPE:
- continue;
+ if (!headerPut(h, &td, HEADERPUT_DEFAULT))
break;
- }
- (void) headerPut(h, &td, HEADERPUT_DEFAULT);
+ rpmtdFreeData(&td);
}
}
- headerFreeIterator(hi);
+ rpmtdFreeData(&td);
+
+ if (xl->stag) {
+ rasprintf(msg, "invalid signature tag %s (%d)",
+ rpmTagGetName(xl->xtag), xl->xtag);
+ }
+
+ return xl->stag;
}
/**
@@ -363,7 +359,8 @@ rpmRC rpmReadPackageFile(rpmts ts, FD_t
goto exit;
/* Append (and remap) signature tags to the metadata. */
- headerMergeLegacySigs(h, sigh);
+ if (headerMergeLegacySigs(h, sigh, &msg))
+ goto exit;
applyRetrofits(h);
/* Bump reference count for return. */

View File

@ -0,0 +1,13 @@
--- rpm-4.14.3/configure.ac.orig 2020-05-04 21:08:41.481365399 +0200
+++ rpm-4.14.3/configure.ac 2020-05-04 21:09:03.550604043 +0200
@@ -129,8 +129,8 @@
AC_PATH_PROG(__PERL, perl, /usr/bin/perl, $MYPATH)
AC_PATH_PROG(__PGP, pgp, /usr/bin/pgp, $MYPATH)
-AC_PATH_PROG(__PYTHON, python2, /usr/bin/python2, $MYPATH)
-AC_PATH_PROG(PYTHON, python2, /usr/bin/python2, $MYPATH)
+AC_PATH_PROG(__PYTHON, python3, /usr/bin/python3, $MYPATH)
+AC_PATH_PROG(PYTHON, python3, /usr/bin/python3, $MYPATH)
AC_PATH_PROG(__RM, rm, /bin/rm, $MYPATH)
AC_PATH_PROG(__RSH, rsh, /usr/bin/rsh, $MYPATH)
AC_PATH_PROG(__SED, sed, /bin/sed, $MYPATH)

View File

@ -0,0 +1,29 @@
From fe274b8f965582fdf97e6c46f90b9e7c124b0b8b Mon Sep 17 00:00:00 2001
From: Florian Festi <ffesti@redhat.com>
Date: Fri, 16 Dec 2022 15:50:12 +0100
Subject: [PATCH] rpm2archive: Don't print usage on no arguments
given as we want to default to reading from stdin and writing to stdout in
that case.
---
rpm2archive.c | 4 ----
1 file changed, 4 deletions(-)
diff --git a/rpm2archive.c b/rpm2archive.c
index 09da8d16b..53f047f58 100644
--- a/rpm2archive.c
+++ b/rpm2archive.c
@@ -241,10 +241,6 @@ int main(int argc, const char *argv[])
exit(EXIT_FAILURE);
}
}
- if (argc < 2 || poptGetNextOpt(optCon) == 0) {
- poptPrintUsage(optCon, stderr, 0);
- exit(EXIT_FAILURE);
- }
rpmts ts = rpmtsCreate();
rpmVSFlags vsflags = 0;
--
2.38.1

View File

@ -0,0 +1,138 @@
From d8a169164cf40fc1cf6448792c1fa991f19bb375 Mon Sep 17 00:00:00 2001
From: Florian Festi <ffesti@redhat.com>
Date: Thu, 22 Apr 2021 14:50:34 +0200
Subject: [PATCH] Add --nocompression option to rpm2archive
Also use popt for the command line handling. As we are using librpm
anyway there is no reason to keep the dependencies low (as with
rpm2cpio).
Resolves: #1530
---
doc/rpm2archive.8 | 16 ++++++++++---
rpm2archive.c | 60 ++++++++++++++++++++++++++++++++++-------------
2 files changed, 57 insertions(+), 19 deletions(-)
diff --git a/rpm2archive.c b/rpm2archive.c
index d96db006ea..cb39c7a712 100644
--- a/rpm2archive.c
+++ b/rpm2archive.c
@@ -10,6 +10,8 @@
#include <rpm/rpmts.h>
+#include <popt.h>
+
#include <archive.h>
#include <archive_entry.h>
#include <unistd.h>
@@ -18,6 +20,16 @@
#define BUFSIZE (128*1024)
+int compress = 1;
+
+static struct poptOption optionsTable[] = {
+ { "nocompression", 'n', POPT_ARG_VAL, &compress, 0,
+ N_("create uncompressed tar file"),
+ NULL },
+ POPT_AUTOHELP
+ POPT_TABLEEND
+};
+
static void fill_archive_entry(struct archive * a, struct archive_entry * entry, rpmfi fi)
{
archive_entry_clear(entry);
@@ -60,7 +72,7 @@ static void write_file_content(struct archive * a, char * buf, rpmfi fi)
}
}
-static int process_package(rpmts ts, char * filename)
+static int process_package(rpmts ts, const char * filename)
{
FD_t fdi;
FD_t gzdi;
@@ -119,9 +131,11 @@ static int process_package(rpmts ts, char * filename)
/* create archive */
a = archive_write_new();
- if (archive_write_add_filter_gzip(a) != ARCHIVE_OK) {
- fprintf(stderr, "Error: Could not create gzip output filter\n");
- exit(EXIT_FAILURE);
+ if (compress) {
+ if (archive_write_add_filter_gzip(a) != ARCHIVE_OK) {
+ fprintf(stderr, "%s\n", archive_error_string(a));
+ exit(EXIT_FAILURE);
+ }
}
if (archive_write_set_format_pax_restricted(a) != ARCHIVE_OK) {
fprintf(stderr, "Error: Format pax restricted is not supported\n");
@@ -142,7 +156,12 @@ static int process_package(rpmts ts, char * filename)
}
archive_write_open_fd(a, STDOUT_FILENO);
} else {
- char * outname = rstrscat(NULL, filename, ".tgz", NULL);
+ char * outname = rstrscat(NULL, filename, NULL);
+ if (compress) {
+ outname = rstrscat(&outname, ".tgz", NULL);
+ } else {
+ outname = rstrscat(&outname, ".tar", NULL);
+ }
if (archive_write_open_filename(a, outname) != ARCHIVE_OK) {
fprintf(stderr, "Error: Can't open output file: %s\n", outname);
exit(EXIT_FAILURE);
@@ -203,21 +222,22 @@ static int process_package(rpmts ts, char * filename)
return rc;
}
-int main(int argc, char *argv[])
+int main(int argc, const char *argv[])
{
- int rc = 0, i;
+ int rc = 0;
+ poptContext optCon;
+ const char *fn;
xsetprogname(argv[0]); /* Portability call -- see system.h */
rpmReadConfigFiles(NULL, NULL);
- if (argc > 1 && (rstreq(argv[1], "-h") || rstreq(argv[1], "--help"))) {
- fprintf(stderr, "Usage: %s [file.rpm ...]\n", argv[0]);
+ optCon = poptGetContext(NULL, argc, argv, optionsTable, 0);
+ poptSetOtherOptionHelp(optCon, "[OPTIONS]* <FILES>");
+ if (argc < 2 || poptGetNextOpt(optCon) == 0) {
+ poptPrintUsage(optCon, stderr, 0);
exit(EXIT_FAILURE);
}
- if (argc == 1)
- argv[argc++] = "-"; /* abuse NULL pointer at the end of argv */
-
rpmts ts = rpmtsCreate();
rpmVSFlags vsflags = 0;
@@ -227,13 +247,21 @@ int main(int argc, char *argv[])
vsflags |= RPMVSF_NOHDRCHK;
(void) rpmtsSetVSFlags(ts, vsflags);
- for (i = 1; i < argc; i++) {
+ /* if no file name is given use stdin/stdout */
+ if (!poptPeekArg(optCon)) {
+ rc = process_package(ts, "-");
+ if (rc != 0)
+ goto exit;
+ }
- rc = process_package(ts, argv[i]);
+ while ((fn = poptGetArg(optCon)) != NULL) {
+ rc = process_package(ts, fn);
if (rc != 0)
- return rc;
+ goto exit;
}
+ exit:
+ poptFreeContext(optCon);
(void) rpmtsFree(ts);
return rc;
}

View File

@ -0,0 +1,36 @@
From 8f416b275a365426b07c75adfc017e0b18a85450 Mon Sep 17 00:00:00 2001
From: Florian Festi <ffesti@redhat.com>
Date: Fri, 16 Dec 2022 15:45:20 +0100
Subject: [PATCH] rpm2archive: Properly parse popt options
and issue an error message for unknown options. Before unknown options
could mess up the argument parsing leading to reading and writing from
stdin/stdout.
Thanks to Eva Mrakova and the Red Hat QE team for spotting this!
---
rpm2archive.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/rpm2archive.c b/rpm2archive.c
index de1a17d2b..09da8d16b 100644
--- a/rpm2archive.c
+++ b/rpm2archive.c
@@ -233,6 +233,14 @@ int main(int argc, const char *argv[])
optCon = poptGetContext(NULL, argc, argv, optionsTable, 0);
poptSetOtherOptionHelp(optCon, "[OPTIONS]* <FILES>");
+ while ((rc = poptGetNextOpt(optCon)) != -1) {
+ if (rc < 0) {
+ fprintf(stderr, "%s: %s\n",
+ poptBadOption(optCon, POPT_BADOPTION_NOALIAS),
+ poptStrerror(rc));
+ exit(EXIT_FAILURE);
+ }
+ }
if (argc < 2 || poptGetNextOpt(optCon) == 0) {
poptPrintUsage(optCon, stderr, 0);
exit(EXIT_FAILURE);
--
2.38.1

View File

@ -0,0 +1,40 @@
From 2e61e5846f8301f85da9d30281538ea736d96fd0 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 67fcabfb1..e130a5d05 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" \
--
2.35.1

View File

@ -0,0 +1,401 @@
From 82c53e4b7f720012a391d8f6e5da9ee3c4f22bed Mon Sep 17 00:00:00 2001
From: Demi Marie Obenour <demi@invisiblethingslab.com>
Date: Thu, 6 May 2021 18:34:45 -0400
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.
Combined with:
5ff86764b17f31535cb247543a90dd739076ec38
b5e8bc74b2b05aa557f663fe227b94d2bc64fbd8
9f03f42e2614a68f589f9db8fe76287146522c0c
b6dffb6dc5ffa2ddc389743f0507876cab341315 (mem-leak fix)
ae3d2d234ae47ff85229d3fce97a266fa1aa5a61 (use-after-free fix)
Fixes CVE-2021-3521.
---
rpmio/rpmpgp.c | 122 +++++++++++++++---
sign/rpmgensig.c | 2 +-
tests/Makefile.am | 3 +
tests/data/keys/CVE-2021-3521-badbind.asc | 25 ++++
.../data/keys/CVE-2021-3521-nosubsig-last.asc | 25 ++++
tests/data/keys/CVE-2021-3521-nosubsig.asc | 37 ++++++
tests/rpmsigdig.at | 28 ++++
7 files changed, 224 insertions(+), 18 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 46cd0f31a..bd4992ec7 100644
--- a/rpmio/rpmpgp.c
+++ b/rpmio/rpmpgp.c
@@ -511,7 +511,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)
{
@@ -524,10 +524,8 @@ static int pgpPrtSigParams(pgpTag tag, uint8_t pubkey_algo, uint8_t sigtype,
int mpil = pgpMpiLen(p);
if (p + mpil > pend)
break;
- if (sigtype == PGPSIGTYPE_BINARY || sigtype == PGPSIGTYPE_TEXT) {
- if (sigalg->setmpi(sigalg, i, p))
- break;
- }
+ if (sigalg->setmpi(sigalg, i, p))
+ break;
p += mpil;
}
@@ -600,7 +598,7 @@ static int pgpPrtSig(pgpTag tag, const uint8_t *h, size_t hlen,
}
p = ((uint8_t *)v) + sizeof(*v);
- 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;
@@ -658,7 +656,7 @@ static int pgpPrtSig(pgpTag tag, const uint8_t *h, size_t hlen,
if (p > (h + hlen))
return 1;
- 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 key: V%d\n"), version);
@@ -999,36 +997,127 @@ 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;
+}
+
+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 = xcalloc(1, sizeof(*digp));
- digp->tag = 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 */
+ int xx = 1; /* assume failure */
+
+ if (!(prevtag == PGPTAG_PUBLIC_SUBKEY &&
+ selfsig->sigtype != PGPSIGTYPE_SUBKEY_BINDING))
+ 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 {
@@ -1063,8 +1152,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);
diff --git a/sign/rpmgensig.c b/sign/rpmgensig.c
index 771d01098..b33fe996c 100644
--- a/sign/rpmgensig.c
+++ b/sign/rpmgensig.c
@@ -409,7 +409,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);
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 5f5207e56..309347262 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -87,6 +87,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
# testsuite voodoo
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 000000000..aea00f9d7
--- /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 000000000..aea00f9d7
--- /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 000000000..3a2e7417f
--- /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 09fcdd525..a74f400ae 100644
--- a/tests/rpmsigdig.at
+++ b/tests/rpmsigdig.at
@@ -212,6 +212,34 @@ UNW2iqnN3BA7guhOv6OMiROF1+I7Q5nWT63mQC7IgQ==
[])
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])
--
2.34.1

View File

@ -0,0 +1,51 @@
From f1634250587479d664b34b6de1a6546b2c2b9de5 Mon Sep 17 00:00:00 2001
From: Florian Festi <ffesti@redhat.com>
Date: Mon, 18 Jan 2021 15:02:34 +0100
Subject: [PATCH] rpm2archive: Add more error handling
Cleanly error out if file can't be written instead of segfaulting
Resolves: #1091
---
rpm2archive.c | 17 ++++++++++++-----
1 file changed, 12 insertions(+), 5 deletions(-)
diff --git a/rpm2archive.c b/rpm2archive.c
index 646f1663d..15c5da016 100644
--- a/rpm2archive.c
+++ b/rpm2archive.c
@@ -119,9 +119,14 @@ static int process_package(rpmts ts, char * filename)
/* create archive */
a = archive_write_new();
- archive_write_add_filter_gzip(a);
- archive_write_set_format_pax_restricted(a);
-
+ if (archive_write_add_filter_gzip(a) != ARCHIVE_OK) {
+ fprintf(stderr, "Error: Could not create gzip output filter\n");
+ exit(EXIT_FAILURE);
+ }
+ if (archive_write_set_format_pax_restricted(a) != ARCHIVE_OK) {
+ fprintf(stderr, "Error: Format pax restricted is not supported\n");
+ exit(EXIT_FAILURE);
+ }
if (!strcmp(filename, "-")) {
if (isatty(STDOUT_FILENO)) {
fprintf(stderr, "Error: refusing to output archive data to a terminal.\n");
@@ -130,9 +135,11 @@ static int process_package(rpmts ts, char * filename)
archive_write_open_fd(a, STDOUT_FILENO);
} else {
char * outname = rstrscat(NULL, filename, ".tgz", NULL);
- archive_write_open_filename(a, outname);
+ if (archive_write_open_filename(a, outname) != ARCHIVE_OK) {
+ fprintf(stderr, "Error: Can't open output file: %s\n", outname);
+ exit(EXIT_FAILURE);
+ }
_free(outname);
- // XXX error handling
}
entry = archive_entry_new();
--
2.38.1

View File

@ -15,9 +15,11 @@
# build with new db format
%bcond_with ndb
# build with zstd support?
%bcond_with zstd
%bcond_without zstd
# build with lmdb support?
%bcond_with lmdb
# build with readonly sqlite support?
%bcond_without sqlite
%if 0%{?rhel} > 7
# Disable python2 build by default
@ -28,9 +30,9 @@
%define rpmhome /usr/lib/rpm
%global rpmver 4.14.2
%global rpmver 4.14.3
#global snapver rc2
%global rel 26
%global rel 31
%global srcver %{version}%{?snapver:-%{snapver}}
%global srcdir %{?snapver:testing}%{!?snapver:%{name}-%(echo %{version} | cut -d'.' -f1-2).x}
@ -72,39 +74,73 @@ Patch5: rpm-4.12.0-rpm2cpio-hack.patch
Patch7: rpm-4.14.1-Add-envvar-that-will-be-present-during-RPM-build.patch
# Patches already upstream:
Patch100: 0001-Fix-nasty-setperms-setugids-regression-in-4.14.2-RhB.patch
Patch101: rpm-4.14.2-RPMTAG_MODULARITYLABEL.patch
Patch102: 0001-Document-noverify-in-the-man-page-RhBug-1646458.patch
Patch103: 0001-Handle-unsupported-digests-the-same-as-disabled-ones.patch
Patch104: 0001-Mark-elements-with-associated-problems-as-failed.patch
Patch105: 0001-Fix-ancient-python-GIL-locking-bug-on-callback-RhBug.patch
Patch106: 0001-Fix-testing-for-wrong-variable-in-selinux-plugin-deb.patch
Patch107: 0001-Log-RPMLOG_ERR-level-messages-on-actual-errors-in-se.patch
Patch108: 0001-Only-read-through-payload-on-verify-if-actually-need.patch
Patch109: 0001-Make-rpmsign-exit-values-more-consistent-with-our-ot.patch
Patch110: 0002-Drop-internal-only-visibility-on-rpmvs-related-API.patch
Patch111: 0003-Verify-packages-before-signing-RhBug-1646388.patch
Patch112: 0001-Fix-FA_TOUCH-on-files-with-suid-sgid-bits-and-or-cap.patch
Patch113: 0001-Sort-list-of-hard-linked-files-in-find-debuginfo.sh-.patch
Patch114: 0001-Correct-rpm-ql-exit-value-when-optional-p-is-omitted.patch
Patch115: 0001-Show-list-of-files-only-once-when-use-rpm-ql-and-mul.patch
Patch116: 0001-Add-flag-to-use-strip-g-instead-of-full-strip-on-DSO.patch
Patch117: 0001-Fix-segfault-on-fingerprinting-symlink-round-RhBug-1.patch
Patch118: 0001-Fix-packages-getting-erased-on-failed-update-with-dn.patch
Patch119: 0001-Use-in-condition-to-avoid-sub-processes-in-find-debu.patch
Patch120: 0001-rpmsign-man-page-Add-line-about-rpmsign-requiring-a-.patch
Patch121: 0001-Use-dpbath-only-with-full-path-RhBug-1696408.patch
Patch122: 0001-Fix-a-blindingly-obvious-memleak-in-package-verify-s.patch
Patch123: 0001-Fix-rpmfiles-memory-leak-on-postuntrans-file-trigger.patch
Patch125: 0001-Remove-capabilities-instead-of-setting-empty-caps-vi.patch
Patch126: 0001-Fix-off-by-one-in-hdrblobGet-making-last-entry-unrea.patch
Patch127: 0001-Fix-memleak-during-transaction-verify-step-in-the-NO.patch
Patch132: 0001-debugedit-Refactor-reading-writing-of-relocated-valu.patch
Patch133: 0002-Handle-.debug_macro-in-debugedit.patch
Patch134: 0003-debugedit-Make-sure-.debug_line-old-new-idx-start-eq.patch
Patch135: 0001-Pass-RPM_BUILD_NCPUS-to-build-scripts.patch
Patch136: 0001-Use-RPM_BUILD_NCPUS-in-brp-strip-static-archive.patch
Patch137: 0001-Fix-brp-strip-static-archive-parallelism.patch
Patch138: 0001-Use-newline-as-a-delimiter-to-avoid-xargs-messing-up.patch
Patch139: 0001-Make-check-buildroot-check-the-build-files-in-parall.patch
Patch140: 0001-Fix-resource-leaks-on-zstd-open-error-paths.patch
# XXX should be before 0001-Pass-RPM_BUILD_NCPUS-to-build-scripts.patch
Patch141: 0001-Isolate-_smp_build_ncpus-and-use-it-for-_smp_mflags.patch
Patch142: rpm-4.14.3-GPG-Switch-back-to-pipe-7-for-signing.patch
Patch143: 0001-Work-around-buggy-signature-region-preventing-resign.patch
Patch144: 0001-Fix-python-ts.addErase-not-raising-exception-on-not-.patch
Patch145: 0001-Always-close-libelf-handle-1313.patch
Patch146: 0001-When-doing-the-same-thing-more-than-once-use-a-loop.patch
Patch147: 0001-Introduce-patch_nums-and-source_nums-Lua-variables-i.patch
Patch148: 0001-Add-limits-to-autopatch-macro.patch
Patch149: rpm-4.14.3-bump-up-the-limit-of-signature-header-to-64MB.patch
Patch150: rpm-4.14.3-add-fapolicyd-rpm-plugin.patch
Patch151: 0001-Unblock-signals-in-forked-scriptlets.patch
Patch152: rpm-4.14.3-fix-ambiguous-diagnostics-on-file-triggers.patch
Patch153: rpm-4.14.3-ELF-files-strip-when-debuginfo-disabled.patch
Patch154: rpm-4.14.3-more-careful-sig-hdr-copy.patch
Patch156: rpm-4.14.3-hdrblobInit-add-bounds-check.patch
Patch157: rpm-4.14.3-add-read-only-support-for-sqlite.patch
Patch158: rpm-4.14.3-imp-covscan-fixes.patch
Patch159: rpm-4.14.3-add-path-query-option.patch
Patch160: rpm-4.14.3-macroize-find-debuginfo-script-location.patch
Patch161: rpm-4.14.3-validate-and-require-subkey-binding-sigs.patch
Patch162: rpm-4.14.3-fix-spurious-transfiletriggerpostun-execution.patch
Patch163: rpm-4.14.3-skip-recorded-symlinks-in-setperms.patch
Patch164: rpm-4.14.3-fapolicyd-make-write-nonblocking.patch
Patch165: rpm-4.16.1.3-rpm2archive-error-handling.patch
Patch166: rpm-4.14.3-rpm2archive-nocompression.patch
Patch167: rpm-4.14.3-rpm2archive-parse-popt-options.patch
Patch168: rpm-4.14.3-rpm2archive-Don-t-print-usage.patch
# Backport fsm to fix CVEs
Patch169: 0001-Eliminate-code-duplication-from-rpmfiNext.patch
Patch170: 0001-Add-optional-callback-on-directory-changes-during-rp.patch
Patch171: 0001-Pass-file-descriptor-to-file-prepare-plugin-hook-use.patch
Patch172: 0001-Swap-over-to-dirfd-basename-based-operation-within-t.patch
Patch173: 0001-Use-file-state-machine-from-rpm-4.19.patch
Patch174: 0001-Emit-full-paths-for-file-disposition-diagnostics-on-.patch
Patch175: 0001-Fix-wrong-return-code-on-O_DIRECTORY-open-of-invalid.patch
Patch176: 0001-Print-full-path-if-file-removal-fails.patch
Patch177: 0001-Don-t-warn-about-missing-user-group-on-skipped-files.patch
# Python 3 string API sanity
Patch500: 0001-In-Python-3-return-all-our-string-data-as-surrogate-.patch
Patch501: 0001-Return-NULL-string-as-None-from-utf8FromString.patch
# Temporary compat crutch, not upstream
Patch502: 0001-Monkey-patch-.decode-method-to-our-strings-as-a-temp.patch
# Make test-suite work with Python 3
Patch503: 0001-Honor-PYTHON-from-configure-when-running-tests.patch
Patch504: 0002-Use-Python-3-compatible-exception-syntax-in-tests.patch
Patch505: 0003-Fix-couple-of-bytes-vs-strings-issues-in-Python-test.patch
Patch506: 0004-Bump-the-minimum-Python-version-requirement-to-2.7.patch
Patch507: 0005-Drop-an-unnecessary-Python-2-vs-3-incompatibility-fr.patch
Patch508: rpm-4.14.3-python3.diff
Patch509: rpm-4-14.3-selinux-log-error.patch
# These are not yet upstream
# Audit support
@ -124,6 +160,8 @@ Patch1000: disable-python-extra.patch
Patch1001: compile-with-Platform-Python-binary-where-relevant.patch
# make unversioned %%__python an error unless explicitly overridden
Patch1002: rpm-4.14.2-unversioned-python.patch
# Make brp-python-bytecompile compatible with Python 3.10+
Patch1003: brp-python-bytecompile-compatibility-with-newer-pyth.patch
# Partially GPL/LGPL dual-licensed and some bits with BSD
# SourceLicense: (GPLv2+ and LGPLv2+ with exceptions) and BSD
@ -164,6 +202,9 @@ BuildRequires: lua-devel >= 5.1
BuildRequires: libcap-devel
BuildRequires: libacl-devel
BuildRequires: audit-libs-devel
%if %{with sqlite}
BuildRequires: sqlite-devel
%endif
%if %{with xz}
BuildRequires: xz-devel >= 4.999.8
%endif
@ -310,6 +351,11 @@ BuildRequires: python3-devel
Requires: %{name}-libs%{?_isa} = %{version}-%{release}
Provides: %{name}-python3 = %{version}-%{release}
Obsoletes: %{name}-python3 < %{version}-%{release}
# Lowest compatible DNF version (acts as a safeguard to protect DNF from
# breaking in case the user attempts to upgrade RPM separately).
# Version 4.2.7 added support for the new API output format introduced in
# rpm-4.14.2-10.
Conflicts: python3-dnf < 4.2.7
%description -n python3-%{name}
The python3-rpm package contains a module that permits applications
@ -384,6 +430,15 @@ Requires: rpm-libs%{_isa} = %{version}-%{release}
Useful on legacy SysV init systems if you run rpm transactions with
nice/ionice priorities. Should not be used on systemd systems.
%package plugin-fapolicyd
Summary: Rpm plugin for fapolicyd functionality
Requires: rpm-libs%{_isa} = %{version}-%{release}
Provides: fapolicyd-plugin
Obsoletes: fapolicyd-dnf-plugin
%description plugin-fapolicyd
%{summary}.
%endif # with plugins
%prep
@ -427,12 +482,16 @@ done;
--with-selinux \
--with-cap \
--with-acl \
%{?with_ndb: --with-ndb} \
%{?with_ndb: --enable-ndb} \
%{!?with_libarchive: --without-archive} \
%{?with_libimaevm: --with-imaevm} \
%{?with_zstd: --enable-zstd} \
%{?with_lmdb: --enable-lmdb} \
%{?with_sqlite: --enable-sqlite} \
--with-fapolicyd \
--enable-python \
--with-crypto=openssl
--with-crypto=openssl \
PYTHON=python3
make %{?_smp_mflags}
@ -524,7 +583,9 @@ make check || cat tests/rpmtests.log
%attr(0644, root, root) %verify(not md5 size mtime) %ghost %config(missingok,noreplace) /var/lib/rpm/*
%{_bindir}/rpm
%if %{with libarchive}
%{_bindir}/rpm2archive
%endif
%{_bindir}/rpm2cpio
%{_bindir}/rpmdb
%{_bindir}/rpmkeys
@ -584,6 +645,10 @@ make check || cat tests/rpmtests.log
%files plugin-prioreset
%{_libdir}/rpm-plugins/prioreset.so
%files plugin-fapolicyd
%{_libdir}/rpm-plugins/fapolicyd.so
%{_mandir}/man8/rpm-plugin-fapolicyd.8*
%endif # with plugins
%files build-libs
@ -646,8 +711,132 @@ make check || cat tests/rpmtests.log
%doc doc/librpm/html/*
%changelog
* Tue Jan 14 2020 Panu Matilainen <pmatilai@redhat.com> - 4.14.2-26
- Revert DBUS-shutdown patch, it causes regressions (#1790794)
* Tue Dec 12 2023 Florian Festi <ffesti@redhat.com> - 4.14.3-31
- Backport file handling code from rpm-4.19 to fix CVE-2021-35937,
CVE-2021-35938 and CVE-2021-35939
* Tue Sep 26 2023 Lumír Balhar <lbalhar@redhat.com> - 4.14.3-27
- Make brp-python-bytecompile script compatible with Python 3.10+
Resolves: RHEL-6423
* Mon Dec 19 2022 Florian Festi <ffesti@redhat.com> - 4.14.3-26
- Add --nocompression to rpm2archive (#2129345)
* Tue Sep 13 2022 Michal Domonkos <mdomonko@redhat.com> - 4.14.3-24
- Make write() nonblocking in fapolicyd plugin (#2110787)
* Tue Apr 05 2022 Michal Domonkos <mdomonko@redhat.com> - 4.14.3-23
- Fix minor ABI regression in rpmcli.h (#1940895)
* Tue Feb 15 2022 Michal Domonkos <mdomonko@redhat.com> - 4.14.3-22
- Fix spurious %transfiletriggerpostun execution (#2023693)
- Skip recorded symlinks in --setperms (#1900662)
* Mon Jan 10 2022 Michal Domonkos <mdomonko@redhat.com> - 4.14.3-21
- Address covscan issues in binding sigs validation patch (#1958480)
* Thu Dec 09 2021 Michal Domonkos <mdomonko@redhat.com> - 4.14.3-20
- Add --path query option (#1940895)
- Macroize find-debuginfo script location (#2019540)
- Validate and require subkey binding sigs on PGP pubkeys (#1958480)
- Fixes CVE-2021-3521
* Wed Oct 06 2021 Michal Domonkos <mdomonko@redhat.com> - 4.14.3-19
- Unbreak in-tree kmod strip by reverting brp-strip fix (#1967291)
* Thu Aug 26 2021 Michal Domonkos <mdomonko@redhat.com> - 4.14.3-18
- Address important covscan issues (#1996665), vol. 2
* Mon Aug 23 2021 Michal Domonkos <mdomonko@redhat.com> - 4.14.3-17
- Address important covscan issues (#1996665)
* Thu Aug 19 2021 Michal Domonkos <mdomonko@redhat.com> - 4.14.3-16
- Add support for read-only sqlite rpmdb (#1938928)
- Drop compat .decode() method from returned Py3 strings (#1840142)
* Thu Jul 15 2021 Michal Domonkos <mdomonko@redhat.com> - 4.14.3-15
- Add out-of-bounds checks to hdrblobInit() (#1929445)
- Fixes CVE-2021-20266
- Fix regression in brp-strip causing kmods to lose SecureBoot sig (#1967291)
* Thu May 27 2021 Michal Domonkos <mdomonko@redhat.com> - 4.14.3-14
- Be more careful about copying data from signature header (#1958477)
- Fixes CVE-2021-20271
* Fri Feb 12 2021 Michal Domonkos <mdomonko@redhat.com> - 4.14.3-13
- Fix minor issues found by COVSCAN in fapolicyd plugin
- Actually honor libarchive bcond at configure time (#1902887)
* Tue Feb 09 2021 Michal Domonkos <mdomonko@redhat.com> - 4.14.3-12
- Bump up the limit of signature header to 64MB (#1918777)
- Add fapolicyd plugin (#1923167)
- Unblock signals in forked scriptlets (#1913765)
- Fix ambiguous diagnostics output on file triggers (#1883338)
- Ensure ELF files get stripped when debuginfo is disabled (#1634084)
* Sun Jan 10 2021 Michal Domonkos <mdomonko@redhat.com> - 4.14.3-10
- Rebuild for libimaevm soname bump, now for real (#1896046)
* Thu Jan 07 2021 Florian Festi <ffesti@redhat.com> - 4.14.3-8
- Add limits to autopatch macro (#1834931)
* Thu Dec 03 2020 Michal Domonkos <mdomonko@redhat.com> - 4.14.3-6
- Rebuild for libimaevm soname bump (#1896046)
* Fri Oct 30 2020 Florian Festi <ffesti@redhat.com> - 4.14.3-5
- Don't error out when replacing an invalid signature (#1874062)
- Raise an expection when erasing a package fails in Python (#1872623)
- Fix builds on NFS filesystems (#1840728)
* Fri Jun 26 2020 Michal Domonkos <mdomonko@redhat.com> - 4.14.3-4
- Fix hang when signing with expired key (#1746353)
* Wed May 13 2020 Panu Matilainen <pmatilai@redhat.com> - 4.14.3-3
- Fix configure option for --with ndb (#1817010, Matthew Almond)
* Mon May 11 2020 Florian Festi <ffesti@redhat.com> - 4.14.3-2
- Re-add selinux fix dropped in rebase
* Mon May 4 2020 Florian Festi <ffesti@redhat.com> - 4.14.3-1
- Rebase to 4.14.3 (#1765187)
* Fri Feb 21 2020 Michal Domonkos <mdomonko@redhat.com> - 4.14.2-37
- Add API safeguard for DNF by using Conflicts: (#1790400)
* Thu Jan 09 2020 Panu Matilainen <pmatilai@redhat.com> - 4.14.2-36
- Revert DBUS shutdown patch, it causes regressions (#1783346)
* Wed Nov 27 2019 Panu Matilainen <pmatilai@redhat.com> - 4.14.2-35
- Revert mistakenly included patch from caret backport
* Thu Nov 21 2019 Panu Matilainen <pmatilai@redhat.com> - 4.14.2-34
- Backport caret version operator (#1654901)
* Thu Nov 21 2019 Panu Matilainen <pmatilai@redhat.com> - 4.14.2-33
- Backport _smp_build_ncpus macro for #1691824 and #1704354
* Thu Nov 21 2019 Panu Matilainen <pmatilai@redhat.com> - 4.14.2-32
- Fix resource leaks on zstd open error
* Mon Nov 18 2019 Florian Festi <ffesti@redhat.com> - 4.14.2-31
- Parallelize /usr/lib/rpm/brp-strip-static-archive (#1691824)
- Parallelize /usr/lib/rpm/check-buildroot (#1704354)
* Tue Nov 12 2019 Panu Matilainen <pmatilai@redhat.com> - 4.14.2-30
- Handle gcc -g3 debug level output in debuginfo (#1630926)
* Thu Oct 24 2019 Panu Matilainen <pmatilai@redhat.com> - 4.14.2-29
- Use Python 3 for the test suite and make it pass (#1724138)
* Thu Oct 24 2019 Panu Matilainen <pmatilai@redhat.com> - 4.14.2-28
- Accept PGP public keys with missing EOL (#1733971)
* Thu Oct 24 2019 Panu Matilainen <pmatilai@redhat.com> - 4.14.2-27
- Support generating build-id's from compressed ELF files (#1650074)
- Compress annobit notes in find-debuginfo (#1719837)
* Wed Oct 16 2019 Panu Matilainen <pmatilai@redhat.com> - 4.14.2-26
- Re-enable support for zstd (#1715799)
* Wed Aug 07 2019 Florian Festi <ffesti@redhat.com> - 4.14.2-25
- Fix memory leak in verify code (#1714657)