summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPádraig Brady <P@draigBrady.com>2013-12-04 19:10:37 +0000
committerPádraig Brady <P@draigBrady.com>2013-12-05 00:18:36 +0000
commit0013de3e603162081c4464ea1f7ad3285f633d78 (patch)
treed93f83bc57d79b098b7d20d9cb60cf1b8296779e /src
parentb53b0fd940382497e58a9e912f1262c2084fe534 (diff)
downloadcoreutils-0013de3e603162081c4464ea1f7ad3285f633d78.tar.xz
selinux: fix --context=CTX for cp and diagnose defaultcon() errors
* src/selinux.h (ignorable_ctx_err): A new function used to determine if a warning should be given after a call to defaultcon() or restorecon(). * src/cp.c (main): Fix the setfscreatecon() call to use the argument passed by the user. * src/mkdir.c (make_ancestor): Show all but "ignoreable" errors from defaultcon() and restorecon(). * tests/misc/selinux.sh: Add a test run as root in selinux enforcing mode, to ensure cp --context=invalid is honored and fails immediately.
Diffstat (limited to 'src')
-rw-r--r--src/copy.c10
-rw-r--r--src/cp.c5
-rw-r--r--src/mkdir.c11
-rw-r--r--src/mv.c3
-rw-r--r--src/selinux.h8
5 files changed, 24 insertions, 13 deletions
diff --git a/src/copy.c b/src/copy.c
index dab8fdd77..0f044d021 100644
--- a/src/copy.c
+++ b/src/copy.c
@@ -805,12 +805,12 @@ set_process_security_ctx (char const *src_name, char const *dst_name,
{
/* With -Z, adjust the default context for the process
to have the type component adjusted as per the destination path. */
- if (new_dst && defaultcon (dst_name, mode) < 0)
+ if (new_dst && defaultcon (dst_name, mode) < 0
+ && ! ignorable_ctx_err (errno))
{
- if (!errno_unsupported (errno))
- error (0, errno,
- _("failed to set default file creation context for %s"),
- quote (dst_name));
+ error (0, errno,
+ _("failed to set default file creation context for %s"),
+ quote (dst_name));
}
}
diff --git a/src/cp.c b/src/cp.c
index 59d659d03..9038d4e7d 100644
--- a/src/cp.c
+++ b/src/cp.c
@@ -1099,7 +1099,6 @@ main (int argc, char **argv)
x.one_file_system = true;
break;
-
case 'Z':
/* politely decline if we're not on a selinux-enabled kernel. */
if (selinux_enabled)
@@ -1195,10 +1194,10 @@ main (int argc, char **argv)
if (scontext)
restorecon (dst_path, 0, true);
*/
- if (scontext && setfscreatecon (optarg) < 0)
+ if (scontext && setfscreatecon (scontext) < 0)
error (EXIT_FAILURE, errno,
_("failed to set default file creation context to %s"),
- quote (optarg));
+ quote (scontext));
#if !USE_XATTR
if (x.require_preserve_xattr)
diff --git a/src/mkdir.c b/src/mkdir.c
index 25b1da5e7..adc293019 100644
--- a/src/mkdir.c
+++ b/src/mkdir.c
@@ -118,7 +118,8 @@ make_ancestor (char const *dir, char const *component, void *options)
{
struct mkdir_options const *o = options;
- if (o->set_security_context && defaultcon (dir, S_IFDIR) < 0)
+ if (o->set_security_context && defaultcon (dir, S_IFDIR) < 0
+ && ! ignorable_ctx_err (errno))
error (0, errno, _("failed to set default creation context for %s"),
quote (dir));
@@ -162,7 +163,8 @@ process_dir (char *dir, struct savewd *wd, void *options)
set_defaultcon = true;
free (pdir);
}
- if (set_defaultcon && defaultcon (dir, S_IFDIR) < 0)
+ if (set_defaultcon && defaultcon (dir, S_IFDIR) < 0
+ && ! ignorable_ctx_err (errno))
error (0, errno, _("failed to set default creation context for %s"),
quote (dir));
}
@@ -180,8 +182,9 @@ process_dir (char *dir, struct savewd *wd, void *options)
and here we set the context for the final component. */
if (ret == EXIT_SUCCESS && o->set_security_context && ! set_defaultcon)
{
- if (restorecon (last_component (dir), false, false) < 0)
- error (0, errno, _("failed to set restore context for %s"),
+ if (! restorecon (last_component (dir), false, false)
+ && ! ignorable_ctx_err (errno))
+ error (0, errno, _("failed to restore context for %s"),
quote (dir));
}
diff --git a/src/mv.c b/src/mv.c
index cb6b70e25..b69b35504 100644
--- a/src/mv.c
+++ b/src/mv.c
@@ -424,7 +424,8 @@ main (int argc, char **argv)
backup_suffix_string = optarg;
break;
case 'Z':
- /* politely decline if we're not on a selinux-enabled kernel. */
+ /* As a performance enhancement, don't even bother trying
+ to "restorecon" when not on an selinux-enabled kernel. */
if (selinux_enabled)
{
x.preserve_security_context = false;
diff --git a/src/selinux.h b/src/selinux.h
index 31771632e..e4ded8466 100644
--- a/src/selinux.h
+++ b/src/selinux.h
@@ -19,6 +19,14 @@
#ifndef COREUTILS_SELINUX_H
# define COREUTILS_SELINUX_H
+/* Return true if ERR corresponds to an unsupported request,
+ or if there is no context or it's inaccessible. */
+static inline bool
+ignorable_ctx_err (int err)
+{
+ return err == ENOTSUP || err == ENODATA;
+}
+
# if HAVE_SELINUX_SELINUX_H
extern bool restorecon (char const *path, bool recurse, bool preserve);