coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[COREUTILS PATCH] selinux: avoid unnecessary security context translatio


From: Christian Göttsche
Subject: [COREUTILS PATCH] selinux: avoid unnecessary security context translations
Date: Tue, 19 Dec 2023 15:55:28 +0100

Do not perform SELinux context translation for operations not involving
user input or output.  Context translation converts MCS/MLS labels into
human readable form, which is useful for user facing applications like
ls(1) or the --context=CTX argument of cp(1).
---
 src/copy.c         | 12 ++++-----
 src/install.c      | 26 +++++++++---------
 src/selinux.c      | 66 +++++++++++++++++++++++-----------------------
 tests/cp/no-ctx.sh |  6 +++++
 4 files changed, 58 insertions(+), 52 deletions(-)

diff --git a/src/copy.c b/src/copy.c
index f54253e5b..b74e27f63 100644
--- a/src/copy.c
+++ b/src/copy.c
@@ -1020,23 +1020,23 @@ set_process_security_ctx (char const *src_name, char 
const *dst_name,
       /* Set the default context for the process to match the source.  */
       bool all_errors = !x->data_copy_required || x->require_preserve_context;
       bool some_errors = !all_errors && !x->reduce_diagnostics;
-      char *con;
+      char *con_raw;
 
-      if (0 <= lgetfilecon (src_name, &con))
+      if (0 <= lgetfilecon_raw (src_name, &con_raw))
         {
-          if (setfscreatecon (con) < 0)
+          if (setfscreatecon_raw (con_raw) < 0)
             {
               if (all_errors || (some_errors && !errno_unsupported (errno)))
                 error (0, errno,
                        _("failed to set default file creation context to %s"),
-                       quote (con));
+                       quote (con_raw));
               if (x->require_preserve_context)
                 {
-                  freecon (con);
+                  freecon (con_raw);
                   return false;
                 }
             }
-          freecon (con);
+          freecon (con_raw);
         }
       else
         {
diff --git a/src/install.c b/src/install.c
index 31a48f114..855c30cd5 100644
--- a/src/install.c
+++ b/src/install.c
@@ -214,23 +214,23 @@ need_copy (char const *src_name, char const *dest_name,
   /* compare SELinux context if preserving */
   if (selinux_enabled && x->preserve_security_context)
     {
-      char *file_scontext = nullptr;
-      char *to_scontext = nullptr;
+      char *file_scontext_raw = nullptr;
+      char *to_scontext_raw = nullptr;
       bool scontext_match;
 
-      if (getfilecon (src_name, &file_scontext) == -1)
+      if (getfilecon_raw (src_name, &file_scontext_raw) == -1)
         return true;
 
-      if (getfilecon (dest_name, &to_scontext) == -1)
+      if (getfilecon_raw (dest_name, &to_scontext_raw) == -1)
         {
-          freecon (file_scontext);
+          freecon (file_scontext_raw);
           return true;
         }
 
-      scontext_match = STREQ (file_scontext, to_scontext);
+      scontext_match = STREQ (file_scontext_raw, to_scontext_raw);
 
-      freecon (file_scontext);
-      freecon (to_scontext);
+      freecon (file_scontext_raw);
+      freecon (to_scontext_raw);
       if (!scontext_match)
         return true;
     }
@@ -323,7 +323,7 @@ static void
 setdefaultfilecon (char const *file)
 {
   struct stat st;
-  char *scontext = nullptr;
+  char *scontext_raw = nullptr;
 
   if (selinux_enabled != 1)
     {
@@ -336,7 +336,7 @@ setdefaultfilecon (char const *file)
   struct selabel_handle *hnd = get_labeling_handle ();
   if (!hnd)
     return;
-  if (selabel_lookup (hnd, &scontext, file, st.st_mode) != 0)
+  if (selabel_lookup_raw (hnd, &scontext_raw, file, st.st_mode) != 0)
     {
       if (errno != ENOENT && ! ignorable_ctx_err (errno))
         error (0, errno, _("warning: %s: context lookup failed"),
@@ -344,12 +344,12 @@ setdefaultfilecon (char const *file)
       return;
     }
 
-  if (lsetfilecon (file, scontext) < 0 && errno != ENOTSUP)
+  if (lsetfilecon_raw (file, scontext_raw) < 0 && errno != ENOTSUP)
     error (0, errno,
            _("warning: %s: failed to change context to %s"),
-           quotef_n (0, file), quote_n (1, scontext));
+           quotef_n (0, file), quote_n (1, scontext_raw));
 
-  freecon (scontext);
+  freecon (scontext_raw);
 }
 
 /* Report that directory DIR was made, if OPTIONS requests this.  */
diff --git a/src/selinux.c b/src/selinux.c
index 0fdd0c81f..d67e4b12c 100644
--- a/src/selinux.c
+++ b/src/selinux.c
@@ -69,36 +69,36 @@ mode_to_security_class (mode_t m)
 */
 
 static int
-computecon (char const *path, mode_t mode, char **con)
+computecon_raw (char const *path, mode_t mode, char **con)
 {
-  char *scon = nullptr;
-  char *tcon = nullptr;
+  char *scon_raw = nullptr;
+  char *tcon_raw = nullptr;
   security_class_t tclass;
   int rc = -1;
 
   char *dir = dir_name (path);
   if (!dir)
     goto quit;
-  if (getcon (&scon) < 0)
+  if (getcon_raw (&scon_raw) < 0)
     goto quit;
-  if (getfilecon (dir, &tcon) < 0)
+  if (getfilecon_raw (dir, &tcon_raw) < 0)
     goto quit;
   tclass = mode_to_security_class (mode);
   if (!tclass)
     goto quit;
-  rc = security_compute_create (scon, tcon, tclass, con);
+  rc = security_compute_create_raw (scon_raw, tcon_raw, tclass, con);
 
  quit:;
   int err = errno;
   free (dir);
-  freecon (scon);
-  freecon (tcon);
+  freecon (scon_raw);
+  freecon (tcon_raw);
   errno = err;
   return rc;
 }
 
 /*
-  This function takes a handle, path and mode, it calls computecon to get the
+  This function takes a handle, path and mode, it calls computecon_raw to get 
the
   label of the path object if the current process created it, then it calls
   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
@@ -111,8 +111,8 @@ defaultcon (struct selabel_handle *selabel_handle,
             char const *path, mode_t mode)
 {
   int rc = -1;
-  char *scon = nullptr;
-  char *tcon = nullptr;
+  char *scon_raw = nullptr;
+  char *tcon_raw = nullptr;
   context_t scontext = 0, tcontext = 0;
   char const *contype;
   char const *constr;
@@ -127,7 +127,7 @@ defaultcon (struct selabel_handle *selabel_handle,
       path = newpath;
     }
 
-  if (selabel_lookup (selabel_handle, &scon, path, mode) < 0)
+  if (selabel_lookup_raw (selabel_handle, &scon_raw, path, mode) < 0)
     {
       /* "No such file or directory" is a confusing error,
          when processing files, when in fact it was the
@@ -138,11 +138,11 @@ defaultcon (struct selabel_handle *selabel_handle,
         errno = ENODATA;
       goto quit;
     }
-  if (computecon (path, mode, &tcon) < 0)
+  if (computecon_raw (path, mode, &tcon_raw) < 0)
     goto quit;
-  if (!(scontext = context_new (scon)))
+  if (!(scontext = context_new (scon_raw)))
     goto quit;
-  if (!(tcontext = context_new (tcon)))
+  if (!(tcontext = context_new (tcon_raw)))
     goto quit;
 
   if (!(contype = context_type_get (scontext)))
@@ -152,14 +152,14 @@ defaultcon (struct selabel_handle *selabel_handle,
   if (!(constr = context_str (tcontext)))
     goto quit;
 
-  rc = setfscreatecon (constr);
+  rc = setfscreatecon_raw (constr);
 
  quit:;
   int err = errno;
   context_free (scontext);
   context_free (tcontext);
-  freecon (scon);
-  freecon (tcon);
+  freecon (scon_raw);
+  freecon (tcon_raw);
   free (newpath);
   errno = err;
   return rc;
@@ -179,8 +179,8 @@ restorecon_private (struct selabel_handle *selabel_handle, 
char const *path)
 {
   int rc = -1;
   struct stat sb;
-  char *scon = nullptr;
-  char *tcon = nullptr;
+  char *scon_raw = nullptr;
+  char *tcon_raw = nullptr;
   context_t scontext = 0, tcontext = 0;
   char const *contype;
   char const *constr;
@@ -188,16 +188,16 @@ restorecon_private (struct selabel_handle 
*selabel_handle, char const *path)
 
   if (!selabel_handle)
     {
-      if (getfscreatecon (&tcon) < 0)
+      if (getfscreatecon_raw (&tcon_raw) < 0)
         return rc;
-      if (!tcon)
+      if (!tcon_raw)
         {
           errno = ENODATA;
           return rc;
         }
-      rc = lsetfilecon (path, tcon);
+      rc = lsetfilecon_raw (path, tcon_raw);
       int err = errno;
-      freecon (tcon);
+      freecon (tcon_raw);
       errno = err;
       return rc;
     }
@@ -217,7 +217,7 @@ restorecon_private (struct selabel_handle *selabel_handle, 
char const *path)
         goto quit;
     }
 
-  if (selabel_lookup (selabel_handle, &scon, path, sb.st_mode) < 0)
+  if (selabel_lookup_raw (selabel_handle, &scon_raw, path, sb.st_mode) < 0)
     {
       /* "No such file or directory" is a confusing error,
          when processing files, when in fact it was the
@@ -228,21 +228,21 @@ restorecon_private (struct selabel_handle 
*selabel_handle, char const *path)
         errno = ENODATA;
       goto quit;
     }
-  if (!(scontext = context_new (scon)))
+  if (!(scontext = context_new (scon_raw)))
     goto quit;
 
   if (fd != -1)
     {
-      if (fgetfilecon (fd, &tcon) < 0)
+      if (fgetfilecon_raw (fd, &tcon_raw) < 0)
         goto quit;
     }
   else
     {
-      if (lgetfilecon (path, &tcon) < 0)
+      if (lgetfilecon_raw (path, &tcon_raw) < 0)
         goto quit;
     }
 
-  if (!(tcontext = context_new (tcon)))
+  if (!(tcontext = context_new (tcon_raw)))
     goto quit;
 
   if (!(contype = context_type_get (scontext)))
@@ -253,9 +253,9 @@ restorecon_private (struct selabel_handle *selabel_handle, 
char const *path)
     goto quit;
 
   if (fd != -1)
-    rc = fsetfilecon (fd, constr);
+    rc = fsetfilecon_raw (fd, constr);
   else
-    rc = lsetfilecon (path, constr);
+    rc = lsetfilecon_raw (path, constr);
 
  quit:;
   int err = errno;
@@ -263,8 +263,8 @@ restorecon_private (struct selabel_handle *selabel_handle, 
char const *path)
     close (fd);
   context_free (scontext);
   context_free (tcontext);
-  freecon (scon);
-  freecon (tcon);
+  freecon (scon_raw);
+  freecon (tcon_raw);
   errno = err;
   return rc;
 }
diff --git a/tests/cp/no-ctx.sh b/tests/cp/no-ctx.sh
index 8c69bf38d..6296f6aa3 100755
--- a/tests/cp/no-ctx.sh
+++ b/tests/cp/no-ctx.sh
@@ -39,8 +39,14 @@ int getfilecon (const char *path, char **con)
   return -1;
 }
 
+int getfilecon_raw (const char *path, char **con)
+{ return getfilecon (path, con); }
+
 int lgetfilecon (const char *path, char **con)
 { return getfilecon (path, con); }
+
+int lgetfilecon_raw (const char *path, char **con)
+{ return getfilecon (path, con); }
 EOF
 
 # Then compile/link it:
-- 
2.43.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]