diff --git a/.gitignore b/.gitignore index f36ddd284d..95f40f19c8 100644 --- a/.gitignore +++ b/.gitignore @@ -73,6 +73,7 @@ stubdom/libxencall-* stubdom/libxenevtchn-* stubdom/libxenforeignmemory-* stubdom/libxengnttab-* +stubdom/libxentoolcore-* stubdom/libxentoollog-* stubdom/lwip-* stubdom/lwip/ @@ -98,6 +99,8 @@ tools/config.cache config/Tools.mk config/Stubdom.mk config/Docs.mk +tools/libs/toolcore/headers.chk +tools/libs/toolcore/xentoolcore.pc tools/libs/toollog/headers.chk tools/libs/toollog/xentoollog.pc tools/libs/evtchn/headers.chk @@ -352,6 +355,7 @@ tools/include/xen-foreign/arm64.h .git tools/misc/xen-hptool tools/misc/xen-mfndump +tools/libs/toolcore/include/_*.h tools/libxc/_*.[ch] tools/libxl/_*.[ch] tools/libxl/testidl diff --git a/tools/Rules.mk b/tools/Rules.mk index dbc7635112..5e1c7cb9e9 100644 --- a/tools/Rules.mk +++ b/tools/Rules.mk @@ -10,6 +10,7 @@ export _INSTALL := $(INSTALL) INSTALL = $(XEN_ROOT)/tools/cross-install XEN_INCLUDE = $(XEN_ROOT)/tools/include +XEN_LIBXENTOOLCORE = $(XEN_ROOT)/tools/libs/toolcore XEN_LIBXENTOOLLOG = $(XEN_ROOT)/tools/libs/toollog XEN_LIBXENEVTCHN = $(XEN_ROOT)/tools/libs/evtchn XEN_LIBXENGNTTAB = $(XEN_ROOT)/tools/libs/gnttab @@ -102,6 +103,11 @@ SHDEPS_libxentoollog = LDLIBS_libxentoollog = $(SHDEPS_libxentoollog) $(XEN_LIBXENTOOLLOG)/libxentoollog$(libextension) SHLIB_libxentoollog = $(SHDEPS_libxentoollog) -Wl,-rpath-link=$(XEN_LIBXENTOOLLOG) +CFLAGS_libxentoolcore = -I$(XEN_LIBXENTOOLCORE)/include $(CFLAGS_xeninclude) +SHDEPS_libxentoolcore = +LDLIBS_libxentoolcore = $(SHDEPS_libxentoolcore) $(XEN_LIBXENTOOLCORE)/libxentoolcore$(libextension) +SHLIB_libxentoolcore = $(SHDEPS_libxentoolcore) -Wl,-rpath-link=$(XEN_LIBXENTOOLCORE) + CFLAGS_libxenevtchn = -I$(XEN_LIBXENEVTCHN)/include $(CFLAGS_xeninclude) SHDEPS_libxenevtchn = LDLIBS_libxenevtchn = $(SHDEPS_libxenevtchn) $(XEN_LIBXENEVTCHN)/libxenevtchn$(libextension) diff --git a/tools/libs/Makefile b/tools/libs/Makefile index 2035873fff..ea9a64d557 100644 --- a/tools/libs/Makefile +++ b/tools/libs/Makefile @@ -2,6 +2,7 @@ XEN_ROOT = $(CURDIR)/../.. include $(XEN_ROOT)/tools/Rules.mk SUBDIRS-y := +SUBDIRS-y += toolcore SUBDIRS-y += toollog SUBDIRS-y += evtchn SUBDIRS-y += gnttab diff --git a/tools/libs/toolcore/Makefile b/tools/libs/toolcore/Makefile new file mode 100644 index 0000000000..73db0bdef1 --- /dev/null +++ b/tools/libs/toolcore/Makefile @@ -0,0 +1,101 @@ +XEN_ROOT = $(CURDIR)/../../.. +include $(XEN_ROOT)/tools/Rules.mk + +MAJOR = 1 +MINOR = 0 +SHLIB_LDFLAGS += -Wl,--version-script=libxentoolcore.map + +CFLAGS += -Werror -Wmissing-prototypes +CFLAGS += -I./include + +SRCS-y += handlereg.c + +LIB_OBJS := $(patsubst %.c,%.o,$(SRCS-y)) +PIC_OBJS := $(patsubst %.c,%.opic,$(SRCS-y)) + +LIB := libxentoolcore.a +ifneq ($(nosharedlibs),y) +LIB += libxentoolcore.so +endif + +PKG_CONFIG := xentoolcore.pc +PKG_CONFIG_VERSION := $(MAJOR).$(MINOR) + +ifneq ($(CONFIG_LIBXC_MINIOS),y) +PKG_CONFIG_INST := $(PKG_CONFIG) +$(PKG_CONFIG_INST): PKG_CONFIG_PREFIX = $(prefix) +$(PKG_CONFIG_INST): PKG_CONFIG_INCDIR = $(includedir) +$(PKG_CONFIG_INST): PKG_CONFIG_LIBDIR = $(libdir) +endif + +PKG_CONFIG_LOCAL := $(foreach pc,$(PKG_CONFIG),$(PKG_CONFIG_DIR)/$(pc)) + +$(PKG_CONFIG_LOCAL): PKG_CONFIG_PREFIX = $(XEN_ROOT) +$(PKG_CONFIG_LOCAL): PKG_CONFIG_INCDIR = $(XEN_LIBXENTOOLCORE)/include +$(PKG_CONFIG_LOCAL): PKG_CONFIG_LIBDIR = $(CURDIR) + +AUTOINCS=include/_xentoolcore_list.h + +.PHONY: all +all: build + +.PHONY: build +build: + $(MAKE) libs + +.PHONY: libs +libs: headers.chk $(LIB) $(PKG_CONFIG_INST) $(PKG_CONFIG_LOCAL) + +$(LIB_OBJS): $(AUTOINCS) +$(PIC_OBJS): $(AUTOINCS) + +headers.chk: $(wildcard include/*.h) $(AUTOINCS) + +include/_xentoolcore_list.h: $(XEN_INCLUDE)/xen-external/bsd-sys-queue-h-seddery $(XEN_INCLUDE)/xen-external/bsd-sys-queue.h + $(PERL) $^ --prefix=xentoolcore >$@.new + $(call move-if-changed,$@.new,$@) + +libxentoolcore.a: $(LIB_OBJS) + $(AR) rc $@ $^ + +libxentoolcore.so: libxentoolcore.so.$(MAJOR) + $(SYMLINK_SHLIB) $< $@ +libxentoolcore.so.$(MAJOR): libxentoolcore.so.$(MAJOR).$(MINOR) + $(SYMLINK_SHLIB) $< $@ + +libxentoolcore.so.$(MAJOR).$(MINOR): $(PIC_OBJS) libxentoolcore.map + $(CC) $(LDFLAGS) -Wl,$(SONAME_LDFLAG) -Wl,libxentoolcore.so.$(MAJOR) $(SHLIB_LDFLAGS) -o $@ $(PIC_OBJS) $(APPEND_LDFLAGS) + +.PHONY: install +install: build + $(INSTALL_DIR) $(DESTDIR)$(libdir) + $(INSTALL_DIR) $(DESTDIR)$(includedir) + $(INSTALL_SHLIB) libxentoolcore.so.$(MAJOR).$(MINOR) $(DESTDIR)$(libdir) + $(INSTALL_DATA) libxentoolcore.a $(DESTDIR)$(libdir) + $(SYMLINK_SHLIB) libxentoolcore.so.$(MAJOR).$(MINOR) $(DESTDIR)$(libdir)/libxentoolcore.so.$(MAJOR) + $(SYMLINK_SHLIB) libxentoolcore.so.$(MAJOR) $(DESTDIR)$(libdir)/libxentoolcore.so + $(INSTALL_DATA) include/xentoolcore.h $(DESTDIR)$(includedir) + $(INSTALL_DATA) xentoolcore.pc $(DESTDIR)$(PKG_INSTALLDIR) + +.PHONY: uinstall +uninstall: + rm -f $(DESTDIR)$(PKG_INSTALLDIR)/xentoolcore.pc + rm -f $(DESTDIR)$(includedir)/xentoolcore.h + rm -f $(DESTDIR)$(libdir)/libxentoolcore.so + rm -f $(DESTDIR)$(libdir)/libxentoolcore.so.$(MAJOR) + rm -f $(DESTDIR)$(libdir)/libxentoolcore.so.$(MAJOR).$(MINOR) + rm -f $(DESTDIR)$(libdir)/libxentoolcore.a + +.PHONY: TAGS +TAGS: + etags -t *.c *.h + +.PHONY: clean +clean: + rm -rf *.rpm $(LIB) *~ $(DEPS_RM) $(LIB_OBJS) $(PIC_OBJS) + rm -f libxentoolcore.so.$(MAJOR).$(MINOR) libxentoolcore.so.$(MAJOR) + rm -f headers.chk + rm -f xentoolcore.pc + +.PHONY: distclean +distclean: clean diff --git a/tools/libs/toolcore/handlereg.c b/tools/libs/toolcore/handlereg.c new file mode 100644 index 0000000000..5a854b2255 --- /dev/null +++ b/tools/libs/toolcore/handlereg.c @@ -0,0 +1,77 @@ +/* + * handlreg.c + * + * implementation of xentoolcore_restrict_all + * + * Copyright (c) 2017 Citrix + * Part of a generic logging interface used by various dom0 userland libraries. + * + * 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; + * version 2.1 of the License. + * + * 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 . + */ + +#include "xentoolcore_internal.h" + +#include +#include + +static pthread_mutex_t handles_lock = PTHREAD_MUTEX_INITIALIZER; +static XENTOOLCORE_LIST_HEAD(, Xentoolcore__Active_Handle) handles; + +static void lock(void) { + int e = pthread_mutex_lock(&handles_lock); + assert(!e); +} + +static void unlock(void) { + int e = pthread_mutex_unlock(&handles_lock); + assert(!e); +} + +void xentoolcore__register_active_handle(Xentoolcore__Active_Handle *ah) { + lock(); + XENTOOLCORE_LIST_INSERT_HEAD(&handles, ah, entry); + unlock(); +} + +void xentoolcore__deregister_active_handle(Xentoolcore__Active_Handle *ah) { + lock(); + XENTOOLCORE_LIST_REMOVE(ah, entry); + unlock(); +} + +int xentoolcore_restrict_all(uint32_t domid) { + int r; + Xentoolcore__Active_Handle *ah; + + lock(); + XENTOOLCORE_LIST_FOREACH(ah, &handles, entry) { + r = ah->restrict_callback(ah, domid); + if (r) goto out; + } + + r = 0; + out: + unlock(); + return r; +} + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/tools/libs/toolcore/include/xentoolcore.h b/tools/libs/toolcore/include/xentoolcore.h new file mode 100644 index 0000000000..32e2af1c00 --- /dev/null +++ b/tools/libs/toolcore/include/xentoolcore.h @@ -0,0 +1,73 @@ +/* + * xentoolcore.h + * + * Copyright (c) 2017 Citrix + * + * Common features used/provided by all Xen tools libraries + * + * 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; + * version 2.1 of the License. + * + * 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 . + */ + +#ifndef XENTOOLCORE_H +#define XENTOOLCORE_H + +#include + +/* + * int xentoolcore_restrict_all(uint32_t domid); + * + * Arranges that Xen library handles (fds etc.) which are currently held + * by Xen libraries, can no longer be used other than to affect domid. + * + * If this cannot be achieved, returns -1 and sets errno. + * If called again with the same domid, it may succeed, or it may + * fail (even though such a call is potentially meaningful). + * (If called again with a different domid, it will necessarily fail.) + * + * ==================================================================== + * IMPORTANT - IMPLEMENTATION STATUS + * + * This function will be implemented insofar as it appears necessary + * for the purposes of running a deprivileged qemu. + * + * However, this function is NOT implemented for all Xen libraries. + * For each use case of this function, the designer must evaluate and + * audit whether the implementation is sufficient in their specific + * context. + * + * Of course, patches to extend the implementation are very welcome. + * ==================================================================== + * + * Thread safe. + * + * We expect that no callers do the following: + * - in one thread call xen_somelibrary_open|close + * - in another thread call fork + * - in the child of the fork, before exec, call + * xen_some[other]library_open|close or xentoolcore_restrict_all + * + */ +int xentoolcore_restrict_all(uint32_t domid); + +#endif /* XENTOOLCORE_H */ + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/tools/libs/toolcore/include/xentoolcore_internal.h b/tools/libs/toolcore/include/xentoolcore_internal.h new file mode 100644 index 0000000000..670e29dd29 --- /dev/null +++ b/tools/libs/toolcore/include/xentoolcore_internal.h @@ -0,0 +1,102 @@ +/* + * xentoolcore_internal.h + * + * Interfaces of xentoolcore directed internally at other Xen libraries + * + * Copyright (c) 2017 Citrix + * + * Common code used by all Xen tools libraries + * + * 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; + * version 2.1 of the License. + * + * 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 . + */ + +#ifndef XENTOOLCORE_INTERNAL_H +#define XENTOOLCORE_INTERNAL_H + +#include "xentoolcore.h" +#include "_xentoolcore_list.h" + +/*---------- active handle registration ----------*/ + +/* + * This is all to support xentoolcore_restrict_all + * + * Any libxl library that opens a Xen control handle of any kind which + * might allow manipulation of dom0, of other domains, or of the whole + * machine, must: + * I. arrange that their own datastructure contains a + * Xentoolcore__Active_Handle + * + * II. during the "open handle" function + * 1. allocate the memory for the own datastructure and initialise it + * 2. set Xentoolcore__Active_Handle.restrict_callback + * 3. call xentoolcore__register_active_handle + * 3a. if the open fails, call xentoolcore__deregister_active_handle + * 4. ONLY THEN actually open the relevant fd or whatever + * + * III. during the "close handle" function + * 1. FIRST close the relevant fd or whatever + * 2. call xentoolcore__deregister_active_handle + * + * IV. in the restrict_callback function + * * Arrange that the fd (or other handle) can no longer by used + * other than with respect to domain domid. + * * Future attempts to manipulate other domains (or the whole + * host) via this handle must cause an error return (and + * perhaps a log message), not a crash + * * If selective restriction is not possible, the handle must + * be completely invalidated so that it is not useable; + * subsequent manipulations may not crash + * * The restrict_callback function should not normally fail + * if this can be easily avoided - it is better to make the + * handle nonfunction instead. + * * NB that restrict_callback might be called again. That must + * work properly: if the domid is the same, it is idempotent. + * If the domid is different. then either the handle must be + * completely invalidated, or restrict_callback must fail.) + * + * Thread safety: + * xentoolcore__[de]register_active_handle are threadsafe + * but MUST NOT be called within restrict_callback + * + * Fork safety: + * Libraries which use these functions do not on that account + * need to take any special care over forks occurring in + * other threads, provided that they obey the rules above. + */ + +typedef struct Xentoolcore__Active_Handle Xentoolcore__Active_Handle; + +typedef int Xentoolcore__Restrict_Callback(Xentoolcore__Active_Handle*, + uint32_t domid); + +struct Xentoolcore__Active_Handle { + Xentoolcore__Restrict_Callback *restrict_callback; + XENTOOLCORE_LIST_ENTRY(Xentoolcore__Active_Handle) entry; +}; + +void xentoolcore__register_active_handle(Xentoolcore__Active_Handle*); +void xentoolcore__deregister_active_handle(Xentoolcore__Active_Handle*); + +#endif /* XENTOOLCORE_INTERNAL_H */ + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/tools/libs/toolcore/libxentoolcore.map b/tools/libs/toolcore/libxentoolcore.map new file mode 100644 index 0000000000..eb5d2519d6 --- /dev/null +++ b/tools/libs/toolcore/libxentoolcore.map @@ -0,0 +1,7 @@ +VERS_1.0 { + global: + xentoolcore_restrict_all; + xentoolcore__register_active_handle; + xentoolcore__deregister_active_handle; + local: *; /* Do not expose anything by default */ +}; diff --git a/tools/libs/toolcore/xentoolcore.pc.in b/tools/libs/toolcore/xentoolcore.pc.in new file mode 100644 index 0000000000..55ff4e25e4 --- /dev/null +++ b/tools/libs/toolcore/xentoolcore.pc.in @@ -0,0 +1,9 @@ +prefix=@@prefix@@ +includedir=@@incdir@@ +libdir=@@libdir@@ + +Name: Xentoolcore +Description: Central support for Xen Hypervisor userland libraries +Version: @@version@@ +Cflags: -I${includedir} +Libs: @@libsflag@@${libdir} -lxentoolcore