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