Received: by 2002:a25:d7c1:0:0:0:0:0 with SMTP id o184csp4093911ybg; Fri, 25 Oct 2019 13:13:53 -0700 (PDT) X-Google-Smtp-Source: APXvYqx1acBxvcEI+S7Qgivggrn512I8FLgB9sDuHeiSPfoyL8bUoBMnwzFF8GIdcv9PsTnXi1Vr X-Received: by 2002:a05:6402:2042:: with SMTP id bc2mr6134125edb.12.1572034433359; Fri, 25 Oct 2019 13:13:53 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1572034433; cv=none; d=google.com; s=arc-20160816; b=OW1zdenvOviAyOceN0M4dbZXkac0F3XCweYicjdb5tb1k5So7JSWexwIkgVh1m2w6h /HVCj238DwB2VUJwDlAAEQIKbABD2pzsXEaYdFSolEFkEf2l814C/WUQez4QbncHX+dM nXNih/4Zhb02ZPqjeGm9/o6bMrKc+ssb6BvT9OqUwWv20yfQ6+GPfxlMNWaCM7pkPLBu E+cSIZWFl6ugaA/6ico+SdOb16DozHHfWCpWuWKb9ohI7cVZEMuDVbfjA8pVrYK+T13M AZy5jdrvEcYegMFOIEj/Ym0dVc1xPHWMMvCV4m3TNZ9t6I1d2Dn6cJ3w+zMm822CH9Pu mlQQ== 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 :references:in-reply-to:message-id:date:subject:cc:to:from; bh=kqACiSZtmXv+0W7dVrFW4cLVIgZsyWbLLfLJhMTFrh4=; b=Gf2InRazDUlSu0VJsPtcvuADxkTqgizrhz3VBamtH5ahIkEibBMFyr4Q6xA2biyjUj dXjsMZIOXJ3auWYl6H7tOjWwSsSyte/wsyLPzGUy7msw8Xl+4DCNyJrxu1X6bRkXfUOk 7h/MbyBVKezi6u7CVc05NJIMuldH1zOYHfScnYmZtXN1pjS3XevWmb7ol0UTzjpoObc5 LiKLeysY14OmoRpmhX+XOfZW7tqnJc36j+I3T552rFh9Nm/LCUDplvCUUkDFIJQPnQqc Btnmj/A7CX9lYz5zxAGlPHEdfWkEpL1LDqwKM/3gOxUDZ4QTTaG9vZJSbkYwKzNIeg5c Sywg== ARC-Authentication-Results: i=1; mx.google.com; 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 v16si235544edc.142.2019.10.25.13.13.29; Fri, 25 Oct 2019 13:13:53 -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; 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 S2439413AbfJYNF2 (ORCPT + 99 others); Fri, 25 Oct 2019 09:05:28 -0400 Received: from mx2.suse.de ([195.135.220.15]:36596 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S2439284AbfJYNF2 (ORCPT ); Fri, 25 Oct 2019 09:05:28 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 4D95CAFA8; Fri, 25 Oct 2019 13:05:26 +0000 (UTC) From: Luis Henriques To: Jeff Layton , Sage Weil , Ilya Dryomov , "Yan, Zheng" Cc: ceph-devel@vger.kernel.org, linux-kernel@vger.kernel.org, Luis Henriques Subject: [PATCH v2] ceph: Fix use-after-free in __ceph_remove_cap Date: Fri, 25 Oct 2019 14:05:24 +0100 Message-Id: <20191025130524.31755-1-lhenriques@suse.com> In-Reply-To: <9c1fe73500ca7dece15c73d7534b9e0ec417c83a.camel@kernel.org> References: <9c1fe73500ca7dece15c73d7534b9e0ec417c83a.camel@kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org KASAN reports a use-after-free when running xfstest generic/531, with the following trace: [ 293.903362] kasan_report+0xe/0x20 [ 293.903365] rb_erase+0x1f/0x790 [ 293.903370] __ceph_remove_cap+0x201/0x370 [ 293.903375] __ceph_remove_caps+0x4b/0x70 [ 293.903380] ceph_evict_inode+0x4e/0x360 [ 293.903386] evict+0x169/0x290 [ 293.903390] __dentry_kill+0x16f/0x250 [ 293.903394] dput+0x1c6/0x440 [ 293.903398] __fput+0x184/0x330 [ 293.903404] task_work_run+0xb9/0xe0 [ 293.903410] exit_to_usermode_loop+0xd3/0xe0 [ 293.903413] do_syscall_64+0x1a0/0x1c0 [ 293.903417] entry_SYSCALL_64_after_hwframe+0x44/0xa9 This happens because __ceph_remove_cap() may queue a cap release (__ceph_queue_cap_release) which can be scheduled before that cap is removed from the inode list with rb_erase(&cap->ci_node, &ci->i_caps); And, when this finally happens, the use-after-free will occur. This can be fixed by removing the cap from the inode list before being removed from the session list, and thus eliminating the risk of an UAF. Signed-off-by: Luis Henriques --- Hi! So, after spending some time trying to find possible races throught code review and testing, I modified the fix according to Jeff's suggestion. Cheers, Luis fs/ceph/caps.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index d3b9c9d5c1bd..a9ce858c37d0 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c @@ -1058,6 +1058,11 @@ void __ceph_remove_cap(struct ceph_cap *cap, bool queue_release) dout("__ceph_remove_cap %p from %p\n", cap, &ci->vfs_inode); + /* remove from inode list */ + rb_erase(&cap->ci_node, &ci->i_caps); + if (ci->i_auth_cap == cap) + ci->i_auth_cap = NULL; + /* remove from session list */ spin_lock(&session->s_cap_lock); if (session->s_cap_iterator == cap) { @@ -1091,11 +1096,6 @@ void __ceph_remove_cap(struct ceph_cap *cap, bool queue_release) spin_unlock(&session->s_cap_lock); - /* remove from inode list */ - rb_erase(&cap->ci_node, &ci->i_caps); - if (ci->i_auth_cap == cap) - ci->i_auth_cap = NULL; - if (removed) ceph_put_cap(mdsc, cap);