import rpm-4.14.2-20.el8

This commit is contained in:
CentOS Sources 2019-08-02 08:54:23 -04:00 committed by Stepan Oksanichenko
commit 3e74ba0e04
37 changed files with 4726 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
SOURCES/rpm-4.14.2.tar.bz2

1
.rpm.metadata Normal file
View File

@ -0,0 +1 @@
1ca664af796ab8d05ea3fccabe2b2e4767a97c74 SOURCES/rpm-4.14.2.tar.bz2

View File

@ -0,0 +1,93 @@
From 1da9e839bb573b9187403983f5a69853ab364306 Mon Sep 17 00:00:00 2001
From: Pavlina Moravcova Varekova <pmoravco@redhat.com>
Date: Sun, 17 Mar 2019 06:47:26 +0100
Subject: [PATCH] Add flag to use strip -g instead of full strip on DSOs
(RhBug:1663264)
The find-debuginfo.sh flag -g had exactly this meaning. But from
version rpm-4.13.0-alpha flag -g changes its behavior. It affects
both libraries and executables.
For some packages the original behavior was preferred. That is why
the new find-debuginfo.sh flag --g-libs is created.
Options -g and --g-libs are mutually exclusive.
Adjusted for rpm-4.14.2 in RHEL
--- rpm-4.14.2/scripts/find-debuginfo.sh.orig 2019-04-24 15:14:29.351010878 +0200
+++ rpm-4.14.2/scripts/find-debuginfo.sh 2019-04-24 15:19:42.296240705 +0200
@@ -4,6 +4,7 @@
#
# Usage: find-debuginfo.sh [--strict-build-id] [-g] [-r] [-m] [-i] [-n]
# [--keep-section SECTION] [--remove-section SECTION]
+# [--g-libs]
# [-j N] [--jobs N]
# [-o debugfiles.list]
# [-S debugsourcefiles.list]
@@ -16,6 +17,8 @@
# [builddir]
#
# The -g flag says to use strip -g instead of full strip on DSOs or EXEs.
+# The --g-libs flag says to use strip -g instead of full strip ONLY on DSOs.
+# Options -g and --g-libs are mutually exclusive.
# The -r flag says to use eu-strip --reloc-debug-sections.
# Use --keep-section SECTION or --remove-section SECTION to explicitly
# keep a (non-allocated) section in the main executable or explicitly
@@ -68,6 +71,9 @@
# With -g arg, pass it to strip on libraries or executables.
strip_g=false
+# With --g-libs arg, pass it to strip on libraries.
+strip_glibs=false
+
# with -r arg, pass --reloc-debug-sections to eu-strip.
strip_r=false
@@ -135,6 +141,9 @@
unique_debug_src_base=$2
shift
;;
+ --g-libs)
+ strip_glibs=true
+ ;;
-g)
strip_g=true
;;
@@ -204,6 +213,11 @@
exit 2
fi
+if ("$strip_g" = "true") && ("$strip_glibs" = "true"); then
+ echo >&2 "*** ERROR: -g and --g-libs cannot be used together"
+ exit 2
+fi
+
i=0
while ((i < nout)); do
outs[$i]="$BUILDDIR/${outs[$i]}"
@@ -237,6 +251,9 @@
application/x-executable*) g=-g ;;
application/x-pie-executable*) g=-g ;;
esac
+ $strip_glibs && case "$(file -bi "$2")" in
+ application/x-sharedlib*) g=-g ;;
+ esac
eu-strip --remove-comment $r $g ${keep_remove_args} -f "$1" "$2" || exit
chmod 444 "$1" || exit
}
@@ -409,8 +426,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
+ if [ "$strip_glibs" = "false" ]; then
+ case "$(file -bi "$f")" in
+ application/x-sharedlib*) skip_mini=false ;;
+ esac
+ fi
case "$(file -bi "$f")" in
- application/x-sharedlib*) skip_mini=false ;;
application/x-executable*) skip_mini=false ;;
esac
$skip_mini || add_minidebug "${debugfn}" "$f"

View File

@ -0,0 +1,38 @@
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,37 @@
From c4f285cff8f830447857e52848ecf909cedb192a Mon Sep 17 00:00:00 2001
Message-Id: <c4f285cff8f830447857e52848ecf909cedb192a.1543566970.git.pmatilai@redhat.com>
From: Panu Matilainen <pmatilai@redhat.com>
Date: Tue, 6 Nov 2018 12:22:55 +0200
Subject: [PATCH] Document --noverify in the man page (RhBug:1646458)
Should've been in commit 765e2c72ae8be369ada41d4747b8999519a0e327
---
doc/rpm.8 | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/doc/rpm.8 b/doc/rpm.8
index 5ab61b2ac..31c51d821 100644
--- a/doc/rpm.8
+++ b/doc/rpm.8
@@ -104,7 +104,7 @@ Scripts and triggers:
[\fB--ignoresize\fR] [\fB--ignorearch\fR] [\fB--ignoreos\fR]
[\fB--includedocs\fR] [\fB--justdb\fR]
[\fB--nodeps\fR] [\fB--nodigest\fR] [\fB--noplugins\fR]
- [\fB--nocaps\fR] [\fB--noorder\fR]
+ [\fB--nocaps\fR] [\fB--noorder\fR] [\fB--noverify\fR]
[\fB--nosignature\fR] [\fB--noscripts\fR] [\fB--notriggers\fR]
[\fB--oldpackage\fR] [\fB--percent\fR] [\fB--prefix \fINEWPATH\fB\fR]
[\fB--relocate \fIOLDPATH\fB=\fINEWPATH\fB\fR]
@@ -315,6 +315,9 @@ Don't set file capabilities.
Don't reorder the packages for an install. The list of
packages would normally be reordered to satisfy dependencies.
.TP
+\fB--noverify\fR
+Don't perform verify package files prior to installation.
+.TP
\fB--noplugins\fR
Do not load and execute plugins.
.TP
--
2.19.2

View File

