From patchwork Sat Oct 11 07:14:25 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?B?WmhhbmcgSGFveXU=?= X-Patchwork-Id: 5068371 Return-Path: X-Original-To: patchwork-kvm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id BE5C6C11AC for ; Sat, 11 Oct 2014 07:14:42 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id EB220201DD for ; Sat, 11 Oct 2014 07:14:41 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 856F9201D3 for ; Sat, 11 Oct 2014 07:14:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751592AbaJKHOc (ORCPT ); Sat, 11 Oct 2014 03:14:32 -0400 Received: from smtp.sanfor.com ([58.251.49.30]:50173 "EHLO mail.sangfor.com" rhost-flags-OK-FAIL-OK-OK) by vger.kernel.org with ESMTP id S1751539AbaJKHOa (ORCPT ); Sat, 11 Oct 2014 03:14:30 -0400 Received: from localhost (mail.sangfor.com [127.0.0.1]) by mail.sangfor.com (Postfix) with ESMTP id 92A4D17C0236; Sat, 11 Oct 2014 14:56:24 +0800 (CST) Received: from mail.sangfor.com ([127.0.0.1]) by localhost (mail.sangfor.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id olDgxsQVaDGb; Sat, 11 Oct 2014 14:56:24 +0800 (CST) Received: from vv-PC (unknown [10.10.6.254]) by mail.sangfor.com (Postfix) with ESMTPA id 31CE217C0233; Sat, 11 Oct 2014 14:56:24 +0800 (CST) Date: Sat, 11 Oct 2014 15:14:25 +0800 From: "Zhang Haoyu" To: "qemu-devel" Cc: "kvm" , "Kevin Wolf" , "Stefan Hajnoczi" Subject: [PATCH] qcow2: fix double-free of Qcow2DiscardRegion in qcow2_process_discards Message-ID: <201410111514227991260@sangfor.com> X-mailer: Foxmail 6, 15, 201, 20 [cn] Mime-Version: 1.0 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP In qcow2_update_snapshot_refcount -> qcow2_process_discards() -> bdrv_discard() may free the Qcow2DiscardRegion which is referenced by "next" pointer in qcow2_process_discards() now, in next iteration, d = next, so g_free(d) will double-free this Qcow2DiscardRegion. qcow2_snapshot_delete |- qcow2_update_snapshot_refcount |-- qcow2_process_discards |--- bdrv_discard |---- aio_poll |----- aio_dispatch |------ bdrv_co_io_em_complete |------- qemu_coroutine_enter(co->coroutine, NULL); <=== coroutine entry is bdrv_co_do_rw |--- g_free(d) <== free first Qcow2DiscardRegion is okay |--- d = next; <== this set is done in QTAILQ_FOREACH_SAFE() macro. |--- g_free(d); <== double-free will happen if during previous iteration, bdrv_discard had free this object. bdrv_co_do_rw |- bdrv_co_do_writev |-- bdrv_co_do_pwritev |--- bdrv_aligned_pwritev |---- qcow2_co_writev |----- qcow2_alloc_cluster_link_l2 |------ qcow2_free_any_clusters |------- qcow2_free_clusters |-------- update_refcount |--------- qcow2_process_discards |---------- g_free(d) <== In next iteration, this Qcow2DiscardRegion will be double-free. Signed-off-by: Zhang Haoyu Signed-off-by: Fu Xuewei --- block/qcow2-refcount.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c index 2bcaaf9..3b759a3 100644 --- a/block/qcow2-refcount.c +++ b/block/qcow2-refcount.c @@ -462,9 +462,9 @@ fail_block: void qcow2_process_discards(BlockDriverState *bs, int ret) { BDRVQcowState *s = bs->opaque; - Qcow2DiscardRegion *d, *next; + Qcow2DiscardRegion *d; - QTAILQ_FOREACH_SAFE(d, &s->discards, next, next) { + while ((d = QTAILQ_FIRST(&s->discards)) != NULL) { QTAILQ_REMOVE(&s->discards, d, next); /* Discard is optional, ignore the return value */