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