diff --git a/0001-virt-aa-helper-handle-more-disk-images.patch b/0001-virt-aa-helper-handle-more-disk-images.patch new file mode 100644 index 0000000..66d88fe --- /dev/null +++ b/0001-virt-aa-helper-handle-more-disk-images.patch @@ -0,0 +1,100 @@ +From 4fafa4c0b150c011ae905dfebcb7b42d20d8390b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?C=C3=A9dric=20Bosdonnat?= +Date: Mon, 11 Dec 2017 11:09:31 +0100 +Subject: [PATCH] virt-aa-helper: handle more disk images + +virt-aa-helper needs read access to the disk image to resolve symlinks +and add the proper rules to the profile. Its profile whitelists a few +common paths, but users can place their images anywhere. + +This commit helps users allowing access to their images by adding their +own rules in apparmor.d/local/usr.lib.libvirt.virt-aa-helper. + +This commit also adds rules to allow reading files named: + - *.raw as this is a rather common disk image extension + - /run/libvirt/**[vd]d[a-z] as these are used by virt-sandbox +--- + examples/Makefile.am | 23 +++++++++++++++++++++-- + examples/apparmor/usr.lib.libvirt.virt-aa-helper | 4 ++++ + 2 files changed, 25 insertions(+), 2 deletions(-) + +diff --git a/examples/Makefile.am b/examples/Makefile.am +index ef2f79db3..eca3506b0 100644 +--- a/examples/Makefile.am ++++ b/examples/Makefile.am +@@ -67,6 +67,9 @@ admin_client_info_SOURCES = admin/client_info.c + admin_client_close_SOURCES = admin/client_close.c + admin_logging_SOURCES = admin/logging.c + ++INSTALL_DATA_LOCAL = ++UNINSTALL_LOCAL = ++ + if WITH_APPARMOR_PROFILES + apparmordir = $(sysconfdir)/apparmor.d/ + apparmor_DATA = \ +@@ -85,20 +88,36 @@ templates_DATA = \ + apparmor/TEMPLATE.qemu \ + apparmor/TEMPLATE.lxc \ + $(NULL) ++ ++APPARMOR_LOCAL_DIR = "$(DESTDIR)$(apparmordir)/local" ++install-apparmor-local: ++ $(MKDIR_P) "$(APPARMOR_LOCAL_DIR)" ++ echo "# Site-specific additions and overrides for 'usr.lib.libvirt.virt-aa-helper'" \ ++ >$(APPARMOR_LOCAL_DIR)/usr.lib.libvirt.virt-aa-helper ++ ++INSTALL_DATA_LOCAL += install-apparmor-local ++UNINSTALL_LOCAL += uninstall-apparmor-local + endif WITH_APPARMOR_PROFILES + + if WITH_NWFILTER + NWFILTER_DIR = "$(DESTDIR)$(sysconfdir)/libvirt/nwfilter" + +-install-data-local: ++install-nwfilter-local: + $(MKDIR_P) "$(NWFILTER_DIR)" + for f in $(FILTERS); do \ + $(INSTALL_DATA) $$f "$(NWFILTER_DIR)"; \ + done + +-uninstall-local:: ++uninstall-nwfilter-local:: + for f in $(FILTERS); do \ + rm -f "$(NWFILTER_DIR)/`basename $$f`"; \ + done + -test -z "$(shell ls $(NWFILTER_DIR))" || rmdir $(NWFILTER_DIR) ++ ++INSTALL_DATA_LOCAL += install-nwfilter-local ++UNINSTALL_LOCAL += uninstall-nwfilter-local + endif WITH_NWFILTER ++ ++install-data-local: $(INSTALL_DATA_LOCAL) ++ ++uninstall-local: $(UNINSTALL_LOCAL) +diff --git a/examples/apparmor/usr.lib.libvirt.virt-aa-helper b/examples/apparmor/usr.lib.libvirt.virt-aa-helper +index bd6181d00..f3069d369 100644 +--- a/examples/apparmor/usr.lib.libvirt.virt-aa-helper ++++ b/examples/apparmor/usr.lib.libvirt.virt-aa-helper +@@ -3,6 +3,7 @@ + + profile virt-aa-helper /usr/{lib,lib64}/libvirt/virt-aa-helper { + #include ++ #include + + # needed for searching directories + capability dac_override, +@@ -50,8 +51,11 @@ profile virt-aa-helper /usr/{lib,lib64}/libvirt/virt-aa-helper { + /var/lib/libvirt/images/ r, + /var/lib/libvirt/images/** r, + /{media,mnt,opt,srv}/** r, ++ # For virt-sandbox ++ /run/libvirt/**/[sv]d[a-z] r + + /**.img r, ++ /**.raw r, + /**.qcow{,2} r, + /**.qed r, + /**.vmdk r, +-- +2.15.1 + diff --git a/daemon-close-crasher.patch b/daemon-close-crasher.patch new file mode 100644 index 0000000..1e41658 --- /dev/null +++ b/daemon-close-crasher.patch @@ -0,0 +1,22 @@ +Index: libvirt-3.10.0/src/rpc/virnetserver.c +=================================================================== +--- libvirt-3.10.0.orig/src/rpc/virnetserver.c ++++ libvirt-3.10.0/src/rpc/virnetserver.c +@@ -775,7 +775,6 @@ void virNetServerDispose(void *obj) + VIR_FREE(srv->programs); + + for (i = 0; i < srv->nclients; i++) { +- virNetServerClientClose(srv->clients[i]); + virObjectUnref(srv->clients[i]); + } + VIR_FREE(srv->clients); +@@ -796,6 +795,9 @@ void virNetServerClose(virNetServerPtr s + for (i = 0; i < srv->nservices; i++) + virNetServerServiceClose(srv->services[i]); + ++ for (i = 0; i < srv->nclients; i++) ++ virNetServerClientClose(srv->clients[i]); ++ + virObjectUnlock(srv); + } + diff --git a/libvirt.changes b/libvirt.changes index 4150f9c..51c9079 100644 --- a/libvirt.changes +++ b/libvirt.changes @@ -1,3 +1,12 @@ +------------------------------------------------------------------- +Wed Dec 20 16:58:50 UTC 2017 - cbosdonnat@suse.com + +- Close clients before drivers are cleaned up to avoid crash at + libvirtd stop (bsc#1073730) + daemon-close-crasher.patch +- Set a hostname on lxc containers based on guest's name. + lxc-hostname.patch + ------------------------------------------------------------------- Mon Dec 18 17:08:28 UTC 2017 - jfehlig@suse.com diff --git a/libvirt.spec b/libvirt.spec index 586a7a4..00ddc4e 100644 --- a/libvirt.spec +++ b/libvirt.spec @@ -321,6 +321,9 @@ Patch152: libvirt-power8-models.patch Patch153: ppc64le-canonical-name.patch Patch154: libxl-set-migration-constraints.patch Patch155: libxl-set-cach-mode.patch +Patch156: 0001-virt-aa-helper-handle-more-disk-images.patch +Patch157: lxc-hostname.patch +Patch158: daemon-close-crasher.patch # Our patches Patch200: suse-libvirtd-disable-tls.patch Patch201: suse-libvirtd-sysconfig-settings.patch @@ -897,6 +900,9 @@ libvirt plugin for NSS for translating domain names into IP addresses. %patch153 -p1 %patch154 -p1 %patch155 -p1 +%patch156 -p1 +%patch157 -p1 +%patch158 -p1 %patch200 -p1 %patch201 -p1 %patch202 -p1 @@ -1389,12 +1395,14 @@ fi %dir %{_sysconfdir}/apparmor.d %dir %{_sysconfdir}/apparmor.d/abstractions %dir %{_sysconfdir}/apparmor.d/libvirt +%dir %{_sysconfdir}/apparmor.d/local %config(noreplace) %{_sysconfdir}/apparmor.d/usr.sbin.libvirtd %config(noreplace) %{_sysconfdir}/apparmor.d/usr.lib.libvirt.virt-aa-helper %config(noreplace) %{_sysconfdir}/apparmor.d/abstractions/libvirt-qemu %config(noreplace) %{_sysconfdir}/apparmor.d/abstractions/libvirt-lxc %config(noreplace) %{_sysconfdir}/apparmor.d/libvirt/TEMPLATE.lxc %config(noreplace) %{_sysconfdir}/apparmor.d/libvirt/TEMPLATE.qemu +%config(noreplace) %{_sysconfdir}/apparmor.d/local/usr.lib.libvirt.virt-aa-helper %{_libdir}/%{name}/virt-aa-helper %endif %config %{_fwdefdir}/libvirtd-relocation-server diff --git a/lxc-hostname.patch b/lxc-hostname.patch new file mode 100644 index 0000000..d5f56a5 --- /dev/null +++ b/lxc-hostname.patch @@ -0,0 +1,176 @@ +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index de4ec4d44..43971db67 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -2751,6 +2751,7 @@ virStrcpy; + virStrdup; + virStringBufferIsPrintable; + virStringEncodeBase64; ++virStringFilterChars; + virStringHasChars; + virStringHasControlChars; + virStringIsEmpty; +diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c +index b7216d6ee..246145fcd 100644 +--- a/src/lxc/lxc_container.c ++++ b/src/lxc/lxc_container.c +@@ -2159,6 +2159,37 @@ static int lxcContainerSetUserGroup(virCommandPtr cmd, + return 0; + } + ++static const char hostname_validchars[] = ++ "abcdefghijklmnopqrstuvwxyz" ++ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" ++ "0123456789-"; ++ ++static int lxcContainerSetHostname(virDomainDefPtr def) ++{ ++ int ret = -1; ++ char *name = NULL; ++ char *hostname = NULL; ++ ++ /* Filter the VM name to get a valid hostname */ ++ if (VIR_STRDUP(name, def->name) < 0) ++ goto cleanup; ++ ++ /* RFC 1123 allows 0-9 digits as a first character in hostname */ ++ virStringFilterChars(name, hostname_validchars); ++ hostname = name; ++ if (strlen(name) > 0 && name[0] == '-') ++ hostname = name + 1; ++ ++ if (sethostname(hostname, strlen(hostname)) < 0) { ++ virReportSystemError(errno, "%s", _("Failed to set hostname")); ++ goto cleanup; ++ } ++ ret = 0; ++ ++ cleanup: ++ VIR_FREE(name); ++ return ret; ++} + + /** + * lxcContainerChild: +@@ -2269,6 +2300,10 @@ static int lxcContainerChild(void *data) + goto cleanup; + } + ++ if (lxcContainerSetHostname(vmDef) < 0) ++ goto cleanup; ++ ++ + /* drop a set of root capabilities */ + if (lxcContainerDropCapabilities(vmDef, !!hasReboot) < 0) + goto cleanup; +diff --git a/src/util/virstring.c b/src/util/virstring.c +index b2ebce27f..b808aff2c 100644 +--- a/src/util/virstring.c ++++ b/src/util/virstring.c +@@ -1293,6 +1293,30 @@ virStringStripControlChars(char *str) + str[j] = '\0'; + } + ++/** ++ * virStringFilterChars: ++ * @str: the string to strip ++ * @valid: the valid characters for the string ++ * ++ * Modify the string in-place to remove the characters that aren't ++ * in the list of valid ones. ++ */ ++void ++virStringFilterChars(char *str, const char *valid) ++{ ++ size_t len, i, j; ++ ++ if (!str) ++ return; ++ ++ len = strlen(str); ++ for (i = 0, j = 0; i < len; i++) { ++ if (strchr(valid, str[i])) ++ str[j++] = str[i]; ++ } ++ str[j] = '\0'; ++} ++ + /** + * virStringToUpper: + * @str: string to capitalize +diff --git a/src/util/virstring.h b/src/util/virstring.h +index b19abaf9f..8af054bce 100644 +--- a/src/util/virstring.h ++++ b/src/util/virstring.h +@@ -293,6 +293,7 @@ bool virStringHasChars(const char *str, + const char *chars); + bool virStringHasControlChars(const char *str); + void virStringStripControlChars(char *str); ++void virStringFilterChars(char *str, const char *valid); + + bool virStringIsPrintable(const char *str); + bool virStringBufferIsPrintable(const uint8_t *buf, size_t buflen); +diff --git a/tests/virstringtest.c b/tests/virstringtest.c +index 320f7a398..e8518ede1 100644 +--- a/tests/virstringtest.c ++++ b/tests/virstringtest.c +@@ -767,6 +767,36 @@ static int testStripControlChars(const void *args) + return ret; + } + ++struct testFilterData { ++ const char *string; ++ const char *valid; ++ const char *result; ++}; ++ ++static int testFilterChars(const void *args) ++{ ++ const struct testFilterData *data = args; ++ int ret = -1; ++ char *res = NULL; ++ ++ if (VIR_STRDUP(res, data->string) < 0) ++ goto cleanup; ++ ++ virStringFilterChars(res, data->valid); ++ ++ if (STRNEQ_NULLABLE(res, data->result)) { ++ fprintf(stderr, "Returned '%s', expected '%s'\n", ++ NULLSTR(res), NULLSTR(data->result)); ++ goto cleanup; ++ } ++ ++ ret = 0; ++ ++ cleanup: ++ VIR_FREE(res); ++ return ret; ++} ++ + static int + mymain(void) + { +@@ -1085,6 +1115,22 @@ mymain(void) + TEST_STRIP_CONTROL_CHARS("\x01H\x02" "E\x03L\x04L\x05O", "HELLO"); + TEST_STRIP_CONTROL_CHARS("\x01\x02\x03\x04HELL\x05O", "HELLO"); + TEST_STRIP_CONTROL_CHARS("\nhello \x01\x07hello\t", "\nhello hello\t"); ++ ++#define TEST_FILTER_CHARS(str, filter, res) \ ++ do { \ ++ struct testFilterData filterData = { \ ++ .string = str, \ ++ .valid = filter, \ ++ .result = res, \ ++ }; \ ++ if (virTestRun("Filter chars from " #str, \ ++ testFilterChars, &filterData) < 0) \ ++ ret = -1; \ ++ } while (0) ++ ++ TEST_FILTER_CHARS(NULL, NULL, NULL); ++ TEST_FILTER_CHARS("hello 123 hello", "helo", "hellohello"); ++ + return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; + } +