diff options
Diffstat (limited to 'backport-Make-sure-dirs-are-not-relocated-twice.patch')
-rw-r--r-- | backport-Make-sure-dirs-are-not-relocated-twice.patch | 114 |
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 + |