X-Git-Url: http://git.linux-vserver.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=util-vserver%2Flib_internal%2Funify-unify.c;h=a3d6a18ab0baa8f3073c6b8b0cc959e56838848d;hb=37705d50d8885d4ec983fc0b373704ab42d95eaf;hp=9b3ef28cdca94bd8dff3793cefb338d843b94b95;hpb=4585bfa86226befff42e1f4c2b810d1bcfff4f99;p=util-vserver.git diff --git a/util-vserver/lib_internal/unify-unify.c b/util-vserver/lib_internal/unify-unify.c index 9b3ef28..a3d6a18 100644 --- a/util-vserver/lib_internal/unify-unify.c +++ b/util-vserver/lib_internal/unify-unify.c @@ -30,7 +30,7 @@ #include bool -Unify_unify(char const *src, struct stat const *src_stat, +Unify_unify(char const *src, struct stat const UNUSED *src_stat, char const *dst) { size_t l = strlen(dst); @@ -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;