Accepting request 331093 from Virtualization

- libxl: set driver log level to the log_level specified in
  libvirtd.conf
  ba25c214-libxl-log-level.patch
  bsc#945796

- CVE-2015-5247 - denial of service through root-squash NFS storage
  bsc#945645
  3468542f-virFileUnlink.patch
  8b1d84e6-refreshVol-failure.patch
  e0025d29-storage-mode-check.patch

OBS-URL: https://build.opensuse.org/request/show/331093
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/libvirt?expand=0&rev=188
This commit is contained in:
Dominique Leuenberger 2015-09-17 07:21:26 +00:00 committed by Git OBS Bridge
commit 1875f8616f
6 changed files with 343 additions and 0 deletions

View File

@ -0,0 +1,179 @@
From 3468542f06f6f5dc94defa1603c6a6adea3e2da8 Mon Sep 17 00:00:00 2001
From: John Ferlan <jferlan@redhat.com>
Date: Mon, 24 Aug 2015 17:00:02 -0400
Subject: [PATCH] virfile: Introduce virFileUnlink
In an NFS root-squashed environment the 'vol-delete' command will fail to
'unlink' the target volume since it was created under a different uid:gid.
This code continues the concepts introduced in virFileOpenForked and
virDirCreate[NoFork] with respect to running the unlink command under
the uid/gid of the child. Unlike the other two, don't retry on EACCES
(that's why we're here doing this now).
(cherry picked from commit 35847860f65f92e444db9730e00cdaef45198e0c)
---
src/libvirt_private.syms | 1 +
src/storage/storage_backend_fs.c | 3 +-
src/util/virfile.c | 106 +++++++++++++++++++++++++++++++++++++++
src/util/virfile.h | 1 +
4 files changed, 110 insertions(+), 1 deletion(-)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index d57bf5b..a96c985 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1462,6 +1462,7 @@ virFileSanitizePath;
virFileSkipRoot;
virFileStripSuffix;
virFileTouch;
+virFileUnlink;
virFileUnlock;
virFileUpdatePerm;
virFileWaitForDevices;
diff --git a/src/storage/storage_backend_fs.c b/src/storage/storage_backend_fs.c
index c0ea1df..f41a41e 100644
--- a/src/storage/storage_backend_fs.c
+++ b/src/storage/storage_backend_fs.c
@@ -1203,7 +1203,8 @@ virStorageBackendFileSystemVolDelete(virConnectPtr conn ATTRIBUTE_UNUSED,
switch ((virStorageVolType) vol->type) {
case VIR_STORAGE_VOL_FILE:
- if (unlink(vol->target.path) < 0) {
+ if (virFileUnlink(vol->target.path, vol->target.perms->uid,
+ vol->target.perms->gid) < 0) {
/* Silently ignore failures where the vol has already gone away */
if (errno != ENOENT) {
virReportSystemError(errno,
diff --git a/src/util/virfile.c b/src/util/virfile.c
index 5f64186..7b14ee8 100644
--- a/src/util/virfile.c
+++ b/src/util/virfile.c
@@ -2306,6 +2306,112 @@ virFileOpenAs(const char *path, int openflags, mode_t mode,
return ret;
}
+
+/* virFileUnlink:
+ * @path: file to unlink
+ * @uid: uid that was used to create the file (not required)
+ * @gid: gid that was used to create the file (not required)
+ *
+ * If a file/volume was created in an NFS root-squash environment,
+ * then we must 'unlink' the file in the same environment. Unlike
+ * the virFileOpenAs[Forked] and virDirCreate[NoFork], this code
+ * takes no extra flags and does not bother with EACCES failures
+ * from the child.
+ */
+int
+virFileUnlink(const char *path,
+ uid_t uid,
+ gid_t gid)
+{
+ pid_t pid;
+ int waitret;
+ int status, ret = 0;
+ gid_t *groups;
+ int ngroups;
+
+ /* If not running as root or if a non explicit uid/gid was being used for
+ * the file/volume, then use unlink directly
+ */
+ if ((geteuid() != 0) ||
+ ((uid == (uid_t) -1) && (gid == (gid_t) -1)))
+ return unlink(path);
+
+ /* Otherwise, we have to deal with the NFS root-squash craziness
+ * to run under the uid/gid that created the volume in order to
+ * perform the unlink of the volume.
+ */
+ if (uid == (uid_t) -1)
+ uid = geteuid();
+ if (gid == (gid_t) -1)
+ gid = getegid();
+
+ ngroups = virGetGroupList(uid, gid, &groups);
+ if (ngroups < 0)
+ return -errno;
+
+ pid = virFork();
+
+ if (pid < 0) {
+ ret = -errno;
+ VIR_FREE(groups);
+ return ret;
+ }
+
+ if (pid) { /* parent */
+ /* wait for child to complete, and retrieve its exit code */
+ VIR_FREE(groups);
+
+ while ((waitret = waitpid(pid, &status, 0)) == -1 && errno == EINTR);
+ if (waitret == -1) {
+ ret = -errno;
+ virReportSystemError(errno,
+ _("failed to wait for child unlinking '%s'"),
+ path);
+ goto parenterror;
+ }
+
+ /*
+ * If waitpid succeeded, but if the child exited abnormally or
+ * reported non-zero status, report failure
+ */
+ if (!WIFEXITED(status) || (WEXITSTATUS(status)) != 0) {
+ char *msg = virProcessTranslateStatus(status);
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("child failed to unlink '%s': %s"),
+ path, msg);
+ VIR_FREE(msg);
+ if (WIFEXITED(status))
+ ret = -WEXITSTATUS(status);
+ else
+ ret = -EACCES;
+ }
+
+ parenterror:
+ return ret;
+ }
+
+ /* child */
+
+ /* set desired uid/gid, then attempt to unlink the file */
+ if (virSetUIDGID(uid, gid, groups, ngroups) < 0) {
+ ret = errno;
+ goto childerror;
+ }
+
+ if (unlink(path) < 0) {
+ ret = errno;
+ goto childerror;
+ }
+
+ childerror:
+ if ((ret & 0xff) != ret) {
+ VIR_WARN("unable to pass desired return value %d", ret);
+ ret = 0xff;
+ }
+ _exit(ret);
+}
+
+
/* return -errno on failure, or 0 on success */
static int
virDirCreateNoFork(const char *path,
diff --git a/src/util/virfile.h b/src/util/virfile.h
index 2d27e89..797ca65 100644
--- a/src/util/virfile.h
+++ b/src/util/virfile.h
@@ -219,6 +219,7 @@ int virFileOpenAs(const char *path, int openflags, mode_t mode,
uid_t uid, gid_t gid,
unsigned int flags)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
+int virFileUnlink(const char *path, uid_t uid, gid_t gid);
enum {
VIR_DIR_CREATE_NONE = 0,
--
2.1.4

View File

@ -0,0 +1,39 @@
From 8b1d84e640f1a6e6ebb47caf23a664e2f651b32d Mon Sep 17 00:00:00 2001
From: John Ferlan <jferlan@redhat.com>
Date: Mon, 24 Aug 2015 12:38:13 -0400
Subject: [PATCH] storage: Handle failure from refreshVol
Commit id '155ca616' added the 'refreshVol' API. In an NFS root-squash
environment it was possible that if the just created volume from XML wasn't
properly created with the right uid/gid and/or mode, then the followup
refreshVol will fail to open the volume in order to get the allocation/
capacity values. This would leave the volume still on the server and
cause a libvirtd crash because 'voldef' would be in the pool list, but
the cleanup code would free it.
(cherry picked from commit db9277a39bc364806e8d3e08a08fc128d59b7094)
---
src/storage/storage_driver.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/src/storage/storage_driver.c b/src/storage/storage_driver.c
index ea7e0f3..0494e5d 100644
--- a/src/storage/storage_driver.c
+++ b/src/storage/storage_driver.c
@@ -1867,8 +1867,12 @@ storageVolCreateXML(virStoragePoolPtr obj,
}
if (backend->refreshVol &&
- backend->refreshVol(obj->conn, pool, voldef) < 0)
+ backend->refreshVol(obj->conn, pool, voldef) < 0) {
+ storageVolDeleteInternal(volobj, backend, pool, voldef,
+ 0, false);
+ voldef = NULL;
goto cleanup;
+ }
/* Update pool metadata ignoring the disk backend since
* it updates the pool values.
--
2.1.4

View File

@ -0,0 +1,51 @@
commit ba25c214f7c622c75448e760f3204844cfff50d0
Author: Jim Fehlig <jfehlig@suse.com>
Date: Tue Sep 15 08:17:44 2015 -0600
libxl: open libxl log stream with libvirtd log_level
Instead of a hardcoded DEBUG log level, use the overall
daemon log level specified in libvirtd.conf when opening
a log stream with libxl. libxl is very verbose when DEBUG
log level is set, resulting in huge log files that can
potentially fill a disk. Control of libxl verbosity should
be placed in the administrator's hands.
Index: libvirt-1.2.18/src/libxl/libxl_conf.c
===================================================================
--- libvirt-1.2.18.orig/src/libxl/libxl_conf.c
+++ libvirt-1.2.18/src/libxl/libxl_conf.c
@@ -1495,6 +1495,7 @@ libxlDriverConfigNew(void)
{
libxlDriverConfigPtr cfg;
char *log_file = NULL;
+ xentoollog_level log_level;
char ebuf[1024];
unsigned int free_mem;
@@ -1539,9 +1540,24 @@ libxlDriverConfigNew(void)
}
VIR_FREE(log_file);
+ switch (virLogGetDefaultPriority()) {
+ case VIR_LOG_DEBUG:
+ log_level = XTL_DEBUG;
+ break;
+ case VIR_LOG_INFO:
+ log_level = XTL_INFO;
+ break;
+ case VIR_LOG_WARN:
+ log_level = XTL_WARN;
+ break;
+ case VIR_LOG_ERROR:
+ log_level = XTL_ERROR;
+ break;
+ }
+
cfg->logger =
(xentoollog_logger *)xtl_createlogger_stdiostream(cfg->logger_file,
- XTL_DEBUG, XTL_STDIOSTREAM_SHOW_DATE);
+ log_level, XTL_STDIOSTREAM_SHOW_DATE);
if (!cfg->logger) {
VIR_ERROR(_("cannot create logger for libxenlight, disabling driver"));
goto error;

View File

@ -0,0 +1,49 @@
From e0025d2967bbe3f283937216c9e2c12b6e9d1010 Mon Sep 17 00:00:00 2001
From: John Ferlan <jferlan@redhat.com>
Date: Mon, 24 Aug 2015 12:48:40 -0400
Subject: [PATCH] storage: Correct the 'mode' check
Commit id '7c2d65dde2' changed the default value of mode to be -1 if not
supplied in the XML, which should cause creation of the volume using the
default mode of VIR_STORAGE_DEFAULT_VOL_PERM_MODE; however, the check
made was whether mode was '0' or not to use default or provided value.
This patch fixes the issue to check if the 'mode' was provided in the XML
and use that value.
(cherry picked from commit 691dd388aee99f8b06177540303b690586d5f5b3)
---
src/storage/storage_backend.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c
index 0418473..6a3146c 100644
--- a/src/storage/storage_backend.c
+++ b/src/storage/storage_backend.c
@@ -486,6 +486,7 @@ virStorageBackendCreateRaw(virConnectPtr conn ATTRIBUTE_UNUSED,
int fd = -1;
int operation_flags;
bool reflink_copy = false;
+ mode_t open_mode = VIR_STORAGE_DEFAULT_VOL_PERM_MODE;
virCheckFlags(VIR_STORAGE_VOL_CREATE_PREALLOC_METADATA |
VIR_STORAGE_VOL_CREATE_REFLINK,
@@ -518,11 +519,12 @@ virStorageBackendCreateRaw(virConnectPtr conn ATTRIBUTE_UNUSED,
if (pool->def->type == VIR_STORAGE_POOL_NETFS)
operation_flags |= VIR_FILE_OPEN_FORK;
+ if (vol->target.perms->mode != (mode_t) -1)
+ open_mode = vol->target.perms->mode;
+
if ((fd = virFileOpenAs(vol->target.path,
O_RDWR | O_CREAT | O_EXCL,
- (vol->target.perms->mode ?
- VIR_STORAGE_DEFAULT_VOL_PERM_MODE :
- vol->target.perms->mode),
+ open_mode,
vol->target.perms->uid,
vol->target.perms->gid,
operation_flags)) < 0) {
--
2.1.4

View File

@ -1,3 +1,20 @@
-------------------------------------------------------------------
Tue Sep 15 17:37:36 UTC 2015 - jfehlig@suse.com
- libxl: set driver log level to the log_level specified in
libvirtd.conf
ba25c214-libxl-log-level.patch
bsc#945796
-------------------------------------------------------------------
Mon Sep 14 08:18:12 UTC 2015 - cbosdonnat@suse.com
- CVE-2015-5247 - denial of service through root-squash NFS storage
bsc#945645
3468542f-virFileUnlink.patch
8b1d84e6-refreshVol-failure.patch
e0025d29-storage-mode-check.patch
-------------------------------------------------------------------
Wed Sep 2 06:14:17 UTC 2015 - jfehlig@suse.com

View File

@ -446,6 +446,10 @@ Source3: libvirtd.init
Source4: libvirtd-relocation-server.fw
Source99: baselibs.conf
# Upstream patches
Patch0: 3468542f-virFileUnlink.patch
Patch1: 8b1d84e6-refreshVol-failure.patch
Patch2: e0025d29-storage-mode-check.patch
Patch3: ba25c214-libxl-log-level.patch
# Patches pending upstream review
# Need to go upstream
Patch150: xen-pv-cdrom.patch
@ -976,6 +980,10 @@ Provides a dissector for the libvirt RPC protocol to help debugging it.
%prep
%setup -q
%patch0 -p1
%patch1 -p1
%patch2 -p1
%patch3 -p1
%patch150 -p1
%patch151 -p1
%patch152 -p1