From a6e23d00fa2a8f3a244bdcaad14c9b2550ee3b38 Mon Sep 17 00:00:00 2001 From: Mark McLoughlin Date: May 21 2009 12:07:09 +0000 Subject: * Thu May 21 2009 Mark McLoughlin - 0.6.3-10.fc12 - Fix XML attribute escaping (bug #499791) - Fix serious event handling issues causing guests to be destroyed (bug #499698) --- diff --git a/libvirt-0.6.3-event-handling-1.patch b/libvirt-0.6.3-event-handling-1.patch new file mode 100644 index 0000000..4104a6b --- /dev/null +++ b/libvirt-0.6.3-event-handling-1.patch @@ -0,0 +1,144 @@ +From e7be6cc841a5652b73ddd2ccd3769c7f8bbad13d Mon Sep 17 00:00:00 2001 +From: Daniel P. Berrange +Date: Tue, 12 May 2009 16:41:49 +0000 +Subject: [PATCH 1/2] Fix interrupting of main event thread & protect against accidental uniniitalized variables + +--- + qemud/event.c | 42 +++++++++++++++++++++++++++++++++++------- + 1 files changed, 35 insertions(+), 7 deletions(-) + +diff --git a/qemud/event.c b/qemud/event.c +index 65f548e..754f2b1 100644 +--- a/qemud/event.c ++++ b/qemud/event.c +@@ -84,10 +84,10 @@ struct virEventLoop { + static struct virEventLoop eventLoop; + + /* Unique ID for the next FD watch to be registered */ +-static int nextWatch = 0; ++static int nextWatch = 1; + + /* Unique ID for the next timer to be registered */ +-static int nextTimer = 0; ++static int nextTimer = 1; + + static void virEventLock(void) + { +@@ -143,15 +143,22 @@ int virEventAddHandleImpl(int fd, int events, + + void virEventUpdateHandleImpl(int watch, int events) { + int i; ++ EVENT_DEBUG("Update handle w=%d e=%d", watch, events); ++ ++ if (watch <= 0) { ++ VIR_WARN("Ignoring invalid update watch %d", watch); ++ return; ++ } ++ + virEventLock(); + for (i = 0 ; i < eventLoop.handlesCount ; i++) { + if (eventLoop.handles[i].watch == watch) { + eventLoop.handles[i].events = + virEventHandleTypeToPollEvent(events); ++ virEventInterruptLocked(); + break; + } + } +- virEventInterruptLocked(); + virEventUnlock(); + } + +@@ -164,6 +171,12 @@ void virEventUpdateHandleImpl(int watch, int events) { + int virEventRemoveHandleImpl(int watch) { + int i; + EVENT_DEBUG("Remove handle %d", watch); ++ ++ if (watch <= 0) { ++ VIR_WARN("Ignoring invalid remove watch %d", watch); ++ return -1; ++ } ++ + virEventLock(); + for (i = 0 ; i < eventLoop.handlesCount ; i++) { + if (eventLoop.handles[i].deleted) +@@ -172,11 +185,11 @@ int virEventRemoveHandleImpl(int watch) { + if (eventLoop.handles[i].watch == watch) { + EVENT_DEBUG("mark delete %d %d", i, eventLoop.handles[i].fd); + eventLoop.handles[i].deleted = 1; ++ virEventInterruptLocked(); + virEventUnlock(); + return 0; + } + } +- virEventInterruptLocked(); + virEventUnlock(); + return -1; + } +@@ -232,6 +245,12 @@ void virEventUpdateTimeoutImpl(int timer, int frequency) { + struct timeval tv; + int i; + EVENT_DEBUG("Updating timer %d timeout with %d ms freq", timer, frequency); ++ ++ if (timer <= 0) { ++ VIR_WARN("Ignoring invalid update timer %d", timer); ++ return; ++ } ++ + if (gettimeofday(&tv, NULL) < 0) { + return; + } +@@ -244,10 +263,10 @@ void virEventUpdateTimeoutImpl(int timer, int frequency) { + frequency >= 0 ? frequency + + (((unsigned long long)tv.tv_sec)*1000) + + (((unsigned long long)tv.tv_usec)/1000) : 0; ++ virEventInterruptLocked(); + break; + } + } +- virEventInterruptLocked(); + virEventUnlock(); + } + +@@ -260,6 +279,12 @@ void virEventUpdateTimeoutImpl(int timer, int frequency) { + int virEventRemoveTimeoutImpl(int timer) { + int i; + EVENT_DEBUG("Remove timer %d", timer); ++ ++ if (timer <= 0) { ++ VIR_WARN("Ignoring invalid remove timer %d", timer); ++ return -1; ++ } ++ + virEventLock(); + for (i = 0 ; i < eventLoop.timeoutsCount ; i++) { + if (eventLoop.timeouts[i].deleted) +@@ -267,11 +292,11 @@ int virEventRemoveTimeoutImpl(int timer) { + + if (eventLoop.timeouts[i].timer == timer) { + eventLoop.timeouts[i].deleted = 1; ++ virEventInterruptLocked(); + virEventUnlock(); + return 0; + } + } +- virEventInterruptLocked(); + virEventUnlock(); + return -1; + } +@@ -617,9 +642,12 @@ static int virEventInterruptLocked(void) + char c = '\0'; + + if (!eventLoop.running || +- pthread_self() == eventLoop.leader) ++ pthread_self() == eventLoop.leader) { ++ VIR_DEBUG("Skip interrupt, %d %d", eventLoop.running, (int)eventLoop.leader); + return 0; ++ } + ++ VIR_DEBUG0("Interrupting"); + if (safewrite(eventLoop.wakeupfd[1], &c, sizeof(c)) != sizeof(c)) + return -1; + return 0; +-- +1.6.0.6 + diff --git a/libvirt-0.6.3-event-handling-2.patch b/libvirt-0.6.3-event-handling-2.patch new file mode 100644 index 0000000..ddcede6 --- /dev/null +++ b/libvirt-0.6.3-event-handling-2.patch @@ -0,0 +1,197 @@ +From 6483ee77ed12f037d68a6adc690624fa1b508dc0 Mon Sep 17 00:00:00 2001 +From: Daniel P. Berrange +Date: Tue, 12 May 2009 16:43:04 +0000 +Subject: [PATCH 2/2] Fix watch/timer event deletion + +--- + qemud/event.c | 112 ++++++++++++++++++++++++++------------------------------- + 1 files changed, 51 insertions(+), 61 deletions(-) + +diff --git a/qemud/event.c b/qemud/event.c +index 754f2b1..a57d967 100644 +--- a/qemud/event.c ++++ b/qemud/event.c +@@ -313,7 +313,7 @@ static int virEventCalculateTimeout(int *timeout) { + EVENT_DEBUG("Calculate expiry of %d timers", eventLoop.timeoutsCount); + /* Figure out if we need a timeout */ + for (i = 0 ; i < eventLoop.timeoutsCount ; i++) { +- if (eventLoop.timeouts[i].deleted || eventLoop.timeouts[i].frequency < 0) ++ if (eventLoop.timeouts[i].frequency < 0) + continue; + + EVENT_DEBUG("Got a timeout scheduled for %llu", eventLoop.timeouts[i].expiresAt); +@@ -350,32 +350,26 @@ static int virEventCalculateTimeout(int *timeout) { + * file handles. The caller must free the returned data struct + * returns: the pollfd array, or NULL on error + */ +-static int virEventMakePollFDs(struct pollfd **retfds) { ++static struct pollfd *virEventMakePollFDs(void) { + struct pollfd *fds; +- int i, nfds = 0; ++ int i; + +- for (i = 0 ; i < eventLoop.handlesCount ; i++) { +- if (eventLoop.handles[i].deleted) +- continue; +- nfds++; +- } +- *retfds = NULL; + /* Setup the poll file handle data structs */ +- if (VIR_ALLOC_N(fds, nfds) < 0) +- return -1; ++ if (VIR_ALLOC_N(fds, eventLoop.handlesCount) < 0) ++ return NULL; + +- for (i = 0, nfds = 0 ; i < eventLoop.handlesCount ; i++) { +- if (eventLoop.handles[i].deleted) +- continue; +- fds[nfds].fd = eventLoop.handles[i].fd; +- fds[nfds].events = eventLoop.handles[i].events; +- fds[nfds].revents = 0; ++ for (i = 0 ; i < eventLoop.handlesCount ; i++) { ++ EVENT_DEBUG("Prepare n=%d w=%d, f=%d e=%d", i, ++ eventLoop.handles[i].watch, ++ eventLoop.handles[i].fd, ++ eventLoop.handles[i].events); ++ fds[i].fd = eventLoop.handles[i].fd; ++ fds[i].events = eventLoop.handles[i].events; ++ fds[i].revents = 0; + //EVENT_DEBUG("Wait for %d %d", eventLoop.handles[i].fd, eventLoop.handles[i].events); +- nfds++; + } + +- *retfds = fds; +- return nfds; ++ return fds; + } + + +@@ -435,26 +429,30 @@ static int virEventDispatchTimeouts(void) { + * Returns 0 upon success, -1 if an error occurred + */ + static int virEventDispatchHandles(int nfds, struct pollfd *fds) { +- int i, n; ++ int i; + +- for (i = 0, n = 0 ; i < eventLoop.handlesCount && n < nfds ; i++) { ++ /* NB, use nfds not eventLoop.handlesCount, because new ++ * fds might be added on end of list, and they're not ++ * in the fds array we've got */ ++ for (i = 0 ; i < nfds ; i++) { + if (eventLoop.handles[i].deleted) { +- EVENT_DEBUG("Skip deleted %d", eventLoop.handles[i].fd); ++ EVENT_DEBUG("Skip deleted n=%d w=%d f=%d", i, ++ eventLoop.handles[i].watch, eventLoop.handles[i].fd); + continue; + } + +- if (fds[n].revents) { ++ if (fds[i].revents) { + virEventHandleCallback cb = eventLoop.handles[i].cb; + void *opaque = eventLoop.handles[i].opaque; +- int hEvents = virPollEventToEventHandleType(fds[n].revents); +- EVENT_DEBUG("Dispatch %d %d %p", fds[n].fd, +- fds[n].revents, eventLoop.handles[i].opaque); ++ int hEvents = virPollEventToEventHandleType(fds[i].revents); ++ EVENT_DEBUG("Dispatch n=%d f=%d w=%d e=%d %p", i, ++ fds[i].fd, eventLoop.handles[i].watch, ++ fds[i].revents, eventLoop.handles[i].opaque); + virEventUnlock(); + (cb)(eventLoop.handles[i].watch, +- fds[n].fd, hEvents, opaque); ++ fds[i].fd, hEvents, opaque); + virEventLock(); + } +- n++; + } + + return 0; +@@ -545,22 +543,21 @@ static int virEventCleanupHandles(void) { + * at least one file handle has an event, or a timer expires + */ + int virEventRunOnce(void) { +- struct pollfd *fds; ++ struct pollfd *fds = NULL; + int ret, timeout, nfds; + + virEventLock(); + eventLoop.running = 1; + eventLoop.leader = pthread_self(); +- if ((nfds = virEventMakePollFDs(&fds)) < 0) { +- virEventUnlock(); +- return -1; +- } + +- if (virEventCalculateTimeout(&timeout) < 0) { +- VIR_FREE(fds); +- virEventUnlock(); +- return -1; +- } ++ if (virEventCleanupTimeouts() < 0 || ++ virEventCleanupHandles() < 0) ++ goto error; ++ ++ if (!(fds = virEventMakePollFDs()) || ++ virEventCalculateTimeout(&timeout) < 0) ++ goto error; ++ nfds = eventLoop.handlesCount; + + virEventUnlock(); + +@@ -572,38 +569,31 @@ int virEventRunOnce(void) { + if (errno == EINTR) { + goto retry; + } +- VIR_FREE(fds); +- return -1; ++ goto error_unlocked; + } + + virEventLock(); +- if (virEventDispatchTimeouts() < 0) { +- VIR_FREE(fds); +- virEventUnlock(); +- return -1; +- } ++ if (virEventDispatchTimeouts() < 0) ++ goto error; + + if (ret > 0 && +- virEventDispatchHandles(nfds, fds) < 0) { +- VIR_FREE(fds); +- virEventUnlock(); +- return -1; +- } +- VIR_FREE(fds); +- +- if (virEventCleanupTimeouts() < 0) { +- virEventUnlock(); +- return -1; +- } ++ virEventDispatchHandles(nfds, fds) < 0) ++ goto error; + +- if (virEventCleanupHandles() < 0) { +- virEventUnlock(); +- return -1; +- } ++ if (virEventCleanupTimeouts() < 0 || ++ virEventCleanupHandles() < 0) ++ goto error; + + eventLoop.running = 0; + virEventUnlock(); ++ VIR_FREE(fds); + return 0; ++ ++error: ++ virEventUnlock(); ++error_unlocked: ++ VIR_FREE(fds); ++ return -1; + } + + static void virEventHandleWakeup(int watch ATTRIBUTE_UNUSED, +-- +1.6.0.6 + diff --git a/libvirt-0.6.3-xml-attribute-escaping.patch b/libvirt-0.6.3-xml-attribute-escaping.patch new file mode 100644 index 0000000..5c9ecf5 --- /dev/null +++ b/libvirt-0.6.3-xml-attribute-escaping.patch @@ -0,0 +1,47 @@ +From 7f7a4403860f56d5a1ad65bfd16f5bf97a971d45 Mon Sep 17 00:00:00 2001 +From: Daniel Veillard +Date: Wed, 13 May 2009 16:19:59 +0000 +Subject: [PATCH 1/1] * src/buf.c: avoid an XML attribute escaping bug #499791 + daniel + +--- + src/buf.c | 16 +++++++++++++++- + 1 files changed, 15 insertions(+), 1 deletions(-) + +diff --git a/src/buf.c b/src/buf.c +index cdcdac9..259175d 100644 +--- a/src/buf.c ++++ b/src/buf.c +@@ -266,7 +266,7 @@ virBufferEscapeString(const virBufferPtr buf, const char *format, const char *st + return; + + len = strlen(str); +- if (VIR_ALLOC_N(escaped, 5 * len + 1) < 0) { ++ if (VIR_ALLOC_N(escaped, 6 * len + 1) < 0) { + virBufferNoMemory(buf); + return; + } +@@ -290,6 +290,20 @@ virBufferEscapeString(const virBufferPtr buf, const char *format, const char *st + *out++ = 'm'; + *out++ = 'p'; + *out++ = ';'; ++ } else if (*cur == '"') { ++ *out++ = '&'; ++ *out++ = 'q'; ++ *out++ = 'u'; ++ *out++ = 'o'; ++ *out++ = 't'; ++ *out++ = ';'; ++ } else if (*cur == '\'') { ++ *out++ = '&'; ++ *out++ = 'a'; ++ *out++ = 'p'; ++ *out++ = 'o'; ++ *out++ = 's'; ++ *out++ = ';'; + } else if ((*cur >= 0x20) || (*cur == '\n') || (*cur == '\t') || + (*cur == '\r')) { + /* +-- +1.6.0.6 + diff --git a/libvirt.spec b/libvirt.spec index 62d43bb..5a254cd 100644 --- a/libvirt.spec +++ b/libvirt.spec @@ -55,7 +55,7 @@ Summary: Library providing a simple API virtualization Name: libvirt Version: 0.6.3 -Release: 9%{?dist}%{?extra_release} +Release: 10%{?dist}%{?extra_release} License: LGPLv2+ Group: Development/Libraries Source: libvirt-%{version}.tar.gz @@ -74,6 +74,11 @@ Patch4: libvirt-0.6.3-enable-qemu-0-10-migration.patch Patch5: libvirt-0.6.2-fix-nosource-label.patch # Fix qemu argv detection with latest qemu (bz 501923) Patch6: libvirt-0.6.3-fix-qemu-argv-detection-with-kvm-85.patch +# Fix XML attribute escaping (bz 499791) +Patch7: libvirt-0.6.3-xml-attribute-escaping.patch +# Fix serious event handling issues causing guests to be destroyed (bz 499698) +Patch8: libvirt-0.6.3-event-handling-1.patch +Patch9: libvirt-0.6.3-event-handling-2.patch # Patches not for upstream. @@ -235,6 +240,9 @@ of recent versions of Linux (and other OSes). %patch4 -p1 %patch5 -p1 %patch6 -p1 +%patch7 -p1 +%patch8 -p1 +%patch9 -p1 %patch200 -p0 @@ -565,6 +573,10 @@ fi %endif %changelog +* Thu May 21 2009 Mark McLoughlin - 0.6.3-10.fc12 +- Fix XML attribute escaping (bug #499791) +- Fix serious event handling issues causing guests to be destroyed (bug #499698) + * Thu May 21 2009 Mark McLoughlin - 0.6.3-9.fc12 - Fix qemu argv detection with latest qemu (bug #501923)