@ -0,0 +1,152 @@
From 13f70e3710b2df49a923cc6450ff4a8f86e65666 Mon Sep 17 00:00:00 2001
Message-Id: <13f70e3710b2df49a923cc6450ff4a8f86e65666.1555050140.git.pmatilai@redhat.com>
From: Panu Matilainen <pmatilai@redhat.com>
Date: Wed, 20 Mar 2019 12:38:00 +0200
Subject: [PATCH] Fix FA_TOUCH on files with suid/sgid bits and/or capabilities
FA_TOUCH used to set suffix to "" instead of NULL which causes fsmCommit()
to rename the file onto itself, which is a bit dumb but mostly harmless
with regular permission. On suid/sgid/capabilities we strip any extra
privileges on rename to make sure hardlinks are neutered, and because
rename occurs after other permissions etc setting, on FA_TOUCH those
extra privileges are stripped and much brokenness will follow.
A more minimal fix would be a strategically placed strcmp(), but NULL
is what the rest of the fsm expects for no suffix and differentiating
between empty and NULL suffix is too subtle for its own good as
witnessed here. So now, NULL suffix is no suffix again and the rest
of the code will do the right thing except where related to creation,
and creation is what FA_TOUCH wont do so lets just explicitly skip it
and restore the original code otherwise. The goto is ugly but reindenting
gets even uglier, shrug. Add a test-case to go with it.
This has been broken since its introduction in commit
79ca74e15e15c1d91a9a31a9ee90abc91736f390 so all current 4.14.x versions
are affected.
---
lib/fsm.c | 17 ++++++++++----
tests/data/SPECS/replacetest.spec | 2 +-
tests/rpmverify.at | 38 ++++++++++++++++++++++++++++++-
3 files changed, 50 insertions(+), 7 deletions(-)
diff --git a/lib/fsm.c b/lib/fsm.c
index 8eb2c185c..432bcbd90 100644
--- a/lib/fsm.c
+++ b/lib/fsm.c
@@ -898,12 +898,12 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files,
action = rpmfsGetAction(fs, rpmfiFX(fi));
skip = XFA_SKIPPING(action);
- suffix = S_ISDIR(rpmfiFMode(fi)) ? NULL : tid;
if (action != FA_TOUCH) {
- fpath = fsmFsPath(fi, suffix);
+ suffix = S_ISDIR(rpmfiFMode(fi)) ? NULL : tid;
} else {
- fpath = fsmFsPath(fi, "");
+ suffix = NULL;
}
+ fpath = fsmFsPath(fi, suffix);
/* Remap file perms, owner, and group. */
rc = rpmfiStat(fi, 1, &sb);
@@ -926,6 +926,10 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files,
if (!skip) {
int setmeta = 1;
+ /* When touching we don't need any of this... */
+ if (action == FA_TOUCH)
+ goto touch;
+
/* Directories replacing something need early backup */
if (!suffix) {
rc = fsmBackup(fi, action);
@@ -934,7 +938,7 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files,
if (!suffix) {
rc = fsmVerify(fpath, fi);
} else {
- rc = (action == FA_TOUCH) ? 0 : RPMERR_ENOENT;
+ rc = RPMERR_ENOENT;
}
if (S_ISREG(sb.st_mode)) {
@@ -970,11 +974,14 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files,
if (!IS_DEV_LOG(fpath))
rc = RPMERR_UNKNOWN_FILETYPE;
}
+
+touch:
/* Set permissions, timestamps etc for non-hardlink entries */
if (!rc && setmeta) {
rc = fsmSetmeta(fpath, fi, plugins, action, &sb, nofcaps);
}
} else if (firsthardlink >= 0 && rpmfiArchiveHasContent(fi)) {
+ /* On FA_TOUCH no hardlinks are created thus this is skipped. */
/* we skip the hard linked file containing the content */
/* write the content to the first used instead */
char *fn = rpmfilesFN(files, firsthardlink);
@@ -987,7 +994,7 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files,
if (rc) {
if (!skip) {
/* XXX only erase if temp fn w suffix is in use */
- if (suffix && (action != FA_TOUCH)) {
+ if (suffix) {
(void) fsmRemove(fpath, sb.st_mode);
}
errno = saveerrno;
diff --git a/tests/data/SPECS/replacetest.spec b/tests/data/SPECS/replacetest.spec
index 54974567b..d5a1729d3 100644
--- a/tests/data/SPECS/replacetest.spec
+++ b/tests/data/SPECS/replacetest.spec
@@ -46,4 +46,4 @@ rm -rf $RPM_BUILD_ROOT
%files
%defattr(-,%{user},%{grp},-)
-/opt/*
+%{?fileattr} /opt/*
diff --git a/tests/rpmverify.at b/tests/rpmverify.at
index 52ee2abfb..f7dd57531 100644
--- a/tests/rpmverify.at
+++ b/tests/rpmverify.at
@@ -575,3 +575,39 @@
],
[])
AT_CLEANUP
+
+AT_SETUP([Upgraded verification with min_writes 5 (suid files)])
+AT_KEYWORDS([upgrade verify min_writes])
+AT_CHECK([
+RPMDB_CLEAR
+RPMDB_INIT
+tf="${RPMTEST}"/opt/foo
+rm -rf "${tf}" "${tf}".rpm*
+rm -rf "${TOPDIR}"
+
+for v in "1.0" "2.0"; do
+ runroot rpmbuild --quiet -bb \
+ --define "ver $v" \
+ --define "filetype file" \
+ --define "filedata foo" \
+ --define "fileattr %attr(2755,-,-)" \
+ /data/SPECS/replacetest.spec
+done
+
+runroot rpm -U /build/RPMS/noarch/replacetest-1.0-1.noarch.rpm
+runroot rpm -Va --nouser --nogroup replacetest
+runroot rpm -U \
+ --define "_minimize_writes 1" \
+ /build/RPMS/noarch/replacetest-2.0-1.noarch.rpm
+runroot rpm -Va --nouser --nogroup replacetest
+chmod 777 "${tf}"
+runroot rpm -U \
+ --oldpackage \
+ --define "_minimize_writes 1" \
+ /build/RPMS/noarch/replacetest-1.0-1.noarch.rpm
+runroot rpm -Va --nouser --nogroup replacetest
+],
+[0],
+[],
+[])
+AT_CLEANUP
--
2.20.1

View File

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

@ -0,0 +1,39 @@
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,60 @@
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

@ -0,0 +1,28 @@
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,47 @@
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,656 @@
From 84920f898315d09a57a3f1067433eaeb7de5e830 Mon Sep 17 00:00:00 2001
Message-Id: <84920f898315d09a57a3f1067433eaeb7de5e830.1554884444.git.pmatilai@redhat.com>
From: Panu Matilainen <pmatilai@redhat.com>
Date: Fri, 22 Feb 2019 19:44:16 +0200
Subject: [PATCH] In Python 3, return all our string data as surrogate-escaped
utf-8 strings
In the almost ten years of rpm sort of supporting Python 3 bindings, quite
obviously nobody has actually tried to use them. There's a major mismatch
between what the header API outputs (bytes) and what all the other APIs
accept (strings), resulting in hysterical TypeErrors all over the place,
including but not limited to labelCompare() (RhBug:1631292). Also a huge
number of other places have been returning strings and silently assuming
utf-8 through use of Py_BuildValue("s", ...), which will just irrevocably
fail when non-utf8 data is encountered.
The politically Python 3-correct solution would be declaring all our data
as bytes with unspecified encoding - that's exactly what it historically is.
However doing so would by definition break every single rpm script people
have developed on Python 2. And when 99% of the rpm content in the world
actually is utf-8 encoded even if it doesn't say so (and in recent times
packages even advertise themselves as utf-8 encoded), the bytes-only route
seems a wee bit too draconian, even to this grumpy old fella.
Instead, route all our string returns through a single helper macro
which on Python 2 just does what we always did, but in Python 3 converts
the data to surrogate-escaped utf-8 strings. This makes stuff "just work"
out of the box pretty much everywhere even with Python 3 (including
our own test-suite!), while still allowing to handle the non-utf8 case.
Handling the non-utf8 case is a bit more uglier but still possible,
which is exactly how you want corner-cases to be. There might be some
uses for retrieving raw byte data from the header, but worrying about
such an API is a case for some other rainy day, for now we mostly only
care that stuff works again.
Also add test-cases for mixed data source labelCompare() and
non-utf8 insert to + retrieve from header.
---
python/header-py.c | 2 +-
python/rpmds-py.c | 8 ++++----
python/rpmfd-py.c | 6 +++---
python/rpmfi-py.c | 24 ++++++++++++------------
python/rpmfiles-py.c | 26 +++++++++++++-------------
python/rpmkeyring-py.c | 2 +-
python/rpmmacro-py.c | 2 +-
python/rpmmodule.c | 2 +-
python/rpmps-py.c | 8 ++++----
python/rpmstrpool-py.c | 2 +-
python/rpmsystem-py.h | 7 +++++++
python/rpmtd-py.c | 2 +-
python/rpmte-py.c | 16 ++++++++--------
python/rpmts-py.c | 11 ++++++-----
python/spec-py.c | 8 ++++----
tests/local.at | 1 +
tests/rpmpython.at | 34 ++++++++++++++++++++++++++++++++++
17 files changed, 102 insertions(+), 59 deletions(-)
diff --git a/python/header-py.c b/python/header-py.c
index c9d54e869..93c241cb7 100644
--- a/python/header-py.c
+++ b/python/header-py.c
@@ -231,7 +231,7 @@ static PyObject * hdrFormat(hdrObject * s, PyObject * args, PyObject * kwds)
return NULL;
}
- result = Py_BuildValue("s", r);
+ result = utf8FromString(r);
free(r);
return result;
diff --git a/python/rpmds-py.c b/python/rpmds-py.c
index 39b26628e..ecc9af9d5 100644
--- a/python/rpmds-py.c
+++ b/python/rpmds-py.c
@@ -31,19 +31,19 @@ rpmds_Ix(rpmdsObject * s)
static PyObject *
rpmds_DNEVR(rpmdsObject * s)
{
- return Py_BuildValue("s", rpmdsDNEVR(s->ds));
+ return utf8FromString(rpmdsDNEVR(s->ds));
}
static PyObject *
rpmds_N(rpmdsObject * s)
{
- return Py_BuildValue("s", rpmdsN(s->ds));
+ return utf8FromString(rpmdsN(s->ds));
}
static PyObject *
rpmds_EVR(rpmdsObject * s)
{
- return Py_BuildValue("s", rpmdsEVR(s->ds));
+ return utf8FromString(rpmdsEVR(s->ds));
}
static PyObject *
@@ -261,7 +261,7 @@ rpmds_subscript(rpmdsObject * s, PyObject * key)
ix = (int) PyInt_AsLong(key);
rpmdsSetIx(s->ds, ix);
- return Py_BuildValue("s", rpmdsDNEVR(s->ds));
+ return utf8FromString(rpmdsDNEVR(s->ds));
}
static PyMappingMethods rpmds_as_mapping = {
diff --git a/python/rpmfd-py.c b/python/rpmfd-py.c
index 85fb0cd24..4b05cce5f 100644
--- a/python/rpmfd-py.c
+++ b/python/rpmfd-py.c
@@ -327,17 +327,17 @@ static PyObject *rpmfd_get_closed(rpmfdObject *s)
static PyObject *rpmfd_get_name(rpmfdObject *s)
{
/* XXX: rpm returns non-paths with [mumble], python files use <mumble> */
- return Py_BuildValue("s", Fdescr(s->fd));
+ return utf8FromString(Fdescr(s->fd));
}
static PyObject *rpmfd_get_mode(rpmfdObject *s)
{
- return Py_BuildValue("s", s->mode);
+ return utf8FromString(s->mode);
}
static PyObject *rpmfd_get_flags(rpmfdObject *s)
{
- return Py_BuildValue("s", s->flags);
+ return utf8FromString(s->flags);
}
static PyGetSetDef rpmfd_getseters[] = {
diff --git a/python/rpmfi-py.c b/python/rpmfi-py.c
index 8d2f926d0..db405c231 100644
--- a/python/rpmfi-py.c
+++ b/python/rpmfi-py.c
@@ -41,19 +41,19 @@ rpmfi_DX(rpmfiObject * s, PyObject * unused)
static PyObject *
rpmfi_BN(rpmfiObject * s, PyObject * unused)
{
- return Py_BuildValue("s", rpmfiBN(s->fi));
+ return utf8FromString(rpmfiBN(s->fi));
}
static PyObject *
rpmfi_DN(rpmfiObject * s, PyObject * unused)
{
- return Py_BuildValue("s", rpmfiDN(s->fi));
+ return utf8FromString(rpmfiDN(s->fi));
}
static PyObject *
rpmfi_FN(rpmfiObject * s, PyObject * unused)
{
- return Py_BuildValue("s", rpmfiFN(s->fi));
+ return utf8FromString(rpmfiFN(s->fi));
}
static PyObject *
@@ -98,7 +98,7 @@ rpmfi_Digest(rpmfiObject * s, PyObject * unused)
{
char *digest = rpmfiFDigestHex(s->fi, NULL);
if (digest) {
- PyObject *dig = Py_BuildValue("s", digest);
+ PyObject *dig = utf8FromString(digest);
free(digest);
return dig;
} else {
@@ -109,7 +109,7 @@ rpmfi_Digest(rpmfiObject * s, PyObject * unused)
static PyObject *
rpmfi_FLink(rpmfiObject * s, PyObject * unused)
{
- return Py_BuildValue("s", rpmfiFLink(s->fi));
+ return utf8FromString(rpmfiFLink(s->fi));
}
static PyObject *
@@ -133,13 +133,13 @@ rpmfi_FMtime(rpmfiObject * s, PyObject * unused)
static PyObject *
rpmfi_FUser(rpmfiObject * s, PyObject * unused)
{
- return Py_BuildValue("s", rpmfiFUser(s->fi));
+ return utf8FromString(rpmfiFUser(s->fi));
}
static PyObject *
rpmfi_FGroup(rpmfiObject * s, PyObject * unused)
{
- return Py_BuildValue("s", rpmfiFGroup(s->fi));
+ return utf8FromString(rpmfiFGroup(s->fi));
}
static PyObject *
@@ -155,7 +155,7 @@ rpmfi_FClass(rpmfiObject * s, PyObject * unused)
if ((FClass = rpmfiFClass(s->fi)) == NULL)
FClass = "";
- return Py_BuildValue("s", FClass);
+ return utf8FromString(FClass);
}
static PyObject *
@@ -208,7 +208,7 @@ rpmfi_iternext(rpmfiObject * s)
Py_INCREF(Py_None);
PyTuple_SET_ITEM(result, 0, Py_None);
} else
- PyTuple_SET_ITEM(result, 0, Py_BuildValue("s", FN));
+ PyTuple_SET_ITEM(result, 0, utf8FromString(FN));
PyTuple_SET_ITEM(result, 1, PyLong_FromLongLong(FSize));
PyTuple_SET_ITEM(result, 2, PyInt_FromLong(FMode));
PyTuple_SET_ITEM(result, 3, PyInt_FromLong(FMtime));
@@ -222,12 +222,12 @@ rpmfi_iternext(rpmfiObject * s)
Py_INCREF(Py_None);
PyTuple_SET_ITEM(result, 10, Py_None);
} else
- PyTuple_SET_ITEM(result, 10, Py_BuildValue("s", FUser));
+ PyTuple_SET_ITEM(result, 10, utf8FromString(FUser));
if (FGroup == NULL) {
Py_INCREF(Py_None);
PyTuple_SET_ITEM(result, 11, Py_None);
} else
- PyTuple_SET_ITEM(result, 11, Py_BuildValue("s", FGroup));
+ PyTuple_SET_ITEM(result, 11, utf8FromString(FGroup));
PyTuple_SET_ITEM(result, 12, rpmfi_Digest(s, NULL));
} else
@@ -313,7 +313,7 @@ rpmfi_subscript(rpmfiObject * s, PyObject * key)
ix = (int) PyInt_AsLong(key);
rpmfiSetFX(s->fi, ix);
- return Py_BuildValue("s", rpmfiFN(s->fi));
+ return utf8FromString(rpmfiFN(s->fi));
}
static PyMappingMethods rpmfi_as_mapping = {
diff --git a/python/rpmfiles-py.c b/python/rpmfiles-py.c
index bc07dbeaf..557246cae 100644
--- a/python/rpmfiles-py.c
+++ b/python/rpmfiles-py.c
@@ -41,37 +41,37 @@ static PyObject *rpmfile_dx(rpmfileObject *s)
static PyObject *rpmfile_name(rpmfileObject *s)
{
char * fn = rpmfilesFN(s->files, s->ix);
- PyObject *o = Py_BuildValue("s", fn);
+ PyObject *o = utf8FromString(fn);
free(fn);
return o;
}
static PyObject *rpmfile_basename(rpmfileObject *s)
{
- return Py_BuildValue("s", rpmfilesBN(s->files, s->ix));
+ return utf8FromString(rpmfilesBN(s->files, s->ix));
}
static PyObject *rpmfile_dirname(rpmfileObject *s)
{
- return Py_BuildValue("s", rpmfilesDN(s->files, rpmfilesDI(s->files, s->ix)));
+ return utf8FromString(rpmfilesDN(s->files, rpmfilesDI(s->files, s->ix)));
}
static PyObject *rpmfile_orig_name(rpmfileObject *s)
{
char * fn = rpmfilesOFN(s->files, s->ix);
- PyObject *o = Py_BuildValue("s", fn);
+ PyObject *o = utf8FromString(fn);
free(fn);
return o;
}
static PyObject *rpmfile_orig_basename(rpmfileObject *s)
{
- return Py_BuildValue("s", rpmfilesOBN(s->files, s->ix));
+ return utf8FromString(rpmfilesOBN(s->files, s->ix));
}
static PyObject *rpmfile_orig_dirname(rpmfileObject *s)
{
- return Py_BuildValue("s", rpmfilesODN(s->files, rpmfilesODI(s->files, s->ix)));
+ return utf8FromString(rpmfilesODN(s->files, rpmfilesODI(s->files, s->ix)));
}
static PyObject *rpmfile_mode(rpmfileObject *s)
{
@@ -105,17 +105,17 @@ static PyObject *rpmfile_nlink(rpmfileObject *s)
static PyObject *rpmfile_linkto(rpmfileObject *s)
{
- return Py_BuildValue("s", rpmfilesFLink(s->files, s->ix));
+ return utf8FromString(rpmfilesFLink(s->files, s->ix));
}
static PyObject *rpmfile_user(rpmfileObject *s)
{
- return Py_BuildValue("s", rpmfilesFUser(s->files, s->ix));
+ return utf8FromString(rpmfilesFUser(s->files, s->ix));
}
static PyObject *rpmfile_group(rpmfileObject *s)
{
- return Py_BuildValue("s", rpmfilesFGroup(s->files, s->ix));
+ return utf8FromString(rpmfilesFGroup(s->files, s->ix));
}
static PyObject *rpmfile_fflags(rpmfileObject *s)
@@ -145,7 +145,7 @@ static PyObject *rpmfile_digest(rpmfileObject *s)
NULL, &diglen);
if (digest) {
char * hex = pgpHexStr(digest, diglen);
- PyObject *o = Py_BuildValue("s", hex);
+ PyObject *o = utf8FromString(hex);
free(hex);
return o;
}
@@ -154,17 +154,17 @@ static PyObject *rpmfile_digest(rpmfileObject *s)
static PyObject *rpmfile_class(rpmfileObject *s)
{
- return Py_BuildValue("s", rpmfilesFClass(s->files, s->ix));
+ return utf8FromString(rpmfilesFClass(s->files, s->ix));
}
static PyObject *rpmfile_caps(rpmfileObject *s)
{
- return Py_BuildValue("s", rpmfilesFCaps(s->files, s->ix));
+ return utf8FromString(rpmfilesFCaps(s->files, s->ix));
}
static PyObject *rpmfile_langs(rpmfileObject *s)
{
- return Py_BuildValue("s", rpmfilesFLangs(s->files, s->ix));
+ return utf8FromString(rpmfilesFLangs(s->files, s->ix));
}
static PyObject *rpmfile_links(rpmfileObject *s)
diff --git a/python/rpmkeyring-py.c b/python/rpmkeyring-py.c
index d5f131e42..8968e0513 100644
--- a/python/rpmkeyring-py.c
+++ b/python/rpmkeyring-py.c
@@ -38,7 +38,7 @@ static PyObject *rpmPubkey_new(PyTypeObject *subtype,
static PyObject * rpmPubkey_Base64(rpmPubkeyObject *s)
{
char *b64 = rpmPubkeyBase64(s->pubkey);
- PyObject *res = Py_BuildValue("s", b64);
+ PyObject *res = utf8FromString(b64);
free(b64);
return res;
}
diff --git a/python/rpmmacro-py.c b/python/rpmmacro-py.c
index 3cb1a51f5..d8a365547 100644
--- a/python/rpmmacro-py.c
+++ b/python/rpmmacro-py.c
@@ -52,7 +52,7 @@ rpmmacro_ExpandMacro(PyObject * self, PyObject * args, PyObject * kwds)
if (rpmExpandMacros(NULL, macro, &str, 0) < 0)
PyErr_SetString(pyrpmError, "error expanding macro");
else
- res = Py_BuildValue("s", str);
+ res = utf8FromString(str);
free(str);
}
return res;
diff --git a/python/rpmmodule.c b/python/rpmmodule.c
index 3faad23c7..05032edc7 100644
--- a/python/rpmmodule.c
+++ b/python/rpmmodule.c
@@ -237,7 +237,7 @@ static void addRpmTags(PyObject *module)
PyModule_AddIntConstant(module, tagname, tagval);
pyval = PyInt_FromLong(tagval);
- pyname = Py_BuildValue("s", shortname);
+ pyname = utf8FromString(shortname);
PyDict_SetItem(dict, pyval, pyname);
Py_DECREF(pyval);
Py_DECREF(pyname);
diff --git a/python/rpmps-py.c b/python/rpmps-py.c
index bdc899a60..902b2ae63 100644
--- a/python/rpmps-py.c
+++ b/python/rpmps-py.c
@@ -18,12 +18,12 @@ static PyObject *rpmprob_get_type(rpmProblemObject *s, void *closure)
static PyObject *rpmprob_get_pkgnevr(rpmProblemObject *s, void *closure)
{
- return Py_BuildValue("s", rpmProblemGetPkgNEVR(s->prob));
+ return utf8FromString(rpmProblemGetPkgNEVR(s->prob));
}
static PyObject *rpmprob_get_altnevr(rpmProblemObject *s, void *closure)
{
- return Py_BuildValue("s", rpmProblemGetAltNEVR(s->prob));
+ return utf8FromString(rpmProblemGetAltNEVR(s->prob));
}
static PyObject *rpmprob_get_key(rpmProblemObject *s, void *closure)
@@ -38,7 +38,7 @@ static PyObject *rpmprob_get_key(rpmProblemObject *s, void *closure)
static PyObject *rpmprob_get_str(rpmProblemObject *s, void *closure)
{
- return Py_BuildValue("s", rpmProblemGetStr(s->prob));
+ return utf8FromString(rpmProblemGetStr(s->prob));
}
static PyObject *rpmprob_get_num(rpmProblemObject *s, void *closure)
@@ -59,7 +59,7 @@ static PyGetSetDef rpmprob_getseters[] = {
static PyObject *rpmprob_str(rpmProblemObject *s)
{
char *str = rpmProblemString(s->prob);
- PyObject *res = Py_BuildValue("s", str);
+ PyObject *res = utf8FromString(str);
free(str);
return res;
}
diff --git a/python/rpmstrpool-py.c b/python/rpmstrpool-py.c
index 356bd1de5..a56e2b540 100644
--- a/python/rpmstrpool-py.c
+++ b/python/rpmstrpool-py.c
@@ -44,7 +44,7 @@ static PyObject *strpool_id2str(rpmstrPoolObject *s, PyObject *item)
const char *str = rpmstrPoolStr(s->pool, id);
if (str)
- ret = PyBytes_FromString(str);
+ ret = utf8FromString(str);
else
PyErr_SetObject(PyExc_KeyError, item);
}
diff --git a/python/rpmsystem-py.h b/python/rpmsystem-py.h
index 955d60cd3..87c750571 100644
--- a/python/rpmsystem-py.h
+++ b/python/rpmsystem-py.h
@@ -19,4 +19,11 @@
#define PyInt_AsSsize_t PyLong_AsSsize_t
#endif
+/* In Python 3, we return all strings as surrogate-escaped utf-8 */
+#if PY_MAJOR_VERSION >= 3
+#define utf8FromString(_s) PyUnicode_DecodeUTF8(_s, strlen(_s), "surrogateescape")
+#else
+#define utf8FromString(_s) PyBytes_FromString(_s)
+#endif
+
#endif /* H_SYSTEM_PYTHON */
diff --git a/python/rpmtd-py.c b/python/rpmtd-py.c
index 247c7502a..23ca10517 100644
--- a/python/rpmtd-py.c
+++ b/python/rpmtd-py.c
@@ -17,7 +17,7 @@ PyObject * rpmtd_ItemAsPyobj(rpmtd td, rpmTagClass tclass)
switch (tclass) {
case RPM_STRING_CLASS:
- res = PyBytes_FromString(rpmtdGetString(td));
+ res = utf8FromString(rpmtdGetString(td));
break;
case RPM_NUMERIC_CLASS:
res = PyLong_FromLongLong(rpmtdGetNumber(td));
diff --git a/python/rpmte-py.c b/python/rpmte-py.c
index 99ff2f496..2b3745754 100644
--- a/python/rpmte-py.c
+++ b/python/rpmte-py.c
@@ -54,49 +54,49 @@ rpmte_TEType(rpmteObject * s, PyObject * unused)
static PyObject *
rpmte_N(rpmteObject * s, PyObject * unused)
{
- return Py_BuildValue("s", rpmteN(s->te));
+ return utf8FromString(rpmteN(s->te));
}
static PyObject *
rpmte_E(rpmteObject * s, PyObject * unused)
{
- return Py_BuildValue("s", rpmteE(s->te));
+ return utf8FromString(rpmteE(s->te));
}
static PyObject *
rpmte_V(rpmteObject * s, PyObject * unused)
{
- return Py_BuildValue("s", rpmteV(s->te));
+ return utf8FromString(rpmteV(s->te));
}
static PyObject *
rpmte_R(rpmteObject * s, PyObject * unused)
{
- return Py_BuildValue("s", rpmteR(s->te));
+ return utf8FromString(rpmteR(s->te));
}
static PyObject *
rpmte_A(rpmteObject * s, PyObject * unused)
{
- return Py_BuildValue("s", rpmteA(s->te));
+ return utf8FromString(rpmteA(s->te));
}
static PyObject *
rpmte_O(rpmteObject * s, PyObject * unused)
{
- return Py_BuildValue("s", rpmteO(s->te));
+ return utf8FromString(rpmteO(s->te));
}
static PyObject *
rpmte_NEVR(rpmteObject * s, PyObject * unused)
{
- return Py_BuildValue("s", rpmteNEVR(s->te));
+ return utf8FromString(rpmteNEVR(s->te));
}
static PyObject *
rpmte_NEVRA(rpmteObject * s, PyObject * unused)
{
- return Py_BuildValue("s", rpmteNEVRA(s->te));
+ return utf8FromString(rpmteNEVRA(s->te));
}
static PyObject *
diff --git a/python/rpmts-py.c b/python/rpmts-py.c
index 1ddfc9a1e..96e3bb28e 100644
--- a/python/rpmts-py.c
+++ b/python/rpmts-py.c
@@ -230,8 +230,9 @@ rpmts_SolveCallback(rpmts ts, rpmds ds, const void * data)
PyEval_RestoreThread(cbInfo->_save);
- args = Py_BuildValue("(Oissi)", cbInfo->tso,
- rpmdsTagN(ds), rpmdsN(ds), rpmdsEVR(ds), rpmdsFlags(ds));
+ args = Py_BuildValue("(OiNNi)", cbInfo->tso,
+ rpmdsTagN(ds), utf8FromString(rpmdsN(ds)),
+ utf8FromString(rpmdsEVR(ds)), rpmdsFlags(ds));
result = PyEval_CallObject(cbInfo->cb, args);
Py_DECREF(args);
@@ -409,7 +410,7 @@ rpmts_HdrCheck(rpmtsObject * s, PyObject *obj)
rpmrc = headerCheck(s->ts, uh, uc, &msg);
Py_END_ALLOW_THREADS;
- return Py_BuildValue("(is)", rpmrc, msg);
+ return Py_BuildValue("(iN)", rpmrc, utf8FromString(msg));
}
static PyObject *
@@ -500,7 +501,7 @@ rpmtsCallback(const void * hd, const rpmCallbackType what,
/* Synthesize a python object for callback (if necessary). */
if (pkgObj == NULL) {
if (h) {
- pkgObj = Py_BuildValue("s", headerGetString(h, RPMTAG_NAME));
+ pkgObj = utf8FromString(headerGetString(h, RPMTAG_NAME));
} else {
pkgObj = Py_None;
Py_INCREF(pkgObj);
@@ -845,7 +846,7 @@ static PyObject *rpmts_get_tid(rpmtsObject *s, void *closure)
static PyObject *rpmts_get_rootDir(rpmtsObject *s, void *closure)
{
- return Py_BuildValue("s", rpmtsRootDir(s->ts));
+ return utf8FromString(rpmtsRootDir(s->ts));
}
static int rpmts_set_scriptFd(rpmtsObject *s, PyObject *value, void *closure)
diff --git a/python/spec-py.c b/python/spec-py.c
index 4efdbf4bf..70b796531 100644
--- a/python/spec-py.c
+++ b/python/spec-py.c
@@ -57,7 +57,7 @@ static PyObject *pkgGetSection(rpmSpecPkg pkg, int section)
{
char *sect = rpmSpecPkgGetSection(pkg, section);
if (sect != NULL) {
- PyObject *ps = PyBytes_FromString(sect);
+ PyObject *ps = utf8FromString(sect);
free(sect);
if (ps != NULL)
return ps;
@@ -158,7 +158,7 @@ static PyObject * getSection(rpmSpec spec, int section)
{
const char *sect = rpmSpecGetSection(spec, section);
if (sect) {
- return Py_BuildValue("s", sect);
+ return utf8FromString(sect);
}
Py_RETURN_NONE;
}
@@ -208,8 +208,8 @@ static PyObject * spec_get_sources(specObject *s, void *closure)
rpmSpecSrcIter iter = rpmSpecSrcIterInit(s->spec);
while ((source = rpmSpecSrcIterNext(iter)) != NULL) {
- PyObject *srcUrl = Py_BuildValue("(sii)",
- rpmSpecSrcFilename(source, 1),
+ PyObject *srcUrl = Py_BuildValue("(Nii)",
+ utf8FromString(rpmSpecSrcFilename(source, 1)),
rpmSpecSrcNum(source),
rpmSpecSrcFlags(source));
if (!srcUrl) {
diff --git a/tests/local.at b/tests/local.at
index 02ead66c9..42eef1c75 100644
--- a/tests/local.at
+++ b/tests/local.at
@@ -10,6 +10,7 @@ rm -rf "${abs_builddir}"/testing`rpm --eval '%_dbpath'`/*
m4_define([RPMPY_RUN],[[
cat << EOF > test.py
+# coding=utf-8
import rpm, sys
dbpath=rpm.expandMacro('%_dbpath')
rpm.addMacro('_dbpath', '${abs_builddir}/testing%s' % dbpath)
diff --git a/tests/rpmpython.at b/tests/rpmpython.at
index ff77f868c..58f3e84a6 100644
--- a/tests/rpmpython.at
+++ b/tests/rpmpython.at
@@ -106,6 +106,25 @@ None
'rpm.hdr' object has no attribute '__foo__']
)
+RPMPY_TEST([non-utf8 data in header],[
+str = u'älämölö'
+enc = 'iso-8859-1'
+b = str.encode(enc)
+h = rpm.hdr()
+h['group'] = b
+d = h['group']
+try:
+ # python 3
+ t = bytes(d, 'utf-8', 'surrogateescape')
+except TypeError:
+ # python 2
+ t = bytes(d)
+res = t.decode(enc)
+myprint(str == res)
+],
+[True]
+)
+
RPMPY_TEST([invalid header data],[
h1 = rpm.hdr()
h1['basenames'] = ['bing', 'bang', 'bong']
@@ -125,6 +144,21 @@ for h in [h1, h2]:
/opt/bing,/opt/bang,/flopt/bong]
)
+RPMPY_TEST([labelCompare],[
+v = '1.0'
+r = '1'
+e = 3
+h = rpm.hdr()
+h['name'] = 'testpkg'
+h['version'] = v
+h['release'] = r
+h['epoch'] = e
+myprint(rpm.labelCompare((str(h['epoch']), h['version'], h['release']),
+ (str(e), v, r)))
+],
+[0]
+)
+
RPMPY_TEST([vfyflags API],[
ts = rpm.ts()
dlv = ts.getVfyFlags()
--
2.20.1

View File

@ -0,0 +1,86 @@
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,49 @@
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

@ -0,0 +1,28 @@
From 57b4f21634429ccd29d47cf93ec0841f70b68404 Mon Sep 17 00:00:00 2001
Message-Id: <57b4f21634429ccd29d47cf93ec0841f70b68404.1545311826.git.pmatilai@redhat.com>
From: Panu Matilainen <pmatilai@redhat.com>
Date: Tue, 18 Sep 2018 11:02:36 +0300
Subject: [PATCH] Mark elements with associated problems as failed
An element with a problem can not possibly succeed so mark these failures
early. Doesn't make much of a difference as problems will prevent the
transaction from starting in the first place but it makes sense anyway.
---
lib/rpmte.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/lib/rpmte.c b/lib/rpmte.c
index 4bdeeaf68..c5d614f67 100644
--- a/lib/rpmte.c
+++ b/lib/rpmte.c
@@ -703,6 +703,7 @@ static void appendProblem(rpmte te, rpmProblemType type,
if (te->probs == NULL)
te->probs = rpmpsCreate();
rpmpsAppendProblem(te->probs, p);
+ rpmteMarkFailed(te);
}
rpmProblemFree(p);
}
--
2.19.2

View File

@ -0,0 +1,89 @@
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

@ -0,0 +1,80 @@
From 362c4401979f896de1e69a3e18d33954953912cc Mon Sep 17 00:00:00 2001
Message-Id: <362c4401979f896de1e69a3e18d33954953912cc.1554983588.git.pmatilai@redhat.com>
From: Panu Matilainen <pmatilai@redhat.com>
Date: Tue, 11 Dec 2018 13:21:47 +0200
Subject: [PATCH] Only read through payload on verify if actually needed
If none of our verify items ranges over the payload, then why bother?
To do this, add an internal rpmvs API to get it's range, and use
that to decide whether trip over the payload is needed or not.
In addition, the payload digest tag needs to be grabbed outside of the
condition to avoid depending on other values. The details including
RPMVSF_NEEDPAYLOAD will be handled internally to rpmvs which makes it
actually nicer code-wise too.
---
lib/rpmchecksig.c | 8 ++++----
lib/rpmvs.c | 12 ++++++++++++
lib/rpmvs.h | 3 +++
3 files changed, 19 insertions(+), 4 deletions(-)
diff --git a/lib/rpmchecksig.c b/lib/rpmchecksig.c
index 1ba72a45e..810f7153d 100644
--- a/lib/rpmchecksig.c
+++ b/lib/rpmchecksig.c
@@ -187,11 +187,11 @@ rpmRC rpmpkgRead(struct rpmvs_s *vs, FD_t fd,
/* Finalize header range */
rpmvsFiniRange(vs, RPMSIG_HEADER);
- /* Unless disabled, read the payload, generating digest(s) on the fly. */
- if (!(rpmvsFlags(vs) & RPMVSF_NEEDPAYLOAD)) {
- /* Fish interesting tags from the main header. This is a bit hacky... */
- rpmvsAppendTag(vs, blob, RPMTAG_PAYLOADDIGEST);
+ /* Fish interesting tags from the main header. This is a bit hacky... */
+ rpmvsAppendTag(vs, blob, RPMTAG_PAYLOADDIGEST);
+ /* If needed and not explicitly disabled, read the payload as well. */
+ if (rpmvsRange(vs) & RPMSIG_PAYLOAD) {
/* Initialize digests ranging over the payload only */
rpmvsInitRange(vs, RPMSIG_PAYLOAD);
diff --git a/lib/rpmvs.c b/lib/rpmvs.c
index 622e48011..0d475af86 100644
--- a/lib/rpmvs.c
+++ b/lib/rpmvs.c
@@ -396,6 +396,18 @@ void rpmvsFiniRange(struct rpmvs_s *sis, int range)
}
}
+int rpmvsRange(struct rpmvs_s *vs)
+{
+ int range = 0;
+ for (int i = 0; i < vs->nsigs; i++) {
+ if (rpmsinfoDisabled(&vs->sigs[i], vs->vsflags))
+ continue;
+ range |= vs->sigs[i].range;
+ }
+
+ return range;
+}
+
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
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);
--
2.20.1

View File

@ -0,0 +1,41 @@
From aea53a4aead8bd71f519df35fcffd9eec76fbc01 Mon Sep 17 00:00:00 2001
Message-Id: <aea53a4aead8bd71f519df35fcffd9eec76fbc01.1554884465.git.pmatilai@redhat.com>
From: Panu Matilainen <pmatilai@redhat.com>
Date: Tue, 26 Feb 2019 11:27:51 +0200
Subject: [PATCH] Return NULL string as None from utf8FromString()
Commit 84920f898315d09a57a3f1067433eaeb7de5e830 regressed dnf install
to segfault at the end due to some NULL string passed to strlen().
Check for NULL and return it as None, make it an inline function
to make this saner.
---
python/rpmsystem-py.h | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/python/rpmsystem-py.h b/python/rpmsystem-py.h
index 87c750571..25938464a 100644
--- a/python/rpmsystem-py.h
+++ b/python/rpmsystem-py.h
@@ -19,11 +19,17 @@
#define PyInt_AsSsize_t PyLong_AsSsize_t
#endif
+static inline PyObject * utf8FromString(const char *s)
+{
/* In Python 3, we return all strings as surrogate-escaped utf-8 */
#if PY_MAJOR_VERSION >= 3
-#define utf8FromString(_s) PyUnicode_DecodeUTF8(_s, strlen(_s), "surrogateescape")
+ if (s != NULL)
+ return PyUnicode_DecodeUTF8(s, strlen(s), "surrogateescape");
#else
-#define utf8FromString(_s) PyBytes_FromString(_s)
+ if (s != NULL)
+ return PyBytes_FromString(s);
#endif
+ Py_RETURN_NONE;
+}
#endif /* H_SYSTEM_PYTHON */
--
2.20.1

View File

@ -0,0 +1,57 @@
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

@ -0,0 +1,27 @@
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,64 @@
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,114 @@
From df089e178da0918dc74a8572a99324b0987bce30 Mon Sep 17 00:00:00 2001
Message-Id: <df089e178da0918dc74a8572a99324b0987bce30.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:56:34 +0200
Subject: [PATCH 3/3] Verify packages before signing (RhBug:1646388)
Permitting corrupted packages to be signed is bad business for everybody
involved, this is something we should've always done. Besides being an
actual security risk, it can lead to odd results with verification
especially with the payload digest on signed packages.
One point worth noting is that this means that pre 4.14-packages cannot
be signed in FIPS mode now because there's no way to validate the package
payload range due to MD5 being disabled. This seems like a feature and
not a limitation, so disabler for the verify step intentionally left out.
Optimally we'd verify the package on the same read that's passed
to gpg but for simplicitys sake that's left as an future exercise,
now we simply read the package twice.
---
sign/rpmgensig.c | 32 ++++++++++++++++++++++++++++++++
tests/rpmsigdig.at | 20 ++++++++++++++++++++
2 files changed, 52 insertions(+)
diff --git a/sign/rpmgensig.c b/sign/rpmgensig.c
index 2bcbab768..5be542001 100644
--- a/sign/rpmgensig.c
+++ b/sign/rpmgensig.c
@@ -21,6 +21,7 @@
#include "lib/rpmlead.h"
#include "lib/signature.h"
+#include "lib/rpmvs.h"
#include "sign/rpmsignfiles.h"
#include "debug.h"
@@ -489,6 +490,31 @@ static rpmRC includeFileSignatures(Header *sigp, Header *hdrp)
#endif
}
+static int msgCb(struct rpmsinfo_s *sinfo, void *cbdata)
+{
+ char **msg = cbdata;
+ if (sinfo->rc && *msg == NULL)
+ *msg = rpmsinfoMsg(sinfo);
+ return (sinfo->rc != RPMRC_FAIL);
+}
+
+/* Require valid digests on entire package for signing. */
+static int checkPkg(FD_t fd, char **msg)
+{
+ int rc;
+ struct rpmvs_s *vs = rpmvsCreate(RPMSIG_DIGEST_TYPE, 0, NULL);
+ off_t offset = Ftell(fd);
+
+ Fseek(fd, 0, SEEK_SET);
+ rc = rpmpkgRead(vs, fd, NULL, NULL, msg);
+ if (!rc)
+ rc = rpmvsVerify(vs, RPMSIG_DIGEST_TYPE, msgCb, msg);
+ Fseek(fd, offset, SEEK_SET);
+
+ rpmvsFree(vs);
+ return rc;
+}
+
/** \ingroup rpmcli
* Create/modify elements in signature header.
* @param rpm path to package
@@ -519,6 +545,12 @@ static int rpmSign(const char *rpm, int deleting, int signfiles)
if (manageFile(&fd, rpm, O_RDWR))
goto exit;
+ /* Ensure package is intact before attempting to sign */
+ if ((rc = checkPkg(fd, &msg))) {
+ rpmlog(RPMLOG_ERR, "not signing corrupt package %s: %s\n", rpm, msg);
+ goto exit;
+ }
+
if ((rc = rpmLeadRead(fd, &msg)) != RPMRC_OK) {
rpmlog(RPMLOG_ERR, "%s: %s\n", rpm, msg);
goto exit;
diff --git a/tests/rpmsigdig.at b/tests/rpmsigdig.at
index 413c3d2c8..e93420306 100644
--- a/tests/rpmsigdig.at
+++ b/tests/rpmsigdig.at
@@ -472,3 +472,23 @@ run rpmsign --key-id 1964C5FC --addsign "${RPMTEST}"/tmp/hello-2.0-1.x86_64-sign
[],
[])
AT_CLEANUP
+
+AT_SETUP([rpmsign --addsign <corrupted>])
+AT_KEYWORDS([rpmsign signature])
+AT_CHECK([
+RPMDB_CLEAR
+RPMDB_INIT
+rm -rf "${TOPDIR}"
+
+pkg="hello-2.0-1.x86_64.rpm"
+cp "${RPMTEST}"/data/RPMS/${pkg} "${RPMTEST}"/tmp/${pkg}
+dd if=/dev/zero of="${RPMTEST}"/tmp/${pkg} \
+ conv=notrunc bs=1 seek=333 count=4 2> /dev/null
+run rpmsign --key-id 1964C5FC --addsign "${RPMTEST}/tmp/${pkg}"
+],
+[1],
+[/home/pmatilai/repos/rpm/tests/testing/tmp/hello-2.0-1.x86_64.rpm:
+],
+[error: not signing corrupt package /home/pmatilai/repos/rpm/tests/testing/tmp/hello-2.0-1.x86_64.rpm: MD5 digest: BAD (Expected 007ca1d8b35cca02a1854ba301c5432e != 137ca1d8b35cca02a1854ba301c5432e)
+])
+AT_CLEANUP
--
2.20.1

View File

@ -0,0 +1,26 @@
From 682397a8e2758058f780cccd51b570d39415b9b2 Mon Sep 17 00:00:00 2001
From: Tomas Orsava <torsava@redhat.com>
Date: Tue, 3 Jul 2018 14:58:32 +0200
Subject: [PATCH] Compile with Platform-Python binary where relevant
---
scripts/brp-python-bytecompile | 3 +++
1 file changed, 3 insertions(+)
diff --git a/scripts/brp-python-bytecompile b/scripts/brp-python-bytecompile
index 7ed1d7f..9d0a421 100644
--- a/scripts/brp-python-bytecompile
+++ b/scripts/brp-python-bytecompile
@@ -60,6 +60,9 @@ shopt -s nullglob
for python_libdir in `find "$RPM_BUILD_ROOT" -type d|grep -E "/usr/lib(64)?/python[0-9]\.[0-9]$"`;
do
python_binary=/usr/bin/$(basename $python_libdir)
+ if [ "$python_binary" = "/usr/bin/python3.6" ]; then
+ python_binary=/usr/libexec/platform-python
+ fi
real_libdir=${python_libdir/$RPM_BUILD_ROOT/}
echo "Bytecompiling .py files below $python_libdir using $python_binary"
--
2.14.4

View File

@ -0,0 +1,11 @@
--- a/platform.in 2018-07-19 17:24:58.737922904 +0200
+++ b/platform.in 2018-07-19 17:25:25.480028741 +0200
@@ -65,7 +65,7 @@
%__arch_install_post @ARCH_INSTALL_POST@
%_python_bytecompile_errors_terminate_build 0
-%_python_bytecompile_extra 1
+%_python_bytecompile_extra 0
# Standard brp-macro naming:
# convert all '-' in basename to '_', add two leading underscores.

View File

@ -0,0 +1,12 @@
diff -up rpm-4.11.1-rc1/macros.in.siteconfig rpm-4.11.1-rc1/macros.in
--- rpm-4.11.1-rc1/macros.in.siteconfig 2013-06-07 13:19:21.000000000 +0300
+++ rpm-4.11.1-rc1/macros.in 2013-06-11 15:06:59.525747503 +0300
@@ -647,6 +647,8 @@ package or when debugging this package.\
export CLASSPATH}\
PKG_CONFIG_PATH=\"${PKG_CONFIG_PATH}:%{_libdir}/pkgconfig:%{_datadir}/pkgconfig\"\
export PKG_CONFIG_PATH\
+ CONFIG_SITE=${CONFIG_SITE:-NONE}\
+ export CONFIG_SITE\
\
%{verbose:set -x}%{!verbose:exec > /dev/null}\
umask 022\

View File

@ -0,0 +1,18 @@
diff --git a/rpm2cpio.c b/rpm2cpio.c
index 89ebdfa..ae999ff 100644
--- a/rpm2cpio.c
+++ b/rpm2cpio.c
@@ -84,7 +84,12 @@ int main(int argc, char *argv[])
exit(EXIT_FAILURE);
}
- rc = (ufdCopy(gzdi, fdo) == payload_size) ? EXIT_SUCCESS : EXIT_FAILURE;
+ /*
+ * XXX HACK for #1142949: should be equality test, but archive size
+ * short by cpio trailer size in packages built with rpm 4.12.0
+ * and its pre-releases.
+ */
+ rc = (ufdCopy(gzdi, fdo) >= payload_size) ? EXIT_SUCCESS : EXIT_FAILURE;
Fclose(fdo);

View File

@ -0,0 +1,95 @@
diff --git a/lib/tagexts.c b/lib/tagexts.c
index f72ff60..2c0b179 100644
--- a/lib/tagexts.c
+++ b/lib/tagexts.c
@@ -535,15 +535,6 @@ static int filerequireTag(Header h, rpmtd td, headerGetFlags hgflags)
return filedepTag(h, RPMTAG_REQUIRENAME, td, hgflags);
}
-/* I18N look aside diversions */
-
-#if defined(ENABLE_NLS)
-extern int _nl_msg_cat_cntr; /* XXX GNU gettext voodoo */
-#endif
-static const char * const language = "LANGUAGE";
-
-static const char * const _macro_i18ndomains = "%{?_i18ndomains}";
-
/**
* Retrieve i18n text.
* @param h header
@@ -554,59 +545,30 @@ static const char * const _macro_i18ndomains = "%{?_i18ndomains}";
*/
static int i18nTag(Header h, rpmTag tag, rpmtd td, headerGetFlags hgflags)
{
- int rc;
+ int rc = headerGet(h, tag, td, HEADERGET_ALLOC);
#if defined(ENABLE_NLS)
- char * dstring = rpmExpand(_macro_i18ndomains, NULL);
-
- td->type = RPM_STRING_TYPE;
- td->data = NULL;
- td->count = 0;
-
- if (dstring && *dstring) {
- char *domain, *de;
- const char * langval;
- char * msgkey;
- const char * msgid;
+ if (rc) {
+ static const char * const _macro_i18ndomains = "%{?_i18ndomains}";
+ char *de, *dstring = rpmExpand(_macro_i18ndomains, NULL);
+ const char *domain;
- rasprintf(&msgkey, "%s(%s)", headerGetString(h, RPMTAG_NAME),
- rpmTagGetName(tag));
-
- /* change to en_US for msgkey -> msgid resolution */
- langval = getenv(language);
- (void) setenv(language, "en_US", 1);
- ++_nl_msg_cat_cntr;
-
- msgid = NULL;
for (domain = dstring; domain != NULL; domain = de) {
+ const char *msgid = td->data;
+ const char *msg = NULL;
+
de = strchr(domain, ':');
if (de) *de++ = '\0';
- msgid = dgettext(domain, msgkey);
- if (msgid != msgkey) break;
- }
-
- /* restore previous environment for msgid -> msgstr resolution */
- if (langval)
- (void) setenv(language, langval, 1);
- else
- unsetenv(language);
- ++_nl_msg_cat_cntr;
-
- if (domain && msgid) {
- td->data = dgettext(domain, msgid);
- td->data = xstrdup(td->data); /* XXX xstrdup has side effects. */
- td->count = 1;
- td->flags = RPMTD_ALLOCED;
+ msg = dgettext(domain, td->data);
+ if (msg != msgid) {
+ free(td->data);
+ td->data = xstrdup(msg);
+ break;
+ }
}
- dstring = _free(dstring);
- free(msgkey);
- if (td->data)
- return 1;
+ free(dstring);
}
-
- free(dstring);
#endif
- rc = headerGet(h, tag, td, HEADERGET_ALLOC);
return rc;
}

View File

@ -0,0 +1,15 @@
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)\
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_DOC_DIR=\"%{_docdir}\"\
export RPM_DOC_DIR\
RPM_PACKAGE_NAME=\"%{NAME}\"\

View File

@ -0,0 +1,28 @@
From bf636421120aa2c97f9e0fdcee3c211b4241bd86 Mon Sep 17 00:00:00 2001
From: Tomas Orsava <torsava@redhat.com>
Date: Mon, 29 Jan 2018 16:13:18 +0100
Subject: [PATCH] Add envvar that will be present during RPM build
Part of a Fedora Change for F28:
"Avoid /usr/bin/python in RPM build"
https://fedoraproject.org/wiki/Changes/Avoid_usr_bin_python_in_RPM_Build
---
macros.in | 2 ++
1 file changed, 2 insertions(+)
diff --git a/macros.in b/macros.in
index dd6ef67..68449e3 100644
--- a/macros.in
+++ b/macros.in
@@ -804,6 +804,8 @@ package or when debugging this package.\
export PKG_CONFIG_PATH\
CONFIG_SITE=${CONFIG_SITE:-NONE}\
export CONFIG_SITE\
+ PYTHON_DISALLOW_AMBIGUOUS_VERSION=warn\
+ export PYTHON_DISALLOW_AMBIGUOUS_VERSION\
\
%{verbose:set -x}%{!verbose:exec > /dev/null}\
umask 022\
--
2.13.6

View File

@ -0,0 +1,107 @@
From 8390fa8515f499994646cf3bd113423744dc7bd9 Mon Sep 17 00:00:00 2001
From: Florian Festi <ffesti@redhat.com>
Date: Fri, 30 Nov 2018 11:02:52 +0100
Subject: [PATCH] Add RPMTAG_MODULARITYLABEL to distinguish packages build for
modularity
Tag can be set with a ModularityLabel: statement in the spec file preamble or
via the modularitylabel macro
---
build/parsePreamble.c | 4 ++++
build/parseSpec.c | 1 +
lib/rpmtag.h | 1 +
macros.in | 5 +++++
tests/rpmgeneral.at | 1 +
5 files changed, 12 insertions(+)
diff --git a/build/parsePreamble.c b/build/parsePreamble.c
index f5e06bac8..e340e5c7a 100644
--- a/build/parsePreamble.c
+++ b/build/parsePreamble.c
@@ -43,6 +43,7 @@ static const rpmTagVal copyTagsDuringParse[] = {
RPMTAG_DISTTAG,
RPMTAG_BUGURL,
RPMTAG_GROUP,
+ RPMTAG_MODULARITYLABEL,
0
};
@@ -526,6 +527,7 @@ static struct optionalTag {
{ RPMTAG_DISTURL, "%{disturl}" },
{ RPMTAG_DISTTAG, "%{disttag}" },
{ RPMTAG_BUGURL, "%{bugurl}" },
+ { RPMTAG_MODULARITYLABEL, "%{modularitylabel}"},
{ -1, NULL }
};
@@ -779,6 +781,7 @@ static rpmRC handlePreambleTag(rpmSpec spec, Package pkg, rpmTagVal tag,
case RPMTAG_URL:
case RPMTAG_DISTTAG:
case RPMTAG_BUGURL:
+ case RPMTAG_MODULARITYLABEL:
/* XXX TODO: validate format somehow */
case RPMTAG_VCS:
SINGLE_TOKEN_ONLY;
@@ -1018,6 +1021,7 @@ static struct PreambleRec_s const preambleList[] = {
{RPMTAG_BUGURL, 0, 0, LEN_AND_STR("bugurl")},
{RPMTAG_ORDERNAME, 2, 0, LEN_AND_STR("orderwithrequires")},
{RPMTAG_REMOVEPATHPOSTFIXES,0, 0, LEN_AND_STR("removepathpostfixes")},
+ {RPMTAG_MODULARITYLABEL, 0, 0, LEN_AND_STR("modularitylabel")},
{0, 0, 0, 0}
};
diff --git a/build/parseSpec.c b/build/parseSpec.c
index bf4789942..c80802baf 100644
--- a/build/parseSpec.c
+++ b/build/parseSpec.c
@@ -517,6 +517,7 @@ static const rpmTagVal sourceTags[] = {
RPMTAG_BUGURL,
RPMTAG_HEADERI18NTABLE,
RPMTAG_VCS,
+ RPMTAG_MODULARITYLABEL,
0
};
diff --git a/lib/rpmtag.h b/lib/rpmtag.h
index 973a6b69d..b9623ef24 100644
--- a/lib/rpmtag.h
+++ b/lib/rpmtag.h
@@ -368,6 +368,7 @@
RPMTAG_FILESIGNATURELENGTH = 5091, /* i */
RPMTAG_PAYLOADDIGEST = 5092, /* s[] */
RPMTAG_PAYLOADDIGESTALGO = 5093, /* i */
+ RPMTAG_MODULARITYLABEL = 5096, /* s */
RPMTAG_FIRSTFREE_TAG /*!< internal */
} rpmTag;
diff --git a/macros.in b/macros.in
index e0a1aea4e..cb4929c10 100644
--- a/macros.in
+++ b/macros.in
@@ -357,6 +357,11 @@ package or when debugging this package.\
%_javadir %{_datadir}/java
%_javadocdir %{_datadir}/javadoc
+
+# Set ModularityLabel: for packages being build
+#
+#%modularitylabel
+
# A colon separated list of paths where files should *not* be installed.
# Usually, these are network file system mount points.
#
diff --git a/tests/rpmgeneral.at b/tests/rpmgeneral.at
index 509277f2c..45d38698b 100644
--- a/tests/rpmgeneral.at
+++ b/tests/rpmgeneral.at
@@ -150,6 +150,7 @@ LONGARCHIVESIZE
LONGFILESIZES
LONGSIGSIZE
LONGSIZE
+MODULARITYLABEL
N
NAME
NEVR
--
2.17.2

View File

@ -0,0 +1,275 @@
From 820dcc1db9f2130a21fdaf721217034376eb8e38 Mon Sep 17 00:00:00 2001
Message-Id: <820dcc1db9f2130a21fdaf721217034376eb8e38.1544785848.git.pmatilai@redhat.com>
From: Panu Matilainen <pmatilai@redhat.com>
Date: Fri, 30 Nov 2018 13:10:44 +0200
Subject: [PATCH] Add support for logging audit events for package installs as
per OSPP v4.2
If enabled at build-time, log audit events for package install, update
and remove. The log includes the operation, package nevra, signature
check result, whether signatures are being enforced enforced and overall
success result. Package install/update/remove are logged as such,
obsoletion is logged as install + remove (whereas the erasure element
on updates is silent)
Loosely based on initial RHEL 7-8 implementations by Pavlina Moravcova
Varekova and Florian Festi (RhBug:1555326, RhBug:1607612)
(cherry picked from commit cfc9dde70fe65e91c83e03e9a9441e627b741489)
---
configure.ac | 21 +++++++++
lib/Makefile.am | 1 +
lib/rpmte.c | 11 +++++
lib/rpmte_internal.h | 6 +++
lib/transaction.c | 104 +++++++++++++++++++++++++++++++++++++++++++
5 files changed, 143 insertions(+)
diff --git a/configure.ac b/configure.ac
index 34ea85f9f..ab8a368d3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -312,6 +312,27 @@ fi
AC_SUBST(WITH_BEECRYPT_LIB)
AC_SUBST(WITH_BEECRYPT_INCLUDE)
+
+#=================
+# Check for audit library.
+AC_ARG_WITH(audit,
+AS_HELP_STRING([--with-audit],[log results using Linux Audit]),
+with_audit=$withval,
+with_audit=auto)
+
+WITH_AUDIT_LIB=
+AS_IF([test "x$with_audit" != xno],[
+ AC_SEARCH_LIBS([audit_open],[audit],[
+ WITH_AUDIT_LIB="$ac_res"
+ AC_DEFINE(WITH_AUDIT, 1, [libaudit support])
+ ],
+ [if test "x$with_audit" != xauto; then
+ AC_MSG_ERROR([missing audit library])
+ fi
+ ])
+])
+AC_SUBST(WITH_AUDIT_LIB)
+
#=================
# Check for OpenSSL library.
# We need evp.h from OpenSSL.
diff --git a/lib/Makefile.am b/lib/Makefile.am
index baf3238ee..c055962a3 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -51,6 +51,7 @@ librpm_la_LIBADD = \
@WITH_POPT_LIB@ \
@WITH_CAP_LIB@ \
@WITH_ACL_LIB@ \
+ @WITH_AUDIT_LIB@ \
@LIBINTL@
if WITH_LUA
diff --git a/lib/rpmte.c b/lib/rpmte.c
index d980a37a4..bd5d53edc 100644
--- a/lib/rpmte.c
+++ b/lib/rpmte.c
@@ -69,6 +69,7 @@ struct rpmte_s {
int nrelocs; /*!< (TR_ADDED) No. of relocations. */
uint8_t *badrelocs; /*!< (TR_ADDED) Bad relocations (or NULL) */
FD_t fd; /*!< (TR_ADDED) Payload file descriptor. */
+ int verified; /*!< (TR_ADDED) Verification status */
#define RPMTE_HAVE_PRETRANS (1 << 0)
#define RPMTE_HAVE_POSTTRANS (1 << 1)
@@ -753,6 +754,16 @@ rpmfs rpmteGetFileStates(rpmte te)
return te->fs;
}
+void rpmteSetVerified(rpmte te, int verified)
+{
+ te->verified = verified;
+}
+
+int rpmteGetVerified(rpmte te)
+{
+ return te->verified;
+}
+
int rpmteProcess(rpmte te, pkgGoal goal, int num)
{
/* Only install/erase resets pkg file info */
diff --git a/lib/rpmte_internal.h b/lib/rpmte_internal.h
index a5a991ec5..2895925ce 100644
--- a/lib/rpmte_internal.h
+++ b/lib/rpmte_internal.h
@@ -86,6 +86,12 @@ int rpmteHaveTransScript(rpmte te, rpmTagVal tag);
/* XXX should be internal too but build code needs for now... */
rpmfs rpmteGetFileStates(rpmte te);
+RPM_GNUC_INTERNAL
+void rpmteSetVerified(rpmte te, int verified);
+
+RPM_GNUC_INTERNAL
+int rpmteGetVerified(rpmte te);
+
/** \ingroup rpmte
* Retrieve size in bytes of package header.
* @param te transaction element
diff --git a/lib/transaction.c b/lib/transaction.c
index 67b9db579..866e87fc2 100644
--- a/lib/transaction.c
+++ b/lib/transaction.c
@@ -7,6 +7,10 @@
#include <inttypes.h>
#include <libgen.h>
+#if WITH_AUDIT
+#include <libaudit.h>
+#endif
+
#include <rpm/rpmlib.h> /* rpmMachineScore, rpmReadPackageFile */
#include <rpm/rpmmacro.h> /* XXX for rpmExpand */
#include <rpm/rpmlog.h>
@@ -1195,12 +1199,17 @@ static rpm_loff_t countPkgs(rpmts ts, rpmElementTypes types)
struct vfydata_s {
char *msg;
+ int signature;
int vfylevel;
};
static int vfyCb(struct rpmsinfo_s *sinfo, void *cbdata)
{
struct vfydata_s *vd = cbdata;
+
+ if (sinfo->type == RPMSIG_SIGNATURE_TYPE && sinfo->rc == RPMRC_OK)
+ vd->signature = RPMRC_OK;
+
switch (sinfo->rc) {
case RPMRC_OK:
break;
@@ -1241,6 +1250,7 @@ static int verifyPackageFiles(rpmts ts, rpm_loff_t total)
struct rpmvs_s *vs = rpmvsCreate(vfylevel, vsflags, keyring);
struct vfydata_s vd = {
.msg = NULL,
+ .signature = RPMRC_NOTFOUND,
.vfylevel = vfylevel,
};
rpmRC prc = RPMRC_FAIL;
@@ -1255,6 +1265,9 @@ static int verifyPackageFiles(rpmts ts, rpm_loff_t total)
if (prc == RPMRC_OK)
prc = rpmvsVerify(vs, RPMSIG_VERIFIABLE_TYPE, vfyCb, &vd);
+ /* Record verify result, signatures only for now */
+ rpmteSetVerified(p, vd.signature == RPMRC_OK);
+
if (prc)
rpmteAddProblem(p, RPMPROB_VERIFY, NULL, vd.msg, 0);
@@ -1619,6 +1632,95 @@ rpmRC runScript(rpmts ts, rpmte te, Header h, ARGV_const_t prefixes,
return rc;
}
+#if WITH_AUDIT
+struct teop {
+ rpmte te;
+ const char *op;
+};
+
+/*
+ * Figure out the actual operations:
+ * Install and remove are straightforward. Updates need to discovered
+ * via their erasure element: locate the updating element, adjust it's
+ * op to update and silence the erasure part. Obsoletion is handled as
+ * as install + remove, which it technically is.
+ */
+static void getAuditOps(rpmts ts, struct teop *ops, int nelem)
+{
+ rpmtsi pi = rpmtsiInit(ts);
+ rpmte p;
+ int i = 0;
+ while ((p = rpmtsiNext(pi, 0)) != NULL) {
+ const char *op = NULL;
+ if (rpmteType(p) == TR_ADDED) {
+ op = "install";
+ } else {
+ op = "remove";
+ rpmte d = rpmteDependsOn(p);
+ /* Fixup op on updating elements, silence the cleanup stage */
+ if (d != NULL && rstreq(rpmteN(d), rpmteN(p))) {
+ /* Linear lookup, but we're only dealing with a few thousand */
+ for (int x = 0; x < i; x++) {
+ if (ops[x].te == d) {
+ ops[x].op = "update";
+ op = NULL;
+ break;
+ }
+ }
+ }
+ }
+ ops[i].te = p;
+ ops[i].op = op;
+ i++;
+ }
+ rpmtsiFree(pi);
+}
+
+/*
+ * If enabled, log audit events for the operations in this transaction.
+ * In the event values, 1 means true/success and 0 false/failure. Shockingly.
+ */
+static void rpmtsAudit(rpmts ts)
+{
+ int auditFd = audit_open();
+ if (auditFd < 0)
+ return;
+
+ int nelem = rpmtsNElements(ts);
+ struct teop *ops = xcalloc(nelem, sizeof(*ops));
+ char *dir = audit_encode_nv_string("root_dir", rpmtsRootDir(ts), 0);
+ int enforce = (rpmtsVfyLevel(ts) & RPMSIG_SIGNATURE_TYPE) != 0;
+
+ getAuditOps(ts, ops, nelem);
+
+ for (int i = 0; i < nelem; i++) {
+ const char *op = ops[i].op;
+ if (op) {
+ rpmte p = ops[i].te;
+ char *nevra = audit_encode_nv_string("sw", rpmteNEVRA(p), 0);
+ char eventTxt[256];
+ int verified = rpmteGetVerified(p);
+ int result = (rpmteFailed(p) == 0);
+
+ snprintf(eventTxt, sizeof(eventTxt),
+ "op=%s %s sw_type=rpm key_enforce=%u gpg_res=%u %s",
+ op, nevra, enforce, verified, dir);
+ audit_log_user_comm_message(auditFd, AUDIT_SOFTWARE_UPDATE,
+ eventTxt, NULL, NULL, NULL, NULL, result);
+ free(nevra);
+ }
+ }
+
+ free(dir);
+ free(ops);
+ audit_close(auditFd);
+}
+#else
+static void rpmtsAudit(rpmts ts)
+{
+}
+#endif
+
int rpmtsRun(rpmts ts, rpmps okProbs, rpmprobFilterFlags ignoreSet)
{
int rc = -1; /* assume failure */
@@ -1732,6 +1834,8 @@ exit:
rpmpluginsCallTsmPost(rpmtsPlugins(ts), ts, rc);
/* Finish up... */
+ if (!(rpmtsFlags(ts) & (RPMTRANS_FLAG_TEST|RPMTRANS_FLAG_BUILD_PROBS)))
+ rpmtsAudit(ts);
(void) umask(oldmask);
(void) rpmtsFinish(ts);
rpmpsFree(tsprobs);
--
2.19.2

View File

@ -0,0 +1,12 @@
diff -up rpm-4.14.2/macros.in.pyerror rpm-4.14.2/macros.in
--- rpm-4.14.2/macros.in.pyerror 2019-06-04 13:33:48.450727270 +0300
+++ rpm-4.14.2/macros.in 2019-06-04 13:34:09.717695822 +0300
@@ -50,7 +50,7 @@
%__mv @__MV@
%__patch @__PATCH@
%__perl @__PERL@
-%__python @__PYTHON@
+%__python %{error:attempt to use unversioned python, define %%__python to %{_bindir}/python2 or %{_bindir}/python3 explicitly}
%__restorecon @__RESTORECON@
%__rm @__RM@
%__rsh @__RSH@

View File

@ -0,0 +1,14 @@
diff --git a/rpmrc.in b/rpmrc.in
index 4a6cca9..d62ddaf 100644
--- a/rpmrc.in
+++ b/rpmrc.in
@@ -281,7 +281,7 @@ arch_compat: alphaev5: alpha
arch_compat: alpha: axp noarch
arch_compat: athlon: i686
-arch_compat: geode: i586
+arch_compat: geode: i686
arch_compat: pentium4: pentium3
arch_compat: pentium3: i686
arch_compat: i686: i586

View File

@ -0,0 +1,12 @@
diff -up rpm-4.8.1/macros.in.gpg2 rpm-4.8.1/macros.in
--- rpm-4.8.0/macros.in.gpg2 2011-01-17 12:17:38.000000000 +0200
+++ rpm-4.8.0/macros.in 2011-01-17 12:17:59.000000000 +0200
@@ -40,7 +40,7 @@
%__cp @__CP@
%__cpio @__CPIO@
%__file @__FILE@
-%__gpg @__GPG@
+%__gpg /usr/bin/gpg2
%__grep @__GREP@
%__gzip @__GZIP@
%__id @__ID@

View File

@ -0,0 +1,12 @@
diff -up rpm-4.9.90.git11486/scripts/find-lang.sh.no-man-dirs rpm-4.9.90.git11486/scripts/find-lang.sh
--- rpm-4.9.90.git11486/scripts/find-lang.sh.no-man-dirs 2012-03-07 11:31:10.000000000 +0200
+++ rpm-4.9.90.git11486/scripts/find-lang.sh 2012-03-07 15:11:57.465801075 +0200
@@ -181,7 +181,7 @@ s:%lang(C) ::
find "$TOP_DIR" -type d|sed '
s:'"$TOP_DIR"'::
'"$ALL_NAME$MAN"'s:\(.*/man/\([^/_]\+\).*/man[a-z0-9]\+/\)::
-'"$ALL_NAME$MAN"'s:\(.*/man/\([^/_]\+\).*/man[a-z0-9]\+$\):%lang(\2) \1*:
+'"$ALL_NAME$MAN"'s:\(.*/man/\([^/_]\+\).*/man[a-z0-9]\+$\):%lang(\2) \1/*:
s:^\([^%].*\)::
s:%lang(C) ::
/^$/d' >> $MO_NAME

2204
SPECS/rpm.spec Normal file

File diff suppressed because it is too large Load Diff