lsscsi: fix xchdir("..") from symlink in /sys/bus/scsi/devices
[oweals/busybox.git] / libbb / selinux_common.c
index 4cb85f00f7c773c4eb04c853dd6dbb9c22802e03..c2585557f200a3505b5bfcbb91df09a5c822fe1b 100644 (file)
@@ -3,12 +3,14 @@
  *   -- common SELinux utility functions
  *
  * Copyright 2007 KaiGai Kohei <kaigai@kaigai.gr.jp>
+ *
+ * Licensed under GPLv2, see file LICENSE in this source tree.
  */
-#include "busybox.h"
+#include "libbb.h"
 #include <selinux/context.h>
 
-context_t set_security_context_component(security_context_t cur_context,
-                                        char *user, char *role, char *type, char *range)
+context_t FAST_FUNC set_security_context_component(security_context_t cur_context,
+                       char *user, char *role, char *type, char *range)
 {
        context_t con = context_new(cur_context);
        if (!con)
@@ -29,12 +31,25 @@ error:
        return NULL;
 }
 
-void setfscreatecon_or_die(security_context_t scontext)
+void FAST_FUNC setfscreatecon_or_die(security_context_t scontext)
 {
        if (setfscreatecon(scontext) < 0) {
                /* Can be NULL. All known printf implementations
                 * display "(null)", "<null>" etc */
-               bb_perror_msg_and_die("cannot set default "
+               bb_perror_msg_and_die("can't set default "
                                "file creation context to %s", scontext);
        }
 }
+
+void FAST_FUNC selinux_preserve_fcontext(int fdesc)
+{
+       security_context_t context;
+
+       if (fgetfilecon(fdesc, &context) < 0) {
+               if (errno == ENODATA || errno == ENOTSUP)
+                       return;
+               bb_perror_msg_and_die("fgetfilecon failed");
+       }
+       setfscreatecon_or_die(context);
+       freecon(context);
+}