diff options
Diffstat (limited to 'lib/fsm.c')
-rw-r--r-- | lib/fsm.c | 9 |
1 files changed, 6 insertions, 3 deletions
@@ -638,7 +638,7 @@ static int fsmUtime(const char *path, mode_t mode, time_t mtime) return rc; } -static int fsmVerify(const char *path, rpmfi fi) +static int fsmVerify(const char *path, rpmfi fi, const struct stat *fsb) { int rc; int saveerrno = errno; @@ -663,11 +663,14 @@ static int fsmVerify(const char *path, rpmfi fi) } else if (S_ISDIR(mode)) { if (S_ISDIR(dsb.st_mode)) return 0; if (S_ISLNK(dsb.st_mode)) { + uid_t luid = dsb.st_uid; rc = fsmStat(path, 0, &dsb); if (rc == RPMERR_ENOENT) rc = 0; if (rc) return rc; errno = saveerrno; - if (S_ISDIR(dsb.st_mode)) return 0; + /* Only permit directory symlinks by target owner and root */ + if (S_ISDIR(dsb.st_mode) && (luid == 0 || luid == fsb->st_uid)) + return 0; } } else if (S_ISLNK(mode)) { if (S_ISLNK(dsb.st_mode)) { @@ -899,7 +902,7 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files, } /* Assume file does't exist when tmp suffix is in use */ if (!suffix) { - rc = fsmVerify(fpath, fi); + rc = fsmVerify(fpath, fi, &sb); } else { rc = RPMERR_ENOENT; } |