From 1609e9b0cde5035ea162567e5bf0146d7cb56e7e Mon Sep 17 00:00:00 2001 From: Richard W.M. Jones Date: Nov 22 2021 15:07:08 +0000 Subject: Add support for qemu-nbd --selinux-relabel option (RHBZ#1984938) --- diff --git a/0001-nbd-server-Add-selinux-label-option.patch b/0001-nbd-server-Add-selinux-label-option.patch new file mode 100644 index 0000000..4430336 --- /dev/null +++ b/0001-nbd-server-Add-selinux-label-option.patch @@ -0,0 +1,315 @@ +From 641c964a09a5b8e52b37d6060895801a393f4073 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Mon, 15 Nov 2021 14:29:43 -0600 +Subject: [PATCH] nbd/server: Add --selinux-label option +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Under SELinux, Unix domain sockets have two labels. One is on the +disk and can be set with commands such as chcon(1). There is a +different label stored in memory (called the process label). This can +only be set by the process creating the socket. When using SELinux + +SVirt and wanting qemu to be able to connect to a qemu-nbd instance, +you must set both labels correctly first. + +For qemu-nbd the options to set the second label are awkward. You can +create the socket in a wrapper program and then exec into qemu-nbd. +Or you could try something with LD_PRELOAD. + +This commit adds the ability to set the label straightforwardly on the +command line, via the new --selinux-label flag. (The name of the flag +is the same as the equivalent nbdkit option.) + +A worked example showing how to use the new option can be found in +this bug: https://bugzilla.redhat.com/show_bug.cgi?id=1984938 + +Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1984938 +Signed-off-by: Richard W.M. Jones +Reviewed-by: Daniel P. Berrangé + +[eblake: rebase to configure changes, reject --selinux-label if it is +not compiled in or not used on a Unix socket] +Note that we may relax some of these restrictions at a later date, +such as making it possible to label a TCP socket, although it may be +smarter to do so as a generic QMP action rather than more one-off +command lines in qemu-nbd. +Signed-off-by: Eric Blake +Message-Id: <20211115202944.615966-1-eblake@redhat.com> +Reviewed-by: Thomas Huth +[eblake: adjust meson output as suggested by thuth] +Signed-off-by: Eric Blake +--- + meson.build | 10 +++- + meson_options.txt | 3 ++ + qemu-nbd.c | 46 +++++++++++++++++++ + tests/docker/dockerfiles/centos8.docker | 1 + + .../dockerfiles/fedora-i386-cross.docker | 1 + + tests/docker/dockerfiles/fedora.docker | 1 + + tests/docker/dockerfiles/opensuse-leap.docker | 1 + + tests/docker/dockerfiles/ubuntu1804.docker | 1 + + tests/docker/dockerfiles/ubuntu2004.docker | 1 + + 9 files changed, 64 insertions(+), 1 deletion(-) + +diff --git a/meson.build b/meson.build +index b3e7ec0e92..7b3fcea684 100644 +--- a/meson.build ++++ b/meson.build +@@ -1064,6 +1064,11 @@ keyutils = dependency('libkeyutils', required: false, + + has_gettid = cc.has_function('gettid') + ++# libselinux ++selinux = dependency('libselinux', ++ required: get_option('selinux'), ++ method: 'pkg-config', kwargs: static_kwargs) ++ + # Malloc tests + + malloc = [] +@@ -1291,6 +1296,7 @@ config_host_data.set('CONFIG_FUSE', fuse.found()) + config_host_data.set('CONFIG_FUSE_LSEEK', fuse_lseek.found()) + config_host_data.set('CONFIG_X11', x11.found()) + config_host_data.set('CONFIG_CFI', get_option('cfi')) ++config_host_data.set('CONFIG_SELINUX', selinux.found()) + config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version())) + config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0]) + config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1]) +@@ -2741,7 +2747,8 @@ if have_tools + qemu_io = executable('qemu-io', files('qemu-io.c'), + dependencies: [block, qemuutil], install: true) + qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'), +- dependencies: [blockdev, qemuutil, gnutls], install: true) ++ dependencies: [blockdev, qemuutil, gnutls, selinux], ++ install: true) + + subdir('storage-daemon') + subdir('contrib/rdmacm-mux') +@@ -3106,6 +3113,7 @@ summary_info += {'libpmem support': libpmem.found()} + summary_info += {'libdaxctl support': libdaxctl.found()} + summary_info += {'libudev': libudev.found()} + summary_info += {'FUSE lseek': fuse_lseek.found()} ++summary_info += {'selinux': selinux} + summary(summary_info, bool_yn: true, section: 'Dependencies') + + if not supported_cpus.contains(cpu) +diff --git a/meson_options.txt b/meson_options.txt +index a9a9b8f4c6..a5938500a3 100644 +--- a/meson_options.txt ++++ b/meson_options.txt +@@ -155,3 +155,6 @@ option('slirp', type: 'combo', value: 'auto', + option('fdt', type: 'combo', value: 'auto', + choices: ['disabled', 'enabled', 'auto', 'system', 'internal'], + description: 'Whether and how to find the libfdt library') ++ ++option('selinux', type: 'feature', value: 'auto', ++ description: 'SELinux support in qemu-nbd') +diff --git a/qemu-nbd.c b/qemu-nbd.c +index 26ffbf15af..94dc2a9cca 100644 +--- a/qemu-nbd.c ++++ b/qemu-nbd.c +@@ -47,6 +47,10 @@ + #include "trace/control.h" + #include "qemu-version.h" + ++#ifdef CONFIG_SELINUX ++#include ++#endif ++ + #ifdef __linux__ + #define HAVE_NBD_DEVICE 1 + #else +@@ -64,6 +68,7 @@ + #define QEMU_NBD_OPT_FORK 263 + #define QEMU_NBD_OPT_TLSAUTHZ 264 + #define QEMU_NBD_OPT_PID_FILE 265 ++#define QEMU_NBD_OPT_SELINUX_LABEL 266 + + #define MBR_SIZE 512 + +@@ -116,6 +121,9 @@ static void usage(const char *name) + " --fork fork off the server process and exit the parent\n" + " once the server is running\n" + " --pid-file=PATH store the server's process ID in the given file\n" ++#ifdef CONFIG_SELINUX ++" --selinux-label=LABEL set SELinux process label on listening socket\n" ++#endif + #if HAVE_NBD_DEVICE + "\n" + "Kernel NBD client support:\n" +@@ -452,6 +460,7 @@ static const char *socket_activation_validate_opts(const char *device, + const char *sockpath, + const char *address, + const char *port, ++ const char *selinux, + bool list) + { + if (device != NULL) { +@@ -470,6 +479,10 @@ static const char *socket_activation_validate_opts(const char *device, + return "TCP port number can't be set when using socket activation"; + } + ++ if (selinux != NULL) { ++ return "SELinux label can't be set when using socket activation"; ++ } ++ + if (list) { + return "List mode is incompatible with socket activation"; + } +@@ -532,6 +545,8 @@ int main(int argc, char **argv) + { "trace", required_argument, NULL, 'T' }, + { "fork", no_argument, NULL, QEMU_NBD_OPT_FORK }, + { "pid-file", required_argument, NULL, QEMU_NBD_OPT_PID_FILE }, ++ { "selinux-label", required_argument, NULL, ++ QEMU_NBD_OPT_SELINUX_LABEL }, + { NULL, 0, NULL, 0 } + }; + int ch; +@@ -558,6 +573,7 @@ int main(int argc, char **argv) + int old_stderr = -1; + unsigned socket_activation; + const char *pid_file_name = NULL; ++ const char *selinux_label = NULL; + BlockExportOptions *export_opts; + + #ifdef CONFIG_POSIX +@@ -747,6 +763,9 @@ int main(int argc, char **argv) + case QEMU_NBD_OPT_PID_FILE: + pid_file_name = optarg; + break; ++ case QEMU_NBD_OPT_SELINUX_LABEL: ++ selinux_label = optarg; ++ break; + } + } + +@@ -786,6 +805,7 @@ int main(int argc, char **argv) + /* Using socket activation - check user didn't use -p etc. */ + const char *err_msg = socket_activation_validate_opts(device, sockpath, + bindto, port, ++ selinux_label, + list); + if (err_msg != NULL) { + error_report("%s", err_msg); +@@ -825,6 +845,18 @@ int main(int argc, char **argv) + } + } + ++ if (selinux_label) { ++#ifdef CONFIG_SELINUX ++ if (sockpath == NULL && device == NULL) { ++ error_report("--selinux-label is not permitted without --socket"); ++ exit(EXIT_FAILURE); ++ } ++#else ++ error_report("SELinux support not enabled in this binary"); ++ exit(EXIT_FAILURE); ++#endif ++ } ++ + if (list) { + saddr = nbd_build_socket_address(sockpath, bindto, port); + return qemu_nbd_client_list(saddr, tlscreds, bindto); +@@ -938,6 +970,13 @@ int main(int argc, char **argv) + } else { + backlog = MIN(shared, SOMAXCONN); + } ++#ifdef CONFIG_SELINUX ++ if (selinux_label && setsockcreatecon_raw(selinux_label) == -1) { ++ error_report("Cannot set SELinux socket create context to %s: %s", ++ selinux_label, strerror(errno)); ++ exit(EXIT_FAILURE); ++ } ++#endif + saddr = nbd_build_socket_address(sockpath, bindto, port); + if (qio_net_listener_open_sync(server, saddr, backlog, + &local_err) < 0) { +@@ -945,6 +984,13 @@ int main(int argc, char **argv) + error_report_err(local_err); + exit(EXIT_FAILURE); + } ++#ifdef CONFIG_SELINUX ++ if (selinux_label && setsockcreatecon_raw(NULL) == -1) { ++ error_report("Cannot clear SELinux socket create context: %s", ++ strerror(errno)); ++ exit(EXIT_FAILURE); ++ } ++#endif + } else { + size_t i; + /* See comment in check_socket_activation above. */ +diff --git a/tests/docker/dockerfiles/centos8.docker b/tests/docker/dockerfiles/centos8.docker +index 46398c61ee..7f135f8e8c 100644 +--- a/tests/docker/dockerfiles/centos8.docker ++++ b/tests/docker/dockerfiles/centos8.docker +@@ -51,6 +51,7 @@ ENV PACKAGES \ + libpng-devel \ + librbd-devel \ + libseccomp-devel \ ++ libselinux-devel \ + libslirp-devel \ + libssh-devel \ + libtasn1-devel \ +diff --git a/tests/docker/dockerfiles/fedora-i386-cross.docker b/tests/docker/dockerfiles/fedora-i386-cross.docker +index dbb8195eb1..91a7c51614 100644 +--- a/tests/docker/dockerfiles/fedora-i386-cross.docker ++++ b/tests/docker/dockerfiles/fedora-i386-cross.docker +@@ -7,6 +7,7 @@ ENV PACKAGES \ + gcc \ + git \ + libffi-devel.i686 \ ++ libselinux-devel.i686 \ + libtasn1-devel.i686 \ + libzstd-devel.i686 \ + make \ +diff --git a/tests/docker/dockerfiles/fedora.docker b/tests/docker/dockerfiles/fedora.docker +index eec1add7f6..c6fd7e1113 100644 +--- a/tests/docker/dockerfiles/fedora.docker ++++ b/tests/docker/dockerfiles/fedora.docker +@@ -53,6 +53,7 @@ ENV PACKAGES \ + libpng-devel \ + librbd-devel \ + libseccomp-devel \ ++ libselinux-devel \ + libslirp-devel \ + libssh-devel \ + libtasn1-devel \ +diff --git a/tests/docker/dockerfiles/opensuse-leap.docker b/tests/docker/dockerfiles/opensuse-leap.docker +index 5a8bee0289..3bbdb67f4f 100644 +--- a/tests/docker/dockerfiles/opensuse-leap.docker ++++ b/tests/docker/dockerfiles/opensuse-leap.docker +@@ -55,6 +55,7 @@ ENV PACKAGES \ + libpulse-devel \ + librbd-devel \ + libseccomp-devel \ ++ libselinux-devel \ + libspice-server-devel \ + libssh-devel \ + libtasn1-devel \ +diff --git a/tests/docker/dockerfiles/ubuntu1804.docker b/tests/docker/dockerfiles/ubuntu1804.docker +index 0880bf3e29..450fd06d0d 100644 +--- a/tests/docker/dockerfiles/ubuntu1804.docker ++++ b/tests/docker/dockerfiles/ubuntu1804.docker +@@ -60,6 +60,7 @@ ENV PACKAGES \ + libsdl2-dev \ + libsdl2-image-dev \ + libseccomp-dev \ ++ libselinux-dev \ + libsnappy-dev \ + libspice-protocol-dev \ + libspice-server-dev \ +diff --git a/tests/docker/dockerfiles/ubuntu2004.docker b/tests/docker/dockerfiles/ubuntu2004.docker +index 39de63d012..15a026be09 100644 +--- a/tests/docker/dockerfiles/ubuntu2004.docker ++++ b/tests/docker/dockerfiles/ubuntu2004.docker +@@ -60,6 +60,7 @@ ENV PACKAGES \ + libsdl2-dev \ + libsdl2-image-dev \ + libseccomp-dev \ ++ libselinux-dev \ + libslirp-dev \ + libsnappy-dev \ + libspice-protocol-dev \ +-- +2.32.0 + diff --git a/qemu.spec b/qemu.spec index d6bd1b3..10b02cf 100644 --- a/qemu.spec +++ b/qemu.spec @@ -287,7 +287,7 @@ Obsoletes: %{name}-system-unicore32-core <= %{epoch}:%{version}-%{release} Summary: QEMU is a FAST! processor emulator Name: qemu Version: 6.1.0 -Release: 10%{?rcrel}%{?dist} +Release: 11%{?rcrel}%{?dist} Epoch: 2 License: GPLv2 and BSD and MIT and CC-BY URL: http://www.qemu.org/ @@ -322,10 +322,16 @@ Patch4: 0001-tests-tcg-Fix-PVH-test-with-binutils-2.36.patch # https://gitlab.com/qemu-project/qemu/-/commit/eb94846 Patch5: 0001-qxl-fix-pre-save-logic.patch +# Add support for qemu-nbd --selinux-relabel option +# https://bugzilla.redhat.com/show_bug.cgi?id=1984938 +# Upstream in 6.2. +Patch6: 0001-nbd-server-Add-selinux-label-option.patch + BuildRequires: meson >= %{meson_version} BuildRequires: zlib-devel BuildRequires: glib2-devel BuildRequires: gnutls-devel +BuildRequires: libselinux-devel BuildRequires: cyrus-sasl-devel BuildRequires: libaio-devel BuildRequires: python3-devel @@ -1420,6 +1426,9 @@ run_configure \ --enable-rdma \ %endif --enable-seccomp \ +%if 0%{?must_remember_to_add_this_in_qemu_6_2} + --enable-selinux \ +%endif --enable-slirp=system \ --enable-slirp-smbd \ --enable-snappy \ @@ -2253,6 +2262,9 @@ useradd -r -u 107 -g qemu -G kvm -d / -s /sbin/nologin \ %changelog +* Mon Nov 22 2021 Richard W.M. Jones - 6.1.0-11 +- Add support for qemu-nbd --selinux-relabel option (RHBZ#1984938) + * Mon Nov 08 2021 Adam Williamson - 6.1.0-10 - Fix snapshot creation with qxl graphics