diff --git a/3aaa42deaaf0c63589ddc23df5549d4dedb0c817.patch b/3aaa42deaaf0c63589ddc23df5549d4dedb0c817.patch new file mode 100644 index 0000000000000000000000000000000000000000..e3fdee6e53222733c9f68385eb43ad9baae6c33e --- /dev/null +++ b/3aaa42deaaf0c63589ddc23df5549d4dedb0c817.patch @@ -0,0 +1,891 @@ +diff --git a/m4/jm-macros.m4 b/m4/jm-macros.m4 +index 266235113..bce7ae7fc 100644 +--- a/m4/jm-macros.m4 ++++ b/m4/jm-macros.m4 +@@ -1,4 +1,4 @@ +-#serial 111 -*- autoconf -*- ++#serial 112 -*- autoconf -*- + + dnl Misc type-related macros for coreutils. + +@@ -52,21 +52,6 @@ AC_DEFUN([coreutils_MACROS], + LIBS="$LIBS $LIB_SELINUX" + # Used by selinux.c. + AC_CHECK_FUNCS([mode_to_security_class], [], []) +- # Used by install.c. +- AC_CHECK_FUNCS([matchpathcon_init_prefix], [], +- [ +- if test "$with_selinux" != no; then +- case "$ac_cv_search_setfilecon:$ac_cv_header_selinux_selinux_h" in +- no:*) # SELinux disabled +- ;; +- *:no) # SELinux disabled +- ;; +- *) +- AC_MSG_WARN([SELinux enabled, but matchpathcon_init_prefix not found]) +- AC_MSG_WARN([The install utility may run slowly]) +- esac +- fi +- ]) + LIBS=$coreutils_saved_libs + + # Used by sort.c. +diff --git a/src/copy.c b/src/copy.c +index 4050f6953..93f3c6db4 100644 +--- a/src/copy.c ++++ b/src/copy.c +@@ -1141,7 +1141,7 @@ 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 (x->set_security_context, dst_name, mode) < 0 + && ! ignorable_ctx_err (errno)) + { + error (0, errno, +@@ -1154,21 +1154,21 @@ set_process_security_ctx (char const *src_name, char const *dst_name, + } + + /* Reset the security context of DST_NAME, to that already set +- as the process default if PROCESS_LOCAL is true. Otherwise ++ as the process default if !X->set_security_context. Otherwise + adjust the type component of DST_NAME's security context as + per the system default for that path. Issue warnings upon +- failure, when allowed by various settings in CP_OPTIONS. +- Return FALSE on failure, TRUE on success. */ ++ failure, when allowed by various settings in X. ++ Return false on failure, true on success. */ + + bool +-set_file_security_ctx (char const *dst_name, bool process_local, ++set_file_security_ctx (char const *dst_name, + bool recurse, const struct cp_options *x) + { + bool all_errors = (!x->data_copy_required + || x->require_preserve_context); + bool some_errors = !all_errors && !x->reduce_diagnostics; + +- if (! restorecon (dst_name, recurse, process_local)) ++ if (! restorecon (x->set_security_context, dst_name, recurse)) + { + if (all_errors || (some_errors && !errno_unsupported (errno))) + error (0, errno, _("failed to set the security context of %s"), +@@ -1330,8 +1330,7 @@ copy_reg (char const *src_name, char const *dst_name, + if ((x->set_security_context || x->preserve_security_context) + && 0 <= dest_desc) + { +- if (! set_file_security_ctx (dst_name, x->preserve_security_context, +- false, x)) ++ if (! set_file_security_ctx (dst_name, false, x)) + { + if (x->require_preserve_context) + { +@@ -2609,7 +2608,7 @@ copy_internal (char const *src_name, char const *dst_name, + if (x->set_security_context) + { + /* -Z failures are only warnings currently. */ +- (void) set_file_security_ctx (dst_name, false, true, x); ++ (void) set_file_security_ctx (dst_name, true, x); + } + + if (rename_succeeded) +@@ -2819,8 +2818,7 @@ copy_internal (char const *src_name, char const *dst_name, + descendents, so use it to set the context for existing dirs here. + This will also give earlier indication of failure to set ctx. */ + if (x->set_security_context || x->preserve_security_context) +- if (! set_file_security_ctx (dst_name, x->preserve_security_context, +- false, x)) ++ if (! set_file_security_ctx (dst_name, false, x)) + { + if (x->require_preserve_context) + goto un_backup; +@@ -3020,8 +3018,7 @@ copy_internal (char const *src_name, char const *dst_name, + if (!new_dst && !x->copy_as_regular && !S_ISDIR (src_mode) + && (x->set_security_context || x->preserve_security_context)) + { +- if (! set_file_security_ctx (dst_name, x->preserve_security_context, +- false, x)) ++ if (! set_file_security_ctx (dst_name, false, x)) + { + if (x->require_preserve_context) + goto un_backup; +diff --git a/src/copy.h b/src/copy.h +index a0ad494b9..344d91bfb 100644 +--- a/src/copy.h ++++ b/src/copy.h +@@ -22,6 +22,8 @@ + # include + # include "hash.h" + ++struct selabel_handle; ++ + /* Control creation of sparse files (files with holes). */ + enum Sparse_type + { +@@ -162,8 +164,8 @@ struct cp_options + bool preserve_timestamps; + bool explicit_no_preserve_mode; + +- /* If true, attempt to set specified security context */ +- bool set_security_context; ++ /* If non-null, attempt to set specified security context */ ++ struct selabel_handle *set_security_context; + + /* Enabled for mv, and for cp by the --preserve=links option. + If true, attempt to preserve in the destination files any +@@ -294,7 +296,7 @@ extern bool set_process_security_ctx (char const *src_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, ++extern bool set_file_security_ctx (char const *dst_name, + bool recurse, const struct cp_options *x); + + void dest_info_init (struct cp_options *); +diff --git a/src/cp.c b/src/cp.c +index a4ecbbc9f..3a451eb99 100644 +--- a/src/cp.c ++++ b/src/cp.c +@@ -20,7 +20,7 @@ + #include + #include + #include +-#include ++#include + + #include "system.h" + #include "argmatch.h" +@@ -531,10 +531,9 @@ make_dir_parents_private (char const *const_dir, size_t src_offset, + if (! *new_dst + && (x->set_security_context || x->preserve_security_context)) + { +- if (! set_file_security_ctx (dir, x->preserve_security_context, +- false, x) ++ if (! set_file_security_ctx (dir, false, x) + && x->require_preserve_context) +- return false; ++ return false; + } + + *slash++ = '/'; +@@ -802,7 +801,7 @@ cp_option_init (struct cp_options *x) + x->explicit_no_preserve_mode = false; + x->preserve_security_context = false; /* -a or --preserve=context. */ + x->require_preserve_context = false; /* --preserve=context. */ +- x->set_security_context = false; /* -Z, set sys default context. */ ++ x->set_security_context = NULL; /* -Z, set sys default context. */ + x->preserve_xattr = false; + x->reduce_diagnostics = false; + x->require_preserve_xattr = false; +@@ -1116,7 +1115,12 @@ main (int argc, char **argv) + if (optarg) + scontext = optarg; + else +- x.set_security_context = true; ++ { ++ x.set_security_context = selabel_open (SELABEL_CTX_FILE, ++ NULL, 0); ++ if (! x.set_security_context) ++ error (0, errno, _("warning: ignoring --context")); ++ } + } + else if (optarg) + { +@@ -1197,8 +1201,8 @@ main (int argc, char **argv) + /* FIXME: This handles new files. But what about existing files? + I.e., if updating a tree, new files would have the specified context, + but shouldn't existing files be updated for consistency like this? +- if (scontext) +- restorecon (dst_path, 0, true); ++ if (scontext && !restorecon (NULL, dst_path, 0)) ++ error (...); + */ + if (scontext && setfscreatecon (se_const (scontext)) < 0) + die (EXIT_FAILURE, errno, +diff --git a/src/install.c b/src/install.c +index a94053f4d..eb6e403e7 100644 +--- a/src/install.c ++++ b/src/install.c +@@ -23,7 +23,7 @@ + #include + #include + #include +-#include ++#include + #include + + #include "system.h" +@@ -65,10 +65,6 @@ static bool use_default_selinux_context = true; + # define lchown(name, uid, gid) chown (name, uid, gid) + #endif + +-#if ! HAVE_MATCHPATHCON_INIT_PREFIX +-# define matchpathcon_init_prefix(a, p) /* empty */ +-#endif +- + /* The user name that will own the files, or NULL to make the owner + the current user ID. */ + static char *owner_name; +@@ -298,24 +294,37 @@ cp_option_init (struct cp_options *x) + x->update = false; + x->require_preserve_context = false; /* Not used by install currently. */ + x->preserve_security_context = false; /* Whether to copy context from src. */ +- x->set_security_context = false; /* Whether to set sys default context. */ ++ x->set_security_context = NULL; /* Whether to set sys default context. */ + x->preserve_xattr = false; + x->verbose = false; + x->dest_info = NULL; + x->src_info = NULL; + } + +-#ifdef ENABLE_MATCHPATHCON ++static struct selabel_handle * ++get_labeling_handle (void) ++{ ++ static bool initialized; ++ static struct selabel_handle *hnd; ++ if (!initialized) ++ { ++ initialized = true; ++ hnd = selabel_open (SELABEL_CTX_FILE, NULL, 0); ++ if (!hnd) ++ error (0, errno, _("warning: security labeling handle failed")); ++ } ++ return hnd; ++} ++ + /* Modify file context to match the specified policy. + If an error occurs the file will remain with the default directory +- context. Note this sets the context to that returned by matchpathcon, ++ context. Note this sets the context to that returned by selabel_lookup + and thus discards MLS levels and user identity of the FILE. */ + static void + setdefaultfilecon (char const *file) + { + struct stat st; + char *scontext = NULL; +- static bool first_call = true; + + if (selinux_enabled != 1) + { +@@ -325,51 +334,14 @@ setdefaultfilecon (char const *file) + if (lstat (file, &st) != 0) + return; + +- if (first_call && IS_ABSOLUTE_FILE_NAME (file)) +- { +- /* Calling matchpathcon_init_prefix (NULL, "/first_component/") +- is an optimization to minimize the expense of the following +- matchpathcon call. Do it only once, just before the first +- matchpathcon call. We *could* call matchpathcon_fini after +- the final matchpathcon call, but that's not necessary, since +- by then we're about to exit, and besides, the buffers it +- would free are still reachable. */ +- char const *p0; +- char const *p = file + 1; +- while (ISSLASH (*p)) +- ++p; +- +- /* Record final leading slash, for when FILE starts with two or more. */ +- p0 = p - 1; +- +- if (*p) +- { +- char *prefix; +- do +- { +- ++p; +- } +- while (*p && !ISSLASH (*p)); +- +- prefix = malloc (p - p0 + 2); +- if (prefix) +- { +- stpcpy (stpncpy (prefix, p0, p - p0), "/"); +- matchpathcon_init_prefix (NULL, prefix); +- free (prefix); +- } +- } +- } +- first_call = false; +- +- /* If there's an error determining the context, or it has none, +- return to allow default context. Note the "<>" check +- is only needed for libselinux < 1.20 (2005-01-04). */ +- if ((matchpathcon (file, st.st_mode, &scontext) != 0) +- || STREQ (scontext, "<>")) ++ struct selabel_handle *hnd = get_labeling_handle (); ++ if (!hnd) ++ return; ++ if (selabel_lookup (hnd, &scontext, file, st.st_mode) != 0) + { +- if (scontext != NULL) +- freecon (scontext); ++ if (errno != ENOENT) ++ error (0, errno, _("warning: %s: context lookup failed"), ++ quotef (file)); + return; + } + +@@ -379,15 +351,7 @@ setdefaultfilecon (char const *file) + quotef_n (0, file), quote_n (1, scontext)); + + freecon (scontext); +- return; + } +-#else +-static void +-setdefaultfilecon (char const *file) +-{ +- (void) file; +-} +-#endif + + /* FILE is the last operand of this command. Return true if FILE is a + directory. But report an error there is a problem accessing FILE, +@@ -427,7 +391,8 @@ static int + make_ancestor (char const *dir, char const *component, void *options) + { + struct cp_options const *x = options; +- if (x->set_security_context && defaultcon (component, S_IFDIR) < 0 ++ if (x->set_security_context ++ && defaultcon (x->set_security_context, component, S_IFDIR) < 0 + && ! ignorable_ctx_err (errno)) + error (0, errno, _("failed to set default creation context for %s"), + quoteaf (dir)); +@@ -457,7 +422,7 @@ process_dir (char *dir, struct savewd *wd, void *options) + and here we set the context for the final component. */ + if (ret == EXIT_SUCCESS && x->set_security_context) + { +- if (! restorecon (last_component (dir), false, false) ++ if (! restorecon (x->set_security_context, last_component (dir), false) + && ! ignorable_ctx_err (errno)) + error (0, errno, _("failed to restore context for %s"), + quoteaf (dir)); +@@ -902,7 +867,7 @@ main (int argc, char **argv) + /* Disable use of the install(1) specific setdefaultfilecon(). + Note setdefaultfilecon() is different from the newer and more + generic restorecon() in that the former sets the context of +- the dest files to that returned by matchpathcon directly, ++ the dest files to that returned by selabel_lookup directly, + thus discarding MLS level and user identity of the file. + TODO: consider removing setdefaultfilecon() in future. */ + use_default_selinux_context = false; +@@ -910,7 +875,7 @@ main (int argc, char **argv) + if (optarg) + scontext = optarg; + else +- x.set_security_context = true; ++ x.set_security_context = get_labeling_handle (); + } + else if (optarg) + { +diff --git a/src/local.mk b/src/local.mk +index 03150bff3..04e3c30e4 100644 +--- a/src/local.mk ++++ b/src/local.mk +@@ -416,8 +416,6 @@ src_base32_CPPFLAGS = -DBASE_TYPE=32 $(AM_CPPFLAGS) + src_basenc_SOURCES = src/basenc.c + src_basenc_CPPFLAGS = -DBASE_TYPE=42 $(AM_CPPFLAGS) + +-src_ginstall_CPPFLAGS = -DENABLE_MATCHPATHCON=1 $(AM_CPPFLAGS) +- + src_expand_SOURCES = src/expand.c src/expand-common.c + src_unexpand_SOURCES = src/unexpand.c src/expand-common.c + +diff --git a/src/mkdir.c b/src/mkdir.c +index 5afc0aa0f..988e53624 100644 +--- a/src/mkdir.c ++++ b/src/mkdir.c +@@ -20,7 +20,7 @@ + #include + #include + #include +-#include ++#include + + #include "system.h" + #include "die.h" +@@ -98,7 +98,7 @@ struct mkdir_options + mode_t mode_bits; + + /* Set the SELinux File Context. */ +- bool set_security_context; ++ struct selabel_handle *set_security_context; + + /* If not null, format to use when reporting newly made directories. */ + char const *created_directory_format; +@@ -123,7 +123,8 @@ make_ancestor (char const *dir, char const *component, void *options) + { + struct mkdir_options const *o = options; + +- if (o->set_security_context && defaultcon (component, S_IFDIR) < 0 ++ if (o->set_security_context ++ && defaultcon (o->set_security_context, component, S_IFDIR) < 0 + && ! ignorable_ctx_err (errno)) + error (0, errno, _("failed to set default creation context for %s"), + quoteaf (dir)); +@@ -156,7 +157,8 @@ process_dir (char *dir, struct savewd *wd, void *options) + /* If possible set context before DIR created. */ + if (o->set_security_context) + { +- if (! o->make_ancestor_function && defaultcon (dir, S_IFDIR) < 0 ++ if (! o->make_ancestor_function ++ && defaultcon (o->set_security_context, dir, S_IFDIR) < 0 + && ! ignorable_ctx_err (errno)) + error (0, errno, _("failed to set default creation context for %s"), + quoteaf (dir)); +@@ -176,7 +178,7 @@ process_dir (char *dir, struct savewd *wd, void *options) + if (ret == EXIT_SUCCESS && o->set_security_context + && o->make_ancestor_function) + { +- if (! restorecon (last_component (dir), false, false) ++ if (! restorecon (o->set_security_context, last_component (dir), false) + && ! ignorable_ctx_err (errno)) + error (0, errno, _("failed to restore context for %s"), + quoteaf (dir)); +@@ -197,7 +199,7 @@ main (int argc, char **argv) + options.mode = S_IRWXUGO; + options.mode_bits = 0; + options.created_directory_format = NULL; +- options.set_security_context = false; ++ options.set_security_context = NULL; + + initialize_main (&argc, &argv); + set_program_name (argv[0]); +@@ -231,7 +233,12 @@ main (int argc, char **argv) + if (optarg) + scontext = optarg; + else +- options.set_security_context = true; ++ { ++ options.set_security_context = selabel_open (SELABEL_CTX_FILE, ++ NULL, 0); ++ if (! options.set_security_context) ++ error (0, errno, _("warning: ignoring --context")); ++ } + } + else if (optarg) + { +@@ -255,7 +262,7 @@ main (int argc, char **argv) + + /* FIXME: This assumes mkdir() is done in the same process. + If that's not always the case we would need to call this +- like we do when options.set_security_context == true. */ ++ like we do when options.set_security_context. */ + if (scontext) + { + int ret = 0; +diff --git a/src/mkfifo.c b/src/mkfifo.c +index 9ec42144b..a28a9b84a 100644 +--- a/src/mkfifo.c ++++ b/src/mkfifo.c +@@ -20,7 +20,7 @@ + #include + #include + #include +-#include ++#include + + #include "system.h" + #include "die.h" +@@ -81,7 +81,7 @@ main (int argc, char **argv) + int exit_status = EXIT_SUCCESS; + int optc; + char const *scontext = NULL; +- bool set_security_context = false; ++ struct selabel_handle *set_security_context = NULL; + + initialize_main (&argc, &argv); + set_program_name (argv[0]); +@@ -109,7 +109,12 @@ main (int argc, char **argv) + if (optarg) + scontext = optarg; + else +- set_security_context = true; ++ { ++ set_security_context = selabel_open (SELABEL_CTX_FILE, ++ NULL, 0); ++ if (! set_security_context) ++ error (0, errno, _("warning: ignoring --context")); ++ } + } + else if (optarg) + { +@@ -164,7 +169,7 @@ main (int argc, char **argv) + for (; optind < argc; ++optind) + { + if (set_security_context) +- defaultcon (argv[optind], S_IFIFO); ++ defaultcon (set_security_context, argv[optind], S_IFIFO); + if (mkfifo (argv[optind], newmode) != 0) + { + error (0, errno, _("cannot create fifo %s"), quoteaf (argv[optind])); +diff --git a/src/mknod.c b/src/mknod.c +index 3f3f79acf..334a39769 100644 +--- a/src/mknod.c ++++ b/src/mknod.c +@@ -20,7 +20,7 @@ + #include + #include + #include +-#include ++#include + + #include "system.h" + #include "die.h" +@@ -98,7 +98,7 @@ main (int argc, char **argv) + size_t expected_operands; + mode_t node_type; + char const *scontext = NULL; +- bool set_security_context = false; ++ struct selabel_handle *set_security_context = NULL; + + initialize_main (&argc, &argv); + set_program_name (argv[0]); +@@ -126,7 +126,12 @@ main (int argc, char **argv) + if (optarg) + scontext = optarg; + else +- set_security_context = true; ++ { ++ set_security_context = selabel_open (SELABEL_CTX_FILE, ++ NULL, 0); ++ if (! set_security_context) ++ error (0, errno, _("warning: ignoring --context")); ++ } + } + else if (optarg) + { +@@ -248,7 +253,7 @@ main (int argc, char **argv) + #endif + + if (set_security_context) +- defaultcon (argv[optind], node_type); ++ defaultcon (set_security_context, argv[optind], node_type); + + if (mknod (argv[optind], newmode | node_type, device) != 0) + die (EXIT_FAILURE, errno, "%s", quotef (argv[optind])); +@@ -257,7 +262,7 @@ main (int argc, char **argv) + + case 'p': /* 'pipe' */ + if (set_security_context) +- defaultcon (argv[optind], S_IFIFO); ++ defaultcon (set_security_context, argv[optind], S_IFIFO); + if (mkfifo (argv[optind], newmode) != 0) + die (EXIT_FAILURE, errno, "%s", quotef (argv[optind])); + break; +diff --git a/src/mv.c b/src/mv.c +index b284dccca..21621af21 100644 +--- a/src/mv.c ++++ b/src/mv.c +@@ -21,7 +21,7 @@ + #include + #include + #include +-#include ++#include + + #include "system.h" + #include "backupfile.h" +@@ -125,7 +125,7 @@ cp_option_init (struct cp_options *x) + x->preserve_timestamps = true; + x->explicit_no_preserve_mode= false; + x->preserve_security_context = selinux_enabled; +- x->set_security_context = false; ++ x->set_security_context = NULL; + x->reduce_diagnostics = false; + x->data_copy_required = true; + x->require_preserve = false; /* FIXME: maybe make this an option */ +@@ -417,7 +417,10 @@ main (int argc, char **argv) + if (selinux_enabled) + { + x.preserve_security_context = false; +- x.set_security_context = true; ++ x.set_security_context = selabel_open (SELABEL_CTX_FILE, ++ NULL, 0); ++ if (! x.set_security_context) ++ error (0, errno, _("warning: ignoring --context")); + } + break; + case_GETOPT_HELP_CHAR; +diff --git a/src/selinux.c b/src/selinux.c +index 874ad5b6d..10fa9d8c6 100644 +--- a/src/selinux.c ++++ b/src/selinux.c +@@ -17,18 +17,15 @@ + /* Written by Daniel Walsh */ + + #include +-#include ++#include + #include + #include + +-#include "die.h" +-#include "error.h" + #include "system.h" +-#include "canonicalize.h" + #include "xfts.h" + #include "selinux.h" + +-#if HAVE_SELINUX_SELINUX_H ++#if HAVE_SELINUX_LABEL_H + + # if ! HAVE_MODE_TO_SECURITY_CLASS + /* +@@ -98,16 +95,17 @@ computecon (char const *path, mode_t mode, char **con) + } + + /* +- This function takes a path and a mode, it calls computecon to get the ++ This function takes a handle, path and mode, it calls computecon to get the + label of the path object if the current process created it, then it calls +- matchpathcon to get the default type for the object. It substitutes the ++ selabel_lookup to get the default type for the object. It substitutes the + default type into label. It tells the SELinux Kernel to label all new file + system objects created by the current process with this label. + + Returns -1 on failure. errno will be set appropriately. + */ + int +-defaultcon (char const *path, mode_t mode) ++defaultcon (struct selabel_handle *selabel_handle, ++ char const *path, mode_t mode) + { + int rc = -1; + char *scon = NULL; +@@ -115,20 +113,8 @@ defaultcon (char const *path, mode_t mode) + context_t scontext = 0, tcontext = 0; + const char *contype; + char *constr; +- char *newpath = NULL; + +- if (! IS_ABSOLUTE_FILE_NAME (path)) +- { +- /* Generate absolute path as required by subsequent matchpathcon(), +- with libselinux < 2.1.5 2011-0826. */ +- newpath = canonicalize_filename_mode (path, CAN_MISSING); +- if (! newpath) +- die (EXIT_FAILURE, errno, _("error canonicalizing %s"), +- quoteaf (path)); +- path = newpath; +- } +- +- if (matchpathcon (path, mode, &scon) < 0) ++ if (selabel_lookup (selabel_handle, &scon, path, mode) < 0) + { + /* "No such file or directory" is a confusing error, + when processing files, when in fact it was the +@@ -160,25 +146,20 @@ defaultcon (char const *path, mode_t mode) + context_free (tcontext); + freecon (scon); + freecon (tcon); +- free (newpath); + return rc; + } + + /* +- This function takes a PATH of an existing file system object, and a LOCAL +- boolean that indicates whether the function should set the object's label +- to the default for the local process, or one using system wide settings. +- If LOCAL == true, it will ask the SELinux Kernel what the default label +- for all objects created should be and then sets the label on the object. +- Otherwise it calls matchpathcon on the object to ask the system what the +- default label should be, extracts the type field and then modifies the file ++ If SELABEL_HANDLE is null, set PATH's label to the default to the ++ local process. Otherwise use selabel_lookup to determine the ++ default label, extract the type field and then modify the file + system object. Note only the type field is updated, thus preserving MLS + levels and user identity etc. of the PATH. + + Returns -1 on failure. errno will be set appropriately. + */ + static int +-restorecon_private (char const *path, bool local) ++restorecon_private (struct selabel_handle *selabel_handle, char const *path) + { + int rc = -1; + struct stat sb; +@@ -189,7 +170,7 @@ restorecon_private (char const *path, bool local) + char *constr; + int fd; + +- if (local) ++ if (!selabel_handle) + { + if (getfscreatecon (&tcon) < 0) + return rc; +@@ -199,7 +180,9 @@ restorecon_private (char const *path, bool local) + return rc; + } + rc = lsetfilecon (path, tcon); ++ int err = errno; + freecon (tcon); ++ errno = err; + return rc; + } + +@@ -218,13 +201,13 @@ restorecon_private (char const *path, bool local) + goto quit; + } + +- if (matchpathcon (path, sb.st_mode, &scon) < 0) ++ if (selabel_lookup (selabel_handle, &scon, path, sb.st_mode) < 0) + { + /* "No such file or directory" is a confusing error, + when processing files, when in fact it was the + associated default context that was not found. + Therefore map the error to something more appropriate +- to the context in which we're using matchpathcon(). */ ++ to the context in which we're using selabel_lookup. */ + if (errno == ENOENT) + errno = ENODATA; + goto quit; +@@ -258,83 +241,51 @@ restorecon_private (char const *path, bool local) + else + rc = lsetfilecon (path, constr); + +-quit: ++ quit:; ++ int err = errno; + if (fd != -1) + close (fd); + context_free (scontext); + context_free (tcontext); + freecon (scon); + freecon (tcon); ++ errno = err; + return rc; + } + + /* + This function takes three parameters: + ++ SELABEL_HANDLE for selabel_lookup, or null to preserve. ++ + PATH of an existing file system object. + + A RECURSE boolean which if the file system object is a directory, will + call restorecon_private on every file system object in the directory. + +- A LOCAL boolean that indicates whether the function should set object labels +- to the default for the local process, or use system wide settings. +- +- Returns false on failure. errno will be set appropriately. ++ Return false on failure. errno will be set appropriately. + */ + bool +-restorecon (char const *path, bool recurse, bool local) ++restorecon (struct selabel_handle *selabel_handle, ++ char const *path, bool recurse) + { +- char *newpath = NULL; +- FTS *fts; +- bool ok = true; +- +- if (! IS_ABSOLUTE_FILE_NAME (path) && ! local) +- { +- /* Generate absolute path as required by subsequent matchpathcon(), +- with libselinux < 2.1.5 2011-0826. Also generating the absolute +- path before the fts walk, will generate absolute paths in the +- fts entries, which may be quicker to process in any case. */ +- newpath = canonicalize_filename_mode (path, CAN_MISSING); +- if (! newpath) +- die (EXIT_FAILURE, errno, _("error canonicalizing %s"), +- quoteaf (path)); +- } +- +- const char *ftspath[2] = { newpath ? newpath : path, NULL }; +- + if (! recurse) +- { +- ok = restorecon_private (*ftspath, local) != -1; +- free (newpath); +- return ok; +- } ++ return restorecon_private (selabel_handle, path) == 0; + +- fts = xfts_open ((char *const *) ftspath, FTS_PHYSICAL, NULL); +- while (1) +- { +- FTSENT *ent; ++ char const *ftspath[2] = { path, NULL }; ++ FTS *fts = xfts_open ((char *const *) ftspath, FTS_PHYSICAL, NULL); + +- ent = fts_read (fts); +- if (ent == NULL) +- { +- if (errno != 0) +- { +- error (0, errno, _("fts_read failed")); +- ok = false; +- } +- break; +- } ++ int err = 0; ++ for (FTSENT *ent; (ent = fts_read (fts)); ) ++ if (restorecon_private (selabel_handle, fts->fts_path) < 0) ++ err = errno; + +- ok &= restorecon_private (fts->fts_path, local) != -1; +- } ++ if (errno != 0) ++ err = errno; + + if (fts_close (fts) != 0) +- { +- error (0, errno, _("fts_close failed")); +- ok = false; +- } ++ err = errno; + +- free (newpath); +- return ok; ++ return !err; + } + #endif +diff --git a/src/selinux.h b/src/selinux.h +index c191c36da..e1c6b3a54 100644 +--- a/src/selinux.h ++++ b/src/selinux.h +@@ -19,6 +19,8 @@ + #ifndef COREUTILS_SELINUX_H + # define COREUTILS_SELINUX_H + ++struct selabel_handle; ++ + /* Return true if ERR corresponds to an unsupported request, + or if there is no context or it's inaccessible. */ + static inline bool +@@ -27,21 +29,25 @@ ignorable_ctx_err (int err) + return err == ENOTSUP || err == ENODATA; + } + +-# if HAVE_SELINUX_SELINUX_H ++# if HAVE_SELINUX_LABEL_H + + extern bool +-restorecon (char const *path, bool recurse, bool preserve); ++restorecon (struct selabel_handle *selabel_handle, ++ char const *path, bool recurse); + extern int +-defaultcon (char const *path, mode_t mode); ++defaultcon (struct selabel_handle *selabel_handle, ++ char const *path, mode_t mode); + + # else + + static inline bool +-restorecon (char const *path, bool recurse, bool preserve) ++restorecon (struct selabel_handle *selabel_handle, ++ char const *path, bool recurse) + { errno = ENOTSUP; return false; } + + static inline int +-defaultcon (char const *path, mode_t mode) ++defaultcon (struct selabel_handle *selabel_handle, ++ char const *path, mode_t mode) + { errno = ENOTSUP; return -1; } + + # endif diff --git a/4c667a86d3b80b8f8dfdc454820f244c8cef876e.patch b/4c667a86d3b80b8f8dfdc454820f244c8cef876e.patch new file mode 100644 index 0000000000000000000000000000000000000000..737ccac3bcc1d902125dbd9a0d9da2dccafa0ac9 --- /dev/null +++ b/4c667a86d3b80b8f8dfdc454820f244c8cef876e.patch @@ -0,0 +1,7 @@ +diff --git a/gnulib b/gnulib +index 2d386f229..cd7fa0904 160000 +--- a/gnulib ++++ b/gnulib +@@ -1 +1 @@ +-Subproject commit 2d386f229aba9ecda85736b931e2964d7922d90e ++Subproject commit cd7fa0904bb6efb451ecc25907077fcfdf031824 diff --git a/5c8e2716b3f206bc063dcc0b7eb509ecd2804cf5.patch b/5c8e2716b3f206bc063dcc0b7eb509ecd2804cf5.patch new file mode 100644 index 0000000000000000000000000000000000000000..b8aa0fbd638ac939ee7c673ef892c0f4c1a851be --- /dev/null +++ b/5c8e2716b3f206bc063dcc0b7eb509ecd2804cf5.patch @@ -0,0 +1,21 @@ +diff --git a/src/local.mk b/src/local.mk +index 79c655036..03150bff3 100644 +--- a/src/local.mk ++++ b/src/local.mk +@@ -250,12 +250,15 @@ src_stat_LDADD += $(LIB_SELINUX) + # for nvlist_lookup_uint64_array + src_stat_LDADD += $(LIB_NVPAIR) + +-# for gettime, settime, utimecmp, utimens ++# for gettime, settime, tempname, utimecmp, utimens + copy_ldadd += $(LIB_CLOCK_GETTIME) + src_date_LDADD += $(LIB_CLOCK_GETTIME) + src_ginstall_LDADD += $(LIB_CLOCK_GETTIME) ++src_ln_LDADD += $(LIB_CLOCK_GETTIME) + src_ls_LDADD += $(LIB_CLOCK_GETTIME) ++src_mktemp_LDADD += $(LIB_CLOCK_GETTIME) + src_pr_LDADD += $(LIB_CLOCK_GETTIME) ++src_tac_LDADD += $(LIB_CLOCK_GETTIME) + src_timeout_LDADD += $(LIB_TIMER_TIME) + src_touch_LDADD += $(LIB_CLOCK_GETTIME) + diff --git a/coreutils.spec b/coreutils.spec index f5a08aa750f6eecebb0afdb66bc44e9d689578f4..37537a1e5511dcc71309f24837d15688ace8572f 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,6 +1,6 @@ Name: coreutils Version: 8.32 -Release: 2 +Release: 3 License: GPLv3+ Summary: A set of basic GNU tools commonly used in shell scripts Url: https://www.gnu.org/software/coreutils/ @@ -25,6 +25,10 @@ Patch8: skip-the-tests-that-require-selinux-if-selinux-is-di.patch Patch9: coreutils-8.32-ls-removed-dir.patch Patch10: coreutils-8.32-leaf-opt-xfs.patch +Patch6000: 4c667a86d3b80b8f8dfdc454820f244c8cef876e.patch +Patch6001: 5c8e2716b3f206bc063dcc0b7eb509ecd2804cf5.patch +Patch6002: 3aaa42deaaf0c63589ddc23df5549d4dedb0c817.patch +Patch6003: fc372b4ba78912f6d0c57cdf7a7cb268fb7a11ba.patch Conflicts: filesystem < 3 # To avoid clobbering installs @@ -135,6 +139,9 @@ fi %{_mandir}/man*/* %changelog +* 20201122113007632935 patch-tracking 8.32-3 +- append patch file of upstream repository from <4c667a86d3b80b8f8dfdc454820f244c8cef876e> to + * Wed Aug 26 2020 chenbo pan - 8.32-2 - fix patch error @@ -221,4 +228,4 @@ fi - reintroduce very old Provides (mktemp, sh-utils, textwrap, fileutils, stat) * Thu Jul 12 2018 hexiaowen - 8.30-1 -- Pacakge init +- Pacakge init \ No newline at end of file diff --git a/fc372b4ba78912f6d0c57cdf7a7cb268fb7a11ba.patch b/fc372b4ba78912f6d0c57cdf7a7cb268fb7a11ba.patch new file mode 100644 index 0000000000000000000000000000000000000000..d081f7f5756fd9c3c35012ba00845cd6e9eefcf7 --- /dev/null +++ b/fc372b4ba78912f6d0c57cdf7a7cb268fb7a11ba.patch @@ -0,0 +1,7 @@ +diff --git a/gnulib b/gnulib +index cd7fa0904..fdf046819 160000 +--- a/gnulib ++++ b/gnulib +@@ -1 +1 @@ +-Subproject commit cd7fa0904bb6efb451ecc25907077fcfdf031824 ++Subproject commit fdf0468198631a456406edc09983972edb8fa5c4