|
|
43fe83 |
From 6deaf5a18aa0c03952cdcaa5ea95f53aebcf995f Mon Sep 17 00:00:00 2001
|
|
|
43fe83 |
Message-Id: <6deaf5a18aa0c03952cdcaa5ea95f53aebcf995f.1378475168.git.jdenemar@redhat.com>
|
|
|
43fe83 |
From: Eric Blake <eblake@redhat.com>
|
|
|
43fe83 |
Date: Tue, 20 Aug 2013 11:08:55 -0600
|
|
|
43fe83 |
Subject: [PATCH] selinux: enhance test to cover nfs label failure
|
|
|
43fe83 |
|
|
|
43fe83 |
https://bugzilla.redhat.com/show_bug.cgi?id=924153
|
|
|
43fe83 |
|
|
|
43fe83 |
Daniel Berrange (correctly) pointed out that we should do a better
|
|
|
43fe83 |
job of testing selinux labeling fallbacks on NFS disks that lack
|
|
|
43fe83 |
labeling support.
|
|
|
43fe83 |
|
|
|
43fe83 |
* tests/securityselinuxhelper.c (includes): Makefile already
|
|
|
43fe83 |
guaranteed xattr support. Add additional headers.
|
|
|
43fe83 |
(init_syms): New function, borrowing from vircgroupmock.c.
|
|
|
43fe83 |
(setfilecon_raw, getfilecon_raw): Fake NFS failure.
|
|
|
43fe83 |
(statfs): Fake an NFS mount point.
|
|
|
43fe83 |
(security_getenforce, security_get_boolean_active): Don't let host
|
|
|
43fe83 |
environment affect test.
|
|
|
43fe83 |
* tests/securityselinuxlabeldata/nfs.data: New file.
|
|
|
43fe83 |
* tests/securityselinuxlabeldata/nfs.xml: New file.
|
|
|
43fe83 |
* tests/securityselinuxlabeltest.c (testSELinuxCreateDisks)
|
|
|
43fe83 |
(testSELinuxDeleteDisks): Setup and cleanup for fake NFS mount.
|
|
|
43fe83 |
(testSELinuxCheckLabels): Test handling of SELinux NFS denial.
|
|
|
43fe83 |
Fix memory leak.
|
|
|
43fe83 |
(testSELinuxLabeling): Avoid infinite loop on dirty tree.
|
|
|
43fe83 |
(mymain): Add new test.
|
|
|
43fe83 |
|
|
|
43fe83 |
(cherry picked from commit 95577af442e503bb209808b04b6482c895c9f561)
|
|
|
43fe83 |
---
|
|
|
43fe83 |
tests/securityselinuxhelper.c | 86 ++++++++++++++++++++++++++++++----
|
|
|
43fe83 |
tests/securityselinuxlabeldata/nfs.txt | 1 +
|
|
|
43fe83 |
tests/securityselinuxlabeldata/nfs.xml | 24 ++++++++++
|
|
|
43fe83 |
tests/securityselinuxlabeltest.c | 17 +++++--
|
|
|
43fe83 |
4 files changed, 117 insertions(+), 11 deletions(-)
|
|
|
43fe83 |
create mode 100644 tests/securityselinuxlabeldata/nfs.txt
|
|
|
43fe83 |
create mode 100644 tests/securityselinuxlabeldata/nfs.xml
|
|
|
43fe83 |
|
|
|
43fe83 |
diff --git a/tests/securityselinuxhelper.c b/tests/securityselinuxhelper.c
|
|
|
43fe83 |
index a82ca6d..89cba3a 100644
|
|
|
43fe83 |
--- a/tests/securityselinuxhelper.c
|
|
|
43fe83 |
+++ b/tests/securityselinuxhelper.c
|
|
|
43fe83 |
@@ -1,5 +1,5 @@
|
|
|
43fe83 |
/*
|
|
|
43fe83 |
- * Copyright (C) 2011-2012 Red Hat, Inc.
|
|
|
43fe83 |
+ * Copyright (C) 2011-2013 Red Hat, Inc.
|
|
|
43fe83 |
*
|
|
|
43fe83 |
* This library is free software; you can redistribute it and/or
|
|
|
43fe83 |
* modify it under the terms of the GNU Lesser General Public
|
|
|
43fe83 |
@@ -19,22 +19,53 @@
|
|
|
43fe83 |
|
|
|
43fe83 |
#include <config.h>
|
|
|
43fe83 |
|
|
|
43fe83 |
+/* This file is only compiled on Linux, and only if xattr support was
|
|
|
43fe83 |
+ * detected. */
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+#include <dlfcn.h>
|
|
|
43fe83 |
+#include <errno.h>
|
|
|
43fe83 |
+#include <linux/magic.h>
|
|
|
43fe83 |
#include <selinux/selinux.h>
|
|
|
43fe83 |
+#include <stdio.h>
|
|
|
43fe83 |
#include <stdlib.h>
|
|
|
43fe83 |
#include <string.h>
|
|
|
43fe83 |
+#include <sys/vfs.h>
|
|
|
43fe83 |
#include <unistd.h>
|
|
|
43fe83 |
-#include <errno.h>
|
|
|
43fe83 |
-#if WITH_ATTR
|
|
|
43fe83 |
-# include <attr/xattr.h>
|
|
|
43fe83 |
-#endif
|
|
|
43fe83 |
+#include <attr/xattr.h>
|
|
|
43fe83 |
|
|
|
43fe83 |
#include "virstring.h"
|
|
|
43fe83 |
|
|
|
43fe83 |
+static int (*realstatfs)(const char *path, struct statfs *buf);
|
|
|
43fe83 |
+static int (*realsecurity_get_boolean_active)(const char *name);
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+static void init_syms(void)
|
|
|
43fe83 |
+{
|
|
|
43fe83 |
+ if (realstatfs)
|
|
|
43fe83 |
+ return;
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+#define LOAD_SYM(name) \
|
|
|
43fe83 |
+ do { \
|
|
|
43fe83 |
+ if (!(real ## name = dlsym(RTLD_NEXT, #name))) { \
|
|
|
43fe83 |
+ fprintf(stderr, "Cannot find real '%s' symbol\n", #name); \
|
|
|
43fe83 |
+ abort(); \
|
|
|
43fe83 |
+ } \
|
|
|
43fe83 |
+ } while (0)
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ LOAD_SYM(statfs);
|
|
|
43fe83 |
+ LOAD_SYM(security_get_boolean_active);
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+#undef LOAD_SYM
|
|
|
43fe83 |
+}
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+
|
|
|
43fe83 |
/*
|
|
|
43fe83 |
* The kernel policy will not allow us to arbitrarily change
|
|
|
43fe83 |
* test process context. This helper is used as an LD_PRELOAD
|
|
|
43fe83 |
* so that the libvirt code /thinks/ it is changing/reading
|
|
|
43fe83 |
- * the process context, where as in fact we're faking it all
|
|
|
43fe83 |
+ * the process context, whereas in fact we're faking it all.
|
|
|
43fe83 |
+ * Furthermore, we fake out that we are using an nfs subdirectory,
|
|
|
43fe83 |
+ * where we control whether selinux is enforcing and whether
|
|
|
43fe83 |
+ * the virt_use_nfs bool is set.
|
|
|
43fe83 |
*/
|
|
|
43fe83 |
|
|
|
43fe83 |
int getcon_raw(security_context_t *context)
|
|
|
43fe83 |
@@ -83,10 +114,13 @@ int setcon(security_context_t context)
|
|
|
43fe83 |
}
|
|
|
43fe83 |
|
|
|
43fe83 |
|
|
|
43fe83 |
-#if WITH_ATTR
|
|
|
43fe83 |
int setfilecon_raw(const char *path, security_context_t con)
|
|
|
43fe83 |
{
|
|
|
43fe83 |
const char *constr = con;
|
|
|
43fe83 |
+ if (STRPREFIX(path, abs_builddir "/securityselinuxlabeldata/nfs/")) {
|
|
|
43fe83 |
+ errno = EOPNOTSUPP;
|
|
|
43fe83 |
+ return -1;
|
|
|
43fe83 |
+ }
|
|
|
43fe83 |
return setxattr(path, "user.libvirt.selinux",
|
|
|
43fe83 |
constr, strlen(constr), 0);
|
|
|
43fe83 |
}
|
|
|
43fe83 |
@@ -101,6 +135,10 @@ int getfilecon_raw(const char *path, security_context_t *con)
|
|
|
43fe83 |
char *constr = NULL;
|
|
|
43fe83 |
ssize_t len = getxattr(path, "user.libvirt.selinux",
|
|
|
43fe83 |
NULL, 0);
|
|
|
43fe83 |
+ if (STRPREFIX(path, abs_builddir "/securityselinuxlabeldata/nfs/")) {
|
|
|
43fe83 |
+ errno = EOPNOTSUPP;
|
|
|
43fe83 |
+ return -1;
|
|
|
43fe83 |
+ }
|
|
|
43fe83 |
if (len < 0)
|
|
|
43fe83 |
return -1;
|
|
|
43fe83 |
if (!(constr = malloc(len+1)))
|
|
|
43fe83 |
@@ -114,8 +152,40 @@ int getfilecon_raw(const char *path, security_context_t *con)
|
|
|
43fe83 |
constr[len] = '\0';
|
|
|
43fe83 |
return 0;
|
|
|
43fe83 |
}
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+
|
|
|
43fe83 |
int getfilecon(const char *path, security_context_t *con)
|
|
|
43fe83 |
{
|
|
|
43fe83 |
return getfilecon_raw(path, con);
|
|
|
43fe83 |
}
|
|
|
43fe83 |
-#endif
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+int statfs(const char *path, struct statfs *buf)
|
|
|
43fe83 |
+{
|
|
|
43fe83 |
+ int ret;
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ init_syms();
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ ret = realstatfs(path, buf);
|
|
|
43fe83 |
+ if (!ret && STREQ(path, abs_builddir "/securityselinuxlabeldata/nfs"))
|
|
|
43fe83 |
+ buf->f_type = NFS_SUPER_MAGIC;
|
|
|
43fe83 |
+ return ret;
|
|
|
43fe83 |
+}
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+int security_getenforce(void)
|
|
|
43fe83 |
+{
|
|
|
43fe83 |
+ /* For the purpose of our test, we are enforcing. */
|
|
|
43fe83 |
+ return 1;
|
|
|
43fe83 |
+}
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+int security_get_boolean_active(const char *name)
|
|
|
43fe83 |
+{
|
|
|
43fe83 |
+ /* For the purpose of our test, nfs is not permitted. */
|
|
|
43fe83 |
+ if (STREQ(name, "virt_use_nfs"))
|
|
|
43fe83 |
+ return 0;
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ init_syms();
|
|
|
43fe83 |
+ return realsecurity_get_boolean_active(name);
|
|
|
43fe83 |
+}
|
|
|
43fe83 |
diff --git a/tests/securityselinuxlabeldata/nfs.txt b/tests/securityselinuxlabeldata/nfs.txt
|
|
|
43fe83 |
new file mode 100644
|
|
|
43fe83 |
index 0000000..4c1698e
|
|
|
43fe83 |
--- /dev/null
|
|
|
43fe83 |
+++ b/tests/securityselinuxlabeldata/nfs.txt
|
|
|
43fe83 |
@@ -0,0 +1 @@
|
|
|
43fe83 |
+/nfs/plain.raw;EOPNOTSUPP
|
|
|
43fe83 |
diff --git a/tests/securityselinuxlabeldata/nfs.xml b/tests/securityselinuxlabeldata/nfs.xml
|
|
|
43fe83 |
new file mode 100644
|
|
|
43fe83 |
index 0000000..46a1440
|
|
|
43fe83 |
--- /dev/null
|
|
|
43fe83 |
+++ b/tests/securityselinuxlabeldata/nfs.xml
|
|
|
43fe83 |
@@ -0,0 +1,24 @@
|
|
|
43fe83 |
+<domain type='kvm'>
|
|
|
43fe83 |
+ <name>vm1</name>
|
|
|
43fe83 |
+ <uuid>c7b3edbd-edaf-9455-926a-d65c16db1800</uuid>
|
|
|
43fe83 |
+ <memory unit='KiB'>219200</memory>
|
|
|
43fe83 |
+ <os>
|
|
|
43fe83 |
+ <type arch='i686' machine='pc-1.0'>hvm</type>
|
|
|
43fe83 |
+ <boot dev='cdrom'/>
|
|
|
43fe83 |
+ </os>
|
|
|
43fe83 |
+ <devices>
|
|
|
43fe83 |
+ <disk type='file' device='disk'>
|
|
|
43fe83 |
+ <driver name='qemu' type='raw'/>
|
|
|
43fe83 |
+ <source file='/nfs/plain.raw'/>
|
|
|
43fe83 |
+ <target dev='vda' bus='virtio'/>
|
|
|
43fe83 |
+ </disk>
|
|
|
43fe83 |
+ <input type='mouse' bus='ps2'/>
|
|
|
43fe83 |
+ <graphics type='vnc' port='-1' autoport='yes' listen='0.0.0.0'>
|
|
|
43fe83 |
+ <listen type='address' address='0.0.0.0'/>
|
|
|
43fe83 |
+ </graphics>
|
|
|
43fe83 |
+ </devices>
|
|
|
43fe83 |
+ <seclabel model="selinux" type="dynamic" relabel="yes">
|
|
|
43fe83 |
+ <label>system_u:system_r:svirt_t:s0:c41,c264</label>
|
|
|
43fe83 |
+ <imagelabel>system_u:object_r:svirt_image_t:s0:c41,c264</imagelabel>
|
|
|
43fe83 |
+ </seclabel>
|
|
|
43fe83 |
+</domain>
|
|
|
43fe83 |
diff --git a/tests/securityselinuxlabeltest.c b/tests/securityselinuxlabeltest.c
|
|
|
43fe83 |
index efe825a..fa99f99 100644
|
|
|
43fe83 |
--- a/tests/securityselinuxlabeltest.c
|
|
|
43fe83 |
+++ b/tests/securityselinuxlabeltest.c
|
|
|
43fe83 |
@@ -209,7 +209,7 @@ testSELinuxCreateDisks(testSELinuxFile *files, size_t nfiles)
|
|
|
43fe83 |
{
|
|
|
43fe83 |
size_t i;
|
|
|
43fe83 |
|
|
|
43fe83 |
- if (virFileMakePath(abs_builddir "/securityselinuxlabeldata") < 0)
|
|
|
43fe83 |
+ if (virFileMakePath(abs_builddir "/securityselinuxlabeldata/nfs") < 0)
|
|
|
43fe83 |
return -1;
|
|
|
43fe83 |
|
|
|
43fe83 |
for (i = 0; i < nfiles; i++) {
|
|
|
43fe83 |
@@ -228,6 +228,10 @@ testSELinuxDeleteDisks(testSELinuxFile *files, size_t nfiles)
|
|
|
43fe83 |
if (unlink(files[i].file) < 0)
|
|
|
43fe83 |
return -1;
|
|
|
43fe83 |
}
|
|
|
43fe83 |
+ if (rmdir(abs_builddir "/securityselinuxlabeldata/nfs") < 0)
|
|
|
43fe83 |
+ return -1;
|
|
|
43fe83 |
+ /* Ignore failure to remove non-empty directory with in-tree build */
|
|
|
43fe83 |
+ rmdir(abs_builddir "/securityselinuxlabeldata");
|
|
|
43fe83 |
return 0;
|
|
|
43fe83 |
}
|
|
|
43fe83 |
|
|
|
43fe83 |
@@ -238,9 +242,13 @@ testSELinuxCheckLabels(testSELinuxFile *files, size_t nfiles)
|
|
|
43fe83 |
security_context_t ctx;
|
|
|
43fe83 |
|
|
|
43fe83 |
for (i = 0; i < nfiles; i++) {
|
|
|
43fe83 |
+ ctx = NULL;
|
|
|
43fe83 |
if (getfilecon(files[i].file, &ctx) < 0) {
|
|
|
43fe83 |
if (errno == ENODATA) {
|
|
|
43fe83 |
- ctx = NULL;
|
|
|
43fe83 |
+ /* nothing to do */
|
|
|
43fe83 |
+ } else if (errno == EOPNOTSUPP) {
|
|
|
43fe83 |
+ if (VIR_STRDUP(ctx, "EOPNOTSUPP") < 0)
|
|
|
43fe83 |
+ return -1;
|
|
|
43fe83 |
} else {
|
|
|
43fe83 |
virReportSystemError(errno,
|
|
|
43fe83 |
"Cannot read label on %s",
|
|
|
43fe83 |
@@ -252,8 +260,10 @@ testSELinuxCheckLabels(testSELinuxFile *files, size_t nfiles)
|
|
|
43fe83 |
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
43fe83 |
"File %s context '%s' did not match epected '%s'",
|
|
|
43fe83 |
files[i].file, ctx, files[i].context);
|
|
|
43fe83 |
+ VIR_FREE(ctx);
|
|
|
43fe83 |
return -1;
|
|
|
43fe83 |
}
|
|
|
43fe83 |
+ VIR_FREE(ctx);
|
|
|
43fe83 |
}
|
|
|
43fe83 |
return 0;
|
|
|
43fe83 |
}
|
|
|
43fe83 |
@@ -287,7 +297,7 @@ testSELinuxLabeling(const void *opaque)
|
|
|
43fe83 |
|
|
|
43fe83 |
cleanup:
|
|
|
43fe83 |
if (testSELinuxDeleteDisks(files, nfiles) < 0)
|
|
|
43fe83 |
- goto cleanup;
|
|
|
43fe83 |
+ VIR_WARN("unable to fully clean up");
|
|
|
43fe83 |
|
|
|
43fe83 |
virDomainDefFree(def);
|
|
|
43fe83 |
for (i = 0; i < nfiles; i++) {
|
|
|
43fe83 |
@@ -334,6 +344,7 @@ mymain(void)
|
|
|
43fe83 |
DO_TEST_LABELING("disks");
|
|
|
43fe83 |
DO_TEST_LABELING("kernel");
|
|
|
43fe83 |
DO_TEST_LABELING("chardev");
|
|
|
43fe83 |
+ DO_TEST_LABELING("nfs");
|
|
|
43fe83 |
|
|
|
43fe83 |
return (ret == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
|
|
|
43fe83 |
}
|
|
|
43fe83 |
--
|
|
|
43fe83 |
1.8.3.2
|
|
|
43fe83 |
|