Memory corruption/double free related to xml parsing
Software environment
- Operating system: arch linux
- Architecture: x86-64
- kernel version: 6.4.4-arch1-1
- libvirt version: master
- Hypervisor and version: lxc 1:5.0.2
Description of problem
Any unprivileged lxc domain (see below) fails to start on my machine since commit d4b6496f with:
internal error: guest failed to start: Failure in libvirt_lxc startup: unsupported configuration: Unsupported root filesystem type (null)
double free or corruption (out)
In later revisions, including master, it still fails but with a different error:
error : virLXCProcessReportStartupLogError:1129 : internal error: guest failed to start: munmap_chunk(): invalid pointer
Steps to reproduce
- define an lxc domain with idmap. The rootfs need not exist for this bug to reproduce.
- start the domain
Additional notes
I tried some modification to the source code. In function virXMLParseHelper at line 1134, replacing
g_autoptr(xmlParserCtxt) pctxt = NULL;
with
xmlParserCtxt* pctxt = NULL;
prevents this issue from showing up (but leaks memory, i guess).
Instead, if one omits the &ctxt out-parameter to virXMLParse and retrieves it manually, the issue does not show up:
virDomainObj *
virDomainObjParseFile(const char *filename,
virDomainXMLOption *xmlopt,
unsigned int flags)
{
g_autoptr(xmlDoc) xml = NULL;
g_autoptr(xmlXPathContext) ctxt = NULL;
int keepBlanksDefault = xmlKeepBlanksDefault(0);
xml = virXMLParse(filename, NULL, NULL, "domstatus", NULL /* CHANGED HERE: WAS &ctxt */, NULL, false);
xmlNodePtr root = xmlDocGetRootElement(xml); // these 4 lines copied from old versions
if (!(ctxt = virXMLXPathContextNew(xml))) //
return NULL; //
ctxt->node = root; //
xmlKeepBlanksDefault(keepBlanksDefault);
if (!xml)
return NULL;
return virDomainObjParseXML(ctxt, xmlopt, flags);
}
Furthermore if one does pass &ctxt to virXMLParse maintaining the 4 inserted lines (which effectively overwrite ctxt) the issue is still present. This seems to suggests that it is quite tricky to reproduce, and maybe was present, albeit dormant, before commit d4b6496f.
EDIT: i can only reproduce this if the xml contains the <idmap>.
Additional information
domain xml:
<domain type="lxc">
<name>debian12</name>
<uuid>4eb681a8-9fb0-454e-9d30-ef55b0aa4d16</uuid>
<memory unit="KiB">524288</memory>
<currentMemory unit="KiB">524288</currentMemory>
<vcpu placement="static">1</vcpu>
<resource>
<partition>/machine</partition>
</resource>
<os>
<type arch="x86_64">exe</type>
<init>/sbin/init</init>
</os>
<idmap>
<uid start="0" target="165536" count="65536"/>
<gid start="0" target="165536" count="65536"/>
</idmap>
<features>
<privnet/>
</features>
<clock offset="utc"/>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
<devices>
<emulator>/usr/locallibvirt/libexec/libvirt_lxc</emulator>
<filesystem type="mount" accessmode="mapped">
<source dir="/path/to/rootfs"/>
<target dir="/"/>
</filesystem>
<console type="pty">
<target type="lxc" port="0"/>
</console>
</devices>
</domain>