[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [RFC][PATCH 01/01]qemu: add SELinux hook for loading virtua
From: |
David Windsor |
Subject: |
[Qemu-devel] [RFC][PATCH 01/01]qemu: add SELinux hook for loading virtual hard disk |
Date: |
Fri, 20 Jul 2007 17:51:10 -0400 |
User-agent: |
Microsoft-Entourage/11.3.3.061214 |
Add infrastructure to qemu to make it an SELinux object manager. Currently,
the AVC is not being used, since only one permission is currently being
checked.
Index: src/kvm-userspace/qemu/vl.c
===================================================================
--- src.orig/kvm-userspace/qemu/vl.c
+++ src/kvm-userspace/qemu/vl.c
@@ -92,6 +92,8 @@
#include "qemu-kvm.h"
#endif
+#include "selinux.h"
+
#define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup"
#ifdef __sun__
#define SMBD_COMMAND "/usr/sfw/sbin/smbd"
@@ -7522,6 +7524,14 @@ int main(int argc, char **argv)
}
#endif
+#ifdef CONFIG_VM_SECURITY
+ /* Initialize SELinux */
+ if (selinux_init()) {
+ fprintf(stderr, "Could not initialize SELinux\n");
+ exit(1);
+ }
+#endif
+
/* we always create the cdrom drive, even if no disk is there */
bdrv_init();
if (cdrom_index >= 0) {
@@ -7537,6 +7547,14 @@ int main(int argc, char **argv)
snprintf(buf, sizeof(buf), "hd%c", i + 'a');
bs_table[i] = bdrv_new(buf);
}
+
+#ifdef CONFIG_VM_SECURITY
+ if (selinux_vm_use_block_device(hd_filename[i])) {
+ fprintf(stderr, "qemu: SELinux denied access to hard disk
image '%s'\n", hd_filename[i]);
+ exit(1);
+ }
+#endif
+
if (bdrv_open(bs_table[i], hd_filename[i], snapshot ?
BDRV_O_SNAPSHOT : 0) < 0) {
fprintf(stderr, "qemu: could not open hard disk image
'%s'\n",
hd_filename[i]);
Index: src/kvm-userspace/qemu/configure
===================================================================
--- src.orig/kvm-userspace/qemu/configure
+++ src/kvm-userspace/qemu/configure
@@ -90,6 +90,7 @@ bsd="no"
linux="no"
kqemu="no"
kvm="no"
+vm_security="no"
profiler="no"
kernel_path=""
cocoa="no"
@@ -238,6 +239,8 @@ for opt do
;;
--enable-kvm) kvm="yes"
;;
+ --enable-vm-security) vm_security="yes"
+ ;;
--enable-profiler) profiler="yes"
;;
--kernel-path=*) kernel_path="$optarg"
@@ -287,6 +290,7 @@ echo "kqemu kernel acceleration support:
echo " --disable-kqemu disable kqemu support"
echo " --kernel-path=PATH set the kernel path (configure probes it)"
echo " --enable-kvm enable kernel virtual machine support"
+echo " --enable-vm-security enable SELinux enforcement hooks"
echo ""
echo "Advanced options (experts only):"
echo " --source-path=PATH path of source code [$source_path]"
@@ -868,13 +872,18 @@ bflt="no"
interp_prefix1=`echo "$interp_prefix" | sed "s/%M/$target_cpu/g"`
echo "#define CONFIG_QEMU_PREFIX \"$interp_prefix1\"" >> $config_h
+if test $vm_security = "yes" ; then
+ echo "#define CONFIG_VM_SECURITY 1" >> $config_h
+ echo "CONFIG_VM_SECURITY=yes" >> $config_mak
+fi
+
configure_kvm() {
if test $kvm = "yes" -a "$target_softmmu" = "yes" -a \
\( "$cpu" = "i386" -o "$cpu" = "x86_64" \); then
echo "#define USE_KVM 1" >> $config_h
echo "CONFIG_KVM_KERNEL_INC=$kernel_path/include" >> $config_mak
fi
-}
+ }
if test "$target_cpu" = "i386" ; then
echo "TARGET_ARCH=i386" >> $config_mak
Index: src/kvm-userspace/configure
===================================================================
--- src.orig/kvm-userspace/configure
+++ src/kvm-userspace/configure
@@ -5,6 +5,7 @@ kerneldir=/lib/modules/$(uname -r)/build
want_module=1
qemu_cc=$(ls /usr/bin/gcc3* /usr/bin/gcc-3* 2>/dev/null | tail -n1)
disable_gcc_check=
+enable_vm_security=
usage() {
cat <<-EOF
@@ -18,6 +19,7 @@ usage() {
--qemu-cc="$qemu_cc" compiler for qemu (needs gcc3.x)
($qemu_cc)
--disable-gcc-check don't insist on gcc-3.x
- this will break running without kvm
+ --enable-vm-security enable SELinux security enforcement
EOF
exit 1
}
@@ -53,6 +55,9 @@ while [[ "$1" = -* ]]; do
--disable-gcc-check)
disable_gcc_check=1
;;
+ --enable-vm-security)
+ enable_vm_security=1
+ ;;
--help)
usage
;;
@@ -87,6 +92,7 @@ target_cpu() {
--enable-kvm --kernel-path="$libkvm_kerneldir" \
--enable-alsa \
${disable_gcc_check:+"--disable-gcc-check"} \
+ ${enable_vm_security:+"--enable-vm-security"}\
--prefix="$prefix"
)
Index: src/kvm-userspace/qemu/Makefile.target
===================================================================
--- src.orig/kvm-userspace/qemu/Makefile.target
+++ src/kvm-userspace/qemu/Makefile.target
@@ -232,7 +232,7 @@ OBJS+= libqemu.a
# cpu emulator library
LIBOBJS=exec.o kqemu.o qemu-kvm.o translate-op.o translate-all.o
cpu-exec.o\
- translate.o op.o
+ translate.o op.o selinux.o
ifdef CONFIG_SOFTFLOAT
LIBOBJS+=fpu/softfloat.o
else
@@ -364,6 +364,9 @@ CFLAGS += -I $(CONFIG_KVM_KERNEL_INC)
LIBS += -lkvm
DEPLIBS += ../user/libkvm.a
endif
+ifdef CONFIG_VM_SECURITY
+LIBS += -lselinux
+endif
# SCSI layer
VL_OBJS+= scsi-disk.o cdrom.o lsi53c895a.o
Index: src/kvm-userspace/qemu/selinux.h
===================================================================
--- /dev/null
+++ src/kvm-userspace/qemu/selinux.h
@@ -0,0 +1,24 @@
+#ifndef _QEMU_SELINUX_H_
+#define _QEMU_SELINUX_H_
+
+/*
+ * Initialize qemu's SELinux subsystem.
+ *
+ * Returns 0 on success, non-zero on error.
+ * This function will only return non-zero when SELinux is
+ * enabled in the running kernel and is in enforcing mode.
+ */
+int selinux_init(void);
+
+/*
+ * Check the SELinux policy as to whether the current process is allowed
+ * to load a virtual disk into a virtual machine.
+ * This function should only be called after calling selinux_init.
+ *
+ * Returns 0 if the operation is allowed, non-zero if the operation is
denied.
+ * This function will only return non-zero if SELinux is enabled
+ * in the running kernel and is in enforcing mode.
+ */
+int selinux_vm_use_block_device(const char *hd_filename);
+
+#endif
Index: src/kvm-userspace/qemu/selinux.c
===================================================================
--- /dev/null
+++ src/kvm-userspace/qemu/selinux.c
@@ -0,0 +1,114 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <selinux/flask.h>
+#include <selinux/av_permissions.h>
+#include <selinux/selinux.h>
+
+#include "selinux.h"
+
+static int qemu_selinux_enabled = 0;
+
+/*
+ * Initialize qemu's SELinux subsystem.
+ *
+ * Returns 0 on success, non-zero on error.
+ * This function will return non-zero only when SELinux is
+ * enabled in the running kernel and is in enforcing mode.
+ */
+int selinux_init(void)
+{
+ int retval = -1;
+ struct security_class_mapping map[] = {
+ { "vm",
+ { "entrypoint", NULL }},
+ { NULL }
+ };
+
+ if (qemu_selinux_enabled) {
+ retval = 0;
+ goto out;
+ }
+
+ retval = is_selinux_enabled();
+ if (!retval)
+ goto out;
+
+ /* Create userspace object class and permission mappings */
+ retval = selinux_set_mapping(map);
+ if (retval < 0) {
+ printf("SELinux: failed to set up security class
mapping\n");
+ goto out;
+ }
+
+ qemu_selinux_enabled = 1;
+out:
+ if (retval != 0 && !security_getenforce())
+ retval = 0;
+ return retval;
+}
+
+/*
+ * Check the SELinux policy as to whether the current process is
+ * allowed to load a virtual disk into a virtual machine.
+ * This function should only be called after calling selinux_init.
+ *
+ * Returns 0 if the operation is allowed, non-zero if the operation is
denied.
+ * This function will only return non-zero if SELinux is enabled
+ * in the running kernel and is in enforcing mode.
+ */
+int selinux_vm_use_block_device(const char *hd_filename)
+{
+ security_context_t scon;
+ security_context_t tcon;
+ security_class_t vm_class;
+ access_vector_t vm_perms;
+ struct av_decision avd;
+ int retval = -1;
+
+ retval = is_selinux_enabled();
+ if (!retval) {
+ retval = 0;
+ goto out;
+ }
+
+ vm_class = string_to_security_class("vm");
+ if (!vm_class) {
+ retval = -1;
+ goto out;
+ }
+
+ vm_perms = string_to_av_perm(vm_class, "entrypoint");
+ if (!vm_perms) {
+ retval = -1;
+ goto out;
+ }
+
+ /* The context of the VM is the context of the current process */
+ retval = getcon(&scon);
+ if (retval)
+ goto out;
+
+ /* Get the context of the virtual disk */
+ retval = getfilecon(hd_filename, &tcon);
+ if (retval < 0) {
+ freecon(scon);
+ goto out;
+ }
+
+ retval = security_compute_av(scon, tcon, vm_class,
+ vm_perms, &avd);
+ freecon(scon);
+ freecon(tcon);
+ if (!retval && ((vm_perms & avd.allowed) == vm_perms)) {
+ goto out;
+ } else {
+ /* Access is denied */
+ retval = 1;
+ goto out;
+ }
+
+out:
+ if (retval != 0 && !security_getenforce())
+ retval = 0;
+ return retval;
+}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Qemu-devel] [RFC][PATCH 01/01]qemu: add SELinux hook for loading virtual hard disk,
David Windsor <=