1
0
mirror of git://git.sv.gnu.org/coreutils.git synced 2026-04-12 23:08:17 +02:00

cp: set SELinux context for --parents directories

* src/copy.c (set_process_security_ctx, set_file_security_ctx):
Export for use in cp.c.
* src/copy.h: Likewise.
* src/cp.c (make_dir_parents_private): Call the exported functions
to set the security context for new and updated directories.
* tests/cp/cp-a-selinux.sh: Add a test case.

Fixes http://bugs.gnu.org/25378
This commit is contained in:
Pádraig Brady
2017-02-20 18:46:49 -08:00
parent e4a4427502
commit db277d6077
5 changed files with 55 additions and 4 deletions

4
NEWS
View File

@@ -10,6 +10,10 @@ GNU coreutils NEWS -*- outline -*-
** Bug fixes
cp --parents will now set an SELinux context for created directories,
as appropriate for the -a, --preseve=context, or -Z options.
[bug present since SELinux support added in coreutils-6.10]
date again converts from a specified time zone. Previously output was
not converted to the local time zone, and remained in the specified one.
[bug introduced in coreutils-8.26]

View File

@@ -889,7 +889,7 @@ set_author (const char *dst_name, int dest_desc, const struct stat *src_sb)
Based on CP_OPTIONS, diagnose warnings and fail when appropriate.
Return FALSE on failure, TRUE on success. */
static bool
bool
set_process_security_ctx (char const *src_name, char const *dst_name,
mode_t mode, bool new_dst, const struct cp_options *x)
{
@@ -951,7 +951,7 @@ set_process_security_ctx (char const *src_name, char const *dst_name,
failure, when allowed by various settings in CP_OPTIONS.
Return FALSE on failure, TRUE on success. */
static bool
bool
set_file_security_ctx (char const *dst_name, bool process_local,
bool recurse, const struct cp_options *x)
{

View File

@@ -285,6 +285,14 @@ bool copy (char const *src_name, char const *dst_name,
bool nonexistent_dst, const struct cp_options *options,
bool *copy_into_self, bool *rename_succeeded);
extern bool set_process_security_ctx (char const *src_name,
char const *dst_name,
mode_t mode, bool new_dst,
const struct cp_options *x);
extern bool set_file_security_ctx (char const *dst_name, bool process_local,
bool recurse, const struct cp_options *x);
void dest_info_init (struct cp_options *);
void src_info_init (struct cp_options *);

View File

@@ -394,6 +394,8 @@ make_dir_parents_private (char const *const_dir, size_t src_offset,
*attr_list = NULL;
/* XXX: If all dirs are present at the destination,
no permissions or security contexts will be updated. */
if (stat (dst_dir, &stats) != 0)
{
/* A parent of CONST_DIR does not exist.
@@ -437,6 +439,12 @@ make_dir_parents_private (char const *const_dir, size_t src_offset,
*attr_list = new;
}
/* If required set the default context for created dirs. */
if (! set_process_security_ctx (src, dir,
missing_dir ? new->st.st_mode : 0,
missing_dir, x))
return false;
if (missing_dir)
{
mode_t src_mode;
@@ -524,6 +532,18 @@ make_dir_parents_private (char const *const_dir, size_t src_offset,
}
else
*new_dst = false;
/* For existing dirs, set the security context as per that already
set for the process global context. */
if (! *new_dst
&& (x->set_security_context || x->preserve_security_context))
{
if (! set_file_security_ctx (dir, x->preserve_security_context,
false, x)
&& x->require_preserve_context)
return false;
}
*slash++ = '/';
/* Avoid unnecessary calls to 'stat' when given

View File

@@ -48,7 +48,6 @@ rm -f f
# due to recursion, and was handled incorrectly in coreutils-8.22
# Note standard permissions are updated for existing directories
# in the destination, so SELinux contexts should be updated too.
chmod o+rw restore/existing_dir
mkdir -p backup/existing_dir/ || framework_failure_
ls -Zd backup/existing_dir > ed_ctx || fail=1
grep $ctx ed_ctx && framework_failure_
@@ -57,11 +56,31 @@ chcon $ctx backup/existing_dir/file || framework_failure_
# Set the dir context to ensure it is reset
mkdir -p --context="$ctx" restore/existing_dir || framework_failure_
# Copy and ensure existing directories updated
cp -a backup/. restore/
cp -a backup/. restore/ || fail=1
ls -Zd restore/existing_dir > ed_ctx || fail=1
grep $ctx ed_ctx &&
{ ls -lZd restore/existing_dir; fail=1; }
# Check context preserved with directories created with --parents,
# which was not handled before coreutils-8.27
mkdir -p parents/a/b || framework_failure_
ls -Zd parents/a/b > ed_ctx || fail=1
grep $ctx ed_ctx && framework_failure_
touch parents/a/b/file || framework_failure_
chcon $ctx parents/a/b || framework_failure_
# Set the dir context to ensure it is reset
mkdir -p --context="$ctx" parents_dest/parents/a || framework_failure_
# Copy and ensure existing directories updated
cp -r --parents --preserve=context parents/a/b/file parents_dest || fail=1
# Check new context
ls -Zd parents_dest/parents/a/b > ed_ctx || fail=1
grep $ctx ed_ctx ||
{ ls -lZd parents_dest/parents/a/b; fail=1; }
# Check updated context
ls -Zd parents_dest/parents/a > ed_ctx || fail=1
grep $ctx ed_ctx &&
{ ls -lZd parents_dest/parents/a; fail=1; }
# Check restorecon (-Z) functionality for file and directory
# Also make a dir with our known context
mkdir c_d || framework_failure_