diff options
Diffstat (limited to 'loader2/selinux.c')
-rw-r--r-- | loader2/selinux.c | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/loader2/selinux.c b/loader2/selinux.c new file mode 100644 index 000000000..7f62a1f5e --- /dev/null +++ b/loader2/selinux.c @@ -0,0 +1,110 @@ +/* + * selinux.c - Various SELinux related functionality needed for the loader. + * + * Jeremy Katz <katzj@redhat.com> + * + * Copyright 2004 Red Hat, Inc. + * Portions extracted from libselinux which was released as public domain + * software by the NSA. + * + * This software may be freely redistributed under the terms of the GNU + * General Public License. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/wait.h> + +#include "loader.h" +#include "loadermisc.h" +#include "log.h" + +static char * getpolicyver() { + int fd; + char * buf; + + fd = open("/selinux/policyvers", O_RDONLY); + if (fd == -1) { + return NULL; + } + + buf = malloc(128); + if ((read(fd, buf, 128)) == -1) { + free(buf); + close(fd); + return NULL; + } + + close(fd); + return buf; +} + +int loadpolicy() { + char * ver, * fn; + char *paths[] = { "/tmp/updates/policy.", + "/mnt/source/RHupdates/policy.", + "/mnt/runtime/etc/security/selinux/policy.", + NULL }; + int i, pid, status; + + ver = getpolicyver(); + if (ver == NULL) { + return -1; + } + + fn = malloc(128); + for (i = 0; paths[i]; i++) { + snprintf(fn, 128, "%s%s", (char *) paths[i], ver); + if (!access(fn, R_OK)) { + break; + } + } + + if (access(fn, R_OK)) { + logMessage("Unable to load suitable SELinux policy"); + return -1; + } + + logMessage("Loading SELinux policy from %s", fn); + if (!(pid = fork())) { + setenv("LD_LIBRARY_PATH", LIBPATH, 1); + execl("/usr/sbin/load_policy", + "/usr/sbin/load_policy", fn, NULL); + logMessage("exec of load_policy failed: %s", strerror(errno)); + exit(1); + } + + waitpid(pid, &status, 0); + free(fn); + if (WIFEXITED(status) && (WEXITSTATUS(status) != 0)) + return 1; + + return 0; +} + +/* set a context for execution, from libselinux */ +int setexeccon(char * context) { + int fd; + ssize_t ret; + + fd = open("/proc/self/attr/exec", O_RDWR); + if (fd < 0) + return -1; + if (context) + ret = write(fd, context, strlen(context)+1); + else + ret = write(fd, NULL, 0); /* clear */ + close(fd); + if (ret < 0) + return -1; + else + return 0; +} |