From patchwork Tue Oct 13 18:06:48 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chris Mason X-Patchwork-Id: 7387931 Return-Path: X-Original-To: patchwork-linux-btrfs@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id D9C529F36A for ; Tue, 13 Oct 2015 18:07:08 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id E43952073E for ; Tue, 13 Oct 2015 18:07:07 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id D20402073D for ; Tue, 13 Oct 2015 18:07:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932926AbbJMSG6 (ORCPT ); Tue, 13 Oct 2015 14:06:58 -0400 Received: from mx0a-00082601.pphosted.com ([67.231.145.42]:21311 "EHLO mx0a-00082601.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932547AbbJMSG5 (ORCPT ); Tue, 13 Oct 2015 14:06:57 -0400 Received: from pps.filterd (m0044010.ppops.net [127.0.0.1]) by mx0a-00082601.pphosted.com (8.15.0.59/8.15.0.59) with SMTP id t9DI4uO7003831; Tue, 13 Oct 2015 11:06:51 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=fb.com; h=date : from : to : subject : message-id : mime-version : content-type; s=facebook; bh=VoE5wHC/LV3zJH9TAEUstTelZYIMpI5r/HzmSgL58js=; b=OU9+0ejaKA6As3cuG3BeSsHfHyj0mlxKWBh9lVa23Z/kv/9MsHGxZ1b12zpISNM185Uv mk/KrypS01RIijreL5+Dsv0B6D9mO55gXedNKJZdLCPVQXa4YeF2O8mEC41k87Pj9bPA Gx2p0DZygmLnAt04bCYw3n4vlvSTDBONHKg= Received: from mail.thefacebook.com ([199.201.64.23]) by mx0a-00082601.pphosted.com with ESMTP id 1xg5gyhxnt-1 (version=TLSv1/SSLv3 cipher=AES128-SHA bits=128 verify=NOT); Tue, 13 Oct 2015 11:06:51 -0700 Received: from localhost (192.168.52.123) by mail.thefacebook.com (192.168.16.24) with Microsoft SMTP Server (TLS) id 14.3.248.2; Tue, 13 Oct 2015 11:06:50 -0700 Date: Tue, 13 Oct 2015 14:06:48 -0400 From: Chris Mason To: , Mark Fasheh , Filipe Manana Subject: [PATCH] btrfs: fix use after free iterating extrefs Message-ID: <20151013180648.GC4890@ret.masoncoding.com> Mail-Followup-To: Chris Mason , linux-btrfs@vger.kernel.org, Mark Fasheh , Filipe Manana MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.23.1 (2014-03-12) X-Originating-IP: [192.168.52.123] X-Proofpoint-Spam-Reason: safe X-FB-Internal: Safe X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2015-10-13_15:, , signatures=0 Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org X-Spam-Status: No, score=-6.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID,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 The code for btrfs inode-resolve has never worked properly for files with enough hard links to trigger extrefs. It was trying to get the leaf out of a path after freeing the path: btrfs_release_path(path); leaf = path->nodes[0]; item_size = btrfs_item_size_nr(leaf, slot); The fix here is to use the extent buffer we cloned just a little higher up to avoid deadlocks caused by using the leaf in the path. Signed-off-by: Chris Mason cc: stable@vger.kernel.org # v3.7+ cc: Mark Fasheh Reviewed-by: Filipe Manana Reviewed-by: Mark Fasheh --- fs/btrfs/backref.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c index ecbc63d..9a2ec79 100644 --- a/fs/btrfs/backref.c +++ b/fs/btrfs/backref.c @@ -1828,7 +1828,6 @@ static int iterate_inode_extrefs(u64 inum, struct btrfs_root *fs_root, int found = 0; struct extent_buffer *eb; struct btrfs_inode_extref *extref; - struct extent_buffer *leaf; u32 item_size; u32 cur_offset; unsigned long ptr; @@ -1856,9 +1855,8 @@ static int iterate_inode_extrefs(u64 inum, struct btrfs_root *fs_root, btrfs_set_lock_blocking_rw(eb, BTRFS_READ_LOCK); btrfs_release_path(path); - leaf = path->nodes[0]; - item_size = btrfs_item_size_nr(leaf, slot); - ptr = btrfs_item_ptr_offset(leaf, slot); + item_size = btrfs_item_size_nr(eb, slot); + ptr = btrfs_item_ptr_offset(eb, slot); cur_offset = 0; while (cur_offset < item_size) { @@ -1872,7 +1870,7 @@ static int iterate_inode_extrefs(u64 inum, struct btrfs_root *fs_root, if (ret) break; - cur_offset += btrfs_inode_extref_name_len(leaf, extref); + cur_offset += btrfs_inode_extref_name_len(eb, extref); cur_offset += sizeof(*extref); } btrfs_tree_read_unlock_blocking(eb);