From: Chuck Lever <cel@kernel.org>
To: viro@zeniv.linux.org.uk, kees@kernel.org, gustavoars@kernel.org
Cc: linux-hardening@vger.kernel.org, linux-block@vger.kernel.org,
linux-fsdevel@vger.kernel.org, <netdev@vger.kernel.org>,
Chuck Lever <chuck.lever@oracle.com>
Subject: [RFC PATCH] iov: Bypass usercopy hardening for kernel iterators
Date: Tue, 3 Mar 2026 11:29:32 -0500 [thread overview]
Message-ID: <20260303162932.22910-1-cel@kernel.org> (raw)
From: Chuck Lever <chuck.lever@oracle.com>
Profiling NFSD under an iozone workload showed that hardened
usercopy checks consume roughly 1.3% of CPU in the TCP receive
path. The runtime check in check_object_size() validates that
copy buffers reside in expected slab regions, which is
meaningful when data crosses the user/kernel boundary but adds
no value when both source and destination are kernel addresses.
Split check_copy_size() so that copy_to_iter() can bypass the
runtime check_object_size() call for kernel-only iterators
(ITER_BVEC, ITER_KVEC). Existing callers of check_copy_size()
are unaffected; user-backed iterators still receive the full
usercopy validation.
This benefits all kernel consumers of copy_to_iter(), including
the TCP receive path used by the NFS client and server,
NVMe-TCP, and any other subsystem that uses ITER_BVEC or
ITER_KVEC receive buffers.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
include/linux/ucopysize.h | 10 +++++++++-
include/linux/uio.h | 9 +++++++--
2 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/include/linux/ucopysize.h b/include/linux/ucopysize.h
index 41c2d9720466..b3eacb4869a8 100644
--- a/include/linux/ucopysize.h
+++ b/include/linux/ucopysize.h
@@ -42,7 +42,7 @@ static inline void copy_overflow(int size, unsigned long count)
}
static __always_inline __must_check bool
-check_copy_size(const void *addr, size_t bytes, bool is_source)
+check_copy_size_nosec(const void *addr, size_t bytes, bool is_source)
{
int sz = __builtin_object_size(addr, 0);
if (unlikely(sz >= 0 && sz < bytes)) {
@@ -56,6 +56,14 @@ check_copy_size(const void *addr, size_t bytes, bool is_source)
}
if (WARN_ON_ONCE(bytes > INT_MAX))
return false;
+ return true;
+}
+
+static __always_inline __must_check bool
+check_copy_size(const void *addr, size_t bytes, bool is_source)
+{
+ if (!check_copy_size_nosec(addr, bytes, is_source))
+ return false;
check_object_size(addr, bytes, is_source);
return true;
}
diff --git a/include/linux/uio.h b/include/linux/uio.h
index a9bc5b3067e3..f860529abfbe 100644
--- a/include/linux/uio.h
+++ b/include/linux/uio.h
@@ -216,8 +216,13 @@ size_t copy_page_to_iter_nofault(struct page *page, unsigned offset,
static __always_inline __must_check
size_t copy_to_iter(const void *addr, size_t bytes, struct iov_iter *i)
{
- if (check_copy_size(addr, bytes, true))
- return _copy_to_iter(addr, bytes, i);
+ if (user_backed_iter(i)) {
+ if (check_copy_size(addr, bytes, true))
+ return _copy_to_iter(addr, bytes, i);
+ } else {
+ if (check_copy_size_nosec(addr, bytes, true))
+ return _copy_to_iter(addr, bytes, i);
+ }
return 0;
}
--
2.53.0
next reply other threads:[~2026-03-03 16:29 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-03 16:29 Chuck Lever [this message]
2026-03-03 18:00 ` [RFC PATCH] iov: Bypass usercopy hardening for kernel iterators Matthew Wilcox
2026-03-03 19:41 ` Chuck Lever
2026-03-03 19:59 ` Matthew Wilcox
2026-03-25 17:26 ` Chuck Lever
2026-03-25 21:27 ` Kees Cook
2026-03-25 21:29 ` Chuck Lever
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260303162932.22910-1-cel@kernel.org \
--to=cel@kernel.org \
--cc=chuck.lever@oracle.com \
--cc=gustavoars@kernel.org \
--cc=kees@kernel.org \
--cc=linux-block@vger.kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-hardening@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=viro@zeniv.linux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.