diff --git a/CHANGES b/CHANGES
index ba018689c356453309147b911476f702afc4cfd4..0b8a8412278a6d33bbe36af8e34723b875b8b7bb 100644
--- a/CHANGES
+++ b/CHANGES
@@ -77,6 +77,18 @@ o Compiler
   - Fixed some corner cases where file names where missing from
     backtraces.
 
+o Filesystem.Tar
+
+  Fix extraction of S_ISUID and S_ISGID bits.
+
+  POSIX mandates that after a chown() (by unprivileged users), the
+  S_ISUID and S_ISGID bits are cleared, Linux 2.2.13 removed the
+  special case for root. The order of chmod() and chown() have been
+  reordered trying to fix an issue with applying utime() under
+  Windows. With this change, utime() is applied first, then chown()
+  and then chmod(), restoring the historical order for chown() and
+  chmod().
+
 o Image.Dims
 
   - Fixed the inconsistency that Image.Dims.get_JPEG (and thus
diff --git a/lib/modules/Filesystem.pmod/Tar.pmod b/lib/modules/Filesystem.pmod/Tar.pmod
index e9a114c9e9c25d8a55e639d5c82c782bf0b1d275..f62c7e54caa33f7ba054636b15364291e3fae962 100644
--- a/lib/modules/Filesystem.pmod/Tar.pmod
+++ b/lib/modules/Filesystem.pmod/Tar.pmod
@@ -357,13 +357,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;
@@ -381,6 +374,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);
+    }
   }
 
 #if !constant(access)