Bug 680281
Summary: | off-by-one in virFileAbsPath can lead to memory corruption | |||
---|---|---|---|---|
Product: | Red Hat Enterprise Linux 6 | Reporter: | Eric Blake <eblake> | |
Component: | libvirt | Assignee: | Eric Blake <eblake> | |
Status: | CLOSED ERRATA | QA Contact: | Virtualization Bugs <virt-bugs> | |
Severity: | unspecified | Docs Contact: | ||
Priority: | unspecified | |||
Version: | 6.1 | CC: | dallan, eblake, gsun, hjiang, mjenner, xen-maint | |
Target Milestone: | rc | |||
Target Release: | --- | |||
Hardware: | Unspecified | |||
OS: | Unspecified | |||
Whiteboard: | ||||
Fixed In Version: | libvirt-0.8.7-8.el6 | Doc Type: | Bug Fix | |
Doc Text: | Story Points: | --- | ||
Clone Of: | ||||
: | 680289 (view as bug list) | Environment: | ||
Last Closed: | 2011-05-19 13:28:14 UTC | Type: | --- | |
Regression: | --- | Mount Type: | --- | |
Documentation: | --- | CRM: | ||
Verified Versions: | Category: | --- | ||
oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | ||
Cloudforms Team: | --- | Target Upstream Version: | ||
Embargoed: | ||||
Bug Depends On: | ||||
Bug Blocks: | 680289 |
Description
Eric Blake
2011-02-24 22:04:33 UTC
related to bug 679164, but the memory bugs in that bug don't extend back to RHEL 5; created this as a separate bug for easier cloning It turns out that virLogParseOutputs in logging.c is the only client of the faulty virFileAbsPath; this in turn is only called when parsing the environment variable LIBVIRT_LOG_OUTPUTS or the log_outputs line in libvirtd.conf. The problem only occurs when accessing a problematic log directive of the form <n>:file:relative-path). A workaround is to always use <n>:file:/absolute-path if it is desired to perform logging via that environment variable or configuration line. Therefore, I'm debating whether this is severe enough to warrant the hassle of a z-stream fix, or whether it is easy enough to avoid. Here's a reproducer under valgrind: $ LIBVIRT_LOG_OUTPUTS='4:file:log' valgrind virsh version ... ==17924== Invalid write of size 1 ==17924== at 0x4A0675F: strcpy (mc_replace_strmem.c:311) ==17924== by 0x3D6543DE3D: virFileAbsPath (string3.h:107) ==17924== by 0x3D65431563: virLogParseOutputs (logging.c:768) ==17924== by 0x3D65472D5A: virInitialize (libvirt.c:337) ==17924== by 0x3D6547389C: virConnectOpenAuth (libvirt.c:1495) ==17924== by 0x41B62F: main (virsh.c:10559) ==17924== Address 0x4c6356f is 0 bytes after a block of size 31 alloc'd I was not able to quickly find a particular file length of $CWD plus the relative name where the out-of-bounds write would scribble over malloc data (rather than in the allocation padding) to the point of actually causing a crash, but that doesn't rule out the possibility of such a length. Verified build: RHEL6.1-20110202.n.0 Packages: libvirt-0.8.7-8.el6.x86_64 valgrind-3.6.0-3.el6.x86_64 qemu-kvm-0.12.1.2-2.143.el6.x86_64 kernel-2.6.32-118.el6.x86_64 libnl-1.1-13.el6.x86_64 Steps: # LIBVIRT_LOG_OUTPUTS='4:file:log' valgrind virsh version Output: LIBVIRT_LOG_OUTPUTS='4:file:log' valgrind virsh version ==10746== Memcheck, a memory error detector ==10746== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al. ==10746== Using Valgrind-3.6.0 and LibVEX; rerun with -h for copyright info ==10746== Command: virsh version ==10746== Compiled against library: libvir 0.8.7 Using library: libvir 0.8.7 Using API: QEMU 0.8.7 Running hypervisor: QEMU 0.12.1 ==10746== ==10746== HEAP SUMMARY: ==10746== in use at exit: 2,962 bytes in 45 blocks ==10746== total heap usage: 194 allocs, 149 frees, 1,970,457 bytes allocated ==10746== ==10746== LEAK SUMMARY: ==10746== definitely lost: 0 bytes in 0 blocks ==10746== indirectly lost: 0 bytes in 0 blocks ==10746== possibly lost: 0 bytes in 0 blocks ==10746== still reachable: 2,962 bytes in 45 blocks ==10746== suppressed: 0 bytes in 0 blocks An advisory has been issued which should help the problem described in this bug report. This report is therefore being closed with a resolution of ERRATA. For more information on therefore solution and/or where to find the updated files, please follow the link below. You may reopen this bug report if the solution does not work for you. http://rhn.redhat.com/errata/RHBA-2011-0596.html Could reproduce this bug on the following components of rh5.6: Packages: libvirt-0.8.2-15.el5 valgrind-3.5.0-1.el5 kernel-2.6.18-238.el5 libnl-1.0-0.10.pre5.5 Steps: # LIBVIRT_LOG_OUTPUTS='4:file:log' valgrind virsh version Outputs: # LIBVIRT_LOG_OUTPUTS='4:file:log' valgrind virsh version ==6569== Memcheck, a memory error detector ==6569== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al. ==6569== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright info ==6569== Command: virsh version ==6569== ==6569== Invalid write of size 1 ==6569== at 0x3B02CE72BF: __vsnprintf_chk (in /lib64/libc-2.5.so) ==6569== by 0x3B02CE722A: __snprintf_chk (in /lib64/libc-2.5.so) ==6569== by 0x3B16C02EC4: numa_init (in /usr/lib64/libnuma.so.1) ==6569== by 0x3B0280D1BA: call_init (in /lib64/ld-2.5.so) ==6569== by 0x3B0280D2C4: _dl_init (in /lib64/ld-2.5.so) ==6569== by 0x3B02800AA9: ??? (in /lib64/ld-2.5.so) ==6569== by 0x1: ??? ==6569== by 0x7FF000946: ??? ==6569== by 0x7FF00094C: ??? ==6569== Address 0x4c501a0 is 0 bytes after a block of size 0 alloc'd ==6569== at 0x4A05E1C: malloc (vg_replace_malloc.c:195) ==6569== by 0x3B16C02D9B: numa_init (in /usr/lib64/libnuma.so.1) ==6569== by 0x3B0280D1BA: call_init (in /lib64/ld-2.5.so) ==6569== by 0x3B0280D2C4: _dl_init (in /lib64/ld-2.5.so) ==6569== by 0x3B02800AA9: ??? (in /lib64/ld-2.5.so) ==6569== by 0x1: ??? ==6569== by 0x7FF000946: ??? ==6569== by 0x7FF00094C: ??? ==6569== ==6569== Invalid write of size 1 ==6569== at 0x3B02C6E3B1: _IO_default_xsputn (in /lib64/libc-2.5.so) ==6569== by 0x3B02C43D38: vfprintf (in /lib64/libc-2.5.so) ==6569== by 0x3B02CE72E7: __vsnprintf_chk (in /lib64/libc-2.5.so) ==6569== by 0x3B02CE722A: __snprintf_chk (in /lib64/libc-2.5.so) ==6569== by 0x3B16C02EC4: numa_init (in /usr/lib64/libnuma.so.1) ==6569== by 0x3B0280D1BA: call_init (in /lib64/ld-2.5.so) ==6569== by 0x3B0280D2C4: _dl_init (in /lib64/ld-2.5.so) ==6569== by 0x3B02800AA9: ??? (in /lib64/ld-2.5.so) ==6569== by 0x1: ??? ==6569== by 0x7FF000946: ??? ==6569== by 0x7FF00094C: ??? ==6569== Address 0x4c501a0 is 0 bytes after a block of size 0 alloc'd ==6569== at 0x4A05E1C: malloc (vg_replace_malloc.c:195) ==6569== by 0x3B16C02D9B: numa_init (in /usr/lib64/libnuma.so.1) ==6569== by 0x3B0280D1BA: call_init (in /lib64/ld-2.5.so) ==6569== by 0x3B0280D2C4: _dl_init (in /lib64/ld-2.5.so) ==6569== by 0x3B02800AA9: ??? (in /lib64/ld-2.5.so) ==6569== by 0x1: ??? ==6569== by 0x7FF000946: ??? ==6569== by 0x7FF00094C: ??? ==6569== ==6569== Invalid write of size 1 ==6569== at 0x3B02CE72FD: __vsnprintf_chk (in /lib64/libc-2.5.so) ==6569== by 0x3B02CE722A: __snprintf_chk (in /lib64/libc-2.5.so) ==6569== by 0x3B16C02EC4: numa_init (in /usr/lib64/libnuma.so.1) ==6569== by 0x3B0280D1BA: call_init (in /lib64/ld-2.5.so) ==6569== by 0x3B0280D2C4: _dl_init (in /lib64/ld-2.5.so) ==6569== by 0x3B02800AA9: ??? (in /lib64/ld-2.5.so) ==6569== by 0x1: ??? ==6569== by 0x7FF000946: ??? ==6569== by 0x7FF00094C: ??? ==6569== Address 0x4c501a1 is 1 bytes after a block of size 0 alloc'd ==6569== at 0x4A05E1C: malloc (vg_replace_malloc.c:195) ==6569== by 0x3B16C02D9B: numa_init (in /usr/lib64/libnuma.so.1) ==6569== by 0x3B0280D1BA: call_init (in /lib64/ld-2.5.so) ==6569== by 0x3B0280D2C4: _dl_init (in /lib64/ld-2.5.so) ==6569== by 0x3B02800AA9: ??? (in /lib64/ld-2.5.so) ==6569== by 0x1: ??? ==6569== by 0x7FF000946: ??? ==6569== by 0x7FF00094C: ??? ==6569== ==6569== Invalid write of size 1 ==6569== at 0x3B02CE72BF: __vsnprintf_chk (in /lib64/libc-2.5.so) ==6569== by 0x3B02CE722A: __snprintf_chk (in /lib64/libc-2.5.so) ==6569== by 0x3B0280D1BA: call_init (in /lib64/ld-2.5.so) ==6569== by 0x3B0280D2C4: _dl_init (in /lib64/ld-2.5.so) ==6569== by 0x3B02800AA9: ??? (in /lib64/ld-2.5.so) ==6569== by 0x1: ??? ==6569== by 0x7FF000946: ??? ==6569== by 0x7FF00094C: ??? ==6569== Address 0x4c501a1 is 1 bytes after a block of size 0 alloc'd ==6569== at 0x4A05E1C: malloc (vg_replace_malloc.c:195) ==6569== by 0x3B16C02D9B: numa_init (in /usr/lib64/libnuma.so.1) ==6569== by 0x3B0280D1BA: call_init (in /lib64/ld-2.5.so) ==6569== by 0x3B0280D2C4: _dl_init (in /lib64/ld-2.5.so) ==6569== by 0x3B02800AA9: ??? (in /lib64/ld-2.5.so) ==6569== by 0x1: ??? ==6569== by 0x7FF000946: ??? ==6569== by 0x7FF00094C: ??? ==6569== ==6569== Invalid write of size 1 ==6569== at 0x3B02C43762: vfprintf (in /lib64/libc-2.5.so) ==6569== by 0x3B02CE72E7: __vsnprintf_chk (in /lib64/libc-2.5.so) ==6569== by 0x3B02CE722A: __snprintf_chk (in /lib64/libc-2.5.so) ==6569== by 0x3B0280D1BA: call_init (in /lib64/ld-2.5.so) ==6569== by 0x3B0280D2C4: _dl_init (in /lib64/ld-2.5.so) ==6569== by 0x3B02800AA9: ??? (in /lib64/ld-2.5.so) ==6569== by 0x1: ??? ==6569== by 0x7FF000946: ??? ==6569== by 0x7FF00094C: ??? ==6569== Address 0x4c501a1 is 1 bytes after a block of size 0 alloc'd ==6569== at 0x4A05E1C: malloc (vg_replace_malloc.c:195) ==6569== by 0x3B16C02D9B: numa_init (in /usr/lib64/libnuma.so.1) ==6569== by 0x3B0280D1BA: call_init (in /lib64/ld-2.5.so) ==6569== by 0x3B0280D2C4: _dl_init (in /lib64/ld-2.5.so) ==6569== by 0x3B02800AA9: ??? (in /lib64/ld-2.5.so) ==6569== by 0x1: ??? ==6569== by 0x7FF000946: ??? ==6569== by 0x7FF00094C: ??? ==6569== ==6569== Invalid write of size 1 ==6569== at 0x3B02CE72FD: __vsnprintf_chk (in /lib64/libc-2.5.so) ==6569== by 0x3B02CE722A: __snprintf_chk (in /lib64/libc-2.5.so) ==6569== by 0x3B0280D1BA: call_init (in /lib64/ld-2.5.so) ==6569== by 0x3B0280D2C4: _dl_init (in /lib64/ld-2.5.so) ==6569== by 0x3B02800AA9: ??? (in /lib64/ld-2.5.so) ==6569== by 0x1: ??? ==6569== by 0x7FF000946: ??? ==6569== by 0x7FF00094C: ??? ==6569== Address 0x4c501a2 is 2 bytes after a block of size 0 alloc'd ==6569== at 0x4A05E1C: malloc (vg_replace_malloc.c:195) ==6569== by 0x3B16C02D9B: numa_init (in /usr/lib64/libnuma.so.1) ==6569== by 0x3B0280D1BA: call_init (in /lib64/ld-2.5.so) ==6569== by 0x3B0280D2C4: _dl_init (in /lib64/ld-2.5.so) ==6569== by 0x3B02800AA9: ??? (in /lib64/ld-2.5.so) ==6569== by 0x1: ??? ==6569== by 0x7FF000946: ??? ==6569== by 0x7FF00094C: ??? ==6569== ==6569== Invalid write of size 1 ==6569== at 0x4A082E7: strcpy (mc_replace_strmem.c:303) ==6569== by 0x3B17037DA9: virFileAbsPath (in /usr/lib64/libvirt.so.0.8.2) ==6569== by 0x3B1702DF27: virLogParseOutputs (in /usr/lib64/libvirt.so.0.8.2) ==6569== by 0x3B17076D02: virInitialize (in /usr/lib64/libvirt.so.0.8.2) ==6569== by 0x3B17076E34: virConnectOpenAuth (in /usr/lib64/libvirt.so.0.8.2) ==6569== by 0x41876A: ??? (in /usr/bin/virsh) ==6569== by 0x3B02C1D993: (below main) (in /lib64/libc-2.5.so) ==6569== Address 0x4c53e08 is 0 bytes after a block of size 8 alloc'd ==6569== at 0x4A05F1D: realloc (vg_replace_malloc.c:476) ==6569== by 0x3B1702E37E: virReallocN (in /usr/lib64/libvirt.so.0.8.2) ==6569== by 0x3B17037D87: virFileAbsPath (in /usr/lib64/libvirt.so.0.8.2) ==6569== by 0x3B1702DF27: virLogParseOutputs (in /usr/lib64/libvirt.so.0.8.2) ==6569== by 0x3B17076D02: virInitialize (in /usr/lib64/libvirt.so.0.8.2) ==6569== by 0x3B17076E34: virConnectOpenAuth (in /usr/lib64/libvirt.so.0.8.2) ==6569== by 0x41876A: ??? (in /usr/bin/virsh) ==6569== by 0x3B02C1D993: (below main) (in /lib64/libc-2.5.so) ==6569== ==6569== Syscall param open(filename) points to unaddressable byte(s) ==6569== at 0x3B0380E210: __open_nocancel (in /lib64/libpthread-2.5.so) ==6569== by 0x3B1702DF48: virLogParseOutputs (in /usr/lib64/libvirt.so.0.8.2) ==6569== by 0x3B17076D02: virInitialize (in /usr/lib64/libvirt.so.0.8.2) ==6569== by 0x3B17076E34: virConnectOpenAuth (in /usr/lib64/libvirt.so.0.8.2) ==6569== by 0x41876A: ??? (in /usr/bin/virsh) ==6569== by 0x3B02C1D993: (below main) (in /lib64/libc-2.5.so) ==6569== Address 0x4c53e08 is 0 bytes after a block of size 8 alloc'd ==6569== at 0x4A05F1D: realloc (vg_replace_malloc.c:476) ==6569== by 0x3B1702E37E: virReallocN (in /usr/lib64/libvirt.so.0.8.2) ==6569== by 0x3B17037D87: virFileAbsPath (in /usr/lib64/libvirt.so.0.8.2) ==6569== by 0x3B1702DF27: virLogParseOutputs (in /usr/lib64/libvirt.so.0.8.2) ==6569== by 0x3B17076D02: virInitialize (in /usr/lib64/libvirt.so.0.8.2) ==6569== by 0x3B17076E34: virConnectOpenAuth (in /usr/lib64/libvirt.so.0.8.2) ==6569== by 0x41876A: ??? (in /usr/bin/virsh) ==6569== by 0x3B02C1D993: (below main) (in /lib64/libc-2.5.so) ==6569== ==6569== Invalid read of size 1 ==6569== at 0x4A06D94: strlen (mc_replace_strmem.c:275) ==6569== by 0x3B02C798B5: strdup (in /lib64/libc-2.5.so) ==6569== by 0x3B1702D3B6: virLogDefineOutput (in /usr/lib64/libvirt.so.0.8.2) ==6569== by 0x3B1702DF76: virLogParseOutputs (in /usr/lib64/libvirt.so.0.8.2) ==6569== by 0x3B17076D02: virInitialize (in /usr/lib64/libvirt.so.0.8.2) ==6569== by 0x3B17076E34: virConnectOpenAuth (in /usr/lib64/libvirt.so.0.8.2) ==6569== by 0x41876A: ??? (in /usr/bin/virsh) ==6569== by 0x3B02C1D993: (below main) (in /lib64/libc-2.5.so) ==6569== Address 0x4c53e08 is 0 bytes after a block of size 8 alloc'd ==6569== at 0x4A05F1D: realloc (vg_replace_malloc.c:476) ==6569== by 0x3B1702E37E: virReallocN (in /usr/lib64/libvirt.so.0.8.2) ==6569== by 0x3B17037D87: virFileAbsPath (in /usr/lib64/libvirt.so.0.8.2) ==6569== by 0x3B1702DF27: virLogParseOutputs (in /usr/lib64/libvirt.so.0.8.2) ==6569== by 0x3B17076D02: virInitialize (in /usr/lib64/libvirt.so.0.8.2) ==6569== by 0x3B17076E34: virConnectOpenAuth (in /usr/lib64/libvirt.so.0.8.2) ==6569== by 0x41876A: ??? (in /usr/bin/virsh) ==6569== by 0x3B02C1D993: (below main) (in /lib64/libc-2.5.so) ==6569== ==6569== Invalid read of size 1 ==6569== at 0x4A080C0: memcpy (mc_replace_strmem.c:482) ==6569== by 0x3B1702D3B6: virLogDefineOutput (in /usr/lib64/libvirt.so.0.8.2) ==6569== by 0x3B1702DF76: virLogParseOutputs (in /usr/lib64/libvirt.so.0.8.2) ==6569== by 0x3B17076D02: virInitialize (in /usr/lib64/libvirt.so.0.8.2) ==6569== by 0x3B17076E34: virConnectOpenAuth (in /usr/lib64/libvirt.so.0.8.2) ==6569== by 0x41876A: ??? (in /usr/bin/virsh) ==6569== by 0x3B02C1D993: (below main) (in /lib64/libc-2.5.so) ==6569== Address 0x4c53e08 is 0 bytes after a block of size 8 alloc'd ==6569== at 0x4A05F1D: realloc (vg_replace_malloc.c:476) ==6569== by 0x3B1702E37E: virReallocN (in /usr/lib64/libvirt.so.0.8.2) ==6569== by 0x3B17037D87: virFileAbsPath (in /usr/lib64/libvirt.so.0.8.2) ==6569== by 0x3B1702DF27: virLogParseOutputs (in /usr/lib64/libvirt.so.0.8.2) ==6569== by 0x3B17076D02: virInitialize (in /usr/lib64/libvirt.so.0.8.2) ==6569== by 0x3B17076E34: virConnectOpenAuth (in /usr/lib64/libvirt.so.0.8.2) ==6569== by 0x41876A: ??? (in /usr/bin/virsh) ==6569== by 0x3B02C1D993: (below main) (in /lib64/libc-2.5.so) ==6569== error: unable to connect to '/var/run/libvirt/libvirt-sock', libvirtd may need to be started: Connection refused error: failed to connect to the hypervisor ==6569== ==6569== HEAP SUMMARY: ==6569== in use at exit: 21,628 bytes in 386 blocks ==6569== total heap usage: 651 allocs, 265 frees, 407,408 bytes allocated ==6569== ==6569== LEAK SUMMARY: ==6569== definitely lost: 11 bytes in 1 blocks ==6569== indirectly lost: 0 bytes in 0 blocks ==6569== possibly lost: 0 bytes in 0 blocks ==6569== still reachable: 21,617 bytes in 385 blocks ==6569== suppressed: 0 bytes in 0 blocks ==6569== Rerun with --leak-check=full to see details of leaked memory ==6569== ==6569== For counts of detected and suppressed errors, rerun with: -v ==6569== ERROR SUMMARY: 10 errors from 10 contexts (suppressed: 4 from 4) |