summaryrefslogtreecommitdiff
path: root/backport-Make-sure-dirs-are-not-relocated-twice.patch
diff options
context:
space:
mode:
Diffstat (limited to 'backport-Make-sure-dirs-are-not-relocated-twice.patch')
-rw-r--r--backport-Make-sure-dirs-are-not-relocated-twice.patch114
1 files changed, 114 insertions, 0 deletions
diff --git a/backport-Make-sure-dirs-are-not-relocated-twice.patch b/backport-Make-sure-dirs-are-not-relocated-twice.patch
new file mode 100644
index 0000000..5848533
--- /dev/null
+++ b/backport-Make-sure-dirs-are-not-relocated-twice.patch
@@ -0,0 +1,114 @@
+From 31c14ba6610568c2d634647fed1fb57221178da9 Mon Sep 17 00:00:00 2001
+From: Michal Domonkos <mdomonko@redhat.com>
+Date: Fri, 26 Jul 2024 10:43:50 +0200
+Subject: [PATCH] Make sure dirs are not relocated twice
+
+Conflict:adapt context
+Reference:https://github.com/rpm-software-management/rpm/commit/31c14ba6610568c2d634647fed1fb57221178da9
+
+When processing relocations, new dirnames are added to dirNames[] first
+and then the rest is relocated. However, we go through the entire array
+in the latter step, meaning that we may accidentally relocate an already
+relocated path.
+
+Most relocations are fine as they involve two separate directory trees,
+and we already skip over directories that don't match the old prefix.
+However, that breaks apart if we're relocating to a nested subdirectory
+(e.g. /opt -> /opt/new/dir).
+
+Fix this by simply stopping at the original dirCount as the new entries
+are always added to the end of dirNames[].
+
+Such relocations are perhaps not very common (or even unsupported) but
+relocating the root directory itself may be useful (see the next commit
+for details) and that is subject to the same issue.
+
+Note that we currently don't handle root relocations properly to start
+with but that will be addressed in the next commit, this prepares the
+ground.
+---
+ lib/relocation.c | 6 +++---
+ tests/rpmi.at | 35 +++++++++++++++++++++++++++++++++++
+ 2 files changed, 38 insertions(+), 3 deletions(-)
+
+diff --git a/lib/relocation.c b/lib/relocation.c
+index 1eab60211..d31cf4779 100644
+--- a/lib/relocation.c
++++ b/lib/relocation.c
+@@ -124,7 +124,7 @@ void rpmRelocateFileList(rpmRelocation *relocations, int numRelocations,
+ char ** baseNames;
+ char ** dirNames;
+ uint32_t * dirIndexes;
+- rpm_count_t fileCount, dirCount;
++ rpm_count_t fileCount, dirCount, dirCountOrig;
+ int nrelocated = 0;
+ int fileAlloced = 0;
+ char * fn = NULL;
+@@ -163,7 +163,7 @@ void rpmRelocateFileList(rpmRelocation *relocations, int numRelocations,
+ baseNames = bnames.data;
+ dirIndexes = dindexes.data;
+ fileCount = rpmtdCount(&bnames);
+- dirCount = rpmtdCount(&dnames);
++ dirCount = dirCountOrig = rpmtdCount(&dnames);
+ /* XXX TODO: use rpmtdDup() instead */
+ dirNames = dnames.data = duparray(dnames.data, dirCount);
+ dnames.flags |= RPMTD_PTR_ALLOCED;
+@@ -297,7 +297,7 @@ assert(fn != NULL); /* XXX can't happen */
+ }
+
+ /* Finish off by relocating directories. */
+- for (i = dirCount - 1; i >= 0; i--) {
++ for (i = dirCountOrig - 1; i >= 0; i--) {
+ for (j = numRelocations - 1; j >= 0; j--) {
+
+ if (relocations[j].oldPath == NULL) /* XXX can't happen */
+diff --git a/tests/rpmi.at b/tests/rpmi.at
+index 7d1a0a871..372be0a8b 100644
+--- a/tests/rpmi.at
++++ b/tests/rpmi.at
+@@ -1135,6 +1135,42 @@ runroot rpm -U --relocate /opt/bin=/bin \
+ ],
+ [])
+ RPMTEST_CLEANUP
++
++AT_SETUP([rpm -i relocatable package 2])
++AT_KEYWORDS([install relocate])
++RPMDB_INIT
++
++runroot rpmbuild --quiet -bb /data/SPECS/reloc.spec
++runroot rpmbuild --quiet -bb /data/SPECS/fakeshell.spec
++
++runroot rpm -U /build/RPMS/noarch/fakeshell-1.0-1.noarch.rpm
++
++RPMTEST_CHECK([
++runroot rpm -U \
++ --relocate /opt/bin=/opt/bin/foo/bar \
++ --relocate /opt/etc=/opt/etc/foo/bar \
++ --relocate /opt/lib=/opt/lib/foo/bar \
++ /build/RPMS/noarch/reloc-1.0-1.noarch.rpm
++runroot rpm -ql reloc
++],
++[0],
++[1: /opt/bin/foo/bar
++2: /opt/etc/foo/bar
++3: /opt/lib/foo/bar
++0: /opt/bin/foo/bar
++1: /opt/etc/foo/bar
++2: /opt/lib/foo/bar
++/opt
++/opt/bin/foo/bar
++/opt/bin/foo/bar/typo
++/opt/etc/foo/bar
++/opt/etc/foo/bar/conf
++/opt/lib/foo/bar
++/opt/lib/foo/bar/notlib
++],
++[])
++RPMTEST_CLEANUP
++
+ AT_SETUP([rpm -i with/without --excludedocs])
+ AT_KEYWORDS([install excludedocs])
+ RPMTEST_CHECK([
+--
+2.33.0
+