summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/verify.c15
-rw-r--r--tests/rpmverify.at56
2 files changed, 59 insertions, 12 deletions
diff --git a/lib/verify.c b/lib/verify.c
index 84e984334..1cc67e389 100644
--- a/lib/verify.c
+++ b/lib/verify.c
@@ -97,9 +97,18 @@ int rpmVerifyFile(const rpmts ts, const rpmfi fi,
}
/* If we expected a directory but got a symlink to one, follow the link */
- if (S_ISDIR(fmode) && S_ISLNK(sb.st_mode) && stat(fn, &sb) != 0) {
- *res |= RPMVERIFY_LSTATFAIL;
- return 1;
+ if (S_ISDIR(fmode) && S_ISLNK(sb.st_mode)) {
+ struct stat dsb;
+ /* ...if it actually points to a directory */
+ if (stat(fn, &dsb) == 0 && S_ISDIR(dsb.st_mode)) {
+ uid_t fuid;
+ /* ...and is by a legit user, to match fsmVerify() behavior */
+ if (sb.st_uid == 0 ||
+ (rpmugUid(rpmfiFUser(fi), &fuid) == 0 &&
+ sb.st_uid == fuid)) {
+ sb = dsb; /* struct assignment */
+ }
+ }
}
/* Links have no mode, other types have no linkto */
diff --git a/tests/rpmverify.at b/tests/rpmverify.at
index cf7abc3fa..265953dcf 100644
--- a/tests/rpmverify.at
+++ b/tests/rpmverify.at
@@ -69,18 +69,56 @@ AT_KEYWORDS([verify])
AT_CHECK([
RPMDB_CLEAR
RPMDB_INIT
+tf="${RPMTEST}"/opt/foo
+rm -rf "${RPMTEST}"/opt/*
+rm -rf "${TOPDIR}"
-runroot rpm -U --nodeps --noscripts --ignorearch --ignoreos \
- /data/RPMS/hello-1.0-1.i386.rpm
-mv "${RPMTEST}"/usr/share/doc/hello-1.0 "${RPMTEST}"/usr/share/doc/hello-1.0.orig
-ln -s hello-1.0.orig "${RPMTEST}"/usr/share/doc/hello-1.0
-runroot rpm -Vva --nodeps --nouser --nogroup
-rm -rf "${RPMTEST}"/usr/share/doc/
+runroot rpmbuild --quiet -bb \
+ --define "ver 1.0" \
+ --define "filetype datadir" \
+ --define "filedata README1" \
+ --define "user $(id -u -n)" \
+ /data/SPECS/replacetest.spec
+
+runroot rpm -U /build/RPMS/noarch/replacetest-1.0-1.noarch.rpm
+mv "${RPMTEST}"/opt/foo "${RPMTEST}"/opt/was
+ln -s was "${RPMTEST}"/opt/foo
+runroot rpm -Vv replacetest
],
[0],
-[......... /usr/local/bin/hello
-......... /usr/share/doc/hello-1.0
-......... d /usr/share/doc/hello-1.0/FAQ
+[......... /opt/foo
+......... /opt/foo/README1
+......... /opt/goo
+......... /opt/zoo
+],
+[])
+AT_CLEANUP
+
+AT_SETUP([directory replaced with an invalid directory symlink])
+AT_KEYWORDS([verify])
+AT_CHECK([
+RPMDB_CLEAR
+RPMDB_INIT
+tf="${RPMTEST}"/opt/foo
+rm -rf "${RPMTEST}"/opt/*
+rm -rf "${TOPDIR}"
+
+runroot rpmbuild --quiet -bb \
+ --define "ver 1.0" \
+ --define "filetype datadir" \
+ --define "filedata README1" \
+ /data/SPECS/replacetest.spec
+
+runroot rpm -U /build/RPMS/noarch/replacetest-1.0-1.noarch.rpm
+mv "${RPMTEST}"/opt/foo "${RPMTEST}"/opt/was
+ln -s was "${RPMTEST}"/opt/foo
+runroot rpm -Vv --nouser --nogroup replacetest
+],
+[1],
+[....L.... /opt/foo
+......... /opt/foo/README1
+......... /opt/goo
+......... /opt/zoo
],
[])
AT_CLEANUP