diff --git a/5004f121-virFdStreamThread-dont-exceed-length.patch b/5004f121-virFdStreamThread-dont-exceed-length.patch new file mode 100644 index 0000000..3b6989e --- /dev/null +++ b/5004f121-virFdStreamThread-dont-exceed-length.patch @@ -0,0 +1,85 @@ +commit 5004f121bc572c58d9721bf7bf3c3a1988720ba8 +Author: Michal Privoznik +Date: Mon Jun 5 13:22:23 2017 +0200 + + virFDStreamThread: Make sure we won't exceed @length + + There's a problem with current streams after I switched them from + iohelper to thread implementation. Previously, iohelper made sure + not to exceed specified @length resulting in the pipe EOF + appearing at the exact right moment (the pipe was used to tunnel + the data from the iohelper to the daemon). Anyway, when switching + to thread I had to write the I/O code from scratch. Whilst doing + that I took an inspiration from the iohelper code, but since the + usage of pipe switched to slightly different meaning, there was + no 1:1 relationship between the codes. + + Moreover, after introducing VIR_FDSTREAM_MSG_TYPE_HOLE, the + condition that should made sure we won't exceed @length was + completely wrong. + + The fix is to: + + a) account for holes for @length + b) cap not just data sections but holes too (if @length would be + exceeded) + + For this purpose, the condition needs to be brought closer to the + code that handles holes and data sections. + + Signed-off-by: Michal Privoznik + +Index: libvirt-3.4.0/src/util/virfdstream.c +=================================================================== +--- libvirt-3.4.0.orig/src/util/virfdstream.c ++++ libvirt-3.4.0/src/util/virfdstream.c +@@ -420,6 +420,8 @@ virFDStreamThreadDoRead(virFDStreamDataP + const int fdout, + const char *fdinname, + const char *fdoutname, ++ size_t length, ++ size_t total, + size_t *dataLen, + size_t buflen) + { +@@ -433,10 +435,18 @@ virFDStreamThreadDoRead(virFDStreamDataP + if (virFileInData(fdin, &inData, §ionLen) < 0) + goto error; + ++ if (length && ++ sectionLen > length - total) ++ sectionLen = length - total; ++ + if (inData) + *dataLen = sectionLen; + } + ++ if (length && ++ buflen > length - total) ++ buflen = length - total; ++ + if (VIR_ALLOC(msg) < 0) + goto error; + +@@ -578,13 +588,6 @@ virFDStreamThread(void *opaque) + while (1) { + ssize_t got; + +- if (length && +- (length - total) < buflen) +- buflen = length - total; +- +- if (buflen == 0) +- break; /* End of requested data from client */ +- + while (doRead == (fdst->msg != NULL) && + !fdst->threadQuit) { + if (virCondWait(&fdst->threadCond, &fdst->parent.lock)) { +@@ -608,6 +611,7 @@ virFDStreamThread(void *opaque) + got = virFDStreamThreadDoRead(fdst, sparse, + fdin, fdout, + fdinname, fdoutname, ++ length, total, + &dataLen, buflen); + else + got = virFDStreamThreadDoWrite(fdst, sparse, diff --git a/libvirt.changes b/libvirt.changes index bdf9d9c..fa2b16f 100644 --- a/libvirt.changes +++ b/libvirt.changes @@ -1,3 +1,9 @@ +------------------------------------------------------------------- +Tue Jun 6 22:01:24 UTC 2017 - jfehlig@suse.com + +- Don't exceed specified length when reading from stream + 5004f121-virFdStreamThread-dont-exceed-length.patch + ------------------------------------------------------------------- Fri Jun 2 17:23:04 UTC 2017 - jfehlig@suse.com diff --git a/libvirt.spec b/libvirt.spec index e7aadae..3e75e53 100644 --- a/libvirt.spec +++ b/libvirt.spec @@ -317,6 +317,7 @@ Source4: libvirtd-relocation-server.fw Source99: baselibs.conf Source100: %{name}-rpmlintrc # Upstream patches +Patch0: 5004f121-virFdStreamThread-dont-exceed-length.patch # Patches pending upstream review Patch100: libxl-dom-reset.patch Patch101: network-don-t-use-dhcp-authoritative-on-static-netwo.patch @@ -885,6 +886,7 @@ libvirt plugin for NSS for translating domain names into IP addresses. %prep %setup -q +%patch0 -p1 %patch100 -p1 %patch101 -p1 %patch150 -p1