Accepting request 201962 from Virtualization

Updated libvirt package for Factory/13.1 that fixes several
CVEs.  Please copy to 13.1 as well, or let me know if I need
an explicit SR for that.  Thanks!

- CVE-2013-4311: Add support for using 3-arg pkcheck syntax for
  process
  db7a5688-CVE-2013-4311.patch, e65667c0-CVE-2013-4311.patch,
  922b7fda-CVE-2013-4311.patch, e4697b92-CVE-2013-4311.patch
  bnc#836931

- CVE-2013-4296: Fix crash in remoteDispatchDomainMemoryStats
  e7f400a1-CVE-2013-4296.patch
  bnc#838638
- CVE-2013-4297: Fix crash in virFileNBDDeviceAssociate
  2dba0323-CVE-2013-4297.patch
  bnc#838642

OBS-URL: https://build.opensuse.org/request/show/201962
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/libvirt?expand=0&rev=130
This commit is contained in:
Tomáš Chvátal 2013-10-03 14:04:53 +00:00 committed by Git OBS Bridge
commit e8fa87a2cc
9 changed files with 509 additions and 2 deletions

View File

@ -0,0 +1,21 @@
commit 2dba0323ff0cec31bdcea9dd3b2428af297401f2
Author: Michal Privoznik <mprivozn@redhat.com>
Date: Tue Sep 3 18:56:06 2013 +0200
virFileNBDDeviceAssociate: Avoid use of uninitialized variable
The @qemunbd variable can be used uninitialized.
Index: libvirt-1.1.2/src/util/virfile.c
===================================================================
--- libvirt-1.1.2.orig/src/util/virfile.c
+++ libvirt-1.1.2/src/util/virfile.c
@@ -732,7 +732,7 @@ int virFileNBDDeviceAssociate(const char
char **dev)
{
char *nbddev;
- char *qemunbd;
+ char *qemunbd = NULL;
virCommandPtr cmd = NULL;
int ret = -1;
const char *fmtstr = NULL;

View File

@ -0,0 +1,171 @@
commit 922b7fda77b094dbf022d625238262ea05335666
Author: Daniel P. Berrange <berrange@redhat.com>
Date: Wed Aug 28 15:25:40 2013 +0100
Add support for using 3-arg pkcheck syntax for process (CVE-2013-4311)
With the existing pkcheck (pid, start time) tuple for identifying
the process, there is a race condition, where a process can make
a libvirt RPC call and in another thread exec a setuid application,
causing it to change to effective UID 0. This in turn causes polkit
to do its permission check based on the wrong UID.
To address this, libvirt must get the UID the caller had at time
of connect() (from SO_PEERCRED) and pass a (pid, start time, uid)
triple to the pkcheck program.
This fix requires that libvirt is re-built against a version of
polkit that has the fix for its CVE-2013-4288, so that libvirt
can see 'pkg-config --variable pkcheck_supports_uid polkit-gobject-1'
Signed-off-by: Colin Walters <walters@redhat.com>
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Index: libvirt-1.1.2/configure.ac
===================================================================
--- libvirt-1.1.2.orig/configure.ac
+++ libvirt-1.1.2/configure.ac
@@ -1184,6 +1184,14 @@ if test "x$with_polkit" = "xyes" || test
AC_PATH_PROG([PKCHECK_PATH],[pkcheck], [], [/usr/sbin:$PATH])
if test "x$PKCHECK_PATH" != "x" ; then
AC_DEFINE_UNQUOTED([PKCHECK_PATH],["$PKCHECK_PATH"],[Location of pkcheck program])
+ AC_MSG_CHECKING([whether pkcheck supports uid value])
+ pkcheck_supports_uid=`$PKG_CONFIG --variable pkcheck_supports_uid polkit-gobject-1`
+ if test "x$pkcheck_supports_uid" = "xtrue"; then
+ AC_MSG_RESULT([yes])
+ AC_DEFINE_UNQUOTED([PKCHECK_SUPPORTS_UID], 1, [Pass uid to pkcheck])
+ else
+ AC_MSG_RESULT([no])
+ fi
AC_DEFINE_UNQUOTED([WITH_POLKIT], 1,
[use PolicyKit for UNIX socket access checks])
AC_DEFINE_UNQUOTED([WITH_POLKIT1], 1,
Index: libvirt-1.1.2/daemon/remote.c
===================================================================
--- libvirt-1.1.2.orig/daemon/remote.c
+++ libvirt-1.1.2/daemon/remote.c
@@ -2738,10 +2738,12 @@ remoteDispatchAuthPolkit(virNetServerPtr
int status = -1;
char *ident = NULL;
bool authdismissed = 0;
+ bool supportsuid = false;
char *pkout = NULL;
struct daemonClientPrivate *priv =
virNetServerClientGetPrivateData(client);
virCommandPtr cmd = NULL;
+ static bool polkitInsecureWarned;
virMutexLock(&priv->lock);
action = virNetServerClientGetReadonly(client) ?
@@ -2763,14 +2765,28 @@ remoteDispatchAuthPolkit(virNetServerPtr
goto authfail;
}
+ if (timestamp == 0) {
+ VIR_WARN("Failing polkit auth due to missing client (pid=%lld) start time",
+ (long long)callerPid);
+ goto authfail;
+ }
+
VIR_INFO("Checking PID %lld running as %d",
(long long) callerPid, callerUid);
virCommandAddArg(cmd, "--process");
- if (timestamp != 0) {
- virCommandAddArgFormat(cmd, "%lld,%llu", (long long) callerPid, timestamp);
+# ifdef PKCHECK_SUPPORTS_UID
+ supportsuid = true;
+# endif
+ if (supportsuid) {
+ virCommandAddArgFormat(cmd, "%lld,%llu,%lu",
+ (long long) callerPid, timestamp, (unsigned long) callerUid);
} else {
- virCommandAddArgFormat(cmd, "%lld", (long long) callerPid);
+ if (!polkitInsecureWarned) {
+ VIR_WARN("No support for caller UID with pkcheck. This deployment is known to be insecure.");
+ polkitInsecureWarned = true;
+ }
+ virCommandAddArgFormat(cmd, "%lld,%llu", (long long) callerPid, timestamp);
}
virCommandAddArg(cmd, "--allow-user-interaction");
Index: libvirt-1.1.2/libvirt.spec.in
===================================================================
--- libvirt-1.1.2.orig/libvirt.spec.in
+++ libvirt-1.1.2/libvirt.spec.in
@@ -508,8 +508,7 @@ BuildRequires: cyrus-sasl-devel
%endif
%if %{with_polkit}
%if 0%{?fedora} >= 12 || 0%{?rhel} >= 6
-# Only need the binary, not -devel
-BuildRequires: polkit >= 0.93
+BuildRequires: polkit-devel >= 0.93
%else
BuildRequires: PolicyKit-devel >= 0.6
%endif
Index: libvirt-1.1.2/src/access/viraccessdriverpolkit.c
===================================================================
--- libvirt-1.1.2.orig/src/access/viraccessdriverpolkit.c
+++ libvirt-1.1.2/src/access/viraccessdriverpolkit.c
@@ -72,8 +72,12 @@ static char *
virAccessDriverPolkitFormatProcess(const char *actionid)
{
virIdentityPtr identity = virIdentityGetCurrent();
- const char *process = NULL;
+ const char *callerPid = NULL;
+ const char *callerTime = NULL;
+ const char *callerUid = NULL;
char *ret = NULL;
+ bool supportsuid = false;
+ static bool polkitInsecureWarned;
if (!identity) {
virAccessError(VIR_ERR_ACCESS_DENIED,
@@ -81,17 +85,43 @@ virAccessDriverPolkitFormatProcess(const
actionid);
return NULL;
}
- if (virIdentityGetAttr(identity, VIR_IDENTITY_ATTR_UNIX_PROCESS_ID, &process) < 0)
+ if (virIdentityGetAttr(identity, VIR_IDENTITY_ATTR_UNIX_PROCESS_ID, &callerPid) < 0)
+ goto cleanup;
+ if (virIdentityGetAttr(identity, VIR_IDENTITY_ATTR_UNIX_PROCESS_TIME, &callerTime) < 0)
+ goto cleanup;
+ if (virIdentityGetAttr(identity, VIR_IDENTITY_ATTR_UNIX_USER_ID, &callerUid) < 0)
goto cleanup;
- if (!process) {
+ if (!callerPid) {
virAccessError(VIR_ERR_INTERNAL_ERROR, "%s",
_("No UNIX process ID available"));
goto cleanup;
}
-
- if (VIR_STRDUP(ret, process) < 0)
+ if (!callerTime) {
+ virAccessError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("No UNIX process start time available"));
+ goto cleanup;
+ }
+ if (!callerUid) {
+ virAccessError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("No UNIX caller UID available"));
goto cleanup;
+ }
+
+#ifdef PKCHECK_SUPPORTS_UID
+ supportsuid = true;
+#endif
+ if (supportsuid) {
+ if (virAsprintf(&ret, "%s,%s,%s", callerPid, callerTime, callerUid) < 0)
+ goto cleanup;
+ } else {
+ if (!polkitInsecureWarned) {
+ VIR_WARN("No support for caller UID with pkcheck. This deployment is known to be insecure.");
+ polkitInsecureWarned = true;
+ }
+ if (virAsprintf(&ret, "%s,%s", callerPid, callerTime) < 0)
+ goto cleanup;
+ }
cleanup:
virObjectUnref(identity);

View File

@ -0,0 +1,149 @@
commit db7a5688c05f3fd60d9d2b74c72427eb9ee9c176
Author: Daniel P. Berrange <berrange@redhat.com>
Date: Thu Aug 22 16:00:01 2013 +0100
Also store user & group ID values in virIdentity
Future improvements to the polkit code will require access to
the numeric user ID, not merely user name.
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Index: libvirt-1.1.2/src/rpc/virnetserverclient.c
===================================================================
--- libvirt-1.1.2.orig/src/rpc/virnetserverclient.c
+++ libvirt-1.1.2/src/rpc/virnetserverclient.c
@@ -652,7 +652,9 @@ virNetServerClientCreateIdentity(virNetS
char *processid = NULL;
char *processtime = NULL;
char *username = NULL;
+ char *userid = NULL;
char *groupname = NULL;
+ char *groupid = NULL;
#if WITH_SASL
char *saslname = NULL;
#endif
@@ -672,8 +674,12 @@ virNetServerClientCreateIdentity(virNetS
if (!(username = virGetUserName(uid)))
goto cleanup;
+ if (virAsprintf(&userid, "%d", (int)uid) < 0)
+ goto cleanup;
if (!(groupname = virGetGroupName(gid)))
goto cleanup;
+ if (virAsprintf(&userid, "%d", (int)gid) < 0)
+ goto cleanup;
if (virAsprintf(&processid, "%llu",
(unsigned long long)pid) < 0)
goto cleanup;
@@ -710,11 +716,21 @@ virNetServerClientCreateIdentity(virNetS
VIR_IDENTITY_ATTR_UNIX_USER_NAME,
username) < 0)
goto error;
+ if (userid &&
+ virIdentitySetAttr(ret,
+ VIR_IDENTITY_ATTR_UNIX_USER_ID,
+ userid) < 0)
+ goto error;
if (groupname &&
virIdentitySetAttr(ret,
VIR_IDENTITY_ATTR_UNIX_GROUP_NAME,
groupname) < 0)
goto error;
+ if (groupid &&
+ virIdentitySetAttr(ret,
+ VIR_IDENTITY_ATTR_UNIX_GROUP_ID,
+ groupid) < 0)
+ goto error;
if (processid &&
virIdentitySetAttr(ret,
VIR_IDENTITY_ATTR_UNIX_PROCESS_ID,
@@ -745,7 +761,9 @@ virNetServerClientCreateIdentity(virNetS
cleanup:
VIR_FREE(username);
+ VIR_FREE(userid);
VIR_FREE(groupname);
+ VIR_FREE(groupid);
VIR_FREE(processid);
VIR_FREE(processtime);
VIR_FREE(seccontext);
Index: libvirt-1.1.2/src/util/viridentity.c
===================================================================
--- libvirt-1.1.2.orig/src/util/viridentity.c
+++ libvirt-1.1.2/src/util/viridentity.c
@@ -133,7 +133,9 @@ int virIdentitySetCurrent(virIdentityPtr
virIdentityPtr virIdentityGetSystem(void)
{
char *username = NULL;
+ char *userid = NULL;
char *groupname = NULL;
+ char *groupid = NULL;
char *seccontext = NULL;
virIdentityPtr ret = NULL;
#if WITH_SELINUX
@@ -147,8 +149,13 @@ virIdentityPtr virIdentityGetSystem(void
if (!(username = virGetUserName(getuid())))
goto cleanup;
+ if (virAsprintf(&userid, "%d", (int)getuid()) < 0)
+ goto cleanup;
+
if (!(groupname = virGetGroupName(getgid())))
goto cleanup;
+ if (virAsprintf(&groupid, "%d", (int)getgid()) < 0)
+ goto cleanup;
#if WITH_SELINUX
if (getcon(&con) < 0) {
@@ -166,16 +173,22 @@ virIdentityPtr virIdentityGetSystem(void
if (!(ret = virIdentityNew()))
goto cleanup;
- if (username &&
- virIdentitySetAttr(ret,
+ if (virIdentitySetAttr(ret,
VIR_IDENTITY_ATTR_UNIX_USER_NAME,
username) < 0)
goto error;
- if (groupname &&
- virIdentitySetAttr(ret,
+ if (virIdentitySetAttr(ret,
+ VIR_IDENTITY_ATTR_UNIX_USER_ID,
+ userid) < 0)
+ goto error;
+ if (virIdentitySetAttr(ret,
VIR_IDENTITY_ATTR_UNIX_GROUP_NAME,
groupname) < 0)
goto error;
+ if (virIdentitySetAttr(ret,
+ VIR_IDENTITY_ATTR_UNIX_GROUP_ID,
+ groupid) < 0)
+ goto error;
if (seccontext &&
virIdentitySetAttr(ret,
VIR_IDENTITY_ATTR_SELINUX_CONTEXT,
@@ -188,7 +201,9 @@ virIdentityPtr virIdentityGetSystem(void
cleanup:
VIR_FREE(username);
+ VIR_FREE(userid);
VIR_FREE(groupname);
+ VIR_FREE(groupid);
VIR_FREE(seccontext);
VIR_FREE(processid);
return ret;
Index: libvirt-1.1.2/src/util/viridentity.h
===================================================================
--- libvirt-1.1.2.orig/src/util/viridentity.h
+++ libvirt-1.1.2/src/util/viridentity.h
@@ -29,7 +29,9 @@ typedef virIdentity *virIdentityPtr;
typedef enum {
VIR_IDENTITY_ATTR_UNIX_USER_NAME,
+ VIR_IDENTITY_ATTR_UNIX_USER_ID,
VIR_IDENTITY_ATTR_UNIX_GROUP_NAME,
+ VIR_IDENTITY_ATTR_UNIX_GROUP_ID,
VIR_IDENTITY_ATTR_UNIX_PROCESS_ID,
VIR_IDENTITY_ATTR_UNIX_PROCESS_TIME,
VIR_IDENTITY_ATTR_SASL_USER_NAME,

View File

@ -0,0 +1,35 @@
commit e4697b92abaad16e8e6b41a1e55be9b084d48d5a
Author: Daniel P. Berrange <berrange@redhat.com>
Date: Mon Sep 23 12:46:25 2013 +0100
Fix typo in identity code which is pre-requisite for CVE-2013-4311
The fix for CVE-2013-4311 had a pre-requisite enhancement
to the identity code
commit db7a5688c05f3fd60d9d2b74c72427eb9ee9c176
Author: Daniel P. Berrange <berrange@redhat.com>
Date: Thu Aug 22 16:00:01 2013 +0100
Also store user & group ID values in virIdentity
This had a typo which caused the group ID to overwrite the
user ID string. This meant any checks using this would have
the wrong ID value. This only affected the ACL code, not the
initial polkit auth. It also leaked memory.
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Index: libvirt-1.1.2/src/rpc/virnetserverclient.c
===================================================================
--- libvirt-1.1.2.orig/src/rpc/virnetserverclient.c
+++ libvirt-1.1.2/src/rpc/virnetserverclient.c
@@ -678,7 +678,7 @@ virNetServerClientCreateIdentity(virNetS
goto cleanup;
if (!(groupname = virGetGroupName(gid)))
goto cleanup;
- if (virAsprintf(&userid, "%d", (int)gid) < 0)
+ if (virAsprintf(&groupid, "%d", (int)gid) < 0)
goto cleanup;
if (virAsprintf(&processid, "%llu",
(unsigned long long)pid) < 0)

View File

@ -0,0 +1,65 @@
commit e65667c0c6e016d42abea077e31628ae43f57b74
Author: Daniel P. Berrange <berrange@redhat.com>
Date: Wed Aug 28 15:22:05 2013 +0100
Ensure system identity includes process start time
The polkit access driver will want to use the process start
time field. This was already set for network identities, but
not for the system identity.
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Index: libvirt-1.1.2/src/util/viridentity.c
===================================================================
--- libvirt-1.1.2.orig/src/util/viridentity.c
+++ libvirt-1.1.2/src/util/viridentity.c
@@ -35,6 +35,7 @@
#include "virthread.h"
#include "virutil.h"
#include "virstring.h"
+#include "virprocess.h"
#define VIR_FROM_THIS VIR_FROM_IDENTITY
@@ -142,11 +143,20 @@ virIdentityPtr virIdentityGetSystem(void
security_context_t con;
#endif
char *processid = NULL;
+ unsigned long long timestamp;
+ char *processtime = NULL;
if (virAsprintf(&processid, "%llu",
(unsigned long long)getpid()) < 0)
goto cleanup;
+ if (virProcessGetStartTime(getpid(), &timestamp) < 0)
+ goto cleanup;
+
+ if (timestamp != 0 &&
+ virAsprintf(&processtime, "%llu", timestamp) < 0)
+ goto cleanup;
+
if (!(username = virGetUserName(getuid())))
goto cleanup;
if (virAsprintf(&userid, "%d", (int)getuid()) < 0)
@@ -198,6 +208,11 @@ virIdentityPtr virIdentityGetSystem(void
VIR_IDENTITY_ATTR_UNIX_PROCESS_ID,
processid) < 0)
goto error;
+ if (processtime &&
+ virIdentitySetAttr(ret,
+ VIR_IDENTITY_ATTR_UNIX_PROCESS_TIME,
+ processtime) < 0)
+ goto error;
cleanup:
VIR_FREE(username);
@@ -206,6 +221,7 @@ cleanup:
VIR_FREE(groupid);
VIR_FREE(seccontext);
VIR_FREE(processid);
+ VIR_FREE(processtime);
return ret;
error:

View File

@ -0,0 +1,35 @@
commit e7f400a110e2e3673b96518170bfea0855dd82c0
Author: Daniel P. Berrange <berrange@redhat.com>
Date: Tue Sep 3 16:52:06 2013 +0100
Fix crash in remoteDispatchDomainMemoryStats (CVE-2013-4296)
The 'stats' variable was not initialized to NULL, so if some
early validation of the RPC call fails, it is possible to jump
to the 'cleanup' label and VIR_FREE an uninitialized pointer.
This is a security flaw, since the API can be called from a
readonly connection which can trigger the validation checks.
This was introduced in release v0.9.1 onwards by
commit 158ba8730e44b7dd07a21ab90499996c5dec080a
Author: Daniel P. Berrange <berrange@redhat.com>
Date: Wed Apr 13 16:21:35 2011 +0100
Merge all returns paths from dispatcher into single path
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Index: libvirt-1.1.2/daemon/remote.c
===================================================================
--- libvirt-1.1.2.orig/daemon/remote.c
+++ libvirt-1.1.2/daemon/remote.c
@@ -1146,7 +1146,7 @@ remoteDispatchDomainMemoryStats(virNetSe
remote_domain_memory_stats_ret *ret)
{
virDomainPtr dom = NULL;
- struct _virDomainMemoryStat *stats;
+ struct _virDomainMemoryStat *stats = NULL;
int nr_stats;
size_t i;
int rv = -1;

View File

@ -10,7 +10,7 @@ Index: libvirt-1.1.2/configure.ac
LIBVIRT_CHECK_NUMACTL
LIBVIRT_CHECK_OPENWSMAN
LIBVIRT_CHECK_PCIACCESS
@@ -2288,11 +2289,12 @@ if test "$with_libvirtd" = "no" ; then
@@ -2296,11 +2297,12 @@ if test "$with_libvirtd" = "no" ; then
with_interface=no
fi
@ -26,7 +26,7 @@ Index: libvirt-1.1.2/configure.ac
esac
if test "$with_interface" = "yes" ; then
@@ -2600,6 +2602,7 @@ LIBVIRT_RESULT_DBUS
@@ -2608,6 +2610,7 @@ LIBVIRT_RESULT_DBUS
LIBVIRT_RESULT_FUSE
LIBVIRT_RESULT_HAL
LIBVIRT_RESULT_NETCF

View File

@ -1,3 +1,22 @@
-------------------------------------------------------------------
Tue Sep 17 16:29:20 MDT 2013 - jfehlig@suse.com
- CVE-2013-4311: Add support for using 3-arg pkcheck syntax for
process
db7a5688-CVE-2013-4311.patch, e65667c0-CVE-2013-4311.patch,
922b7fda-CVE-2013-4311.patch, e4697b92-CVE-2013-4311.patch
bnc#836931
-------------------------------------------------------------------
Thu Sep 5 15:28:28 MDT 2013 - jfehlig@suse.com
- CVE-2013-4296: Fix crash in remoteDispatchDomainMemoryStats
e7f400a1-CVE-2013-4296.patch
bnc#838638
- CVE-2013-4297: Fix crash in virFileNBDDeviceAssociate
2dba0323-CVE-2013-4297.patch
bnc#838642
-------------------------------------------------------------------
Tue Sep 3 11:04:45 MDT 2013 - jfehlig@suse.com

View File

@ -404,6 +404,12 @@ Source1: libvirtd.init
Source2: libvirtd-relocation-server.fw
Source99: baselibs.conf
# Upstream patches
Patch0: e7f400a1-CVE-2013-4296.patch
Patch1: 2dba0323-CVE-2013-4297.patch
Patch2: db7a5688-CVE-2013-4311.patch
Patch3: e65667c0-CVE-2013-4311.patch
Patch4: 922b7fda-CVE-2013-4311.patch
Patch5: e4697b92-CVE-2013-4311.patch
# Need to go upstream
Patch100: xen-name-for-devid.patch
Patch101: clone.patch
@ -902,6 +908,12 @@ of recent versions of Linux (and other OSes).
%prep
%setup -q
%patch0 -p1
%patch1 -p1
%patch2 -p1
%patch3 -p1
%patch4 -p1
%patch5 -p1
%patch100 -p1
%patch101
%patch102 -p1