From nobody Fri May 10 09:44:03 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 16370082917241020.1128771050041; Mon, 15 Nov 2021 12:31:31 -0800 (PST) Received: from localhost ([::1]:60192 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mmidW-0000zb-0N for importer@patchew.org; Mon, 15 Nov 2021 15:31:30 -0500 Received: from eggs.gnu.org ([209.51.188.92]:56972) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mmicL-0000AX-TA for qemu-devel@nongnu.org; Mon, 15 Nov 2021 15:30:17 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:40405) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mmicH-0003Nu-ET for qemu-devel@nongnu.org; Mon, 15 Nov 2021 15:30:16 -0500 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-482-HzOKqe9PM6WsJXv8YD9BRg-1; Mon, 15 Nov 2021 15:30:06 -0500 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id E9EAB2FD05; Mon, 15 Nov 2021 20:30:04 +0000 (UTC) Received: from blue.redhat.com (ovpn-114-146.phx2.redhat.com [10.3.114.146]) by smtp.corp.redhat.com (Postfix) with ESMTP id F383D1017CF2; Mon, 15 Nov 2021 20:29:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1637008211; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=pIgbZjJEtEcH/o2iK437mlFagl+dzW/5p0hVQf0at9w=; b=VJm19z/+m+7+24tCcHxovZ5bAl7UyyTKPQAWb+gU5QUXdlj/mI7d9m+nFr3zkFezGZfzlS pGB0KCTOL4HjjMMeVrI2Sm/lLzDuhAjKcBPqNmSwNNxUNpqyenrQr2u3dqCApXGWsn6Kvj 65f7OwF1p1sG8xEDl8fIIPZ0e8RENsY= X-MC-Unique: HzOKqe9PM6WsJXv8YD9BRg-1 From: Eric Blake To: qemu-devel@nongnu.org Subject: [PATCH for 6.2 v4] nbd/server: Add --selinux-label option Date: Mon, 15 Nov 2021 14:29:43 -0600 Message-Id: <20211115202944.615966-1-eblake@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=eblake@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.133.124; envelope-from=eblake@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -34 X-Spam_score: -3.5 X-Spam_bar: --- X-Spam_report: (-3.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.7, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, thuth@redhat.com, vsementsov@virtuozzo.com, berrange@redhat.com, "open list:Network Block Dev..." , richard.henderson@linaro.org, rjones@redhat.com, wainersm@redhat.com, f4bug@amsat.org, willianr@redhat.com, pbonzini@redhat.com, alex.bennee@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1637008294074100001 From: "Richard W.M. Jones" 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=3D1984938 Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=3D1984938 Signed-off-by: Richard W.M. Jones Reviewed-by: Daniel P. Berrang=C3=A9 Message-Id: <20210930084701.3899578-1-rjones@redhat.com> [eblake: rebase to configure changes, reject --selinux-label if it is not compiled in or not used on a Unix socket] Signed-off-by: Eric Blake Reviewed-by: Thomas Huth --- v3 was here: https://lists.gnu.org/archive/html/qemu-devel/2021-09/msg07677.html since then: another rework of the configure logic (now that meson-buildoptions.sh exists), and a rework of the error reporting (for now, loudly complain on all unsupported attempts at labeling. We may later allow things that currently fail) Candidate for 6.2 in spite of soft freeze because of earlier attempted pull request here: https://lists.gnu.org/archive/html/qemu-devel/2021-09/msg07081.html and my apologies for letting this slip a month without action. meson.build | 10 +++- qemu-nbd.c | 46 +++++++++++++++++++ meson_options.txt | 3 ++ scripts/meson-buildoptions.sh | 3 ++ 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 + 10 files changed, 67 insertions(+), 1 deletion(-) diff --git a/meson.build b/meson.build index 2ece4fe0889a..73b7deaa0ef3 100644 --- a/meson.build +++ b/meson.build @@ -1201,6 +1201,11 @@ keyutils =3D dependency('libkeyutils', required: fal= se, has_gettid =3D cc.has_function('gettid') +# libselinux +selinux =3D dependency('libselinux', + required: get_option('selinux'), + method: 'pkg-config', kwargs: static_kwargs) + # Malloc tests malloc =3D [] @@ -1479,6 +1484,7 @@ config_host_data.set('CONFIG_SPICE_PROTOCOL', spice_p= rotocol.found()) config_host_data.set('CONFIG_SPICE', spice.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]) @@ -3054,7 +3060,8 @@ if have_tools qemu_io =3D executable('qemu-io', files('qemu-io.c'), dependencies: [block, qemuutil], install: true) qemu_nbd =3D 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') @@ -3430,6 +3437,7 @@ summary_info +=3D {'libdaxctl support': libdaxctl} summary_info +=3D {'libudev': libudev} # Dummy dependency, keep .found() summary_info +=3D {'FUSE lseek': fuse_lseek.found()} +summary_info +=3D {'selinux': selinux.found()} summary(summary_info, bool_yn: true, section: 'Dependencies') if not supported_cpus.contains(cpu) diff --git a/qemu-nbd.c b/qemu-nbd.c index 9d895ba24b1e..c6c20df68a4d 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 pare= nt\n" " once the server is running\n" " --pid-file=3DPATH store the server's process ID in the given = file\n" +#ifdef CONFIG_SELINUX +" --selinux-label=3DLABEL set SELinux process label on listening sock= et\n" +#endif #if HAVE_NBD_DEVICE "\n" "Kernel NBD client support:\n" @@ -454,6 +462,7 @@ static const char *socket_activation_validate_opts(cons= t char *device, const char *sockpath, const char *address, const char *port, + const char *selinux, bool list) { if (device !=3D NULL) { @@ -472,6 +481,10 @@ static const char *socket_activation_validate_opts(con= st char *device, return "TCP port number can't be set when using socket activation"; } + if (selinux !=3D NULL) { + return "SELinux label can't be set when using socket activation"; + } + if (list) { return "List mode is incompatible with socket activation"; } @@ -534,6 +547,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; @@ -560,6 +575,7 @@ int main(int argc, char **argv) int old_stderr =3D -1; unsigned socket_activation; const char *pid_file_name =3D NULL; + const char *selinux_label =3D NULL; BlockExportOptions *export_opts; #ifdef CONFIG_POSIX @@ -749,6 +765,9 @@ int main(int argc, char **argv) case QEMU_NBD_OPT_PID_FILE: pid_file_name =3D optarg; break; + case QEMU_NBD_OPT_SELINUX_LABEL: + selinux_label =3D optarg; + break; } } @@ -788,6 +807,7 @@ int main(int argc, char **argv) /* Using socket activation - check user didn't use -p etc. */ const char *err_msg =3D socket_activation_validate_opts(device, so= ckpath, bindto, port, + selinux_labe= l, list); if (err_msg !=3D NULL) { error_report("%s", err_msg); @@ -827,6 +847,18 @@ int main(int argc, char **argv) } } + if (selinux_label) { +#ifdef CONFIG_SELINUX + if (sockpath =3D=3D NULL && device =3D=3D NULL) { + error_report("--selinux-label is not permitted without --socke= t"); + exit(EXIT_FAILURE); + } +#else + error_report("SELinux support not enabled in this binary"); + exit(EXIT_FAILURE); +#endif + } + if (list) { saddr =3D nbd_build_socket_address(sockpath, bindto, port); return qemu_nbd_client_list(saddr, tlscreds, bindto); @@ -940,6 +972,13 @@ int main(int argc, char **argv) } else { backlog =3D MIN(shared, SOMAXCONN); } +#ifdef CONFIG_SELINUX + if (selinux_label && setsockcreatecon_raw(selinux_label) =3D=3D -1= ) { + error_report("Cannot set SELinux socket create context to %s: = %s", + selinux_label, strerror(errno)); + exit(EXIT_FAILURE); + } +#endif saddr =3D nbd_build_socket_address(sockpath, bindto, port); if (qio_net_listener_open_sync(server, saddr, backlog, &local_err) < 0) { @@ -947,6 +986,13 @@ int main(int argc, char **argv) error_report_err(local_err); exit(EXIT_FAILURE); } +#ifdef CONFIG_SELINUX + if (selinux_label && setsockcreatecon_raw(NULL) =3D=3D -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/meson_options.txt b/meson_options.txt index 411952bc91af..e3923237322a 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -201,3 +201,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/scripts/meson-buildoptions.sh b/scripts/meson-buildoptions.sh index 45e1f2e20daa..7a17ff42182f 100644 --- a/scripts/meson-buildoptions.sh +++ b/scripts/meson-buildoptions.sh @@ -72,6 +72,7 @@ meson_options_help() { printf "%s\n" ' sdl SDL user interface' printf "%s\n" ' sdl-image SDL Image support for icons' printf "%s\n" ' seccomp seccomp support' + printf "%s\n" ' selinux SELinux support in qemu-nbd' printf "%s\n" ' smartcard CA smartcard emulation support' printf "%s\n" ' snappy snappy compression support' printf "%s\n" ' sparse sparse checker' @@ -215,6 +216,8 @@ _meson_option_parse() { --disable-sdl-image) printf "%s" -Dsdl_image=3Ddisabled ;; --enable-seccomp) printf "%s" -Dseccomp=3Denabled ;; --disable-seccomp) printf "%s" -Dseccomp=3Ddisabled ;; + --enable-selinux) printf "%s" -Dselinux=3Denabled ;; + --disable-selinux) printf "%s" -Dselinux=3Ddisabled ;; --enable-slirp) printf "%s" -Dslirp=3Denabled ;; --disable-slirp) printf "%s" -Dslirp=3Ddisabled ;; --enable-slirp=3D*) quote_sh "-Dslirp=3D$2" ;; diff --git a/tests/docker/dockerfiles/centos8.docker b/tests/docker/dockerf= iles/centos8.docker index 46398c61eea9..7f135f8e8c00 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/dock= er/dockerfiles/fedora-i386-cross.docker index f62a71ce2296..13328e6081f9 100644 --- a/tests/docker/dockerfiles/fedora-i386-cross.docker +++ b/tests/docker/dockerfiles/fedora-i386-cross.docker @@ -8,6 +8,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/dockerfi= les/fedora.docker index eec1add7f620..c6fd7e1113d4 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/d= ockerfiles/opensuse-leap.docker index 5a8bee028951..3bbdb67f4fad 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/dock= erfiles/ubuntu1804.docker index 0880bf3e2928..450fd06d0d57 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/dock= erfiles/ubuntu2004.docker index 39de63d0129f..15a026be0913 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 \ --=20 2.33.1