Received: by 2002:a5b:505:0:0:0:0:0 with SMTP id o5csp26206ybp; Thu, 3 Oct 2019 09:41:20 -0700 (PDT) X-Google-Smtp-Source: APXvYqztFkikJRrsqMSCGWMMGS0WmOTTnD4lmvr+eUn/6+7lAqq6+8feTjPIbmLbDh25R/ow6OQJ X-Received: by 2002:a05:6402:750:: with SMTP id p16mr10655382edy.188.1570120880107; Thu, 03 Oct 2019 09:41:20 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1570120880; cv=none; d=google.com; s=arc-20160816; b=AsTT4xWpygVlQT+awyYuU/sYRbnUeUEA3gISd7IQH0CsQzwNFbQH8lcAQh8USC1VQj VxCsBBx1zQYLp+Y4fM1Vyey04Z2rvkH9Lu+XHx8sfN9rNey9+GmKCloEyRhD5zkm1g4/ Z1qW8EoOTEluS4thfsoQSkHaugDOsG+wbPk7qWjihAs/BEdqQfr2IyaFpBzSMNCpYthN hM2j/tx/IcM96gEuIXRdPLAvj8KPPWTEg9pZQyYHR3RfxaKbpBnXX2rzucW1nuYFeDtl VDiAP64cMBN5UuNzQ9eBxTH9ccNUbI+J9bemlHpj+ZOdtInAgMhi5pV7GYoq5yzeqra/ 14zA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=nBqXravFYl/pulx7hCC6Iv6bAKQ9TssbxHelBypg6qA=; b=nLJP6YvCDT18pMtQnbhBR5iUBBHMec7KO3+RmCpw7LPZeyI+O7MkjAyjOnSjFN1Mzb 5N/vZ2l65XnsOZzU7OWIDHqAkQqcnoVUzsxLTzgsK14+zIF7rb1uOy3W5qfaa9zutnbu dZWCZ+H/BBaNcvQVG7Rvgju0Y2r0eJI4aFX1946XFE90Cvccx7atIq4EWjOLO5PdVZ8n msy0iBOBaTFip1NFGKCdjMappUnj7kmlmoZQpXQdEND2jd5kgf5vXjmP/kAbQumPRAL1 PS5at5iwtmEZc0o39bHfFqcOnAZye5BNEtTNn4r93X7X8ov3/4Nf7VL8l4C321XPNhr8 7qOg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=03XJpzUJ; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id s14si2006765edc.83.2019.10.03.09.40.55; Thu, 03 Oct 2019 09:41:20 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=03XJpzUJ; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2391906AbfJCQiM (ORCPT + 99 others); Thu, 3 Oct 2019 12:38:12 -0400 Received: from mail.kernel.org ([198.145.29.99]:47760 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2404781AbfJCQiJ (ORCPT ); Thu, 3 Oct 2019 12:38:09 -0400 Received: from localhost (83-86-89-107.cable.dynamic.v4.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 60CD320830; Thu, 3 Oct 2019 16:38:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1570120688; bh=OZi46/LEW9kyWJKIzQu9CrXEOyEZid01NguqZCh4Q1M=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=03XJpzUJEr8sT7KBllJJZGH4aHf6dkGszRPfQDDOnDXtMZMzo0PTSAtDqC0Ye+/hj n77ZUS0sWFtomaScEyuBaaPIvxdtxpyaMtzKM7CyeDSeJ8xNG9ugJ/JCh6HH/li24J fkPczQiNU7FZqPKMCw60noDNQev6Tu3qGDeyCB7w= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Qu Wenruo , David Sterba Subject: [PATCH 5.2 287/313] btrfs: qgroup: Fix reserved data space leak if we have multiple reserve calls Date: Thu, 3 Oct 2019 17:54:25 +0200 Message-Id: <20191003154601.353973257@linuxfoundation.org> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20191003154533.590915454@linuxfoundation.org> References: <20191003154533.590915454@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Qu Wenruo commit d4e204948fe3e0dc8e1fbf3f8f3290c9c2823be3 upstream. [BUG] The following script can cause btrfs qgroup data space leak: mkfs.btrfs -f $dev mount $dev -o nospace_cache $mnt btrfs subv create $mnt/subv btrfs quota en $mnt btrfs quota rescan -w $mnt btrfs qgroup limit 128m $mnt/subv for (( i = 0; i < 3; i++)); do # Create 3 64M holes for latter fallocate to fail truncate -s 192m $mnt/subv/file xfs_io -c "pwrite 64m 4k" $mnt/subv/file > /dev/null xfs_io -c "pwrite 128m 4k" $mnt/subv/file > /dev/null sync # it's supposed to fail, and each failure will leak at least 64M # data space xfs_io -f -c "falloc 0 192m" $mnt/subv/file &> /dev/null rm $mnt/subv/file sync done # Shouldn't fail after we removed the file xfs_io -f -c "falloc 0 64m" $mnt/subv/file [CAUSE] Btrfs qgroup data reserve code allow multiple reservations to happen on a single extent_changeset: E.g: btrfs_qgroup_reserve_data(inode, &data_reserved, 0, SZ_1M); btrfs_qgroup_reserve_data(inode, &data_reserved, SZ_1M, SZ_2M); btrfs_qgroup_reserve_data(inode, &data_reserved, 0, SZ_4M); Btrfs qgroup code has its internal tracking to make sure we don't double-reserve in above example. The only pattern utilizing this feature is in the main while loop of btrfs_fallocate() function. However btrfs_qgroup_reserve_data()'s error handling has a bug in that on error it clears all ranges in the io_tree with EXTENT_QGROUP_RESERVED flag but doesn't free previously reserved bytes. This bug has a two fold effect: - Clearing EXTENT_QGROUP_RESERVED ranges This is the correct behavior, but it prevents btrfs_qgroup_check_reserved_leak() to catch the leakage as the detector is purely EXTENT_QGROUP_RESERVED flag based. - Leak the previously reserved data bytes. The bug manifests when N calls to btrfs_qgroup_reserve_data are made and the last one fails, leaking space reserved in the previous ones. [FIX] Also free previously reserved data bytes when btrfs_qgroup_reserve_data fails. Fixes: 524725537023 ("btrfs: qgroup: Introduce btrfs_qgroup_reserve_data function") CC: stable@vger.kernel.org # 4.4+ Signed-off-by: Qu Wenruo Signed-off-by: David Sterba Signed-off-by: Greg Kroah-Hartman --- fs/btrfs/qgroup.c | 3 +++ 1 file changed, 3 insertions(+) --- a/fs/btrfs/qgroup.c +++ b/fs/btrfs/qgroup.c @@ -3425,6 +3425,9 @@ cleanup: while ((unode = ulist_next(&reserved->range_changed, &uiter))) clear_extent_bit(&BTRFS_I(inode)->io_tree, unode->val, unode->aux, EXTENT_QGROUP_RESERVED, 0, 0, NULL); + /* Also free data bytes of already reserved one */ + btrfs_qgroup_free_refroot(root->fs_info, root->root_key.objectid, + orig_reserved, BTRFS_QGROUP_RSV_DATA); extent_changeset_release(reserved); return ret; }