From 8997057d211a506e55a4d2eaabd4447e34b57c28 Mon Sep 17 00:00:00 2001
From: "Tobias S. Josefowitz" <tobij@tobij.de>
Date: Sun, 31 Mar 2019 18:54:09 +0200
Subject: [PATCH] Filesystem.Tar: Reorder operations in extract_bits()

As is mentioned in [LysLysKOM 23152065], Linux of recent versions clears
the S_ISUID and S_ISGID bits when chowning to another user. While POSIX
mandates this only for unprivileged users performing the chown, Linux
starting with 2.2.13 does not treat root as a special case anymore.

The operations were previously reordered to make utime() on __NT__ more
robust, which caused chown() to be executed after chmod(). In the
current order, we do utime() first, then chown(), then chmod().

While it seems a bit weird to chown() files that do not belong to us,
especially in the non-root-case, this has been the historical order of
operations in Filesystem.Tar.

Thanks to Per Cederqvist <ceder@lysator.liu.se> for the report.
---
 lib/modules/Filesystem.pmod/Tar.pmod | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/lib/modules/Filesystem.pmod/Tar.pmod b/lib/modules/Filesystem.pmod/Tar.pmod
index 8c06a9f7ad..58088267f1 100644
--- a/lib/modules/Filesystem.pmod/Tar.pmod
+++ b/lib/modules/Filesystem.pmod/Tar.pmod
@@ -351,13 +351,6 @@ class _Tar
     }
 #endif
 
-    if (!(which_bits & EXTRACT_SKIP_MODE) && !r->islnk) {
-      if (which_bits & EXTRACT_SKIP_EXT_MODE)
-	chmod (dest, r->mode & 0777);
-      else
-	chmod (dest, r->mode & 07777);
-    }
-
 #if constant (chown)
     if (which_bits & EXTRACT_CHOWN) {
       int uid;
@@ -375,6 +368,13 @@ class _Tar
       chown (dest, uid, gid, 1);
     }
 #endif
+
+    if (!(which_bits & EXTRACT_SKIP_MODE) && !r->islnk) {
+      if (which_bits & EXTRACT_SKIP_EXT_MODE)
+	chmod (dest, r->mode & 0777);
+      else
+	chmod (dest, r->mode & 07777);
+    }
   }
 
   void extract (string src_dir, string dest_dir,
-- 
GitLab