mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-11 23:37:42 +00:00
a7483a5631
Regression introduced in commit e6b68d7 (Nov 2010). Prior to that point, handlesAlloc was always a multiple of EVENT_ALLOC_EXTENT (10), and was an int (so even if the subtraction had been able to wrap, a negative value would be less than the count not try to free the handles array). But after that point, VIR_RESIZE_N made handlesAlloc grow geometrically (with a pattern of 10, 20, 30, 45 for the handles array) but still freed in multiples of EVENT_ALLOC_EXTENT; and the count changed to size_t. Which means that after 31 handles have been created, then 30 handles destroyed, handlesAlloc is 5 while handlesCount is 1, and since (size_t)(1 - 5) is indeed greater than 1, this then tried to free 10 elements, which had the awful effect of nuking the handles array while there were still live handles. Nuking live handles puts libvirtd in an inconsistent state, and was easily reproducible by starting and then stopping 60 faqemu guests. * daemon/event.c (virEventCleanupTimeouts, virEventCleanupHandles): Avoid integer wrap-around causing us to delete the entire array while entries are still active. * tests/eventtest.c (mymain): Expose the bug.