From patchwork Tue Jan 12 00:30:12 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Willem de Bruijn X-Patchwork-Id: 12011935 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=-15.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable 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 30472C43381 for ; Tue, 12 Jan 2021 00:33:24 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 0179122CB8 for ; Tue, 12 Jan 2021 00:33:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728524AbhALAdB (ORCPT ); Mon, 11 Jan 2021 19:33:01 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54346 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726554AbhALAbD (ORCPT ); Mon, 11 Jan 2021 19:31:03 -0500 Received: from mail-io1-xd2a.google.com (mail-io1-xd2a.google.com [IPv6:2607:f8b0:4864:20::d2a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6AD0BC061794; Mon, 11 Jan 2021 16:30:23 -0800 (PST) Received: by mail-io1-xd2a.google.com with SMTP id q1so486161ion.8; Mon, 11 Jan 2021 16:30:23 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=6DEYbNHjZWOz6bmEdkUW7JB71u8LtpaVhWTfcACEFps=; b=aplyj3S/LR+szlAbiCz+u4zSfrKX+vYOBjErzLa63S+eozb+TFVEgr6a2yEYfKC1sa HyAgXbdimI0mYce59reSgOw4n+8NYnFKbwHzV/keS67i7uX9igMONHS7EQQOCvWOxE3f QGyIXcyI1pA33zKXnT944xT0x2OnQQT0v7oAETZg00TSET7Q5lBQkgD9GS9Ydwz/YVJQ 0eJP2N7ZgLtX9XcyHPe1hMv8HyNT7Al0D7Fkltbuj9Ax3hB4he6r3feFBNa5aHCHNO9K XtIkqoYRas1sEh50Dx90ir+w5NRNi+9eONji4qGar4fRwn3K4M+353wA3mouLs1QAMyV 2eQg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=6DEYbNHjZWOz6bmEdkUW7JB71u8LtpaVhWTfcACEFps=; b=JyeB4HF8QiAtAKUDlITrJh9hQ0mqJjCAw21zT9a0CKQQZ4bu8YDztLnZjfnyRLE6aE MUlbLXklMPnMIHTu5bDqXB+DrY/LzAatbVNTr44YYflEjqX9afWHzhXoYFa+JhmiheOZ zblNrXTNxJa/PwyZYmSm4dpQFDEBPrCBZKi1RReWYg7j9TwazSg9FuZBysYtfUaSPsPy DdjIZ4P/D0toZy7PNzSAe888YQ6cmg5UTiCZgEAcajf5YNlyDhKSyYz6OM1h/keOOeuK VijK+QwL/CY5dZogdz9gvJlZKeSOZqVOCvQyGqTfAwb0gQp0WWw9fslVkGsGkuNB4jFY xPbA== X-Gm-Message-State: AOAM531HSFbZUneRGeUbc1GDBr3ALnIBKq9wuH7S2P5UWfn97srknGGK K1KecjSatOTh2F36M/K4Jlqj6gk9NC0= X-Google-Smtp-Source: ABdhPJzol9tuNj0EM+RGeF5Pp/6MJTBlNgwGN/6IP+cUOq3Wok0fmYHYoKz5CXM0W+aB3UWS1NpX1g== X-Received: by 2002:a5d:9e0a:: with SMTP id h10mr1305223ioh.149.1610411422496; Mon, 11 Jan 2021 16:30:22 -0800 (PST) Received: from willemb.nyc.corp.google.com ([2620:0:1003:312:f693:9fff:fef4:3e8a]) by smtp.gmail.com with ESMTPSA id z10sm741723ioi.47.2021.01.11.16.30.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 11 Jan 2021 16:30:21 -0800 (PST) From: Willem de Bruijn To: linux-fsdevel@vger.kernel.org Cc: linux-kernel@vger.kernel.org, viro@zeniv.linux.org.uk, akpm@linux-foundation.org, willy@infradead.org, arnd@kernel.org, Willem de Bruijn Subject: [PATCH 1/6] selftests/filesystems: add initial select and poll selftest Date: Mon, 11 Jan 2021 19:30:12 -0500 Message-Id: <20210112003017.4010304-2-willemdebruijn.kernel@gmail.com> X-Mailer: git-send-email 2.30.0.284.gd98b1dd5eaa7-goog In-Reply-To: <20210112003017.4010304-1-willemdebruijn.kernel@gmail.com> References: <20210112003017.4010304-1-willemdebruijn.kernel@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org From: Willem de Bruijn Add initial code coverage for select, pselect, poll and ppoll. Open a socketpair and wait for a read event. 1. run with data waiting 2. run to timeout, if a (short) timeout is specified. Also optionally pass sigset to pselect and ppoll, to exercise all datapaths. Build with -m32, -mx32 and -m64 to cover all the various compat and 32/64-bit time syscall implementations. Signed-off-by: Willem de Bruijn --- .../testing/selftests/filesystems/.gitignore | 1 + tools/testing/selftests/filesystems/Makefile | 2 +- .../selftests/filesystems/selectpoll.c | 207 ++++++++++++++++++ 3 files changed, 209 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/filesystems/selectpoll.c diff --git a/tools/testing/selftests/filesystems/.gitignore b/tools/testing/selftests/filesystems/.gitignore index f0c0ff20d6cf..d4a2e50475ea 100644 --- a/tools/testing/selftests/filesystems/.gitignore +++ b/tools/testing/selftests/filesystems/.gitignore @@ -1,3 +1,4 @@ # SPDX-License-Identifier: GPL-2.0-only dnotify_test devpts_pts +selectpoll diff --git a/tools/testing/selftests/filesystems/Makefile b/tools/testing/selftests/filesystems/Makefile index 129880fb42d3..8de184865fa4 100644 --- a/tools/testing/selftests/filesystems/Makefile +++ b/tools/testing/selftests/filesystems/Makefile @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 CFLAGS += -I../../../../usr/include/ -TEST_GEN_PROGS := devpts_pts +TEST_GEN_PROGS := devpts_pts selectpoll TEST_GEN_PROGS_EXTENDED := dnotify_test include ../lib.mk diff --git a/tools/testing/selftests/filesystems/selectpoll.c b/tools/testing/selftests/filesystems/selectpoll.c new file mode 100644 index 000000000000..315da0786a6c --- /dev/null +++ b/tools/testing/selftests/filesystems/selectpoll.c @@ -0,0 +1,207 @@ +// SPDX-License-Identifier: GPL-2.0 + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include "../kselftest_harness.h" + +const unsigned long timeout_us = 5UL * 1000; +const unsigned long timeout_ns = timeout_us * 1000; + +/* (p)select: basic invocation, optionally with data waiting */ + +FIXTURE(select_basic) +{ + fd_set readfds; + int sfd[2]; +}; + +FIXTURE_SETUP(select_basic) +{ + ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, self->sfd), 0); + + FD_ZERO(&self->readfds); + FD_SET(self->sfd[0], &self->readfds); + FD_SET(self->sfd[1], &self->readfds); +} + +FIXTURE_TEARDOWN(select_basic) +{ + /* FD_ISSET(self->sfd[0] tested in TEST_F: depends on timeout */ + ASSERT_EQ(FD_ISSET(self->sfd[1], &self->readfds), 0); + + EXPECT_EQ(close(self->sfd[0]), 0); + EXPECT_EQ(close(self->sfd[1]), 0); +} + +TEST_F(select_basic, select) +{ + ASSERT_EQ(write(self->sfd[1], "w", 1), 1); + ASSERT_EQ(select(self->sfd[1] + 1, &self->readfds, + NULL, NULL, NULL), 1); + ASSERT_NE(FD_ISSET(self->sfd[0], &self->readfds), 0); +} + +TEST_F(select_basic, select_with_timeout) +{ + struct timeval tv = { .tv_usec = timeout_us }; + + ASSERT_EQ(write(self->sfd[1], "w", 1), 1); + ASSERT_EQ(select(self->sfd[1] + 1, &self->readfds, + NULL, NULL, &tv), 1); + ASSERT_GE(tv.tv_usec, 1000); + ASSERT_NE(FD_ISSET(self->sfd[0], &self->readfds), 0); +} + +TEST_F(select_basic, select_timeout) +{ + struct timeval tv = { .tv_usec = timeout_us }; + + ASSERT_EQ(select(self->sfd[1] + 1, &self->readfds, + NULL, NULL, &tv), 0); + ASSERT_EQ(FD_ISSET(self->sfd[0], &self->readfds), 0); +} + +TEST_F(select_basic, pselect) +{ + ASSERT_EQ(write(self->sfd[1], "w", 1), 1); + ASSERT_EQ(pselect(self->sfd[1] + 1, &self->readfds, + NULL, NULL, NULL, NULL), 1); + ASSERT_NE(FD_ISSET(self->sfd[0], &self->readfds), 0); +} + +TEST_F(select_basic, pselect_with_timeout) +{ + struct timespec ts = { .tv_nsec = timeout_ns }; + + ASSERT_EQ(write(self->sfd[1], "w", 1), 1); + ASSERT_EQ(pselect(self->sfd[1] + 1, &self->readfds, + NULL, NULL, &ts, NULL), 1); + ASSERT_GE(ts.tv_nsec, 1000); + ASSERT_NE(FD_ISSET(self->sfd[0], &self->readfds), 0); +} + +TEST_F(select_basic, pselect_timeout) +{ + struct timespec ts = { .tv_nsec = timeout_ns }; + + ASSERT_EQ(pselect(self->sfd[1] + 1, &self->readfds, + NULL, NULL, &ts, NULL), 0); + ASSERT_EQ(FD_ISSET(self->sfd[0], &self->readfds), 0); +} + +TEST_F(select_basic, pselect_sigset_with_timeout) +{ + struct timespec ts = { .tv_nsec = timeout_ns }; + sigset_t sigmask; + + sigemptyset(&sigmask); + sigaddset(&sigmask, SIGUSR1); + sigprocmask(SIG_SETMASK, &sigmask, NULL); + sigemptyset(&sigmask); + + ASSERT_EQ(write(self->sfd[1], "w", 1), 1); + ASSERT_EQ(pselect(self->sfd[1] + 1, &self->readfds, + NULL, NULL, &ts, &sigmask), 1); + ASSERT_GE(ts.tv_nsec, 1000); + ASSERT_NE(FD_ISSET(self->sfd[0], &self->readfds), 0); +} + +/* (p)poll: basic invocation with data waiting */ + +FIXTURE(poll_basic) +{ + struct pollfd pfds[2]; + int sfd[2]; +}; + +FIXTURE_SETUP(poll_basic) +{ + ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, self->sfd), 0); + + self->pfds[0].events = POLLIN; + self->pfds[0].revents = 0; + self->pfds[0].fd = self->sfd[0]; + + self->pfds[1].events = POLLIN; + self->pfds[1].revents = 0; + self->pfds[1].fd = self->sfd[1]; +} + +FIXTURE_TEARDOWN(poll_basic) +{ + /* FD_ISSET(self->pfds[0] tested in TEST_F: depends on timeout */ + EXPECT_EQ(self->pfds[1].revents & POLLIN, 0); + + EXPECT_EQ(close(self->sfd[0]), 0); + EXPECT_EQ(close(self->sfd[1]), 0); +} + +TEST_F(poll_basic, poll) +{ + ASSERT_EQ(write(self->sfd[1], "w", 1), 1); + EXPECT_EQ(poll(self->pfds, ARRAY_SIZE(self->pfds), 0), 1); + EXPECT_EQ(self->pfds[0].revents & POLLIN, POLLIN); +} + +TEST_F(poll_basic, poll_with_timeout) +{ + ASSERT_EQ(write(self->sfd[1], "w", 1), 1); + EXPECT_EQ(poll(self->pfds, ARRAY_SIZE(self->pfds), 1001), 1); + EXPECT_EQ(self->pfds[0].revents & POLLIN, POLLIN); +} + +TEST_F(poll_basic, poll_timeout) +{ + EXPECT_EQ(poll(self->pfds, ARRAY_SIZE(self->pfds), 1001), 0); + EXPECT_EQ(self->pfds[0].revents & POLLIN, 0); +} + +TEST_F(poll_basic, ppoll) +{ + ASSERT_EQ(write(self->sfd[1], "w", 1), 1); + EXPECT_EQ(ppoll(self->pfds, ARRAY_SIZE(self->pfds), NULL, NULL), 1); + EXPECT_EQ(self->pfds[0].revents & POLLIN, POLLIN); +} + +TEST_F(poll_basic, ppoll_with_timeout) +{ + struct timespec ts = { .tv_nsec = timeout_ns }; + + ASSERT_EQ(write(self->sfd[1], "w", 1), 1); + EXPECT_EQ(ppoll(self->pfds, ARRAY_SIZE(self->pfds), &ts, NULL), 1); + ASSERT_GE(ts.tv_nsec, 1000); + EXPECT_EQ(self->pfds[0].revents & POLLIN, POLLIN); +} + +TEST_F(poll_basic, ppoll_timeout) +{ + struct timespec ts = { .tv_nsec = timeout_ns }; + + EXPECT_EQ(ppoll(self->pfds, ARRAY_SIZE(self->pfds), &ts, NULL), 0); + EXPECT_EQ(self->pfds[0].revents & POLLIN, 0); +} + +TEST_F(poll_basic, ppoll_sigset_with_timeout) +{ + struct timespec ts = { .tv_nsec = timeout_ns }; + sigset_t sigmask; + + sigemptyset(&sigmask); + sigaddset(&sigmask, SIGUSR1); + sigprocmask(SIG_SETMASK, &sigmask, NULL); + sigemptyset(&sigmask); + + ASSERT_EQ(write(self->sfd[1], "w", 1), 1); + EXPECT_EQ(ppoll(self->pfds, ARRAY_SIZE(self->pfds), &ts, &sigmask), 1); + ASSERT_GE(ts.tv_nsec, 1000); + EXPECT_EQ(self->pfds[0].revents & POLLIN, POLLIN); +} + +TEST_HARNESS_MAIN From patchwork Tue Jan 12 00:30:13 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Willem de Bruijn X-Patchwork-Id: 12011937 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=-15.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,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 BDA16C433E6 for ; Tue, 12 Jan 2021 00:33:23 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8D8A322CF7 for ; Tue, 12 Jan 2021 00:33:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728179AbhALAcy (ORCPT ); Mon, 11 Jan 2021 19:32:54 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54354 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726778AbhALAbF (ORCPT ); Mon, 11 Jan 2021 19:31:05 -0500 Received: from mail-il1-x129.google.com (mail-il1-x129.google.com [IPv6:2607:f8b0:4864:20::129]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B7771C061575; Mon, 11 Jan 2021 16:30:24 -0800 (PST) Received: by mail-il1-x129.google.com with SMTP id t3so1191452ilh.9; Mon, 11 Jan 2021 16:30:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=M6EHLJJ6+gpWtEBuXlVgzDefY9wB/OjVkEQk+6H+7KA=; b=pahmPHg0lCIpL+uEish6P+uUlvsyuRffx5ZlB4dlkWq3LYv2CT1YQLIEf9Yn5zWpyq WPPSki+2yCkoTr2U/Tjd4pMy684VxuWJOlOFaA2stKf6q99yiUCWxvc9ggqaSgrW8xf8 xWVndZZq/0IRnxgaSa8bfDBxobKqYsQ0wCwPfQQ74i/47vJSUEgi4LZ36IcMZ1eq2292 UsaUbWyMbjh+mFVO4Qw+vX24Ff66nu9w5M28NS90VOn6PqQ19lv7lMy6a5LGGgwLeaCo 2RaAkrnLHDV4ZHKkP7E7KCIV9AM8fMdmnGOsHtGTwOZ42PXEkQtDMwUPebZSwLXVeT31 2NSg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=M6EHLJJ6+gpWtEBuXlVgzDefY9wB/OjVkEQk+6H+7KA=; b=OA1P7rpiuWFATwnycAZH6b66lojvqPSbGYQxH+Zs7XRLSwi65BNNvQk0xIax90En2k Dp68EGnS6Fmg8SVGMp2e2R3Za9WPAQHpSD5jHYYrFLYaEr1YiANg/jSYw7Feqy4RzZat UGe7QX9MBQu6GT3f7v4KQdNlJPjq0X5w/kqYNwv7uWuE41aFcIXyLmrirN+BQXfMyCzA GZcxIk4NVPT95A2n2hNwzoP0fQUi5/h5dODMh6oYgZDO7ApSy2qZslv6v2wjAOhG4aPA 2Rz8AuXRlZ8BpFQiFsBHnU/88P+f3NvKve63Lfzd7/YuKNmiI4KwpLyIDc3+FXFp+pqm Thsw== X-Gm-Message-State: AOAM532GHCH13Yn0lj1x/myHo0jhf9rngZMgSRBRbV8Z/p+99bb20lr/ GL6GIfpRSva0nlGKQB2dEAFSoLMf+6A= X-Google-Smtp-Source: ABdhPJxouAx0r5yGZIgmXx0Rf6FA1fdQC6+I/Rc53B0Eyk3Ssm60bRrAAkMVM6PZyW4ARk8a1ZUVDw== X-Received: by 2002:a92:9510:: with SMTP id y16mr1643455ilh.26.1610411423692; Mon, 11 Jan 2021 16:30:23 -0800 (PST) Received: from willemb.nyc.corp.google.com ([2620:0:1003:312:f693:9fff:fef4:3e8a]) by smtp.gmail.com with ESMTPSA id z10sm741723ioi.47.2021.01.11.16.30.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 11 Jan 2021 16:30:23 -0800 (PST) From: Willem de Bruijn To: linux-fsdevel@vger.kernel.org Cc: linux-kernel@vger.kernel.org, viro@zeniv.linux.org.uk, akpm@linux-foundation.org, willy@infradead.org, arnd@kernel.org, Willem de Bruijn Subject: [PATCH 2/6] select: deduplicate compat logic Date: Mon, 11 Jan 2021 19:30:13 -0500 Message-Id: <20210112003017.4010304-3-willemdebruijn.kernel@gmail.com> X-Mailer: git-send-email 2.30.0.284.gd98b1dd5eaa7-goog In-Reply-To: <20210112003017.4010304-1-willemdebruijn.kernel@gmail.com> References: <20210112003017.4010304-1-willemdebruijn.kernel@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org From: Willem de Bruijn Select and pselect have multiple syscall implementations to handle compat and 32-bit time variants. Deduplicate core logic, which can cause divergence over time as changes may not be applied consistently. See vmalloc support in select, for one example. Handle compat differences using in_compat_syscall() where needed. Specifically, fd_set and sigmask may be compat variants. Handle the !in_compat_syscall() case first, for branch prediction. Handle timeval/timespec differences by passing along the type to where the pointer is used. Compat variants of select and old_select can now call standard kern_select, removing all callers to do_compat_select. Compat variants of pselect6 (time32 and time64) can now call standard do_pselect, removing all callers to do_compat_pselect. That removes both callers to compat_core_sys_select. And with that callers to compat_[gs]et_fd_set. Also move up zero_fd_set, to avoid one open-coded variant. Signed-off-by: Willem de Bruijn --- fs/select.c | 254 ++++++++++++---------------------------------------- 1 file changed, 57 insertions(+), 197 deletions(-) diff --git a/fs/select.c b/fs/select.c index 37aaa8317f3a..dee7dfc5217b 100644 --- a/fs/select.c +++ b/fs/select.c @@ -382,32 +382,39 @@ typedef struct { #define FDS_LONGS(nr) (((nr)+FDS_BITPERLONG-1)/FDS_BITPERLONG) #define FDS_BYTES(nr) (FDS_LONGS(nr)*sizeof(long)) +static inline +void zero_fd_set(unsigned long nr, unsigned long *fdset) +{ + memset(fdset, 0, FDS_BYTES(nr)); +} + /* * Use "unsigned long" accesses to let user-mode fd_set's be long-aligned. */ static inline int get_fd_set(unsigned long nr, void __user *ufdset, unsigned long *fdset) { - nr = FDS_BYTES(nr); - if (ufdset) - return copy_from_user(fdset, ufdset, nr) ? -EFAULT : 0; + if (!ufdset) { + zero_fd_set(nr, fdset); + return 0; + } - memset(fdset, 0, nr); - return 0; + if (!in_compat_syscall()) + return copy_from_user(fdset, ufdset, FDS_BYTES(nr)) ? -EFAULT : 0; + else + return compat_get_bitmap(fdset, ufdset, nr); } static inline unsigned long __must_check set_fd_set(unsigned long nr, void __user *ufdset, unsigned long *fdset) { - if (ufdset) - return __copy_to_user(ufdset, fdset, FDS_BYTES(nr)); - return 0; -} + if (!ufdset) + return 0; -static inline -void zero_fd_set(unsigned long nr, unsigned long *fdset) -{ - memset(fdset, 0, FDS_BYTES(nr)); + if (!in_compat_syscall()) + return __copy_to_user(ufdset, fdset, FDS_BYTES(nr)); + else + return compat_put_bitmap(ufdset, fdset, nr); } #define FDS_IN(fds, n) (fds->in + n) @@ -698,15 +705,29 @@ int core_sys_select(int n, fd_set __user *inp, fd_set __user *outp, } static int kern_select(int n, fd_set __user *inp, fd_set __user *outp, - fd_set __user *exp, struct __kernel_old_timeval __user *tvp) + fd_set __user *exp, void __user *tvp, + enum poll_time_type type) { struct timespec64 end_time, *to = NULL; struct __kernel_old_timeval tv; + struct old_timeval32 otv; int ret; if (tvp) { - if (copy_from_user(&tv, tvp, sizeof(tv))) - return -EFAULT; + switch (type) { + case PT_TIMEVAL: + if (copy_from_user(&tv, tvp, sizeof(tv))) + return -EFAULT; + break; + case PT_OLD_TIMEVAL: + if (copy_from_user(&otv, tvp, sizeof(otv))) + return -EFAULT; + tv.tv_sec = otv.tv_sec; + tv.tv_usec = otv.tv_usec; + break; + default: + BUG(); + } to = &end_time; if (poll_select_set_timeout(to, @@ -716,18 +737,18 @@ static int kern_select(int n, fd_set __user *inp, fd_set __user *outp, } ret = core_sys_select(n, inp, outp, exp, to); - return poll_select_finish(&end_time, tvp, PT_TIMEVAL, ret); + return poll_select_finish(&end_time, tvp, type, ret); } SYSCALL_DEFINE5(select, int, n, fd_set __user *, inp, fd_set __user *, outp, fd_set __user *, exp, struct __kernel_old_timeval __user *, tvp) { - return kern_select(n, inp, outp, exp, tvp); + return kern_select(n, inp, outp, exp, tvp, PT_TIMEVAL); } static long do_pselect(int n, fd_set __user *inp, fd_set __user *outp, fd_set __user *exp, void __user *tsp, - const sigset_t __user *sigmask, size_t sigsetsize, + const void __user *sigmask, size_t sigsetsize, enum poll_time_type type) { struct timespec64 ts, end_time, *to = NULL; @@ -752,7 +773,10 @@ static long do_pselect(int n, fd_set __user *inp, fd_set __user *outp, return -EINVAL; } - ret = set_user_sigmask(sigmask, sigsetsize); + if (!in_compat_syscall()) + ret = set_user_sigmask(sigmask, sigsetsize); + else + ret = set_compat_user_sigmask(sigmask, sigsetsize); if (ret) return ret; @@ -829,7 +853,7 @@ SYSCALL_DEFINE1(old_select, struct sel_arg_struct __user *, arg) if (copy_from_user(&a, arg, sizeof(a))) return -EFAULT; - return kern_select(a.n, a.inp, a.outp, a.exp, a.tvp); + return kern_select(a.n, a.inp, a.outp, a.exp, a.tvp, PT_TIMEVAL); } #endif @@ -1148,146 +1172,14 @@ SYSCALL_DEFINE5(ppoll_time32, struct pollfd __user *, ufds, unsigned int, nfds, #endif #ifdef CONFIG_COMPAT -#define __COMPAT_NFDBITS (8 * sizeof(compat_ulong_t)) - -/* - * Ooo, nasty. We need here to frob 32-bit unsigned longs to - * 64-bit unsigned longs. - */ -static -int compat_get_fd_set(unsigned long nr, compat_ulong_t __user *ufdset, - unsigned long *fdset) -{ - if (ufdset) { - return compat_get_bitmap(fdset, ufdset, nr); - } else { - zero_fd_set(nr, fdset); - return 0; - } -} - -static -int compat_set_fd_set(unsigned long nr, compat_ulong_t __user *ufdset, - unsigned long *fdset) -{ - if (!ufdset) - return 0; - return compat_put_bitmap(ufdset, fdset, nr); -} - - -/* - * This is a virtual copy of sys_select from fs/select.c and probably - * should be compared to it from time to time - */ - -/* - * We can actually return ERESTARTSYS instead of EINTR, but I'd - * like to be certain this leads to no problems. So I return - * EINTR just for safety. - * - * Update: ERESTARTSYS breaks at least the xview clock binary, so - * I'm trying ERESTARTNOHAND which restart only when you want to. - */ -static int compat_core_sys_select(int n, compat_ulong_t __user *inp, - compat_ulong_t __user *outp, compat_ulong_t __user *exp, - struct timespec64 *end_time) -{ - fd_set_bits fds; - void *bits; - int size, max_fds, ret = -EINVAL; - struct fdtable *fdt; - long stack_fds[SELECT_STACK_ALLOC/sizeof(long)]; - - if (n < 0) - goto out_nofds; - - /* max_fds can increase, so grab it once to avoid race */ - rcu_read_lock(); - fdt = files_fdtable(current->files); - max_fds = fdt->max_fds; - rcu_read_unlock(); - if (n > max_fds) - n = max_fds; - - /* - * We need 6 bitmaps (in/out/ex for both incoming and outgoing), - * since we used fdset we need to allocate memory in units of - * long-words. - */ - size = FDS_BYTES(n); - bits = stack_fds; - if (size > sizeof(stack_fds) / 6) { - bits = kmalloc_array(6, size, GFP_KERNEL); - ret = -ENOMEM; - if (!bits) - goto out_nofds; - } - fds.in = (unsigned long *) bits; - fds.out = (unsigned long *) (bits + size); - fds.ex = (unsigned long *) (bits + 2*size); - fds.res_in = (unsigned long *) (bits + 3*size); - fds.res_out = (unsigned long *) (bits + 4*size); - fds.res_ex = (unsigned long *) (bits + 5*size); - - if ((ret = compat_get_fd_set(n, inp, fds.in)) || - (ret = compat_get_fd_set(n, outp, fds.out)) || - (ret = compat_get_fd_set(n, exp, fds.ex))) - goto out; - zero_fd_set(n, fds.res_in); - zero_fd_set(n, fds.res_out); - zero_fd_set(n, fds.res_ex); - - ret = do_select(n, &fds, end_time); - - if (ret < 0) - goto out; - if (!ret) { - ret = -ERESTARTNOHAND; - if (signal_pending(current)) - goto out; - ret = 0; - } - - if (compat_set_fd_set(n, inp, fds.res_in) || - compat_set_fd_set(n, outp, fds.res_out) || - compat_set_fd_set(n, exp, fds.res_ex)) - ret = -EFAULT; -out: - if (bits != stack_fds) - kfree(bits); -out_nofds: - return ret; -} - -static int do_compat_select(int n, compat_ulong_t __user *inp, - compat_ulong_t __user *outp, compat_ulong_t __user *exp, - struct old_timeval32 __user *tvp) -{ - struct timespec64 end_time, *to = NULL; - struct old_timeval32 tv; - int ret; - - if (tvp) { - if (copy_from_user(&tv, tvp, sizeof(tv))) - return -EFAULT; - - to = &end_time; - if (poll_select_set_timeout(to, - tv.tv_sec + (tv.tv_usec / USEC_PER_SEC), - (tv.tv_usec % USEC_PER_SEC) * NSEC_PER_USEC)) - return -EINVAL; - } - - ret = compat_core_sys_select(n, inp, outp, exp, to); - return poll_select_finish(&end_time, tvp, PT_OLD_TIMEVAL, ret); -} COMPAT_SYSCALL_DEFINE5(select, int, n, compat_ulong_t __user *, inp, compat_ulong_t __user *, outp, compat_ulong_t __user *, exp, struct old_timeval32 __user *, tvp) { - return do_compat_select(n, inp, outp, exp, tvp); + return kern_select(n, (void __user *)inp, (void __user *)outp, + (void __user *)exp, (void __user *)tvp, + PT_OLD_TIMEVAL); } struct compat_sel_arg_struct { @@ -1304,43 +1196,9 @@ COMPAT_SYSCALL_DEFINE1(old_select, struct compat_sel_arg_struct __user *, arg) if (copy_from_user(&a, arg, sizeof(a))) return -EFAULT; - return do_compat_select(a.n, compat_ptr(a.inp), compat_ptr(a.outp), - compat_ptr(a.exp), compat_ptr(a.tvp)); -} - -static long do_compat_pselect(int n, compat_ulong_t __user *inp, - compat_ulong_t __user *outp, compat_ulong_t __user *exp, - void __user *tsp, compat_sigset_t __user *sigmask, - compat_size_t sigsetsize, enum poll_time_type type) -{ - struct timespec64 ts, end_time, *to = NULL; - int ret; - - if (tsp) { - switch (type) { - case PT_OLD_TIMESPEC: - if (get_old_timespec32(&ts, tsp)) - return -EFAULT; - break; - case PT_TIMESPEC: - if (get_timespec64(&ts, tsp)) - return -EFAULT; - break; - default: - BUG(); - } - - to = &end_time; - if (poll_select_set_timeout(to, ts.tv_sec, ts.tv_nsec)) - return -EINVAL; - } - - ret = set_compat_user_sigmask(sigmask, sigsetsize); - if (ret) - return ret; - - ret = compat_core_sys_select(n, inp, outp, exp, to); - return poll_select_finish(&end_time, tsp, type, ret); + return kern_select(a.n, compat_ptr(a.inp), compat_ptr(a.outp), + compat_ptr(a.exp), compat_ptr(a.tvp), + PT_OLD_TIMEVAL); } struct compat_sigset_argpack { @@ -1372,8 +1230,9 @@ COMPAT_SYSCALL_DEFINE6(pselect6_time64, int, n, compat_ulong_t __user *, inp, if (get_compat_sigset_argpack(&x, sig)) return -EFAULT; - return do_compat_pselect(n, inp, outp, exp, tsp, compat_ptr(x.p), - x.size, PT_TIMESPEC); + return do_pselect(n, (void __user *)inp, (void __user *)outp, + (void __user *)exp, (void __user *)tsp, + compat_ptr(x.p), x.size, PT_TIMESPEC); } #if defined(CONFIG_COMPAT_32BIT_TIME) @@ -1387,8 +1246,9 @@ COMPAT_SYSCALL_DEFINE6(pselect6_time32, int, n, compat_ulong_t __user *, inp, if (get_compat_sigset_argpack(&x, sig)) return -EFAULT; - return do_compat_pselect(n, inp, outp, exp, tsp, compat_ptr(x.p), - x.size, PT_OLD_TIMESPEC); + return do_pselect(n, (void __user *)inp, (void __user *)outp, + (void __user *)exp, (void __user *)tsp, + compat_ptr(x.p), x.size, PT_OLD_TIMESPEC); } #endif From patchwork Tue Jan 12 00:30:14 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Willem de Bruijn X-Patchwork-Id: 12011841 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=-15.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=unavailable 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 2A4DEC433E6 for ; Tue, 12 Jan 2021 00:32:57 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id F2C4C22D08 for ; Tue, 12 Jan 2021 00:32:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728458AbhALAcj (ORCPT ); Mon, 11 Jan 2021 19:32:39 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54360 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727768AbhALAbG (ORCPT ); Mon, 11 Jan 2021 19:31:06 -0500 Received: from mail-il1-x130.google.com (mail-il1-x130.google.com [IPv6:2607:f8b0:4864:20::130]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E1FA1C061795; Mon, 11 Jan 2021 16:30:25 -0800 (PST) Received: by mail-il1-x130.google.com with SMTP id q1so1204218ilt.6; Mon, 11 Jan 2021 16:30:25 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=QY4rVYyu6E/6EmhURp973qid4e3oR/DMlYXIb6itw4o=; b=mStwfFMTSroR0iUvcTwJfk75Ns0P5glJNuMQ7gNdd1l+9JHi6eLSGTNYKfZnX00W0H rcFIzjvSZ84Pddvt1IsOkucc8V6JY3qTQNw5S2vBDMWV9b8afJjrmR3oaZA1Q+KgvTbo ChVbuIlI5gCo0S04+xb4EACfAB/+dRgpOYJM0S6Zch0zQnjitjAa0Xm/SblcABaTidCo LF1mk8kRH8IGyog4xyVfyGH/tOf6NQkBh0nBpPFME7udWPOwLlNubXXWle7lA9q7R2op VVZ9kUk/R1EsB0Hdj6OM0bPOIkCLeMJ+v9+bz3hIM6Mq81cQbOnIN+Et7vlSSjgQc0Vb lVIQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=QY4rVYyu6E/6EmhURp973qid4e3oR/DMlYXIb6itw4o=; b=J6Gciv+1HbkFNZi6QjgzUF1BUQfNCY5jv2Z14X3Vpwdrh2VVsuEPo/GsQOAVxjhPXv CCfPd09WlLQs7mVWYxhk3fMZGCDp9pkm9nPMxBiEZsoL8tdXO2fzJXm1sItIlk1HznXs zz4YBHShlkeYn0hvXjddhvpu6YcpDWgn/q6nkyUVkEnUyG7diUI7olkijs9OKeQcjxSZ 9Wrc3eqsJQI59OMR88h4qKdlEw0ghgPSZKoGaT6MKWYwH0MSa0nFyaKxnzcAPW6NrZq7 oX/WCfMIaZigRc8bMO1sEPLyf+bpajeUiopVlM1GAjSjK3rGh8vilPc/Fi8PQNMeQcRq AfJg== X-Gm-Message-State: AOAM5322qN/oqo7kTSlSU9K0tkr5cunbUvjYA1bZz268yynm5tfITpGD g4EujtlXivxzRZcyd36eaETtsU9T/Ps= X-Google-Smtp-Source: ABdhPJzxIYBWZ6+a+hxa0seYD4rhHzW43p+pTBvYyEkGzr7DYBIlKnO4Whu1QOFqEB2L6cnS6z+V0A== X-Received: by 2002:a05:6e02:b2e:: with SMTP id e14mr1558354ilu.164.1610411425002; Mon, 11 Jan 2021 16:30:25 -0800 (PST) Received: from willemb.nyc.corp.google.com ([2620:0:1003:312:f693:9fff:fef4:3e8a]) by smtp.gmail.com with ESMTPSA id z10sm741723ioi.47.2021.01.11.16.30.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 11 Jan 2021 16:30:24 -0800 (PST) From: Willem de Bruijn To: linux-fsdevel@vger.kernel.org Cc: linux-kernel@vger.kernel.org, viro@zeniv.linux.org.uk, akpm@linux-foundation.org, willy@infradead.org, arnd@kernel.org, Willem de Bruijn Subject: [PATCH 3/6] ppoll: deduplicate compat logic Date: Mon, 11 Jan 2021 19:30:14 -0500 Message-Id: <20210112003017.4010304-4-willemdebruijn.kernel@gmail.com> X-Mailer: git-send-email 2.30.0.284.gd98b1dd5eaa7-goog In-Reply-To: <20210112003017.4010304-1-willemdebruijn.kernel@gmail.com> References: <20210112003017.4010304-1-willemdebruijn.kernel@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org From: Willem de Bruijn Apply the same compat deduplication strategy to ppoll that was previously applied to select and pselect. Like pselect, ppoll has timespec and sigmask arguments, which have compat variants. poll has neither, so is not modified. Convert the ppoll syscall to a do_ppoll() helper that branches on timespec and sigmask variants internally. This allows calling the same implementation for all syscall variants: standard, time32, compat, compat + time32. Signed-off-by: Willem de Bruijn --- fs/select.c | 91 ++++++++++++++++++----------------------------------- 1 file changed, 30 insertions(+), 61 deletions(-) diff --git a/fs/select.c b/fs/select.c index dee7dfc5217b..27567795a892 100644 --- a/fs/select.c +++ b/fs/select.c @@ -1120,28 +1120,48 @@ SYSCALL_DEFINE3(poll, struct pollfd __user *, ufds, unsigned int, nfds, return ret; } -SYSCALL_DEFINE5(ppoll, struct pollfd __user *, ufds, unsigned int, nfds, - struct __kernel_timespec __user *, tsp, const sigset_t __user *, sigmask, - size_t, sigsetsize) +static int do_ppoll(struct pollfd __user *ufds, unsigned int nfds, + void __user *tsp, const void __user *sigmask, + size_t sigsetsize, enum poll_time_type type) { struct timespec64 ts, end_time, *to = NULL; int ret; if (tsp) { - if (get_timespec64(&ts, tsp)) - return -EFAULT; + switch (type) { + case PT_TIMESPEC: + if (get_timespec64(&ts, tsp)) + return -EFAULT; + break; + case PT_OLD_TIMESPEC: + if (get_old_timespec32(&ts, tsp)) + return -EFAULT; + break; + default: + BUG(); + } to = &end_time; if (poll_select_set_timeout(to, ts.tv_sec, ts.tv_nsec)) return -EINVAL; } - ret = set_user_sigmask(sigmask, sigsetsize); + if (!in_compat_syscall()) + ret = set_user_sigmask(sigmask, sigsetsize); + else + ret = set_compat_user_sigmask(sigmask, sigsetsize); if (ret) return ret; ret = do_sys_poll(ufds, nfds, to); - return poll_select_finish(&end_time, tsp, PT_TIMESPEC, ret); + return poll_select_finish(&end_time, tsp, type, ret); +} + +SYSCALL_DEFINE5(ppoll, struct pollfd __user *, ufds, unsigned int, nfds, + struct __kernel_timespec __user *, tsp, const sigset_t __user *, sigmask, + size_t, sigsetsize) +{ + return do_ppoll(ufds, nfds, tsp, sigmask, sigsetsize, PT_TIMESPEC); } #if defined(CONFIG_COMPAT_32BIT_TIME) && !defined(CONFIG_64BIT) @@ -1150,24 +1170,7 @@ SYSCALL_DEFINE5(ppoll_time32, struct pollfd __user *, ufds, unsigned int, nfds, struct old_timespec32 __user *, tsp, const sigset_t __user *, sigmask, size_t, sigsetsize) { - struct timespec64 ts, end_time, *to = NULL; - int ret; - - if (tsp) { - if (get_old_timespec32(&ts, tsp)) - return -EFAULT; - - to = &end_time; - if (poll_select_set_timeout(to, ts.tv_sec, ts.tv_nsec)) - return -EINVAL; - } - - ret = set_user_sigmask(sigmask, sigsetsize); - if (ret) - return ret; - - ret = do_sys_poll(ufds, nfds, to); - return poll_select_finish(&end_time, tsp, PT_OLD_TIMESPEC, ret); + return do_ppoll(ufds, nfds, tsp, sigmask, sigsetsize, PT_OLD_TIMESPEC); } #endif @@ -1258,24 +1261,7 @@ COMPAT_SYSCALL_DEFINE5(ppoll_time32, struct pollfd __user *, ufds, unsigned int, nfds, struct old_timespec32 __user *, tsp, const compat_sigset_t __user *, sigmask, compat_size_t, sigsetsize) { - struct timespec64 ts, end_time, *to = NULL; - int ret; - - if (tsp) { - if (get_old_timespec32(&ts, tsp)) - return -EFAULT; - - to = &end_time; - if (poll_select_set_timeout(to, ts.tv_sec, ts.tv_nsec)) - return -EINVAL; - } - - ret = set_compat_user_sigmask(sigmask, sigsetsize); - if (ret) - return ret; - - ret = do_sys_poll(ufds, nfds, to); - return poll_select_finish(&end_time, tsp, PT_OLD_TIMESPEC, ret); + return do_ppoll(ufds, nfds, tsp, sigmask, sigsetsize, PT_OLD_TIMESPEC); } #endif @@ -1284,24 +1270,7 @@ COMPAT_SYSCALL_DEFINE5(ppoll_time64, struct pollfd __user *, ufds, unsigned int, nfds, struct __kernel_timespec __user *, tsp, const compat_sigset_t __user *, sigmask, compat_size_t, sigsetsize) { - struct timespec64 ts, end_time, *to = NULL; - int ret; - - if (tsp) { - if (get_timespec64(&ts, tsp)) - return -EFAULT; - - to = &end_time; - if (poll_select_set_timeout(to, ts.tv_sec, ts.tv_nsec)) - return -EINVAL; - } - - ret = set_compat_user_sigmask(sigmask, sigsetsize); - if (ret) - return ret; - - ret = do_sys_poll(ufds, nfds, to); - return poll_select_finish(&end_time, tsp, PT_TIMESPEC, ret); + return do_ppoll(ufds, nfds, tsp, sigmask, sigsetsize, PT_TIMESPEC); } #endif From patchwork Tue Jan 12 00:30:15 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Willem de Bruijn X-Patchwork-Id: 12011839 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=-15.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=unavailable 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 02A46C433E0 for ; Tue, 12 Jan 2021 00:32:55 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id BBA3E22CB8 for ; Tue, 12 Jan 2021 00:32:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728409AbhALAbJ (ORCPT ); Mon, 11 Jan 2021 19:31:09 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54368 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728045AbhALAbH (ORCPT ); Mon, 11 Jan 2021 19:31:07 -0500 Received: from mail-io1-xd2c.google.com (mail-io1-xd2c.google.com [IPv6:2607:f8b0:4864:20::d2c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 09AB8C06179F; Mon, 11 Jan 2021 16:30:27 -0800 (PST) Received: by mail-io1-xd2c.google.com with SMTP id d9so498327iob.6; Mon, 11 Jan 2021 16:30:27 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=UAMxIDbTziLFJUvywaK2ZNZ+Q4hesEIu8XKmRJ1p2y0=; b=gmi5u04GjO9Ds2D4RL79j/1jn+HXdk+n4+O7fdPDvf7a/9eQqWsZxbMmZciHI1csvC 2pfMethWqgC5lEqxos+6FCcLOc0B8fqf/UY5by+jz5iMyd2n3vrDd3TyjYUoo71jzLxY zPY/58p0lSwPjxzf0gumnso1h6rwGBn81yiyKajGuIPOU92E2QtHG5wSpbq5cFkJRaZ7 I0QODVkUWTNNjqaLfwIP6vFRptZA/bbVpjakIjtWKR0OfAxqrj6Bl7TRbm8kvoy2Hsc3 P5tjKt6PXZezm83BjGqNgJzXb5LYCyJlLQ3IIxsLtspWQLwE5YimbAOkYIQ3HDjE6IDl 2d/w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=UAMxIDbTziLFJUvywaK2ZNZ+Q4hesEIu8XKmRJ1p2y0=; b=lAhV4+m226hdPHCUWRJFsWsneY5l+Uaplf9Am2mB0XTjZQiQ0vveMmh/3ajvjz0+9R MZBa/B1inmLR7N12XIutb3r9AUL8keU87BUtUJU+CPktzDseVwilgGKCNzssH8FX1MP2 Wlyrg281sLIeTa4nhXmIWlZaHlQDTY6V1ZlHbhzITZgGak8D8Bg/e6z0Qr+WdPBssD97 9Q/qpE44Uic03yuoex83oK2ApdqvWcyYcjSxhLobmPBZ9ExC8sIs84z7/2rpf1LNLhEA j9eHMdu8jxVA6CSPqbkmn5uzP7N6RsdZ0xZrNB94ySf7Gpd7UhBeeGuVQ32qmkTvD0V2 G2BA== X-Gm-Message-State: AOAM5334bfzOrhym2UVJR25W2FlLRlb7BuwmnQGJ1TO1S0zGKxxokmRH u1V8cXIcjZCKH2IACsHGNxu6s700sjU= X-Google-Smtp-Source: ABdhPJyPPKTIeR5EuFUFOku6/rJjWP/q97RCtO7qqv7/gaq4ZM1vr1ax14hdkaPqPKYOQ3mMknVYhA== X-Received: by 2002:a02:2ace:: with SMTP id w197mr1926451jaw.132.1610411426160; Mon, 11 Jan 2021 16:30:26 -0800 (PST) Received: from willemb.nyc.corp.google.com ([2620:0:1003:312:f693:9fff:fef4:3e8a]) by smtp.gmail.com with ESMTPSA id z10sm741723ioi.47.2021.01.11.16.30.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 11 Jan 2021 16:30:25 -0800 (PST) From: Willem de Bruijn To: linux-fsdevel@vger.kernel.org Cc: linux-kernel@vger.kernel.org, viro@zeniv.linux.org.uk, akpm@linux-foundation.org, willy@infradead.org, arnd@kernel.org, Willem de Bruijn Subject: [PATCH 4/6] epoll: deduplicate compat logic Date: Mon, 11 Jan 2021 19:30:15 -0500 Message-Id: <20210112003017.4010304-5-willemdebruijn.kernel@gmail.com> X-Mailer: git-send-email 2.30.0.284.gd98b1dd5eaa7-goog In-Reply-To: <20210112003017.4010304-1-willemdebruijn.kernel@gmail.com> References: <20210112003017.4010304-1-willemdebruijn.kernel@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org From: Willem de Bruijn Apply the same compat deduplication strategy to epoll that was previously applied to (p)select and ppoll. Make do_epoll_wait handle both variants of sigmask. This removes the need for near duplicate do_compat_epoll_pwait. Signed-off-by: Willem de Bruijn --- fs/eventpoll.c | 38 +++++++++----------------------------- 1 file changed, 9 insertions(+), 29 deletions(-) diff --git a/fs/eventpoll.c b/fs/eventpoll.c index a829af074eb5..c9dcffba2da1 100644 --- a/fs/eventpoll.c +++ b/fs/eventpoll.c @@ -2239,7 +2239,7 @@ SYSCALL_DEFINE4(epoll_wait, int, epfd, struct epoll_event __user *, events, */ static int do_epoll_pwait(int epfd, struct epoll_event __user *events, int maxevents, struct timespec64 *to, - const sigset_t __user *sigmask, size_t sigsetsize) + const void __user *sigmask, size_t sigsetsize) { int error; @@ -2247,7 +2247,10 @@ static int do_epoll_pwait(int epfd, struct epoll_event __user *events, * If the caller wants a certain signal mask to be set during the wait, * we apply it here. */ - error = set_user_sigmask(sigmask, sigsetsize); + if (!in_compat_syscall()) + error = set_user_sigmask(sigmask, sigsetsize); + else + error = set_compat_user_sigmask(sigmask, sigsetsize); if (error) return error; @@ -2288,28 +2291,6 @@ SYSCALL_DEFINE6(epoll_pwait2, int, epfd, struct epoll_event __user *, events, } #ifdef CONFIG_COMPAT -static int do_compat_epoll_pwait(int epfd, struct epoll_event __user *events, - int maxevents, struct timespec64 *timeout, - const compat_sigset_t __user *sigmask, - compat_size_t sigsetsize) -{ - long err; - - /* - * If the caller wants a certain signal mask to be set during the wait, - * we apply it here. - */ - err = set_compat_user_sigmask(sigmask, sigsetsize); - if (err) - return err; - - err = do_epoll_wait(epfd, events, maxevents, timeout); - - restore_saved_sigmask_unless(err == -EINTR); - - return err; -} - COMPAT_SYSCALL_DEFINE6(epoll_pwait, int, epfd, struct epoll_event __user *, events, int, maxevents, int, timeout, @@ -2318,9 +2299,9 @@ COMPAT_SYSCALL_DEFINE6(epoll_pwait, int, epfd, { struct timespec64 to; - return do_compat_epoll_pwait(epfd, events, maxevents, - ep_timeout_to_timespec(&to, timeout), - sigmask, sigsetsize); + return do_epoll_pwait(epfd, events, maxevents, + ep_timeout_to_timespec(&to, timeout), + sigmask, sigsetsize); } COMPAT_SYSCALL_DEFINE6(epoll_pwait2, int, epfd, @@ -2340,8 +2321,7 @@ COMPAT_SYSCALL_DEFINE6(epoll_pwait2, int, epfd, return -EINVAL; } - return do_compat_epoll_pwait(epfd, events, maxevents, to, - sigmask, sigsetsize); + return do_epoll_pwait(epfd, events, maxevents, to, sigmask, sigsetsize); } #endif From patchwork Tue Jan 12 00:30:16 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Willem de Bruijn X-Patchwork-Id: 12011845 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=-15.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=unavailable 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 62614C433E0 for ; Tue, 12 Jan 2021 00:32:57 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 339A022CF7 for ; Tue, 12 Jan 2021 00:32:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726685AbhALAci (ORCPT ); Mon, 11 Jan 2021 19:32:38 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54372 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726603AbhALAbI (ORCPT ); Mon, 11 Jan 2021 19:31:08 -0500 Received: from mail-il1-x12c.google.com (mail-il1-x12c.google.com [IPv6:2607:f8b0:4864:20::12c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 346A6C0617A2; Mon, 11 Jan 2021 16:30:28 -0800 (PST) Received: by mail-il1-x12c.google.com with SMTP id v3so1220621ilo.5; Mon, 11 Jan 2021 16:30:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=e85jGa4l7Ltpm4J5B4ttRB7c3u6YAvgPMu6mhyi+DSY=; b=vhppCzJeoOG642HV7mKXuPYQnMIDxj83Oei9LxecFI5l+zQa3c0Imccad4Ac3REk9a XQvTApPuhJG09yGAOeDT/lhD970Z4GbKH450BzvW9Q3dfxNErNhOuiMMo5RuluJrTzWf cGvQCoXV6Kb+7OOE59oOCA4lSKnVke4EWqycx5d5OfdieeiJQsx68w8cMqivkYDH5BzN GO/sINuJweTkFKX91yv5YPWTF3JnnRS1mLv+tTVkGZAI0QL04dHYXKJrjPUI1b6i0osn dyDqBDTZvmH6ZMSrQTJb0Pa4BMJoPEwJvd9PFm6yDY8jOSD2kU2HXmmOIe00gTORM0jY cUHA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=e85jGa4l7Ltpm4J5B4ttRB7c3u6YAvgPMu6mhyi+DSY=; b=eZVA/gESWTA5JcaQJOsWHpFl7OLZcHFDyTsSKJezO79UKu0CqhvjjTZDUOlfeJMQyg //OP3KXDQ/v8LnFCXATCpyxhqbcLcO11MZBEO8+Rt+Db09qZjmT5HsVt1D5fXlZ7X9OI Of/RI0ZeMLmQjQ03SZYbZC76cZeX2DQGE62JSkxW4OOpPShHWWQeAl5FbxKvd0kHa+/s mA6Mv1oLEo8cfJQZJw+6Iwc/ZzrpUFghR7Cif0/HCJCugbVG/wvlo2R4kJbQBsNMkqgE 2/GdyzItxZx8gbt7h6YIuVjEfFSNytJz1FQ7SFeONodEjMS8M54L8en1VIy/OCrnOdnl JsHw== X-Gm-Message-State: AOAM530/wdXYkSaA3Jbu9aO7VHqcBS0SIKoQ7HO7y/gJbkxmNMTDM3qJ 226bt/bTlfCRwM6yKxxOtqgW39jcs70= X-Google-Smtp-Source: ABdhPJy4j0pcFI0rW4p5IWzBMmcZ3A1rycMAHBZE/RMwRmcumYpng0XuMrsbSF879zvIMOvZCVhxHQ== X-Received: by 2002:a92:6a0c:: with SMTP id f12mr606003ilc.122.1610411427282; Mon, 11 Jan 2021 16:30:27 -0800 (PST) Received: from willemb.nyc.corp.google.com ([2620:0:1003:312:f693:9fff:fef4:3e8a]) by smtp.gmail.com with ESMTPSA id z10sm741723ioi.47.2021.01.11.16.30.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 11 Jan 2021 16:30:26 -0800 (PST) From: Willem de Bruijn To: linux-fsdevel@vger.kernel.org Cc: linux-kernel@vger.kernel.org, viro@zeniv.linux.org.uk, akpm@linux-foundation.org, willy@infradead.org, arnd@kernel.org, Willem de Bruijn , Jens Axboe Subject: [PATCH 5/6] compat: add set_maybe_compat_user_sigmask helper Date: Mon, 11 Jan 2021 19:30:16 -0500 Message-Id: <20210112003017.4010304-6-willemdebruijn.kernel@gmail.com> X-Mailer: git-send-email 2.30.0.284.gd98b1dd5eaa7-goog In-Reply-To: <20210112003017.4010304-1-willemdebruijn.kernel@gmail.com> References: <20210112003017.4010304-1-willemdebruijn.kernel@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org From: Willem de Bruijn Deduplicate the open coded branch on sigmask compat handling. Signed-off-by: Willem de Bruijn Cc: Jens Axboe Reported-by: kernel test robot --- fs/eventpoll.c | 5 +---- fs/io_uring.c | 9 +-------- fs/select.c | 10 ++-------- include/linux/compat.h | 10 ++++++++++ 4 files changed, 14 insertions(+), 20 deletions(-) diff --git a/fs/eventpoll.c b/fs/eventpoll.c index c9dcffba2da1..c011327c8402 100644 --- a/fs/eventpoll.c +++ b/fs/eventpoll.c @@ -2247,10 +2247,7 @@ static int do_epoll_pwait(int epfd, struct epoll_event __user *events, * If the caller wants a certain signal mask to be set during the wait, * we apply it here. */ - if (!in_compat_syscall()) - error = set_user_sigmask(sigmask, sigsetsize); - else - error = set_compat_user_sigmask(sigmask, sigsetsize); + error = set_maybe_compat_user_sigmask(sigmask, sigsetsize); if (error) return error; diff --git a/fs/io_uring.c b/fs/io_uring.c index fdc923e53873..abc88bc738ce 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -7190,14 +7190,7 @@ static int io_cqring_wait(struct io_ring_ctx *ctx, int min_events, } while (1); if (sig) { -#ifdef CONFIG_COMPAT - if (in_compat_syscall()) - ret = set_compat_user_sigmask((const compat_sigset_t __user *)sig, - sigsz); - else -#endif - ret = set_user_sigmask(sig, sigsz); - + ret = set_maybe_compat_user_sigmask(sig, sigsz); if (ret) return ret; } diff --git a/fs/select.c b/fs/select.c index 27567795a892..c013662bbf51 100644 --- a/fs/select.c +++ b/fs/select.c @@ -773,10 +773,7 @@ static long do_pselect(int n, fd_set __user *inp, fd_set __user *outp, return -EINVAL; } - if (!in_compat_syscall()) - ret = set_user_sigmask(sigmask, sigsetsize); - else - ret = set_compat_user_sigmask(sigmask, sigsetsize); + ret = set_maybe_compat_user_sigmask(sigmask, sigsetsize); if (ret) return ret; @@ -1146,10 +1143,7 @@ static int do_ppoll(struct pollfd __user *ufds, unsigned int nfds, return -EINVAL; } - if (!in_compat_syscall()) - ret = set_user_sigmask(sigmask, sigsetsize); - else - ret = set_compat_user_sigmask(sigmask, sigsetsize); + ret = set_maybe_compat_user_sigmask(sigmask, sigsetsize); if (ret) return ret; diff --git a/include/linux/compat.h b/include/linux/compat.h index 6e65be753603..4a9b740496b4 100644 --- a/include/linux/compat.h +++ b/include/linux/compat.h @@ -18,6 +18,7 @@ #include /* for aio_context_t */ #include #include +#include #include @@ -942,6 +943,15 @@ static inline bool in_compat_syscall(void) { return false; } #endif /* CONFIG_COMPAT */ +static inline int set_maybe_compat_user_sigmask(const void __user *umask, + size_t sigsetsize) +{ + if (!in_compat_syscall()) + return set_user_sigmask(umask, sigsetsize); + else + return set_compat_user_sigmask(umask, sigsetsize); +} + /* * Some legacy ABIs like the i386 one use less than natural alignment for 64-bit * types, and will need special compat treatment for that. Most architectures From patchwork Tue Jan 12 00:30:17 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Willem de Bruijn X-Patchwork-Id: 12011837 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=-15.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=unavailable 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 78064C433E6 for ; Tue, 12 Jan 2021 00:32:31 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3585D22D08 for ; Tue, 12 Jan 2021 00:32:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728518AbhALAbw (ORCPT ); Mon, 11 Jan 2021 19:31:52 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54498 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726444AbhALAbn (ORCPT ); Mon, 11 Jan 2021 19:31:43 -0500 Received: from mail-il1-x12d.google.com (mail-il1-x12d.google.com [IPv6:2607:f8b0:4864:20::12d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4F944C0617A3; Mon, 11 Jan 2021 16:30:29 -0800 (PST) Received: by mail-il1-x12d.google.com with SMTP id t3so1191602ilh.9; Mon, 11 Jan 2021 16:30:29 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=1bBzMydguUVXlJygZy+L+A0TLEvNxN16shoUGEugiOE=; b=cdKYCMkJT6j0/WukuM7xLyLMsjNCArvFlXBUi0hiSFZChaB45MAM9Ri6QUi21Xp13o 6UzV87LjpOLviKXDAb4h75gGPH7RANkjJCTBbyVm/pj2RmkoLxZyIWV/XiMz71fj26he 6JFjlFLqABDeltopFgQuG3+s1FPpXrusNJTE08eaRekZMmBrUUZNffn8GNuck4ukwZEP iXG6/kijx93tFQk4hs/XxW1W1mOBg0EJfkfsFL4oibKUxp9Nl9mlU+qPCjjmWrEqT0R8 emT8laVy6Ksrvx3fYTTX+jxQGT4lscm2ZEt1JD6p9i+4K0vbZfj3EISy5w64IHoFcyl1 zqWw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=1bBzMydguUVXlJygZy+L+A0TLEvNxN16shoUGEugiOE=; b=Ial7GatJZk/a5DidSZSpCosgW/kK8QXswsllOLtfoXTs7ygMtCBPTMmkQyDOFlJzgw tRGr804jqttm+9Dd3LgE+TV2bTIhL0tzUIFz/pAhtE3bu8cxsTDDis23skEf7LlSetiA IDjfBunwEr53WnlUd/RUGZPCXuIbrpvkMfg7eBUuxloorEvUlcAUIaj79aoYYbjSQ5Fu 6IhP/6oRaYIOxXOgMEQG9cNUxup4ByrB1g53UnARp4OTxQd2Xoa4DIFWFEvxUC3fGN4l Lv2U4retB9IlKXsYXW1icoaMUfZqjR5QUMIcxpkANMuTETwOEjuuDt3qypqWCIU3SMhV RBTQ== X-Gm-Message-State: AOAM530YQ/WJ4oKvQP9pCrhgQzWa38qVoKqM7iwjtimoGWFjrLIOfLaJ m18e07tF8ROjmcoX19wEF+ctqCx9mbs= X-Google-Smtp-Source: ABdhPJxuG0iilI9x/mweoOX+8NEI3wrg+1n34TnEKT+2KJRo+cQ76mBHnUVeM2zoQyOQgxTUuXK3cg== X-Received: by 2002:a92:d350:: with SMTP id a16mr1551482ilh.262.1610411428446; Mon, 11 Jan 2021 16:30:28 -0800 (PST) Received: from willemb.nyc.corp.google.com ([2620:0:1003:312:f693:9fff:fef4:3e8a]) by smtp.gmail.com with ESMTPSA id z10sm741723ioi.47.2021.01.11.16.30.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 11 Jan 2021 16:30:27 -0800 (PST) From: Willem de Bruijn To: linux-fsdevel@vger.kernel.org Cc: linux-kernel@vger.kernel.org, viro@zeniv.linux.org.uk, akpm@linux-foundation.org, willy@infradead.org, arnd@kernel.org, Willem de Bruijn , Benjamin LaHaise Subject: [PATCH 6/6] io_pgetevents: deduplicate compat logic Date: Mon, 11 Jan 2021 19:30:17 -0500 Message-Id: <20210112003017.4010304-7-willemdebruijn.kernel@gmail.com> X-Mailer: git-send-email 2.30.0.284.gd98b1dd5eaa7-goog In-Reply-To: <20210112003017.4010304-1-willemdebruijn.kernel@gmail.com> References: <20210112003017.4010304-1-willemdebruijn.kernel@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org From: Willem de Bruijn io_pgetevents has four variants, including compat variants of both timespec and sigmask. With set_maybe_compat_user_sigmask helper, the latter can be deduplicated. Move the shared logic to new do_io_pgetevents, analogous to do_io_getevents. Signed-off-by: Willem de Bruijn Cc: Benjamin LaHaise --- fs/aio.c | 94 ++++++++++++++++++++++---------------------------------- 1 file changed, 37 insertions(+), 57 deletions(-) diff --git a/fs/aio.c b/fs/aio.c index d213be7b8a7e..56460ab47d64 100644 --- a/fs/aio.c +++ b/fs/aio.c @@ -2101,6 +2101,31 @@ struct __aio_sigset { size_t sigsetsize; }; +static long do_io_pgetevents(aio_context_t ctx_id, + long min_nr, + long nr, + struct io_event __user *events, + struct timespec64 *ts, + const void __user *umask, + size_t sigsetsize) +{ + bool interrupted; + int ret; + + ret = set_maybe_compat_user_sigmask(umask, sigsetsize); + if (ret) + return ret; + + ret = do_io_getevents(ctx_id, min_nr, nr, events, ts); + + interrupted = signal_pending(current); + restore_saved_sigmask_unless(interrupted); + if (interrupted && !ret) + ret = -ERESTARTNOHAND; + + return ret; +} + SYSCALL_DEFINE6(io_pgetevents, aio_context_t, ctx_id, long, min_nr, @@ -2111,8 +2136,6 @@ SYSCALL_DEFINE6(io_pgetevents, { struct __aio_sigset ksig = { NULL, }; struct timespec64 ts; - bool interrupted; - int ret; if (timeout && unlikely(get_timespec64(&ts, timeout))) return -EFAULT; @@ -2120,18 +2143,9 @@ SYSCALL_DEFINE6(io_pgetevents, if (usig && copy_from_user(&ksig, usig, sizeof(ksig))) return -EFAULT; - ret = set_user_sigmask(ksig.sigmask, ksig.sigsetsize); - if (ret) - return ret; - - ret = do_io_getevents(ctx_id, min_nr, nr, events, timeout ? &ts : NULL); - - interrupted = signal_pending(current); - restore_saved_sigmask_unless(interrupted); - if (interrupted && !ret) - ret = -ERESTARTNOHAND; - - return ret; + return do_io_pgetevents(ctx_id, min_nr, nr, events, + timeout ? &ts : NULL, + ksig.sigmask, ksig.sigsetsize); } #if defined(CONFIG_COMPAT_32BIT_TIME) && !defined(CONFIG_64BIT) @@ -2146,8 +2160,6 @@ SYSCALL_DEFINE6(io_pgetevents_time32, { struct __aio_sigset ksig = { NULL, }; struct timespec64 ts; - bool interrupted; - int ret; if (timeout && unlikely(get_old_timespec32(&ts, timeout))) return -EFAULT; @@ -2155,19 +2167,9 @@ SYSCALL_DEFINE6(io_pgetevents_time32, if (usig && copy_from_user(&ksig, usig, sizeof(ksig))) return -EFAULT; - - ret = set_user_sigmask(ksig.sigmask, ksig.sigsetsize); - if (ret) - return ret; - - ret = do_io_getevents(ctx_id, min_nr, nr, events, timeout ? &ts : NULL); - - interrupted = signal_pending(current); - restore_saved_sigmask_unless(interrupted); - if (interrupted && !ret) - ret = -ERESTARTNOHAND; - - return ret; + return do_io_pgetevents(ctx_id, min_nr, nr, events, + timeout ? &ts : NULL, + ksig.sigmask, ksig.sigsetsize); } #endif @@ -2213,8 +2215,6 @@ COMPAT_SYSCALL_DEFINE6(io_pgetevents, { struct __compat_aio_sigset ksig = { 0, }; struct timespec64 t; - bool interrupted; - int ret; if (timeout && get_old_timespec32(&t, timeout)) return -EFAULT; @@ -2222,18 +2222,9 @@ COMPAT_SYSCALL_DEFINE6(io_pgetevents, if (usig && copy_from_user(&ksig, usig, sizeof(ksig))) return -EFAULT; - ret = set_compat_user_sigmask(compat_ptr(ksig.sigmask), ksig.sigsetsize); - if (ret) - return ret; - - ret = do_io_getevents(ctx_id, min_nr, nr, events, timeout ? &t : NULL); - - interrupted = signal_pending(current); - restore_saved_sigmask_unless(interrupted); - if (interrupted && !ret) - ret = -ERESTARTNOHAND; - - return ret; + return do_io_pgetevents(ctx_id, min_nr, nr, events, + timeout ? &t : NULL, + compat_ptr(ksig.sigmask), ksig.sigsetsize); } #endif @@ -2248,8 +2239,6 @@ COMPAT_SYSCALL_DEFINE6(io_pgetevents_time64, { struct __compat_aio_sigset ksig = { 0, }; struct timespec64 t; - bool interrupted; - int ret; if (timeout && get_timespec64(&t, timeout)) return -EFAULT; @@ -2257,17 +2246,8 @@ COMPAT_SYSCALL_DEFINE6(io_pgetevents_time64, if (usig && copy_from_user(&ksig, usig, sizeof(ksig))) return -EFAULT; - ret = set_compat_user_sigmask(compat_ptr(ksig.sigmask), ksig.sigsetsize); - if (ret) - return ret; - - ret = do_io_getevents(ctx_id, min_nr, nr, events, timeout ? &t : NULL); - - interrupted = signal_pending(current); - restore_saved_sigmask_unless(interrupted); - if (interrupted && !ret) - ret = -ERESTARTNOHAND; - - return ret; + return do_io_pgetevents(ctx_id, min_nr, nr, events, + timeout ? &t : NULL, + compat_ptr(ksig.sigmask), ksig.sigsetsize); } #endif