43fe83
From 969db345161bd108c3d38eee0da68fbc66e79f08 Mon Sep 17 00:00:00 2001
43fe83
Message-Id: <969db345161bd108c3d38eee0da68fbc66e79f08.1383321464.git.jdenemar@redhat.com>
43fe83
From: "Daniel P. Berrange" <berrange@redhat.com>
43fe83
Date: Wed, 30 Oct 2013 17:01:44 +0000
43fe83
Subject: [PATCH] Don't link virt-login-shell against libvirt.so
43fe83
43fe83
CVE-2013-4400
43fe83
43fe83
The libvirt.so library has far too many library deps to allow
43fe83
linking against it from setuid programs. Those libraries can
43fe83
do stuff in __attribute__((constructor) functions which is
43fe83
not setuid safe.
43fe83
43fe83
The virt-login-shell needs to link directly against individual
43fe83
files that it uses, with all library deps turned off except
43fe83
for libxml2 and libselinux.
43fe83
43fe83
Create a libvirt-setuid-rpc-client.la library which is linked
43fe83
to by virt-login-shell. A config-post.h file allows this library
43fe83
to disable all external deps except libselinux and libxml2.
43fe83
43fe83
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
43fe83
(cherry picked from commit 3e2f27e13b94f7302ad948bcacb5e02c859a25fc)
43fe83
43fe83
Conflicts:
43fe83
	tools/Makefile.am: Due to missing d9527b6d565f0561c7920db65b841b0e13041827
43fe83
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
43fe83
---
43fe83
 Makefile.am                                 |  1 +
43fe83
 config-post.h                               | 44 ++++++++++++++++++
43fe83
 configure.ac                                |  1 +
43fe83
 daemon/Makefile.am                          |  1 +
43fe83
 examples/domain-events/events-c/Makefile.am |  3 +-
43fe83
 examples/hellolibvirt/Makefile.am           |  2 +-
43fe83
 examples/openauth/Makefile.am               |  2 +-
43fe83
 gnulib/lib/Makefile.am                      |  2 +-
43fe83
 python/Makefile.am                          |  1 +
43fe83
 src/Makefile.am                             | 72 +++++++++++++++++++++++++++++
43fe83
 src/libvirt.c                               | 36 +++++++++------
43fe83
 tools/Makefile.am                           |  9 +++-
43fe83
 12 files changed, 153 insertions(+), 21 deletions(-)
43fe83
 create mode 100644 config-post.h
43fe83
43fe83
diff --git a/Makefile.am b/Makefile.am
43fe83
index 4e24ecf..15bd5bf 100644
43fe83
--- a/Makefile.am
43fe83
+++ b/Makefile.am
43fe83
@@ -31,6 +31,7 @@ XML_EXAMPLES = \
43fe83
 					test/*.xml storage/*.xml)))
43fe83
 
43fe83
 EXTRA_DIST = \
43fe83
+  config-post.h \
43fe83
   ChangeLog-old \
43fe83
   libvirt.spec libvirt.spec.in \
43fe83
   mingw-libvirt.spec.in \
43fe83
diff --git a/config-post.h b/config-post.h
43fe83
new file mode 100644
43fe83
index 0000000..d371e8c
43fe83
--- /dev/null
43fe83
+++ b/config-post.h
43fe83
@@ -0,0 +1,44 @@
43fe83
+/*
43fe83
+ * Copyright (C) 2013 Red Hat, Inc.
43fe83
+ *
43fe83
+ * This library is free software; you can redistribute it and/or
43fe83
+ * modify it under the terms of the GNU Lesser General Public
43fe83
+ * License as published by the Free Software Foundation; either
43fe83
+ * version 2.1 of the License, or (at your option) any later version.
43fe83
+ *
43fe83
+ * This library is distributed in the hope that it will be useful,
43fe83
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
43fe83
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
43fe83
+ * Lesser General Public License for more details.
43fe83
+ *
43fe83
+ * You should have received a copy of the GNU Lesser General Public
43fe83
+ * License along with this library.  If not, see
43fe83
+ * <http://www.gnu.org/licenses/>.
43fe83
+ */
43fe83
+
43fe83
+/*
43fe83
+ * Since virt-login-shell will be setuid, we must do everything
43fe83
+ * we can to avoid linking to other libraries. Many of them do
43fe83
+ * unsafe things in functions marked __atttribute__((constructor)).
43fe83
+ * The only way avoid to avoid such deps is to re-compile the
43fe83
+ * functions with the code in question disabled, and for that we
43fe83
+ * must override the main config.h rules. Hence this file :-(
43fe83
+ */
43fe83
+
43fe83
+#ifdef LIBVIRT_SETUID_RPC_CLIENT
43fe83
+# undef HAVE_LIBDEVMAPPER_H
43fe83
+# undef HAVE_LIBNL
43fe83
+# undef HAVE_LIBNL3
43fe83
+# undef HAVE_LIBSASL2
43fe83
+# undef WITH_CAPNG
43fe83
+# undef WITH_CURL
43fe83
+# undef WITH_DTRACE_PROBES
43fe83
+# undef WITH_GNUTLS
43fe83
+# undef WITH_MACVTAP
43fe83
+# undef WITH_NUMACTL
43fe83
+# undef WITH_SASL
43fe83
+# undef WITH_SSH2
43fe83
+# undef WITH_VIRTUALPORT
43fe83
+# undef WITH_YAJL
43fe83
+# undef WITH_YAJL2
43fe83
+#endif
43fe83
diff --git a/configure.ac b/configure.ac
43fe83
index 7dd6ca3..cdb2969 100644
43fe83
--- a/configure.ac
43fe83
+++ b/configure.ac
43fe83
@@ -20,6 +20,7 @@ AC_INIT([libvirt], [1.1.1], [libvir-list@redhat.com], [], [http://libvirt.org])
43fe83
 AC_CONFIG_SRCDIR([src/libvirt.c])
43fe83
 AC_CONFIG_AUX_DIR([build-aux])
43fe83
 AC_CONFIG_HEADERS([config.h])
43fe83
+AH_BOTTOM([#include <config-post.h>])
43fe83
 AC_CONFIG_MACRO_DIR([m4])
43fe83
 dnl Make automake keep quiet about wildcards & other GNUmake-isms
43fe83
 AM_INIT_AUTOMAKE([-Wno-portability tar-ustar])
43fe83
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
43fe83
index ad7544c..7dbfcec 100644
43fe83
--- a/daemon/Makefile.am
43fe83
+++ b/daemon/Makefile.am
43fe83
@@ -18,6 +18,7 @@
43fe83
 
43fe83
 INCLUDES = \
43fe83
 	-I$(top_builddir)/gnulib/lib -I$(top_srcdir)/gnulib/lib \
43fe83
+	-I$(top_srcdir) \
43fe83
 	-I$(top_builddir)/include -I$(top_srcdir)/include \
43fe83
 	-I$(top_builddir)/src -I$(top_srcdir)/src \
43fe83
 	-I$(top_srcdir)/src/util \
43fe83
diff --git a/examples/domain-events/events-c/Makefile.am b/examples/domain-events/events-c/Makefile.am
43fe83
index 0646aee..86500a0 100644
43fe83
--- a/examples/domain-events/events-c/Makefile.am
43fe83
+++ b/examples/domain-events/events-c/Makefile.am
43fe83
@@ -15,7 +15,8 @@
43fe83
 ## <http://www.gnu.org/licenses/>.
43fe83
 
43fe83
 INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include \
43fe83
-	   -I$(top_builddir)/gnulib/lib -I$(top_srcdir)/gnulib/lib
43fe83
+	   -I$(top_builddir)/gnulib/lib -I$(top_srcdir)/gnulib/lib \
43fe83
+	   -I$(top_srcdir)
43fe83
 noinst_PROGRAMS = event-test
43fe83
 event_test_CFLAGS = $(WARN_CFLAGS)
43fe83
 event_test_SOURCES = event-test.c
43fe83
diff --git a/examples/hellolibvirt/Makefile.am b/examples/hellolibvirt/Makefile.am
43fe83
index 060cc71..55ea972 100644
43fe83
--- a/examples/hellolibvirt/Makefile.am
43fe83
+++ b/examples/hellolibvirt/Makefile.am
43fe83
@@ -14,7 +14,7 @@
43fe83
 ## License along with this library.  If not, see
43fe83
 ## <http://www.gnu.org/licenses/>.
43fe83
 
43fe83
-INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include
43fe83
+INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include -I$(top_srcdir)
43fe83
 noinst_PROGRAMS = hellolibvirt
43fe83
 hellolibvirt_CFLAGS = $(WARN_CFLAGS)
43fe83
 hellolibvirt_SOURCES = hellolibvirt.c
43fe83
diff --git a/examples/openauth/Makefile.am b/examples/openauth/Makefile.am
43fe83
index 1eb23fc..7bb8604 100644
43fe83
--- a/examples/openauth/Makefile.am
43fe83
+++ b/examples/openauth/Makefile.am
43fe83
@@ -14,7 +14,7 @@
43fe83
 ## License along with this library.  If not, see
43fe83
 ## <http://www.gnu.org/licenses/>.
43fe83
 
43fe83
-INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include
43fe83
+INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include -I$(top_srcdir)
43fe83
 noinst_PROGRAMS = openauth
43fe83
 openauth_CFLAGS = $(WARN_CFLAGS)
43fe83
 openauth_SOURCES = openauth.c
43fe83
diff --git a/gnulib/lib/Makefile.am b/gnulib/lib/Makefile.am
43fe83
index e27c658..f098e82 100644
43fe83
--- a/gnulib/lib/Makefile.am
43fe83
+++ b/gnulib/lib/Makefile.am
43fe83
@@ -27,4 +27,4 @@ noinst_LTLIBRARIES =
43fe83
 
43fe83
 include gnulib.mk
43fe83
 
43fe83
-INCLUDES = $(GETTEXT_CPPFLAGS)
43fe83
+INCLUDES = -I$(top_srcdir) $(GETTEXT_CPPFLAGS)
43fe83
diff --git a/python/Makefile.am b/python/Makefile.am
43fe83
index 925e1f4..5ef9f1c 100644
43fe83
--- a/python/Makefile.am
43fe83
+++ b/python/Makefile.am
43fe83
@@ -20,6 +20,7 @@ INCLUDES = \
43fe83
 	$(PYTHON_INCLUDES) \
43fe83
 	-I$(top_builddir)/gnulib/lib \
43fe83
 	-I$(top_srcdir)/gnulib/lib \
43fe83
+	-I$(top_srcdir) \
43fe83
 	-I$(top_builddir)/src \
43fe83
 	-I$(top_srcdir)/src \
43fe83
 	-I$(top_srcdir)/src/util \
43fe83
diff --git a/src/Makefile.am b/src/Makefile.am
43fe83
index 5976a68..969d09b 100644
43fe83
--- a/src/Makefile.am
43fe83
+++ b/src/Makefile.am
43fe83
@@ -21,6 +21,7 @@
43fe83
 # that actually use them. Also keep GETTEXT_CPPFLAGS at the end.
43fe83
 INCLUDES =	-I../gnulib/lib					\
43fe83
 		-I$(top_srcdir)/gnulib/lib			\
43fe83
+		-I$(top_srcdir)					\
43fe83
 		-I../include					\
43fe83
 		-I$(top_srcdir)/include				\
43fe83
 		-I$(top_srcdir)/src/util			\
43fe83
@@ -1914,6 +1915,77 @@ libvirt_lxc_la_LDFLAGS = \
43fe83
 libvirt_lxc_la_CFLAGS = $(AM_CFLAGS)
43fe83
 libvirt_lxc_la_LIBADD = libvirt.la $(CYGWIN_EXTRA_LIBADD)
43fe83
 
43fe83
+# Since virt-login-shell will be setuid, we must do everything
43fe83
+# we can to avoid linking to other libraries. Many of them do
43fe83
+# unsafe things in functions marked __atttribute__((constructor)).
43fe83
+# This library is built to include the bare minimum required to
43fe83
+# have a RPC client for local UNIX socket access only. We use
43fe83
+# the ../config-post.h header to disable all external deps that
43fe83
+# we don't want
43fe83
+if WITH_LXC
43fe83
+noinst_LTLIBRARIES += libvirt-setuid-rpc-client.la
43fe83
+
43fe83
+libvirt_setuid_rpc_client_la_SOURCES = 		\
43fe83
+		util/viralloc.c			\
43fe83
+		util/virbitmap.c		\
43fe83
+		util/virbuffer.c		\
43fe83
+		util/vircommand.c		\
43fe83
+		util/virconf.c			\
43fe83
+		util/virerror.c			\
43fe83
+		util/virevent.c			\
43fe83
+		util/vireventpoll.c		\
43fe83
+		util/virfile.c			\
43fe83
+		util/virhash.c			\
43fe83
+		util/virhashcode.c		\
43fe83
+		util/virjson.c			\
43fe83
+		util/virlog.c			\
43fe83
+		util/virobject.c		\
43fe83
+		util/virpidfile.c		\
43fe83
+		util/virprocess.c		\
43fe83
+		util/virrandom.c		\
43fe83
+		util/virsocketaddr.c		\
43fe83
+		util/virstoragefile.c		\
43fe83
+		util/virstring.c		\
43fe83
+		util/virtime.c			\
43fe83
+		util/virthread.c		\
43fe83
+		util/virtypedparam.c		\
43fe83
+		util/viruri.c			\
43fe83
+		util/virutil.c			\
43fe83
+		util/viruuid.c			\
43fe83
+		conf/domain_event.c		\
43fe83
+		rpc/virnetsocket.c		\
43fe83
+		rpc/virnetsocket.h		\
43fe83
+		rpc/virnetmessage.h		\
43fe83
+		rpc/virnetmessage.c		\
43fe83
+		rpc/virkeepalive.c		\
43fe83
+		rpc/virkeepalive.h		\
43fe83
+		rpc/virnetclient.c		\
43fe83
+		rpc/virnetclientprogram.c	\
43fe83
+		rpc/virnetclientstream.c	\
43fe83
+		rpc/virnetprotocol.c		\
43fe83
+		remote/remote_driver.c		\
43fe83
+		remote/remote_protocol.c	\
43fe83
+		remote/qemu_protocol.c		\
43fe83
+		remote/lxc_protocol.c		\
43fe83
+		datatypes.c			\
43fe83
+		libvirt.c			\
43fe83
+		libvirt-lxc.c			\
43fe83
+		$(NULL)
43fe83
+
43fe83
+libvirt_setuid_rpc_client_la_LDFLAGS =		\
43fe83
+		$(AM_LDFLAGS)			\
43fe83
+		$(LIBXML_LIBS)			\
43fe83
+		$(SELINUX_LIBS)			\
43fe83
+		$(NULL)
43fe83
+libvirt_setuid_rpc_client_la_CFLAGS =		\
43fe83
+		-DLIBVIRT_SETUID_RPC_CLIENT	\
43fe83
+		-I$(top_srcdir)/src/conf	\
43fe83
+		-I$(top_srcdir)/src/rpc		\
43fe83
+		$(AM_CFLAGS)			\
43fe83
+		$(SELINUX_CFLAGS)		\
43fe83
+		$(NULL)
43fe83
+endif WITH_LXC
43fe83
+
43fe83
 lockdriverdir = $(libdir)/libvirt/lock-driver
43fe83
 lockdriver_LTLIBRARIES =
43fe83
 
43fe83
diff --git a/src/libvirt.c b/src/libvirt.c
43fe83
index 1a6c771..4c1992c 100644
43fe83
--- a/src/libvirt.c
43fe83
+++ b/src/libvirt.c
43fe83
@@ -446,40 +446,46 @@ virGlobalInit(void)
43fe83
         goto error;
43fe83
 
43fe83
     /*
43fe83
+     * Note we must avoid everything except 'remote' driver
43fe83
+     * for virt-login-shell usage
43fe83
+     */
43fe83
+#ifndef LIBVIRT_SETUID_RPC_CLIENT
43fe83
+    /*
43fe83
      * Note that the order is important: the first ones have a higher
43fe83
      * priority when calling virConnectOpen.
43fe83
      */
43fe83
-#ifdef WITH_TEST
43fe83
+# ifdef WITH_TEST
43fe83
     if (testRegister() == -1)
43fe83
         goto error;
43fe83
-#endif
43fe83
-#ifdef WITH_OPENVZ
43fe83
+# endif
43fe83
+# ifdef WITH_OPENVZ
43fe83
     if (openvzRegister() == -1)
43fe83
         goto error;
43fe83
-#endif
43fe83
-#ifdef WITH_VMWARE
43fe83
+# endif
43fe83
+# ifdef WITH_VMWARE
43fe83
     if (vmwareRegister() == -1)
43fe83
         goto error;
43fe83
-#endif
43fe83
-#ifdef WITH_PHYP
43fe83
+# endif
43fe83
+# ifdef WITH_PHYP
43fe83
     if (phypRegister() == -1)
43fe83
         goto error;
43fe83
-#endif
43fe83
-#ifdef WITH_ESX
43fe83
+# endif
43fe83
+# ifdef WITH_ESX
43fe83
     if (esxRegister() == -1)
43fe83
         goto error;
43fe83
-#endif
43fe83
-#ifdef WITH_HYPERV
43fe83
+# endif
43fe83
+# ifdef WITH_HYPERV
43fe83
     if (hypervRegister() == -1)
43fe83
         goto error;
43fe83
-#endif
43fe83
-#ifdef WITH_XENAPI
43fe83
+# endif
43fe83
+# ifdef WITH_XENAPI
43fe83
     if (xenapiRegister() == -1)
43fe83
         goto error;
43fe83
-#endif
43fe83
-#ifdef WITH_PARALLELS
43fe83
+# endif
43fe83
+# ifdef WITH_PARALLELS
43fe83
     if (parallelsRegister() == -1)
43fe83
         goto error;
43fe83
+# endif
43fe83
 #endif
43fe83
 #ifdef WITH_REMOTE
43fe83
     if (remoteRegister() == -1)
43fe83
diff --git a/tools/Makefile.am b/tools/Makefile.am
43fe83
index d48883c..9ae4004 100644
43fe83
--- a/tools/Makefile.am
43fe83
+++ b/tools/Makefile.am
43fe83
@@ -133,6 +133,11 @@ virt_host_validate_CFLAGS = \
43fe83
 		$(COVERAGE_CFLAGS)				\
43fe83
 		$(NULL)
43fe83
 
43fe83
+# Since virt-login-shell will be setuid, we must do everything
43fe83
+# we can to avoid linking to other libraries. Many of them do
43fe83
+# unsafe things in functions marked __atttribute__((constructor)).
43fe83
+# This we statically link to a library containing only the minimal
43fe83
+# libvirt client code, not libvirt.so itself.
43fe83
 virt_login_shell_SOURCES =					\
43fe83
 		virt-login-shell.c
43fe83
 
43fe83
@@ -141,11 +146,11 @@ virt_login_shell_LDADD =					\
43fe83
 		$(STATIC_BINARIES)				\
43fe83
 		$(PIE_LDFLAGS)					\
43fe83
 		$(RELRO_LDFLAGS) \
43fe83
-		../src/libvirt.la				\
43fe83
-		../src/libvirt-lxc.la				\
43fe83
+		../src/libvirt-setuid-rpc-client.la		\
43fe83
 		../gnulib/lib/libgnu.la
43fe83
 
43fe83
 virt_login_shell_CFLAGS =					\
43fe83
+		-DLIBVIRT_SETUID_RPC_CLIENT			\
43fe83
 		$(WARN_CFLAGS)					\
43fe83
 		$(PIE_CFLAGS)					\
43fe83
 		$(COVERAGE_CFLAGS)
43fe83
-- 
43fe83
1.8.4.2
43fe83