switchToWatchXid(): modified the new migrate-path to work when there exists a process...
[util-vserver.git] / util-vserver / lib_internal / unify-unify.c
index 6423f58..a3d6a18 100644 (file)
@@ -30,8 +30,8 @@
 #include <sys/stat.h>
 
 bool
-Unify_unify(char const *src, struct stat const *src_stat,
-           char const *dst, struct stat const UNUSED *dst_stat)
+Unify_unify(char const *src, struct stat const UNUSED *src_stat,
+           char const *dst)
 {
   size_t       l = strlen(dst);
   char         tmpfile[l + sizeof(";XXXXXX")];
@@ -39,9 +39,10 @@ Unify_unify(char const *src, struct stat const *src_stat,
   bool         res = false;
 
   // at first, set the ILI flags on 'src'
-  if (vc_set_iattr_compat(src, src_stat->st_dev, src_stat->st_ino,
-                         0, VC_IATTR_IUNLINK, VC_IATTR_IUNLINK,
-                         &src_stat->st_mode)==-1)
+  if (vc_set_iattr(src,
+                  0,
+                  VC_IATTR_IUNLINK|VC_IATTR_IMMUTABLE,
+                  VC_IATTR_IUNLINK|VC_IATTR_IMMUTABLE)==-1)
     return false;
 
   // now, create a temporary filename
@@ -56,6 +57,10 @@ Unify_unify(char const *src, struct stat const *src_stat,
   }
 
   // and rename the old file to this name
+
+  // NOTE: this rename() is race-free; when an attacker makes 'tmpfile' a
+  // directory, the operation would fail; when making it a symlink to a file
+  // or directory, the symlink but not the file/directory would be overridden
   if (rename(dst, tmpfile)==-1) {
     perror("rename()");
     goto err;