From b6a119f2ba8c532dd632a318a4ba1ed97f98514b Mon Sep 17 00:00:00 2001 From: Jason Zaman Date: Tue, 15 Jul 2014 05:48:00 +0400 Subject: [PATCH 3/3] checkpath: restore the SELinux context Signed-off-by: Jason Zaman --- mk/os-Linux.mk | 6 +++ src/rc/Makefile | 4 ++ src/rc/checkpath.c | 28 +++++++--- src/rc/rc-selinux-util.c | 135 +++++++++++++++++++++++++++++++++++++++++++++++ src/rc/rc-selinux-util.h | 33 ++++++++++++ 5 files changed, 200 insertions(+), 6 deletions(-) create mode 100644 src/rc/rc-selinux-util.c create mode 100644 src/rc/rc-selinux-util.h diff --git a/mk/os-Linux.mk b/mk/os-Linux.mk index 40d9c34..dc76b96 100644 --- a/mk/os-Linux.mk +++ b/mk/os-Linux.mk @@ -6,3 +6,9 @@ PKG_PREFIX?= /usr CPPFLAGS+= -D_BSD_SOURCE -D_XOPEN_SOURCE=700 LIBDL= -Wl,-Bdynamic -ldl + +ifeq (${MKSELINUX},yes) +CPPFLAGS+= -DHAVE_SELINUX +LIBSELINUX= -lselinux +LDADD += $(LIBSELINUX) +endif diff --git a/src/rc/Makefile b/src/rc/Makefile index 5f5aa63..7c2721c 100644 --- a/src/rc/Makefile +++ b/src/rc/Makefile @@ -4,6 +4,10 @@ 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 +ifeq (${MKSELINUX},yes) +SRCS+= rc-selinux-util.c +endif + CLEANFILES= version.h BINDIR= ${PREFIX}/bin 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..f3057e2 --- /dev/null +++ b/src/rc/rc-selinux-util.c @@ -0,0 +1,135 @@ +/* + rc-selinux.c + SELinux helpers to get and set contexts. +*/ + +/* + * Copyright (c) 2014 Jason Zaman + * + * 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. + */ + +// TODO: take out the printf's +#include + +#include +#include + +#include +#include + +#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; + + printf("Labelling file: %s\n", path); + + 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; + + printf("Opening selinux handle\n"); + + retval = is_selinux_enabled(); + if (retval <= 0) + return retval; + + hnd = selabel_open(SELABEL_CTX_FILE, NULL, 0); + if (NULL == hnd) + return -2; + + printf("Opened selinux handle\n"); + 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; + + printf("Closing selinux handle\n"); + + 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 + * + * 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 -- 1.8.5.5