From patchwork Wed Jul 7 04:40:37 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthew Ruffell X-Patchwork-Id: 1501573 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4GKRZY0Qsgz9t0k; Wed, 7 Jul 2021 14:41:09 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1m0zMt-00057C-Ks; Wed, 07 Jul 2021 04:41:03 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1m0zMo-00053J-6X for kernel-team@lists.ubuntu.com; Wed, 07 Jul 2021 04:40:58 +0000 Received: from mail-pl1-f197.google.com ([209.85.214.197]) by youngberry.canonical.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.93) (envelope-from ) id 1m0zMn-0008Ew-O9 for kernel-team@lists.ubuntu.com; Wed, 07 Jul 2021 04:40:57 +0000 Received: by mail-pl1-f197.google.com with SMTP id x15-20020a170902e04fb02900f5295925dbso372749plx.9 for ; Tue, 06 Jul 2021 21:40:57 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=pZGESlubqnjUV5I2lBZxJC/5dXzjTGUgFYxQjQ+jCYc=; b=QQaQfJJKRYP/1QIHZV5jx5wulZAOGVu8WrqfJt81a/c5n6DvMSPHZ0gWhNrBg7fjA7 t69qCpvw+S/ce34OkMQxg9ehQfwZ6FxzzPmOsHfAmKh3RPRpvq8joQw/iPrOkXXVTYIq nh12ya6uC2jrbmlNdgrkIS2EM+5cCSK5d2FAd97keZB5diG28kcHOE3xcR37hbBPTWpk bcOwM4u+JGpI8DSdYHae5AjUJQKyUvLLr+tERBwxpbyZDJSxDe+zqFz+9Bpn23UVrKfO sXlDMjbPVnOFIF8O0dG8IRR4yC3hFV4viLt1J/kJfOoUtxhqOJ3FV9Q6SJ/NOshJhQC/ JS3A== X-Gm-Message-State: AOAM532VJ0CxzFLDAFxyLYrFZWDKNefpqIP9LyMAsxf8lXfs1SEOMBDt PKUNybHcxmnfy9f379v4BxN8/nCw8ImltP7P2oHQh6XYZcCL7FWBtjaBafnqGbKSekCIwPOQjqj X0Kubfo45sDlhtyUwTyFF1TcHptkfRzqvkF2B+wd5tA== X-Received: by 2002:a63:5966:: with SMTP id j38mr24147615pgm.451.1625632856469; Tue, 06 Jul 2021 21:40:56 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzthpnLU58k7071mQoIZ2vz+Ne/X0SKJAoksMfqC6dansGgIYYOgue6OBMB9ADzLJW4jQ5sDg== X-Received: by 2002:a63:5966:: with SMTP id j38mr24147599pgm.451.1625632856208; Tue, 06 Jul 2021 21:40:56 -0700 (PDT) Received: from desktop.. (125-237-197-94-fibre.sparkbb.co.nz. [125.237.197.94]) by smtp.gmail.com with ESMTPSA id d1sm16861332pfu.6.2021.07.06.21.40.54 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Jul 2021 21:40:55 -0700 (PDT) From: Matthew Ruffell To: kernel-team@lists.ubuntu.com Subject: [SRU][B][PATCH 6/6] btrfs: Detect unbalanced tree with empty leaf before crashing btree operations Date: Wed, 7 Jul 2021 16:40:37 +1200 Message-Id: <20210707044037.37992-7-matthew.ruffell@canonical.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210707044037.37992-1-matthew.ruffell@canonical.com> References: <20210707044037.37992-1-matthew.ruffell@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Qu Wenruo BugLink: https://bugs.launchpad.net/bugs/1934709 [BUG] With crafted image, btrfs will panic at btree operations: kernel BUG at fs/btrfs/ctree.c:3894! invalid opcode: 0000 [#1] SMP PTI CPU: 0 PID: 1138 Comm: btrfs-transacti Not tainted 5.0.0-rc8+ #9 RIP: 0010:__push_leaf_left+0x6b6/0x6e0 RSP: 0018:ffffc0bd4128b990 EFLAGS: 00010246 RAX: 0000000000000000 RBX: ffffa0a4ab8f0e38 RCX: 0000000000000000 RDX: ffffa0a280000000 RSI: 0000000000000000 RDI: ffffa0a4b3814000 RBP: ffffc0bd4128ba38 R08: 0000000000001000 R09: ffffc0bd4128b948 R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000240 R13: ffffa0a4b556fb60 R14: ffffa0a4ab8f0af0 R15: ffffa0a4ab8f0af0 FS: 0000000000000000(0000) GS:ffffa0a4b7a00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f2461c80020 CR3: 000000022b32a006 CR4: 00000000000206f0 Call Trace: ? _cond_resched+0x1a/0x50 push_leaf_left+0x179/0x190 btrfs_del_items+0x316/0x470 btrfs_del_csums+0x215/0x3a0 __btrfs_free_extent.isra.72+0x5a7/0xbe0 __btrfs_run_delayed_refs+0x539/0x1120 btrfs_run_delayed_refs+0xdb/0x1b0 btrfs_commit_transaction+0x52/0x950 ? start_transaction+0x94/0x450 transaction_kthread+0x163/0x190 kthread+0x105/0x140 ? btrfs_cleanup_transaction+0x560/0x560 ? kthread_destroy_worker+0x50/0x50 ret_from_fork+0x35/0x40 Modules linked in: ---[ end trace c2425e6e89b5558f ]--- [CAUSE] The offending csum tree looks like this: checksum tree key (CSUM_TREE ROOT_ITEM 0) node 29741056 level 1 items 14 free 107 generation 19 owner CSUM_TREE ... key (EXTENT_CSUM EXTENT_CSUM 85975040) block 29630464 gen 17 key (EXTENT_CSUM EXTENT_CSUM 89911296) block 29642752 gen 17 <<< key (EXTENT_CSUM EXTENT_CSUM 92274688) block 29646848 gen 17 ... leaf 29630464 items 6 free space 1 generation 17 owner CSUM_TREE item 0 key (EXTENT_CSUM EXTENT_CSUM 85975040) itemoff 3987 itemsize 8 range start 85975040 end 85983232 length 8192 ... leaf 29642752 items 0 free space 3995 generation 17 owner 0 ^ empty leaf invalid owner ^ leaf 29646848 items 1 free space 602 generation 17 owner CSUM_TREE item 0 key (EXTENT_CSUM EXTENT_CSUM 92274688) itemoff 627 itemsize 3368 range start 92274688 end 95723520 length 3448832 So we have a corrupted csum tree where one tree leaf is completely empty, causing unbalanced btree, thus leading to unexpected btree balance error. [FIX] For this particular case, we handle it in two directions to catch it: - Check if the tree block is empty through btrfs_verify_level_key() So that invalid tree blocks won't be read out through btrfs_search_slot() and its variants. - Check 0 tree owner in tree checker NO tree is using 0 as its tree owner, detect it and reject at tree block read time. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=202821 Reviewed-by: Nikolay Borisov Signed-off-by: Qu Wenruo Signed-off-by: David Sterba (backported from commit 62fdaa52a3d00a875da771719b6dc537ca79fce1) [mruffell: context adjustment for "Unknown tree" in check_leaf()] CVE-2019-19036 Signed-off-by: Matthew Ruffell --- fs/btrfs/disk-io.c | 10 ++++++++++ fs/btrfs/tree-checker.c | 7 +++++++ 2 files changed, 17 insertions(+) diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 40e166cb263b..2961283a12c6 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -467,6 +467,16 @@ static int verify_level_key(struct btrfs_fs_info *fs_info, */ if (btrfs_header_generation(eb) > fs_info->last_trans_committed) return 0; + + /* We have @first_key, so this @eb must have at least one item */ + if (btrfs_header_nritems(eb) == 0) { + btrfs_err(fs_info, + "invalid tree nritems, bytenr=%llu nritems=0 expect >0", + eb->start); + WARN_ON(IS_ENABLED(CONFIG_BTRFS_DEBUG)); + return -EUCLEAN; + } + if (found_level) btrfs_node_key_to_cpu(eb, &found_key, 0); else diff --git a/fs/btrfs/tree-checker.c b/fs/btrfs/tree-checker.c index 1e0516b3d1d6..8cc527fd6f5b 100644 --- a/fs/btrfs/tree-checker.c +++ b/fs/btrfs/tree-checker.c @@ -1354,6 +1354,13 @@ static int check_leaf(struct extent_buffer *leaf, bool check_item_data) owner); return -EUCLEAN; } + /* Unknown tree */ + if (owner == 0) { + generic_err(leaf, 0, + "invalid owner, root 0 is not defined"); + return -EUCLEAN; + } + key.objectid = owner; key.type = BTRFS_ROOT_ITEM_KEY; key.offset = (u64)-1;