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=-6.8 required=3.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,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 C4297C352A3 for ; Mon, 10 Feb 2020 13:32:00 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 99BF720715 for ; Mon, 10 Feb 2020 13:32:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1581341520; bh=4KXAlEUprwiRHITH1OVqudzMd7YQXD6DXCaRbJRCIao=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=Novoo1+RGO22hZ8oGofEwLa7k4HvJS9ePVghY6JB2pioZfNTUzFzzCIbV+1XT28op 74cPYRbcH9l6bSEDELHsv0ehjljPplAAzncxs3T21DXHrI3FNEREgvdjlQc3h1u314 2toHzkVsJphhXt7HhOK243htMzacMvy9wYwM0t70= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731357AbgBJNb7 (ORCPT ); Mon, 10 Feb 2020 08:31:59 -0500 Received: from mail.kernel.org ([198.145.29.99]:54184 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728173AbgBJMf4 (ORCPT ); Mon, 10 Feb 2020 07:35:56 -0500 Received: from localhost (unknown [209.37.97.194]) (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 4D56520863; Mon, 10 Feb 2020 12:35:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1581338155; bh=4KXAlEUprwiRHITH1OVqudzMd7YQXD6DXCaRbJRCIao=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=nuLzgBd4JiC9Ua9m1YZH1/T7T3h+BsHKV0P6kCtViI7vgEPtLSTao28MjVkfZyvVY p9kaVZpWvM3l4NMzLYLaAZHl2rhOV5K2jagC5VqFjyepwVPR+QI0RzNoX+mPh1nJA2 CDr7aiTu4GrdgjtXw3BbsORrhmSpjR9bZwF1VxXI= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Jeff Moyer , Jens Axboe Subject: [PATCH 4.19 122/195] aio: prevent potential eventfd recursion on poll Date: Mon, 10 Feb 2020 04:33:00 -0800 Message-Id: <20200210122317.328504019@linuxfoundation.org> X-Mailer: git-send-email 2.25.0 In-Reply-To: <20200210122305.731206734@linuxfoundation.org> References: <20200210122305.731206734@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: Jens Axboe commit 01d7a356872eec22ef34a33a5f9cfa917d145468 upstream. If we have nested or circular eventfd wakeups, then we can deadlock if we run them inline from our poll waitqueue wakeup handler. It's also possible to have very long chains of notifications, to the extent where we could risk blowing the stack. Check the eventfd recursion count before calling eventfd_signal(). If it's non-zero, then punt the signaling to async context. This is always safe, as it takes us out-of-line in terms of stack and locking context. Cc: stable@vger.kernel.org # 4.19+ Reviewed-by: Jeff Moyer Signed-off-by: Jens Axboe Signed-off-by: Greg Kroah-Hartman --- fs/aio.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) --- a/fs/aio.c +++ b/fs/aio.c @@ -1600,6 +1600,14 @@ static int aio_fsync(struct fsync_iocb * return 0; } +static void aio_poll_put_work(struct work_struct *work) +{ + struct poll_iocb *req = container_of(work, struct poll_iocb, work); + struct aio_kiocb *iocb = container_of(req, struct aio_kiocb, poll); + + iocb_put(iocb); +} + static void aio_poll_complete_work(struct work_struct *work) { struct poll_iocb *req = container_of(work, struct poll_iocb, work); @@ -1664,6 +1672,8 @@ static int aio_poll_wake(struct wait_que list_del_init(&req->wait.entry); if (mask && spin_trylock_irqsave(&iocb->ki_ctx->ctx_lock, flags)) { + struct kioctx *ctx = iocb->ki_ctx; + /* * Try to complete the iocb inline if we can. Use * irqsave/irqrestore because not all filesystems (e.g. fuse) @@ -1673,8 +1683,14 @@ static int aio_poll_wake(struct wait_que list_del(&iocb->ki_list); iocb->ki_res.res = mangle_poll(mask); req->done = true; - spin_unlock_irqrestore(&iocb->ki_ctx->ctx_lock, flags); - iocb_put(iocb); + if (iocb->ki_eventfd && eventfd_signal_count()) { + iocb = NULL; + INIT_WORK(&req->work, aio_poll_put_work); + schedule_work(&req->work); + } + spin_unlock_irqrestore(&ctx->ctx_lock, flags); + if (iocb) + iocb_put(iocb); } else { schedule_work(&req->work); }