SHA256
1
0
forked from pool/qemu

Accepting request 800526 from home:bfrogers:branches:Virtualization

- Fix DoS in virtiofsd, where a FUSE client could exhaust the
  number of available open files on the host (CVE-2020-10717
  bsc#1171110)
  virtiofsd-add-rlimit-nofile-NUM-option.patch
  virtiofsd-stay-below-fs.file-max-sysctl-.patch
- Add more fixes for gcc10 compatibility: Use NO_WERROR=1 when
  building ipxe sources, at least until we get gcc10 compatibility
  figured out. Also add patch for explicitly using -fcommon
  (boo#1171140)
  Be-explicit-about-fcommon-compiler-direc.patch
  and fix for tighter enum compatibility checking (boo#1171139)
  add-enum-cast-to-avoid-gcc10-warning.patch
  and a work around for what seems to be a compiler regression
  (boo#1171123)
  work-around-gcc10-problem-with-zero-leng.patch

OBS-URL: https://build.opensuse.org/request/show/800526
OBS-URL: https://build.opensuse.org/package/show/Virtualization/qemu?expand=0&rev=549
This commit is contained in:
Bruce Rogers 2020-05-05 23:41:07 +00:00 committed by Git OBS Bridge
parent 3b42969e09
commit 827e886f53
9 changed files with 367 additions and 8 deletions

View File

@ -0,0 +1,35 @@
From: Bruce Rogers <brogers@suse.com>
Date: Tue, 5 May 2020 10:09:47 -0600
Subject: Be explicit about -fcommon compiler directive
References: boo#1171140
gcc10 switched default behavior from -fcommon to -fno-common. Since
"__shared" relies on the legacy behavior, explicitly specify it.
Signed-off-by: Bruce Rogers <brogers@suse.com>
---
src/Makefile.housekeeping | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/roms/ipxe/src/Makefile.housekeeping b/roms/ipxe/src/Makefile.housekeeping
index 1ddbddd247d9929d63b1654d7206..3f091c7dc937fbdac6434d10aec7 100644
--- a/roms/ipxe/src/Makefile.housekeeping
+++ b/roms/ipxe/src/Makefile.housekeeping
@@ -170,6 +170,16 @@ CFI_FLAGS := $(shell $(CFI_TEST) && \
WORKAROUND_CFLAGS += $(CFI_FLAGS)
endif
+# gcc 10 switched default behavior from -fcommon to -fno-common. Since
+# "__shared" relies on the legacy behavior, explicitly specify it.
+#
+ifeq ($(CCTYPE),gcc)
+FCOMMON_TEST = $(CC) -fcommon -x c -c /dev/null \
+ -o /dev/null >/dev/null 2>&1
+FCOMMON_FLAGS := $(shell $(FCOMMON_TEST) && $(ECHO) '-fcommon')
+WORKAROUND_CFLAGS += $(FCOMMON_FLAGS)
+endif
+
# gcc 4.6 generates spurious warnings if -Waddress is in force.
# Inhibit this.
#

View File

@ -0,0 +1,38 @@
From: Bruce Rogers <brogers@suse.com>
Date: Tue, 5 May 2020 13:33:49 -0600
Subject: add enum cast to avoid gcc10 warning
References: boo#1171139
Two enums are practically the same, and have been used interchangably
without problem. But gcc10 has flagged that usage as problematic.
Casting from one type to the other clears use the warning, and adds some
clarity that this is intentional usage.
Signed-off-by: Bruce Rogers <brogers@suse.com>
---
src/drivers/infiniband/flexboot_nodnic.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/roms/ipxe/src/drivers/infiniband/flexboot_nodnic.c b/roms/ipxe/src/drivers/infiniband/flexboot_nodnic.c
index c13fcefc56866da67d701baa96b8..ac28949d3cca6b0c29a8a32165e7 100644
--- a/roms/ipxe/src/drivers/infiniband/flexboot_nodnic.c
+++ b/roms/ipxe/src/drivers/infiniband/flexboot_nodnic.c
@@ -365,7 +365,7 @@ static int flexboot_nodnic_create_qp ( struct ib_device *ibdev,
goto qp_alloc_err;
}
- status = nodnic_port_create_qp(&port->port_priv, qp->type,
+ status = nodnic_port_create_qp(&port->port_priv, (nodnic_queue_pair_type)qp->type,
qp->send.num_wqes * sizeof(struct nodnic_send_wqbb),
qp->send.num_wqes,
qp->recv.num_wqes * sizeof(struct nodnic_recv_wqe),
@@ -406,7 +406,7 @@ static void flexboot_nodnic_destroy_qp ( struct ib_device *ibdev,
struct flexboot_nodnic_port *port = &flexboot_nodnic->port[ibdev->port - 1];
struct flexboot_nodnic_queue_pair *flexboot_nodnic_qp = ib_qp_get_drvdata ( qp );
- nodnic_port_destroy_qp(&port->port_priv, qp->type,
+ nodnic_port_destroy_qp(&port->port_priv, (nodnic_queue_pair_type)qp->type,
flexboot_nodnic_qp->nodnic_queue_pair);
free(flexboot_nodnic_qp);

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:7b48585377489cd7edb49ea0ca8195b1340f2d70d1c487aad8a71dd15dc333b3
size 64676
oid sha256:5bc454d2f284d04edfb3f0e3b8edf72a939e2935fcc81401b483b755a7e239be
size 64236

View File

@ -1,3 +1,26 @@
-------------------------------------------------------------------
Tue May 5 21:11:11 UTC 2020 - Bruce Rogers <brogers@suse.com>
- Fix DoS in virtiofsd, where a FUSE client could exhaust the
number of available open files on the host (CVE-2020-10717
bsc#1171110)
virtiofsd-add-rlimit-nofile-NUM-option.patch
virtiofsd-stay-below-fs.file-max-sysctl-.patch
-------------------------------------------------------------------
Tue May 5 19:41:48 UTC 2020 - Bruce Rogers <brogers@suse.com>
- Add more fixes for gcc10 compatibility: Use NO_WERROR=1 when
building ipxe sources, at least until we get gcc10 compatibility
figured out. Also add patch for explicitly using -fcommon
(boo#1171140)
Be-explicit-about-fcommon-compiler-direc.patch
and fix for tighter enum compatibility checking (boo#1171139)
add-enum-cast-to-avoid-gcc10-warning.patch
and a work around for what seems to be a compiler regression
(boo#1171123)
work-around-gcc10-problem-with-zero-leng.patch
-------------------------------------------------------------------
Tue Apr 28 18:10:25 UTC 2020 - Bruce Rogers <brogers@suse.com>

View File

@ -186,6 +186,8 @@ Patch00055: s390x-s390-virtio-ccw-Fix-build-on-syste.patch
Patch00056: configure-remove-pkgversion-from-CONFIG_.patch
Patch00057: gcc10-maybe-uninitialized.patch
Patch00058: docs-add-SUSE-support-statements-to-html.patch
Patch00059: virtiofsd-add-rlimit-nofile-NUM-option.patch
Patch00060: virtiofsd-stay-below-fs.file-max-sysctl-.patch
# Patches applied in roms/seabios/:
Patch01000: seabios-use-python2-explicitly-as-needed.patch
Patch01001: seabios-switch-to-python3-as-needed.patch
@ -196,6 +198,9 @@ Patch02001: ipxe-Makefile-fix-issues-of-build-reprod.patch
Patch02002: Fix-s-directive-argument-is-null-error.patch
Patch02003: Workaround-compilation-error-with-gcc-9..patch
Patch02004: Do-not-apply-WORKAROUND_CFLAGS-for-host-.patch
Patch02005: Be-explicit-about-fcommon-compiler-direc.patch
Patch02006: work-around-gcc10-problem-with-zero-leng.patch
Patch02007: add-enum-cast-to-avoid-gcc10-warning.patch
# Patches applied in roms/sgabios/:
Patch03000: sgabios-Makefile-fix-issues-of-build-rep.patch
Patch03001: roms-sgabios-Fix-csum8-to-be-built-by-ho.patch
@ -952,6 +957,8 @@ This package provides a service file for starting and stopping KSM.
%if %{legacy_qemu_kvm} && 0%{?is_opensuse} == 0
%patch00058 -p1
%endif
%patch00059 -p1
%patch00060 -p1
%patch01000 -p1
%patch01001 -p1
%patch01002 -p1
@ -964,6 +971,9 @@ This package provides a service file for starting and stopping KSM.
%ifarch aarch64
%patch02004 -p1
%endif
%patch02005 -p1
%patch02006 -p1
%patch02007 -p1
%patch03000 -p1
%patch03001 -p1
%patch08000 -p1
@ -1358,11 +1368,11 @@ make %{?_smp_mflags} -C %{_builddir}/%buildsubdir/roms seavgabios-ati \
HOSTCC=cc \
%endif
make %{?_smp_mflags} -C %{_builddir}/%buildsubdir/roms pxerom
make %{?_smp_mflags} -C %{_builddir}/%buildsubdir/roms pxerom NO_WERROR=1
%ifnarch %ix86
make %{?_smp_mflags} -C %{_builddir}/%buildsubdir/roms efirom \
EDK2_BASETOOLS_OPTFLAGS='-fPIE'
EDK2_BASETOOLS_OPTFLAGS='-fPIE' NO_WERROR=1
%endif
make -C %{_builddir}/%buildsubdir/roms sgabios \
@ -1372,7 +1382,8 @@ make -C %{_builddir}/%buildsubdir/roms sgabios \
pushd %{_builddir}/%buildsubdir
patch -p1 < %_sourcedir/stub-out-the-SAN-req-s-in-int13.patch
popd
make %{?_smp_mflags} -C %{_builddir}/%buildsubdir/roms pxerom_variants=virtio pxerom_targets=1af41000 pxerom
make %{?_smp_mflags} -C %{_builddir}/%buildsubdir/roms \
pxerom_variants=virtio pxerom_targets=1af41000 pxerom NO_WERROR=1
%endif
# enforce pxe rom sizes for migration compatability from SLE 11 SP3 forward

View File

@ -1201,11 +1201,11 @@ make %{?_smp_mflags} -C %{_builddir}/%buildsubdir/roms seavgabios-ati \
HOSTCC=cc \
%endif
make %{?_smp_mflags} -C %{_builddir}/%buildsubdir/roms pxerom
make %{?_smp_mflags} -C %{_builddir}/%buildsubdir/roms pxerom NO_WERROR=1
%ifnarch %ix86
make %{?_smp_mflags} -C %{_builddir}/%buildsubdir/roms efirom \
EDK2_BASETOOLS_OPTFLAGS='-fPIE'
EDK2_BASETOOLS_OPTFLAGS='-fPIE' NO_WERROR=1
%endif
make -C %{_builddir}/%buildsubdir/roms sgabios \
@ -1215,7 +1215,8 @@ make -C %{_builddir}/%buildsubdir/roms sgabios \
pushd %{_builddir}/%buildsubdir
patch -p1 < %_sourcedir/stub-out-the-SAN-req-s-in-int13.patch
popd
make %{?_smp_mflags} -C %{_builddir}/%buildsubdir/roms pxerom_variants=virtio pxerom_targets=1af41000 pxerom
make %{?_smp_mflags} -C %{_builddir}/%buildsubdir/roms \
pxerom_variants=virtio pxerom_targets=1af41000 pxerom NO_WERROR=1
%endif
# enforce pxe rom sizes for migration compatability from SLE 11 SP3 forward

View File

@ -0,0 +1,147 @@
From: Stefan Hajnoczi <stefanha@redhat.com>
Date: Fri, 1 May 2020 15:06:43 +0100
Subject: virtiofsd: add --rlimit-nofile=NUM option
Git-commit: 6dbb716877728ce4eb51619885ef6ef4ada9565f
References: bsc#1171110
Make it possible to specify the RLIMIT_NOFILE on the command-line.
Users running multiple virtiofsd processes should allocate a certain
number to each process so that the system-wide limit can never be
exhausted.
When this option is set to 0 the rlimit is left at its current value.
This is useful when a management tool wants to configure the rlimit
itself.
The default behavior remains unchanged: try to set the limit to
1,000,000 file descriptors if the current rlimit is lower.
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Message-Id: <20200501140644.220940-2-stefanha@redhat.com>
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Bruce Rogers <brogers@suse.com>
---
tools/virtiofsd/fuse_lowlevel.h | 1 +
tools/virtiofsd/helper.c | 23 +++++++++++++++++++++++
tools/virtiofsd/passthrough_ll.c | 22 ++++++++--------------
3 files changed, 32 insertions(+), 14 deletions(-)
diff --git a/tools/virtiofsd/fuse_lowlevel.h b/tools/virtiofsd/fuse_lowlevel.h
index 8f6d705b5ccdb318b860ed2d2dc7..562fd5241ed400013f6fa65116ee 100644
--- a/tools/virtiofsd/fuse_lowlevel.h
+++ b/tools/virtiofsd/fuse_lowlevel.h
@@ -1777,6 +1777,7 @@ struct fuse_cmdline_opts {
int syslog;
int log_level;
unsigned int max_idle_threads;
+ unsigned long rlimit_nofile;
};
/**
diff --git a/tools/virtiofsd/helper.c b/tools/virtiofsd/helper.c
index 819c2bc13cf7c23c2876f175104b..dc59f38af02c73c2a492fd3b2d6f 100644
--- a/tools/virtiofsd/helper.c
+++ b/tools/virtiofsd/helper.c
@@ -23,6 +23,8 @@
#include <stdlib.h>
#include <string.h>
#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/resource.h>
#include <unistd.h>
#define FUSE_HELPER_OPT(t, p) \
@@ -53,6 +55,7 @@ static const struct fuse_opt fuse_helper_opts[] = {
FUSE_HELPER_OPT("subtype=", nodefault_subtype),
FUSE_OPT_KEY("subtype=", FUSE_OPT_KEY_KEEP),
FUSE_HELPER_OPT("max_idle_threads=%u", max_idle_threads),
+ FUSE_HELPER_OPT("--rlimit-nofile=%lu", rlimit_nofile),
FUSE_HELPER_OPT("--syslog", syslog),
FUSE_HELPER_OPT_VALUE("log_level=debug", log_level, FUSE_LOG_DEBUG),
FUSE_HELPER_OPT_VALUE("log_level=info", log_level, FUSE_LOG_INFO),
@@ -171,6 +174,9 @@ void fuse_cmdline_help(void)
" default: no_writeback\n"
" -o xattr|no_xattr enable/disable xattr\n"
" default: no_xattr\n"
+ " --rlimit-nofile=<num> set maximum number of file descriptors\n"
+ " (0 leaves rlimit unchanged)\n"
+ " default: 1,000,000 if the current rlimit is lower\n"
);
}
@@ -191,11 +197,28 @@ static int fuse_helper_opt_proc(void *data, const char *arg, int key,
}
}
+static unsigned long get_default_rlimit_nofile(void)
+{
+ rlim_t max_fds = 1000000; /* our default RLIMIT_NOFILE target */
+ struct rlimit rlim;
+
+ if (getrlimit(RLIMIT_NOFILE, &rlim) < 0) {
+ fuse_log(FUSE_LOG_ERR, "getrlimit(RLIMIT_NOFILE): %m\n");
+ exit(1);
+ }
+
+ if (rlim.rlim_cur >= max_fds) {
+ return 0; /* we have more fds available than required! */
+ }
+ return max_fds;
+}
+
int fuse_parse_cmdline(struct fuse_args *args, struct fuse_cmdline_opts *opts)
{
memset(opts, 0, sizeof(struct fuse_cmdline_opts));
opts->max_idle_threads = 10;
+ opts->rlimit_nofile = get_default_rlimit_nofile();
opts->foreground = 1;
if (fuse_opt_parse(args, opts, fuse_helper_opts, fuse_helper_opt_proc) ==
diff --git a/tools/virtiofsd/passthrough_ll.c b/tools/virtiofsd/passthrough_ll.c
index 4c35c95b256cbaa5d888037800a7..f7b9c1d20c312d1eefb4c8782c27 100644
--- a/tools/virtiofsd/passthrough_ll.c
+++ b/tools/virtiofsd/passthrough_ll.c
@@ -2707,24 +2707,18 @@ static void setup_sandbox(struct lo_data *lo, struct fuse_session *se,
setup_seccomp(enable_syslog);
}
-/* Raise the maximum number of open file descriptors */
-static void setup_nofile_rlimit(void)
+/* Set the maximum number of open file descriptors */
+static void setup_nofile_rlimit(unsigned long rlimit_nofile)
{
- const rlim_t max_fds = 1000000;
- struct rlimit rlim;
-
- if (getrlimit(RLIMIT_NOFILE, &rlim) < 0) {
- fuse_log(FUSE_LOG_ERR, "getrlimit(RLIMIT_NOFILE): %m\n");
- exit(1);
- }
+ struct rlimit rlim = {
+ .rlim_cur = rlimit_nofile,
+ .rlim_max = rlimit_nofile,
+ };
- if (rlim.rlim_cur >= max_fds) {
+ if (rlimit_nofile == 0) {
return; /* nothing to do */
}
- rlim.rlim_cur = max_fds;
- rlim.rlim_max = max_fds;
-
if (setrlimit(RLIMIT_NOFILE, &rlim) < 0) {
/* Ignore SELinux denials */
if (errno == EPERM) {
@@ -2977,7 +2971,7 @@ int main(int argc, char *argv[])
fuse_daemonize(opts.foreground);
- setup_nofile_rlimit();
+ setup_nofile_rlimit(opts.rlimit_nofile);
/* Must be before sandbox since it wants /proc */
setup_capng();

View File

@ -0,0 +1,74 @@
From: Stefan Hajnoczi <stefanha@redhat.com>
Date: Fri, 1 May 2020 15:06:44 +0100
Subject: virtiofsd: stay below fs.file-max sysctl value (CVE-2020-10717)
Git-commit: 8c1d353d107b4fc344e27f2f08ea7fa25de2eea2
References: bsc#1171110, CVE-2020-10717
The system-wide fs.file-max sysctl value determines how many files can
be open. It defaults to a value calculated based on the machine's RAM
size. Previously virtiofsd would try to set RLIMIT_NOFILE to 1,000,000
and this allowed the FUSE client to exhaust the number of open files
system-wide on Linux hosts with less than 10 GB of RAM!
Take fs.file-max into account when choosing the default RLIMIT_NOFILE
value.
Fixes: CVE-2020-10717
Reported-by: Yuval Avrahami <yavrahami@paloaltonetworks.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Message-Id: <20200501140644.220940-3-stefanha@redhat.com>
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Bruce Rogers <brogers@suse.com>
---
tools/virtiofsd/helper.c | 26 +++++++++++++++++++++++++-
1 file changed, 25 insertions(+), 1 deletion(-)
diff --git a/tools/virtiofsd/helper.c b/tools/virtiofsd/helper.c
index dc59f38af02c73c2a492fd3b2d6f..00a1ef666a510068bb687bb34756 100644
--- a/tools/virtiofsd/helper.c
+++ b/tools/virtiofsd/helper.c
@@ -176,7 +176,8 @@ void fuse_cmdline_help(void)
" default: no_xattr\n"
" --rlimit-nofile=<num> set maximum number of file descriptors\n"
" (0 leaves rlimit unchanged)\n"
- " default: 1,000,000 if the current rlimit is lower\n"
+ " default: min(1000000, fs.file-max - 16384)\n"
+ " if the current rlimit is lower\n"
);
}
@@ -199,9 +200,32 @@ static int fuse_helper_opt_proc(void *data, const char *arg, int key,
static unsigned long get_default_rlimit_nofile(void)
{
+ g_autofree gchar *file_max_str = NULL;
+ const rlim_t reserved_fds = 16384; /* leave at least this many fds free */
rlim_t max_fds = 1000000; /* our default RLIMIT_NOFILE target */
+ rlim_t file_max;
struct rlimit rlim;
+ /*
+ * Reduce max_fds below the system-wide maximum, if necessary. This
+ * ensures there are fds available for other processes so we don't
+ * cause resource exhaustion.
+ */
+ if (!g_file_get_contents("/proc/sys/fs/file-max", &file_max_str,
+ NULL, NULL)) {
+ fuse_log(FUSE_LOG_ERR, "can't read /proc/sys/fs/file-max\n");
+ exit(1);
+ }
+ file_max = g_ascii_strtoull(file_max_str, NULL, 10);
+ if (file_max < 2 * reserved_fds) {
+ fuse_log(FUSE_LOG_ERR,
+ "The fs.file-max sysctl is too low (%lu) to allow a "
+ "reasonable number of open files.\n",
+ (unsigned long)file_max);
+ exit(1);
+ }
+ max_fds = MIN(file_max - reserved_fds, max_fds);
+
if (getrlimit(RLIMIT_NOFILE, &rlim) < 0) {
fuse_log(FUSE_LOG_ERR, "getrlimit(RLIMIT_NOFILE): %m\n");
exit(1);

View File

@ -0,0 +1,30 @@
From: Bruce Rogers <brogers@suse.com>
Date: Tue, 5 May 2020 13:26:33 -0600
Subject: work around gcc10 problem with zero-length array
References: boo#1171123
gcc10 has introduced a regression in handling zero-length array under
certain cirumstances. For now simply work around it by extending the
array to have 1 member. I've audited the code to ensure that will still
work right.
See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94940
Signed-off-by: Bruce Rogers <brogers@suse.com>
---
src/drivers/net/intelvf.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/roms/ipxe/src/drivers/net/intelvf.h b/roms/ipxe/src/drivers/net/intelvf.h
index ab404698fe6de9f48370931fdf56..abc2cd254bd44f4b2168e1ecee54 100644
--- a/roms/ipxe/src/drivers/net/intelvf.h
+++ b/roms/ipxe/src/drivers/net/intelvf.h
@@ -132,7 +132,7 @@ union intelvf_msg {
/** Queue configuration message */
struct intelvf_msg_queues queues;
/** Raw dwords */
- uint32_t dword[0];
+ uint32_t dword[1];
};
/** Maximum time to wait for mailbox message