From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.1 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,INCLUDES_PATCH,MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E6E51C433DF for ; Fri, 21 Aug 2020 16:54:14 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id BBFAB20702 for ; Fri, 21 Aug 2020 16:54:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1598028854; bh=1v4KHE1+YA41Db40668v7f3dhI/gEuZHXs9BUxbBK0I=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=OL1BzR6m9p7nKbx598T12+yvoTsCdlh8Qa6ycaAV4hXnTIwA3hL/iOQ69zFI1CuGG bs1frUIAEYEHnIFceeAOOGMwjtEmDImPwX4BJmpYXQL750Kjm9JV4rAArWlp7HloXD sBo4E1w6zPsBHVozngTob3dPydoNm4GvNi6Yq1To= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728084AbgHUQyC (ORCPT ); Fri, 21 Aug 2020 12:54:02 -0400 Received: from mail.kernel.org ([198.145.29.99]:50114 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728312AbgHUQTm (ORCPT ); Fri, 21 Aug 2020 12:19:42 -0400 Received: from sasha-vm.mshome.net (c-73-47-72-35.hsd1.nh.comcast.net [73.47.72.35]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id C95CD22D6E; Fri, 21 Aug 2020 16:18:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1598026733; bh=1v4KHE1+YA41Db40668v7f3dhI/gEuZHXs9BUxbBK0I=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=IIbhi5t7GAxSlIW9deowyFcOn0xJAlU8i6kOxh2vySfP+Velrx0Q8B2sba2hQq1hP CB5Qbw2B24LWAUNTR6aYVK3hLzXtf2B7ly9p5ps8Nz403v37pHZGO743UxAAuFTQ2o gooaqq/2o8p/5Y1hKhAJ/ulbcxnkxmcU5KlW3CDc= From: Sasha Levin To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Xiubo Li , Jeff Layton , Ilya Dryomov , Sasha Levin , ceph-devel@vger.kernel.org Subject: [PATCH AUTOSEL 4.19 36/38] ceph: fix potential mdsc use-after-free crash Date: Fri, 21 Aug 2020 12:18:05 -0400 Message-Id: <20200821161807.348600-36-sashal@kernel.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200821161807.348600-1-sashal@kernel.org> References: <20200821161807.348600-1-sashal@kernel.org> MIME-Version: 1.0 X-stable: review X-Patchwork-Hint: Ignore Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Xiubo Li [ Upstream commit fa9967734227b44acb1b6918033f9122dc7825b9 ] Make sure the delayed work stopped before releasing the resources. cancel_delayed_work_sync() will only guarantee that the work finishes executing if the work is already in the ->worklist. That means after the cancel_delayed_work_sync() returns, it will leave the work requeued if it was rearmed at the end. That can lead to a use after free once the work struct is freed. Fix it by flushing the delayed work instead of trying to cancel it, and ensure that the work doesn't rearm if the mdsc is stopping. URL: https://tracker.ceph.com/issues/46293 Signed-off-by: Xiubo Li Reviewed-by: Jeff Layton Signed-off-by: Ilya Dryomov Signed-off-by: Sasha Levin --- fs/ceph/mds_client.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index a2e903203bf9f..ff2022b07d1de 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -3615,6 +3615,9 @@ static void delayed_work(struct work_struct *work) dout("mdsc delayed_work\n"); ceph_check_delayed_caps(mdsc); + if (mdsc->stopping) + return; + mutex_lock(&mdsc->mutex); renew_interval = mdsc->mdsmap->m_session_timeout >> 2; renew_caps = time_after_eq(jiffies, HZ*renew_interval + @@ -3949,7 +3952,16 @@ void ceph_mdsc_force_umount(struct ceph_mds_client *mdsc) static void ceph_mdsc_stop(struct ceph_mds_client *mdsc) { dout("stop\n"); - cancel_delayed_work_sync(&mdsc->delayed_work); /* cancel timer */ + /* + * Make sure the delayed work stopped before releasing + * the resources. + * + * Because the cancel_delayed_work_sync() will only + * guarantee that the work finishes executing. But the + * delayed work will re-arm itself again after that. + */ + flush_delayed_work(&mdsc->delayed_work); + if (mdsc->mdsmap) ceph_mdsmap_destroy(mdsc->mdsmap); kfree(mdsc->sessions); -- 2.25.1