diff options
-rw-r--r-- | src/rc/Makefile | 6 | ||||
-rw-r--r-- | src/rc/checkpath.c | 28 | ||||
-rw-r--r-- | src/rc/rc-selinux-util.c | 126 | ||||
-rw-r--r-- | 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 5f5aa631..fb5265c6 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 6a0f8939..6945b670 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 00000000..6cbb5db9 --- /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 <jason@perfinion.com> + * + * 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 00000000..69624b39 --- /dev/null +++ b/src/rc/rc-selinux-util.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2014 Jason Zaman <jason@perfinion.com> + * + * 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 |