GNU bug report logs - #20616
mkdir: -p breaks -Z

Previous Next

Package: coreutils;

Reported by: Hannes Reich <hannes <at> skynet.ie>

Date: Wed, 20 May 2015 15:30:06 UTC

Severity: normal

Done: Pádraig Brady <P <at> draigBrady.com>

Bug is archived. No further changes may be made.

Full log


View this message in rfc822 format

From: Pádraig Brady <P <at> draigBrady.com>
To: Hannes Reich <hannes <at> skynet.ie>, 20616 <at> debbugs.gnu.org
Subject: bug#20616: mkdir: -p breaks -Z
Date: Thu, 21 May 2015 11:09:59 +0100
On 20/05/15 13:03, Hannes Reich wrote:
> The "-Z" (set SELinux context) option to mkdir appears to have no effect 
> when "-p" (no error if existing, create parents) is also specified.
> 
> For example, on my CentOS 7 system, the correct context for 
> subdirectories of "/home" is "user_home_dir_t", but when I create such a 
> directory with "mkdir -p -Z", it has the "home_root_t" context:
> 
>      # rm -rf /home/with-p
>      # mkdir -p -Z /home/with-p
>      # ls -Zd /home/with-p
>      drwxr-xr-x. root root unconfined_u:object_r:home_root_t:s0 /home/with-p
>      #
> 
> That's wrong. Running restorecon(1) fixes it:
> 
>      # restorecon -v /home/with-p
>      restorecon reset /home/with-p context 
> unconfined_u:object_r:home_root_t:s0->unconfined_u:object_r:user_home_dir_t:s0
>      #
> 
> Without the "-p" option, "-Z" works as expected:
> 
>      # mkdir -Z /home/without-p
>      # ls -Zd /home/without-p
>      drwxr-xr-x. root root unconfined_u:object_r:user_home_dir_t:s0 
> /home/without-p
>      # restorecon -v /home/without-p
>      #
> 
> The coreutils version in CentOS 7 is 8.22.
> 
> coreutils-8.23 compiled from source has the same behaviour.

I see the issue. I had assumed that defaultcon() for the
ancestors was not called if they existed.  That can't be
done without races, so we must call restorecon for the final
component, even if only creating a single dir.
Alternatively you could temp disable o->set_security_context around
make_dir_parents(), but that would be subject to TOCTOU races.

I'll apply something like the following.

thanks!
Pádraig.

diff --git a/src/mkdir.c b/src/mkdir.c
index 404a04a..ff51ae1 100644
--- a/src/mkdir.c
+++ b/src/mkdir.c
@@ -151,23 +151,11 @@ static int
 process_dir (char *dir, struct savewd *wd, void *options)
 {
   struct mkdir_options const *o = options;
-  bool set_defaultcon = false;

   /* If possible set context before DIR created.  */
   if (o->set_security_context)
     {
-      if (! o->make_ancestor_function)
-        set_defaultcon = true;
-      else
-        {
-          char *pdir = dir_name (dir);
-          struct stat st;
-          if (STREQ (pdir, ".")
-              || (stat (pdir, &st) == 0 && S_ISDIR (st.st_mode)))
-            set_defaultcon = true;
-          free (pdir);
-        }
-      if (set_defaultcon && defaultcon (dir, S_IFDIR) < 0
+      if (! o->make_ancestor_function && defaultcon (dir, S_IFDIR) < 0
           && ! ignorable_ctx_err (errno))
         error (0, errno, _("failed to set default creation context for %s"),
                quote (dir));
@@ -184,7 +172,8 @@ process_dir (char *dir, struct savewd *wd, void *options)
      final component of DIR is created.  So for now, create the
      final component with the context from previous component
      and here we set the context for the final component. */
-  if (ret == EXIT_SUCCESS && o->set_security_context && ! set_defaultcon)
+  if (ret == EXIT_SUCCESS && o->set_security_context
+      && o->make_ancestor_function)
     {
       if (! restorecon (last_component (dir), false, false)
           && ! ignorable_ctx_err (errno))





This bug report was last modified 10 years and 80 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.