From da79e3c3ae7da8719f0bf87a1a60e046597b8240 Mon Sep 17 00:00:00 2001
From: Panu Matilainen <pmatilai@redhat.com>
Date: Fri, 11 Feb 2022 13:28:25 +0200
Subject: [PATCH] Move file metadata setting back to unpack stage

Commit a82251b44ee2d2802ee8aea1b3d89f88beee4bad moved metadata setting
to a separate step because there are potential benefits to doing so, but
the current downsides are worse: as long as we operate in potentially
untrusted directories, we'd need to somehow verify the content is what we
initially laid down to avoid possible privilege escalation from non-root
owned directories.

This commit does not fix that vulnerability, only makes the window much
smaller and paves the way for the real fix(es) without introducing a
second round of directory tree validation chase to the picture.
---
 lib/fsm.c | 22 +++++++---------------
 1 file changed, 7 insertions(+), 15 deletions(-)

diff --git a/lib/fsm.c b/lib/fsm.c
index d9cfe6fa9..ae1bd3f48 100644
--- a/lib/fsm.c
+++ b/lib/fsm.c
@@ -880,7 +880,7 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files,
 
 	    /* When touching we don't need any of this... */
 	    if (fp->action == FA_TOUCH)
-		continue;
+		goto setmeta;
 
             if (S_ISREG(fp->sb.st_mode)) {
 		if (rc == RPMERR_ENOENT) {
@@ -1143,6 +1143,12 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files,
 		    rc = RPMERR_OPEN_FAILED;
 	    }
 
+setmeta:
+	    if (!rc && fp->setmeta) {
+		rc = fsmSetmeta(fp->fpath, fi, plugins, fp->action,
+				&fp->sb, nofcaps);
+	    }
+
 	    if (fd != firstlinkfile)
 		fsmClose(&fd);
 	}
@@ -931,20 +937,6 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files,
     if (!rc && fx < 0 && fx != RPMERR_ITER_END)
 	rc = fx;
 
-    /* Set permissions, timestamps etc for non-hardlink entries */
-    fi = rpmfilesIter(files, RPMFI_ITER_FWD);
-    while (!rc && (fx = rpmfiNext(fi)) >= 0) {
-	struct filedata_s *fp = &fdata[fx];
-	if (!fp->skip && fp->setmeta) {
-	    rc = fsmSetmeta(fp->fpath, fi, plugins, fp->action,
-			    &fp->sb, nofcaps);
-	}
-	if (rc)
-	    *failedFile = xstrdup(fp->fpath);
-	fp->stage = FILE_PREP;
-    }
-    fi = rpmfiFree(fi);
-
     /* If all went well, commit files to final destination */
     fi = rpmfilesIter(files, RPMFI_ITER_FWD);
     while (!rc && (fx = rpmfiNext(fi)) >= 0) {
-- 
2.27.0

