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