In QEMU's USB MTP (Media Transfer Protocol) device emulation, the usb_mtp_deletefn() function in hw/usb/dev-mtp.c iterates over a child object list using QLIST_FOREACH while the recursive call may free the current element. After the free, the macro reads the le_next field from freed memory to advance the iterator.
Replace QLIST_FOREACH with QLIST_FOREACH_SAFE, which saves the next pointer before the iteration body executes. Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3991 Signed-off-by: Tommaso Califano <[email protected]> --- hw/usb/dev-mtp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/usb/dev-mtp.c b/hw/usb/dev-mtp.c index 1d8cfd32dc..c2d36a73cf 100644 --- a/hw/usb/dev-mtp.c +++ b/hw/usb/dev-mtp.c @@ -1152,7 +1152,7 @@ enum { static int usb_mtp_deletefn(MTPState *s, MTPObject *o, uint32_t trans) { - MTPObject *iter, *iter2; + MTPObject *iter, *iter2, *iter2_next; int ret = 0; /* @@ -1161,7 +1161,7 @@ static int usb_mtp_deletefn(MTPState *s, MTPObject *o, uint32_t trans) QLIST_FOREACH(iter, &o->children, list) { if (iter->format == FMT_ASSOCIATION) { - QLIST_FOREACH(iter2, &iter->children, list) { + QLIST_FOREACH_SAFE(iter2, &iter->children, list, iter2_next) { ret |= usb_mtp_deletefn(s, iter2, trans); } } -- 2.55.0
