From patchwork Tue Jan 31 12:11:27 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wiktor Garbacz X-Patchwork-Id: 13122941 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 65691C636D3 for ; Tue, 31 Jan 2023 12:11:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231404AbjAaMLe (ORCPT ); Tue, 31 Jan 2023 07:11:34 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35088 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230244AbjAaMLd (ORCPT ); Tue, 31 Jan 2023 07:11:33 -0500 Received: from mail-yw1-x114a.google.com (mail-yw1-x114a.google.com [IPv6:2607:f8b0:4864:20::114a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4CA1B367C5 for ; Tue, 31 Jan 2023 04:11:32 -0800 (PST) Received: by mail-yw1-x114a.google.com with SMTP id 00721157ae682-5005ef73cf3so163690387b3.2 for ; Tue, 31 Jan 2023 04:11:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:message-id:mime-version:date:from:to:cc:subject :date:message-id:reply-to; bh=epkWVsTjN+Zr3lw8HyawPlURfWhDUej7yTmuN0bxxtQ=; b=Yg7zDNJcofuxAL7B2Zqi1aoU+82S5ZanM52KyHuxMoY9U8h1sfygVNQhRdaIxTXzGs +kI+aj9hnTbBH7N8KQJD5YvtTi6v/aGPdyjnp1hJ8+9QDmXq4TXBRixo8IKwqbVD93Lp 2Doo1HO/QpwcT89nxklTi35WlGsTAwZWP7FL9K9ET9dW3A1bsgHCJXA8TVXQqJ6kNJkP Y2WCDNLDSEtEuKT3n1nJh3XXZirMvzxQaki/ynnDQVTOiVWQsrA5f+6PxbEacB1g7eNh bEtNOxFqVfmH4GNtlwe3lk150+keBI4NBYX8hOCqv0gLsGWReOVEvorfh/feZXJObNLE xXlA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:message-id:mime-version:date:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=epkWVsTjN+Zr3lw8HyawPlURfWhDUej7yTmuN0bxxtQ=; b=oBnFdwCsX4GEWQa/zmKyhHu1XQo2QaNQ5HykyFUw1eACBhr5zcjaikVJaumP3qEpgF SzP22N6m1+mH6GVlN1SzoOslKdOC5buFvtnjP/mpPnUX+wwppNQqLfqV/t9Am6zCm2TS PZrOeF92qAj6u68Iz6IGaUe6ab24zbS8U7L0DuuN7pKyyD6M579IZTcAVfR2pETAJ56v 8zIxTLbxjxSSEuLwk5n3TGg3bAsQ3fmRecqt/+CPH5Kdzf7iqZkJSJNb2ZY7DKORkoDZ hxRZXyC881TROu/gDRxpayf85T+prW2d2nOo1tFO8PhKFW+wWHF3VzC9RVDlcuKBYlT/ 1pyA== X-Gm-Message-State: AFqh2kqy9nohDkSixn/KBhNBdB0MeSFeDqOnuEPziHqARTDrBcLnz8rX jcGBUj0EhFnd62Q5GnE0upjN4HSVuiWO X-Google-Smtp-Source: AMrXdXvX9GhxS/ati3RDazQMdA2bTySyNUm1RfWYXlAnJSCwEFWNc6mhG9DHSOaPCSI2q2a0NA564iZQnv2b X-Received: from localhost ([2a00:79e0:9d:6:8477:8f3f:5b11:3eb9]) (user=wiktorg job=sendgmr) by 2002:a81:1751:0:b0:501:abfc:b927 with SMTP id 78-20020a811751000000b00501abfcb927mr4815110ywx.129.1675167091502; Tue, 31 Jan 2023 04:11:31 -0800 (PST) Date: Tue, 31 Jan 2023 13:11:27 +0100 Mime-Version: 1.0 X-Mailer: git-send-email 2.39.1.456.gfc5497dd1b-goog Message-ID: <20230131121127.466443-1-wiktorg@google.com> Subject: [PATCH RESEND] pipe: avoid creating empty pipe buffers From: Wiktor Garbacz To: Alexander Viro , David Howells Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, Wiktor Garbacz , stable@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org pipe_write cannot be called on notification pipes so post_one_notification cannot race it. Locking and second pipe_full check are thus redundant. This fixes an issue where pipe write could unexpectedly block: // Assume there is no reader or reader polls and uses FIONREAD ioctl // to read all the available bytes. for (int i = 0; i < PIPE_DEF_BUFFERS+1; ++i) { write(pipe_fd, buf_that_efaults, PAGE_SIZE); } // Never reached Fixes: a194dfe6e6f6 ("pipe: Rearrange sequence in pipe_write() to preallocate slot") Cc: stable@vger.kernel.org Signed-off-by: Wiktor Garbacz --- fs/pipe.c | 35 +++++++++-------------------------- 1 file changed, 9 insertions(+), 26 deletions(-) diff --git a/fs/pipe.c b/fs/pipe.c index 42c7ff41c2db..87356a2823cf 100644 --- a/fs/pipe.c +++ b/fs/pipe.c @@ -501,43 +501,26 @@ pipe_write(struct kiocb *iocb, struct iov_iter *from) pipe->tmp_page = page; } - /* Allocate a slot in the ring in advance and attach an - * empty buffer. If we fault or otherwise fail to use - * it, either the reader will consume it or it'll still - * be there for the next write. - */ - spin_lock_irq(&pipe->rd_wait.lock); - - head = pipe->head; - if (pipe_full(head, pipe->tail, pipe->max_usage)) { - spin_unlock_irq(&pipe->rd_wait.lock); - continue; + copied = copy_page_from_iter(page, 0, PAGE_SIZE, from); + if (unlikely(copied < PAGE_SIZE && iov_iter_count(from))) { + if (!ret) + ret = -EFAULT; + break; } - - pipe->head = head + 1; - spin_unlock_irq(&pipe->rd_wait.lock); + ret += copied; /* Insert it into the buffer array */ - buf = &pipe->bufs[head & mask]; buf->page = page; buf->ops = &anon_pipe_buf_ops; buf->offset = 0; - buf->len = 0; + buf->len = copied; if (is_packetized(filp)) buf->flags = PIPE_BUF_FLAG_PACKET; else buf->flags = PIPE_BUF_FLAG_CAN_MERGE; pipe->tmp_page = NULL; - - copied = copy_page_from_iter(page, 0, PAGE_SIZE, from); - if (unlikely(copied < PAGE_SIZE && iov_iter_count(from))) { - if (!ret) - ret = -EFAULT; - break; - } - ret += copied; - buf->offset = 0; - buf->len = copied; + head++; + pipe->head = head; if (!iov_iter_count(from)) break;