diff options
-rw-r--r-- | lib/verify.c | 15 | ||||
-rw-r--r-- | tests/rpmverify.at | 56 |
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 |