Received: by 2002:a5b:505:0:0:0:0:0 with SMTP id o5csp25098ybp; Thu, 3 Oct 2019 09:40:17 -0700 (PDT) X-Google-Smtp-Source: APXvYqzZMefGVpNSDEqQWlL1y8t/6LAIdI++s3/a5DZOwaqJ5rVeRr8MwKsybHow+lXxxk7XXvCD X-Received: by 2002:aa7:dcca:: with SMTP id w10mr10551852edu.183.1570120817538; Thu, 03 Oct 2019 09:40:17 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1570120817; cv=none; d=google.com; s=arc-20160816; b=HpjigIv83fmCwMVE//Xam/7K2vGnZo4Gp9yYFWtI4KRhJCkb9fOYLPqYVO2/G7g0bv QMecl7lauqt+28QOY1LcEEjm7zjXMro0nufVCqp1qh45uzoEWTbS5JtbOvDbLqDxp/ZZ UtoLFc1NzW0y1Ugin36d0cnh4ONBXW2cOMhZNAyB5ZNM1QnofS39vF+lTQTMBvpGIUaM bCeFauOItsFz1ONAUGkCfP552muweCNmQ4w/nTco0upjbTkYhyp0f75efZyM6HvgSmqC YgkV12ElhX0uz9+pFz0/wQ568iqHaRo76hqCcIHS6IYdDEgVRcqKDvZsQpJvvCfVLUDO DbWg== 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=kgl9kGybK4E4abGCRQQSy1PkuJQ1CCpGO5C+NHFZ+nc=; b=tVJIAmZ7Z3zM1XCJuCYjrmuF22njHVK7GvrsH3JGw920qqokvAUzdYCTf1mdSZzi2w Qo6+O3xbIxe7gSO6DhM3Ihz58KYNhDuQ9KdXHF6YtSXxi0ENIJS9iDT+vJV0PNzjwoiZ MqVHNNMucOxaXfqK9BdBXT7pJPzSVVH5DWAaIepJqfVppyhAyiRP/XQHi3xuppcagIo8 GUBGUk9qAq97Nr7FyK9+gnvLmyLI7hswkTJkyYLyzx9oXlw+B5BEUgMgXH/38my+ZMFV 3YNLgEcE6MVXjaXiBOotXdH8p9vwJ1YD8u+HwSeDVeeYTSC9ziwW2XERDfzwXmlIxf5V csmg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=KevOMz6Y; 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 j28si2149881eda.161.2019.10.03.09.39.53; Thu, 03 Oct 2019 09:40:17 -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=KevOMz6Y; 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 S2392320AbfJCQi2 (ORCPT + 99 others); Thu, 3 Oct 2019 12:38:28 -0400 Received: from mail.kernel.org ([198.145.29.99]:48128 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2392152AbfJCQi0 (ORCPT ); Thu, 3 Oct 2019 12:38:26 -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 8FD6D20830; Thu, 3 Oct 2019 16:38:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1570120704; bh=5Bb89N5oXv2dC+H8SkfOlk0iDEwpe8+f4bD2UlOZwvg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=KevOMz6YKI33JoRXuopwp3/Cjz3ZOjudnAPBS8AzItqm07GC3G9FNjv3MjG6eZ7QK 0h3RtNFPAid5q9NelFDQ0TJBk7YzUQGKZFVyvp0THK2c4tFeYxFP12eLyqjhG8vyLV uaFK7lhzYPgyBJ2Z49bbUgdFtOSSE+mKpqQm9waI= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Nikolay Borisov , Anand Jain , Filipe Manana , David Sterba Subject: [PATCH 5.2 283/313] Btrfs: fix use-after-free when using the tree modification log Date: Thu, 3 Oct 2019 17:54:21 +0200 Message-Id: <20191003154600.948769282@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: Filipe Manana commit efad8a853ad2057f96664328a0d327a05ce39c76 upstream. At ctree.c:get_old_root(), we are accessing a root's header owner field after we have freed the respective extent buffer. This results in an use-after-free that can lead to crashes, and when CONFIG_DEBUG_PAGEALLOC is set, results in a stack trace like the following: [ 3876.799331] stack segment: 0000 [#1] SMP DEBUG_PAGEALLOC PTI [ 3876.799363] CPU: 0 PID: 15436 Comm: pool Not tainted 5.3.0-rc3-btrfs-next-54 #1 [ 3876.799385] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.12.0-0-ga698c8995f-prebuilt.qemu.org 04/01/2014 [ 3876.799433] RIP: 0010:btrfs_search_old_slot+0x652/0xd80 [btrfs] (...) [ 3876.799502] RSP: 0018:ffff9f08c1a2f9f0 EFLAGS: 00010286 [ 3876.799518] RAX: ffff8dd300000000 RBX: ffff8dd85a7a9348 RCX: 000000038da26000 [ 3876.799538] RDX: 0000000000000000 RSI: ffffe522ce368980 RDI: 0000000000000246 [ 3876.799559] RBP: dae1922adadad000 R08: 0000000008020000 R09: ffffe522c0000000 [ 3876.799579] R10: ffff8dd57fd788c8 R11: 000000007511b030 R12: ffff8dd781ddc000 [ 3876.799599] R13: ffff8dd9e6240578 R14: ffff8dd6896f7a88 R15: ffff8dd688cf90b8 [ 3876.799620] FS: 00007f23ddd97700(0000) GS:ffff8dda20200000(0000) knlGS:0000000000000000 [ 3876.799643] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 3876.799660] CR2: 00007f23d4024000 CR3: 0000000710bb0005 CR4: 00000000003606f0 [ 3876.799682] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 3876.799703] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 3876.799723] Call Trace: [ 3876.799735] ? do_raw_spin_unlock+0x49/0xc0 [ 3876.799749] ? _raw_spin_unlock+0x24/0x30 [ 3876.799779] resolve_indirect_refs+0x1eb/0xc80 [btrfs] [ 3876.799810] find_parent_nodes+0x38d/0x1180 [btrfs] [ 3876.799841] btrfs_check_shared+0x11a/0x1d0 [btrfs] [ 3876.799870] ? extent_fiemap+0x598/0x6e0 [btrfs] [ 3876.799895] extent_fiemap+0x598/0x6e0 [btrfs] [ 3876.799913] do_vfs_ioctl+0x45a/0x700 [ 3876.799926] ksys_ioctl+0x70/0x80 [ 3876.799938] ? trace_hardirqs_off_thunk+0x1a/0x20 [ 3876.799953] __x64_sys_ioctl+0x16/0x20 [ 3876.799965] do_syscall_64+0x62/0x220 [ 3876.799977] entry_SYSCALL_64_after_hwframe+0x49/0xbe [ 3876.799993] RIP: 0033:0x7f23e0013dd7 (...) [ 3876.800056] RSP: 002b:00007f23ddd96ca8 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 [ 3876.800078] RAX: ffffffffffffffda RBX: 00007f23d80210f8 RCX: 00007f23e0013dd7 [ 3876.800099] RDX: 00007f23d80210f8 RSI: 00000000c020660b RDI: 0000000000000003 [ 3876.800626] RBP: 000055fa2a2a2440 R08: 0000000000000000 R09: 00007f23ddd96d7c [ 3876.801143] R10: 00007f23d8022000 R11: 0000000000000246 R12: 00007f23ddd96d80 [ 3876.801662] R13: 00007f23ddd96d78 R14: 00007f23d80210f0 R15: 00007f23ddd96d80 (...) [ 3876.805107] ---[ end trace e53161e179ef04f9 ]--- Fix that by saving the root's header owner field into a local variable before freeing the root's extent buffer, and then use that local variable when needed. Fixes: 30b0463a9394d9 ("Btrfs: fix accessing the root pointer in tree mod log functions") CC: stable@vger.kernel.org # 3.10+ Reviewed-by: Nikolay Borisov Reviewed-by: Anand Jain Signed-off-by: Filipe Manana Reviewed-by: David Sterba Signed-off-by: David Sterba Signed-off-by: Greg Kroah-Hartman --- fs/btrfs/ctree.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c @@ -1343,6 +1343,7 @@ get_old_root(struct btrfs_root *root, u6 struct tree_mod_elem *tm; struct extent_buffer *eb = NULL; struct extent_buffer *eb_root; + u64 eb_root_owner = 0; struct extent_buffer *old; struct tree_mod_root *old_root = NULL; u64 old_generation = 0; @@ -1380,6 +1381,7 @@ get_old_root(struct btrfs_root *root, u6 free_extent_buffer(old); } } else if (old_root) { + eb_root_owner = btrfs_header_owner(eb_root); btrfs_tree_read_unlock(eb_root); free_extent_buffer(eb_root); eb = alloc_dummy_extent_buffer(fs_info, logical); @@ -1396,7 +1398,7 @@ get_old_root(struct btrfs_root *root, u6 if (old_root) { btrfs_set_header_bytenr(eb, eb->start); btrfs_set_header_backref_rev(eb, BTRFS_MIXED_BACKREF_REV); - btrfs_set_header_owner(eb, btrfs_header_owner(eb_root)); + btrfs_set_header_owner(eb, eb_root_owner); btrfs_set_header_level(eb, old_root->level); btrfs_set_header_generation(eb, old_generation); }