[libvirt] [PATCH 1/2] qemuProcessReadLog: Fix memcpy arguments
Ján Tomko
jtomko at redhat.com
Mon Jan 18 12:25:25 UTC 2016
s/memcpy/memmove/ in the summary
On Mon, Jan 18, 2016 at 11:39:34AM +0100, Michal Privoznik wrote:
> So I can observe this crasher that with freshly started daemon
> (and virtlogd enabled) I am trying to startup a domain that
> immediately dies (because it's said to use huge pages but I
> haven't allocated a single one in the pool).
> But what's
> interesting is that the daemon crashes too.
Redundant sentence.
> Hardly reproducible
> with -O0 or under valgrind.
> But I just got lucky:
Also redundant.
>
> ==20469== Invalid write of size 8
> ==20469== at 0x4C2E99B: memcpy at GLIBC_2.2.5 (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
> ==20469== by 0x217EDD07: qemuProcessReadLog (qemu_process.c:1670)
> ==20469== by 0x217EDE1D: qemuProcessReportLogError (qemu_process.c:1696)
> ==20469== by 0x217EE8C1: qemuProcessWaitForMonitor (qemu_process.c:1957)
> ==20469== by 0x217F6636: qemuProcessLaunch (qemu_process.c:4955)
> ==20469== by 0x217F71A4: qemuProcessStart (qemu_process.c:5152)
> ==20469== by 0x21846582: qemuDomainObjStart (qemu_driver.c:7396)
> ==20469== by 0x218467DE: qemuDomainCreateWithFlags (qemu_driver.c:7450)
> ==20469== by 0x21846845: qemuDomainCreate (qemu_driver.c:7468)
> ==20469== by 0x5611CD0: virDomainCreate (libvirt-domain.c:6753)
> ==20469== by 0x125D9A: remoteDispatchDomainCreate (remote_dispatch.h:3613)
> ==20469== by 0x125CB7: remoteDispatchDomainCreateHelper (remote_dispatch.h:3589)
> ==20469== Address 0x27a52ad0 is 0 bytes after a block of size 5,584 alloc'd
> ==20469== at 0x4C29F80: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
> ==20469== by 0x9B8D1DB: xdr_string (in /lib64/libc-2.21.so)
> ==20469== by 0x563B39C: xdr_virLogManagerProtocolNonNullString (log_protocol.c:24)
> ==20469== by 0x563B6B7: xdr_virLogManagerProtocolDomainReadLogFileRet (log_protocol.c:123)
> ==20469== by 0x164B34: virNetMessageDecodePayload (virnetmessage.c:407)
> ==20469== by 0x5682360: virNetClientProgramCall (virnetclientprogram.c:379)
> ==20469== by 0x563B30E: virLogManagerDomainReadLogFile (log_manager.c:272)
> ==20469== by 0x217CD613: qemuDomainLogContextRead (qemu_domain.c:2485)
> ==20469== by 0x217EDC76: qemuProcessReadLog (qemu_process.c:1660)
> ==20469== by 0x217EDE1D: qemuProcessReportLogError (qemu_process.c:1696)
> ==20469== by 0x217EE8C1: qemuProcessWaitForMonitor (qemu_process.c:1957)
> ==20469== by 0x217F6636: qemuProcessLaunch (qemu_process.c:4955)
>
The backtrace matches this report by Luyao:
https://www.redhat.com/archives/libvir-list/2015-December/msg00329.html
> This points to memmove() in qemuProcessReadLog().
> And in fact
> after few moments and a couple of papers (to debug the code) I
> can observe the bug.
This can be dropped too.
> Imagine we just read the following string
> from qemu:
>
> "abc\n2016-01-18T09:40:44.022744Z qemu-system-x86_64: Error\n"
>
> After the first pass of the while() loop in the
> qemuProcessReadLog() @buf still points to the beginning of the
> string, @filter_next points to the beginning of the second line.
> So we start second iteration because there is yet another newline
> character at the end. In this iteration @eol points to it
> actually. Now, the control gets inside true branch of if(). Just
> to remind you:
>
> got = 58
> filter_next = buf + 5,
> eol = buf + 58.
>
> Therefore skip = 54 which is correct. The message we want to skip
> is 54 bytes long. However:
>
> memmove(filter_next, eol + 1, (got - skip) +1);
>
> which is
>
> memmove(filter_next, eol + 1, 5)
>
> is obviously wrong as there is only one byte we can access, not 5!
>
> Signed-off-by: Michal Privoznik <mprivozn at redhat.com>
Introduced by v1.2.21-150-g69b0992
> ---
> src/qemu/qemu_process.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
ACK if you strip your life story from the commit message.
Jan
> diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
> index 05cbda2..f85afd5 100644
> --- a/src/qemu/qemu_process.c
> +++ b/src/qemu/qemu_process.c
> @@ -1667,7 +1667,7 @@ qemuProcessReadLog(qemuDomainLogContextPtr logCtxt, char **msg)
> if (virLogProbablyLogMessage(filter_next) ||
> STRPREFIX(filter_next, "char device redirected to")) {
> size_t skip = (eol + 1) - filter_next;
> - memmove(filter_next, eol + 1, (got - skip) + 1);
> + memmove(filter_next, eol + 1, buf + got - eol);
> got -= skip;
> } else {
> filter_next = eol + 1;
> --
> 2.4.10
>
> --
> libvir-list mailing list
> libvir-list at redhat.com
> https://www.redhat.com/mailman/listinfo/libvir-list
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20160118/bfdbfeee/attachment-0001.sig>
More information about the libvir-list
mailing list