Skip to content

Commit

Permalink
Fix root relocation regression
Browse files Browse the repository at this point in the history
When relocating the root directory, make sure we insert the new path's
dirname to dirNames[] even if the root itself is owned by the package.

This appears to have been the intention from the first version (largely
untouched since) of this code as we allow the root to pass through the
first checks (by setting len to 0 in that case) as well as the second
for loop where we do the relocations.

This allows fsm to properly create and remove the relocated directory
since we're now using fd-based calls (#1919) and the parent directory
needs to be opened first.

No need to do string comparison here, the empty basename signals that
we're processing the root directory, so just use that.

Building a relocatable package that owns the root directory seems to be
a handy way to create user-installable packages (see RHEL-28967) and it
happened to work before with the path-based calls so this technically
was a regression.  Add a test that emulates this use case.

Fixes: #3173
  • Loading branch information
dmnks authored and pmatilai committed Aug 1, 2024
1 parent 31c14ba commit 308ac60
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 3 deletions.
8 changes: 5 additions & 3 deletions lib/relocation.c
Original file line number Diff line number Diff line change
Expand Up @@ -181,8 +181,9 @@ void rpmRelocateFileList(rpmRelocation *relocations, int numRelocations,
rpmFileTypes ft;
int fnlen;

size_t baselen = strlen(baseNames[i]);
size_t len = maxlen +
strlen(dirNames[dirIndexes[i]]) + strlen(baseNames[i]) + 1;
strlen(dirNames[dirIndexes[i]]) + baselen + 1;
if (len >= fileAlloced) {
fileAlloced = len * 2;
fn = xrealloc(fn, fileAlloced);
Expand Down Expand Up @@ -244,8 +245,9 @@ assert(fn != NULL); /* XXX can't happen */
continue;
}

/* Relocation on full paths only, please. */
if (fnlen != len) continue;
/* Relocation on '/' and full paths only, please. */
if (baselen && fnlen != len)
continue;

rpmlog(RPMLOG_DEBUG, "relocating %s to %s\n",
fn, relocations[j].newPath);
Expand Down
17 changes: 17 additions & 0 deletions tests/data/SPECS/rootfs.spec
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
Name: rootfs
Version: 1.0
Release: 1
Summary: Package owning top-level root directory
License: GPL
BuildArch: noarch
Prefix: /

%description
%{summary}.

%install
mkdir -p $RPM_BUILD_ROOT/foo
touch $RPM_BUILD_ROOT/foo/bar

%files
/
25 changes: 25 additions & 0 deletions tests/rpmi.at
Original file line number Diff line number Diff line change
Expand Up @@ -1170,6 +1170,31 @@ runroot rpm -ql reloc
[])
RPMTEST_CLEANUP

AT_SETUP([rpm -i relocatable package 3])
AT_KEYWORDS([install relocate])
RPMTEST_USER
RPMDB_INIT

runroot rpmbuild --quiet -bb /data/SPECS/rootfs.spec

RPMTEST_CHECK([
runroot_user \
rpm -U --prefix \$PWD/root --dbpath \$PWD/rpmdb \
/build/RPMS/noarch/rootfs-1.0-1.noarch.rpm
],
[0],
[],
[])

RPMTEST_CHECK([
runroot_user rpm -e --dbpath \$PWD/rpmdb rootfs
runroot_user test ! -d \$PWD/root
],
[0],
[],
[])
RPMTEST_CLEANUP

AT_SETUP([rpm -i with/without --excludedocs])
AT_KEYWORDS([install excludedocs])
RPMTEST_CHECK([
Expand Down

0 comments on commit 308ac60

Please sign in to comment.