commit:     9c689542c3246e793310db938374bc97600435e6
Author:     Jason Zaman <jason <AT> perfinion <DOT> com>
AuthorDate: Tue Jul 15 18:27:34 2014 +0000
Commit:     William Hubbs <williamh <AT> gentoo <DOT> org>
CommitDate: Wed Jul 16 18:09:38 2014 +0000
URL:        
http://git.overlays.gentoo.org/gitweb/?p=proj/openrc.git;a=commit;h=9c689542

checkpath: restore the SELinux context

X-Gentoo-Bug: 516956
X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=516956

---
 src/rc/Makefile          |   6 ++-
 src/rc/checkpath.c       |  28 ++++++++---
 src/rc/rc-selinux-util.c | 126 +++++++++++++++++++++++++++++++++++++++++++++++
 src/rc/rc-selinux-util.h |  33 +++++++++++++
 4 files changed, 186 insertions(+), 7 deletions(-)

diff --git a/src/rc/Makefile b/src/rc/Makefile
index 5f5aa63..fb5265c 100644
--- a/src/rc/Makefile
+++ b/src/rc/Makefile
@@ -4,7 +4,11 @@ SRCS=          checkpath.c fstabinfo.c mountinfo.c 
start-stop-daemon.c \
                rc-misc.c rc-plugin.c rc-service.c rc-status.c rc-update.c \
                runscript.c rc.c swclock.c
 
-CLEANFILES=    version.h
+ifeq (${MKSELINUX},yes)
+SRCS+=         rc-selinux-util.c
+endif
+
+CLEANFILES=    version.h rc-selinux-util.o
 
 BINDIR=                ${PREFIX}/bin
 SBINDIR=       ${PREFIX}/sbin

diff --git a/src/rc/checkpath.c b/src/rc/checkpath.c
index 6a0f893..6945b67 100644
--- a/src/rc/checkpath.c
+++ b/src/rc/checkpath.c
@@ -46,6 +46,10 @@
 #include "einfo.h"
 #include "rc-misc.h"
 
+#ifdef HAVE_SELINUX
+#include "rc-selinux-util.h"
+#endif
+
 typedef enum {
        inode_unknown = 0,
        inode_file = 1,
@@ -55,13 +59,9 @@ typedef enum {
 
 extern const char *applet;
 
-/* TODO: SELinux
- * This needs a LOT of SELinux loving
- * See systemd's src/label.c:label_mkdir
- */
 static int
 do_check(char *path, uid_t uid, gid_t gid, mode_t mode, inode_t type,
-               bool trunc, bool chowner)
+               bool trunc, bool chowner, bool selinux_on)
 {
        struct stat st;
        int fd, flags;
@@ -149,6 +149,11 @@ do_check(char *path, uid_t uid, gid_t gid, mode_t mode, 
inode_t type,
                }
        }
 
+#ifdef HAVE_SELINUX
+       if (selinux_on)
+               selinux_util_label(path);
+#endif
+
        return 0;
 }
 
@@ -226,6 +231,7 @@ checkpath(int argc, char **argv)
        bool trunc = false;
        bool chowner = false;
        bool writable = false;
+       bool selinux_on = false;
 
        while ((opt = getopt_long(argc, argv, getoptstring,
                    longopts, (int *) 0)) != -1)
@@ -276,13 +282,23 @@ checkpath(int argc, char **argv)
        if (gr)
                gid = gr->gr_gid;
 
+#ifdef HAVE_SELINUX
+       if (1 == selinux_util_open())
+               selinux_on = true;
+#endif
+
        while (optind < argc) {
                if (writable)
                        exit(!is_writable(argv[optind]));
-               if (do_check(argv[optind], uid, gid, mode, type, trunc, 
chowner))
+               if (do_check(argv[optind], uid, gid, mode, type, trunc, 
chowner, selinux_on))
                        retval = EXIT_FAILURE;
                optind++;
        }
 
+#ifdef HAVE_SELINUX
+       if (selinux_on)
+               selinux_util_close();
+#endif
+
        return retval;
 }

diff --git a/src/rc/rc-selinux-util.c b/src/rc/rc-selinux-util.c
new file mode 100644
index 0000000..6cbb5db
--- /dev/null
+++ b/src/rc/rc-selinux-util.c
@@ -0,0 +1,126 @@
+/*
+  rc-selinux.c
+  SELinux helpers to get and set contexts.
+*/
+
+/*
+ * Copyright (c) 2014 Jason Zaman <[email protected]>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stddef.h>
+#include <errno.h>
+
+#include <sys/stat.h>
+
+#include <selinux/selinux.h>
+#include <selinux/label.h>
+
+#include "rc-selinux-util.h"
+
+static struct selabel_handle *hnd = NULL;
+
+int
+selinux_util_label(const char *path)
+{
+       int retval = 0;
+       int enforce;
+       struct stat st;
+       security_context_t con;
+
+       enforce = security_getenforce();
+       if (retval < 0)
+               return retval;
+
+       if (NULL == hnd)
+               return (enforce) ? -1 : 0;
+
+       retval = lstat(path, &st);
+       if (retval < 0) {
+               if (ENOENT == errno)
+                       return 0;
+               return (enforce) ? -1 : 0;
+       }
+
+       /* lookup the context */
+       retval = selabel_lookup_raw(hnd, &con, path, st.st_mode);
+       if (retval < 0) {
+               if (ENOENT == errno)
+                       return 0;
+               return (enforce) ? -1 : 0;
+       }
+
+       /* apply the context */
+       retval = lsetfilecon(path, con);
+       freecon(con);
+       if (retval < 0) {
+               if (ENOENT == errno)
+                       return 0;
+               if (ENOTSUP == errno)
+                       return 0;
+               return (enforce) ? -1 : 0;
+       }
+
+       return 0;
+}
+
+/*
+ * Open the label handle
+ * returns 1 on success, 0 if no selinux, negative on error
+ */
+int
+selinux_util_open(void)
+{
+       int retval = 0;
+
+       retval = is_selinux_enabled();
+       if (retval <= 0)
+               return retval;
+
+       hnd = selabel_open(SELABEL_CTX_FILE, NULL, 0);
+       if (NULL == hnd)
+               return -2;
+
+       return 1;
+}
+
+/*
+ * Close the label handle
+ * returns 1 on success, 0 if no selinux, negative on error
+ */
+int
+selinux_util_close(void)
+{
+       int retval = 0;
+
+       retval = is_selinux_enabled();
+       if (retval <= 0)
+               return retval;
+
+       if (hnd) {
+               selabel_close(hnd);
+               hnd = NULL;
+       }
+
+       return 0;
+}

diff --git a/src/rc/rc-selinux-util.h b/src/rc/rc-selinux-util.h
new file mode 100644
index 0000000..69624b3
--- /dev/null
+++ b/src/rc/rc-selinux-util.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2014 Jason Zaman <[email protected]>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef RC_SELINUX_UTIL_H
+#define RC_SELINUX_UTIL_H
+
+int selinux_util_open(void);
+int selinux_util_label(const char *path);
+int selinux_util_close(void);
+
+#endif

Reply via email to