Spurious file conflicts may appear when a package update replaces a
directory symlink with a plain directory *and* also installs the same
file name(s) in it, but with different contents, as is the case with
RhBug 1936422:

$ rpm -i /path/to/squid-4.rpm
$ rpm -ql squid-4:
...
/usr/share/squid/errors/es      # directory
/usr/share/squid/errors/es-mx   # symlink to "es"
...
$ stat -c '%i' /usr/share/squid/errors/es{,-mx}/ERR_ACCESS_DENIED
2680891
2680891

$ rpm -U --test /path/to/squid-5.rpm  # this fails
$ rpm -U /path/to/squid-5.rpm
$ rpm -ql squid-5:
...
/usr/share/squid/errors/es      # directory
/usr/share/squid/errors/es-mx   # directory
...
$ stat -c '%i' /usr/share/squid/errors/es{,-mx}/ERR_ACCESS_DENIED
2696662
2696619

When we compute file fingerprints during transaction preparation, we use
stat(2) to obtain input data (such as the inode number) from the
existing files on disk.  Since stat(2) follows symlinks, any file in the
original directory (pointed to by the symlink) for which we're about to
install a namesake in the new directory, including the symlink itself,
gets a hash collision with its counterpart and appears as "overlapped"
to us.

A %pretrans scriptlet may be defined [1] which removes the symlink
beforehand to avoid the collision, however that still won't let DNF
through since it runs a test transaction first, during which we don't
run scriptlets, to avoid file system modification.

Therefore, for the symlink replacement itself, we already have a simple
heuristic that ignores the conflict in a test transaction if a %pretrans
scriptlet also is defined, in the hope that it fixes the conflict in a
real transaction (or we abort gracefully).  This runs when checking the
transaction files against the rpmdb in handleInstInstalledFile().  Also
see commits 00d82f1 and a7a06ec.

This commit extends that heuristic also to files installed in the new
directory, to allow namesakes as described above.  This needs to run a
bit later, when checking the transaction files against each other in
handleOverlappedFiles().

We really should look into proper support for symlink replacements in
the future, but for the time being (and to address this bug), this
should be good enough.

[1] https://docs.fedoraproject.org/en-US/packaging-guidelines/
    Directory_Replacement/
You can view, comment on, or merge this pull request online at:

  https://github.com/rpm-software-management/rpm/pull/1684

-- Commit Summary --

  * Allow file namesakes on symlink->dir replacement

-- File Changes --

    M lib/transaction.c (12)
    A tests/data/SPECS/symlinktest-pretrans.spec (48)
    M tests/rpmconflict.at (53)

-- Patch Links --

https://github.com/rpm-software-management/rpm/pull/1684.patch
https://github.com/rpm-software-management/rpm/pull/1684.diff

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/rpm-software-management/rpm/pull/1684
_______________________________________________
Rpm-maint mailing list
Rpm-maint@lists.rpm.org
http://lists.rpm.org/mailman/listinfo/rpm-maint

Reply via email to