From: Pavel Begunkov <[email protected]>
To: [email protected]
Cc: [email protected]
Subject: [PATCH 4/7] io_uring/net: verify msghdr before copying iovec
Date: Wed, 26 Feb 2025 11:41:18 +0000 [thread overview]
Message-ID: <cd35dc1b48d4e6e31f59ae7304c037fbe8a3fd3d.1740569495.git.asml.silence@gmail.com> (raw)
In-Reply-To: <[email protected]>
Normally, net/ would verify msghdr before importing iovec, for example
see copy_msghdr_from_user(), which further assumed by __copy_msghdr()
validating msg->msg_iovlen.
io_uring does it in reverse order, which is fine, but it'll be more
convenient for flip it so that the iovec business is done at the end and
eventually can be nicely pulled out of msghdr parsing section and
thought as a sepaarate step. That also makes structure accesses more
localised, which should be better for caches.
Signed-off-by: Pavel Begunkov <[email protected]>
---
io_uring/net.c | 43 ++++++++++++++++++-------------------------
1 file changed, 18 insertions(+), 25 deletions(-)
diff --git a/io_uring/net.c b/io_uring/net.c
index 67d768e6ecdd..14eeebfd8a5a 100644
--- a/io_uring/net.c
+++ b/io_uring/net.c
@@ -195,7 +195,8 @@ static inline void io_mshot_prep_retry(struct io_kiocb *req,
#ifdef CONFIG_COMPAT
static int io_compat_msg_copy_hdr(struct io_kiocb *req,
struct io_async_msghdr *iomsg,
- struct compat_msghdr *msg, int ddir)
+ struct compat_msghdr *msg, int ddir,
+ struct sockaddr __user **save_addr)
{
struct io_sr_msg *sr = io_kiocb_to_cmd(req, struct io_sr_msg);
struct compat_iovec __user *uiov;
@@ -213,6 +214,10 @@ static int io_compat_msg_copy_hdr(struct io_kiocb *req,
if (copy_from_user(msg, sr->umsg_compat, sizeof(*msg)))
return -EFAULT;
+ ret = __get_compat_msghdr(&iomsg->msg, msg, save_addr);
+ if (ret)
+ return ret;
+
uiov = compat_ptr(msg->msg_iov);
if (req->flags & REQ_F_BUFFER_SELECT) {
if (msg->msg_iovlen == 0) {
@@ -262,7 +267,8 @@ static int io_copy_msghdr_from_user(struct user_msghdr *msg,
}
static int io_msg_copy_hdr(struct io_kiocb *req, struct io_async_msghdr *iomsg,
- struct user_msghdr *msg, int ddir)
+ struct user_msghdr *msg, int ddir,
+ struct sockaddr __user **save_addr)
{
struct io_sr_msg *sr = io_kiocb_to_cmd(req, struct io_sr_msg);
struct user_msghdr __user *umsg = sr->umsg;
@@ -283,6 +289,10 @@ static int io_msg_copy_hdr(struct io_kiocb *req, struct io_async_msghdr *iomsg,
msg->msg_flags = 0;
+ ret = __copy_msghdr(&iomsg->msg, msg, save_addr);
+ if (ret)
+ return ret;
+
if (req->flags & REQ_F_BUFFER_SELECT) {
if (msg->msg_iovlen == 0) {
sr->len = iov->iov_len = 0;
@@ -322,22 +332,14 @@ static int io_sendmsg_copy_hdr(struct io_kiocb *req,
if (io_is_compat(req->ctx)) {
struct compat_msghdr cmsg;
- ret = io_compat_msg_copy_hdr(req, iomsg, &cmsg, ITER_SOURCE);
- if (unlikely(ret))
- return ret;
-
- ret = __get_compat_msghdr(&iomsg->msg, &cmsg, NULL);
+ ret = io_compat_msg_copy_hdr(req, iomsg, &cmsg, ITER_SOURCE,
+ NULL);
sr->msg_control = iomsg->msg.msg_control_user;
return ret;
}
#endif
- ret = io_msg_copy_hdr(req, iomsg, &msg, ITER_SOURCE);
- if (unlikely(ret))
- return ret;
-
- ret = __copy_msghdr(&iomsg->msg, &msg, NULL);
-
+ ret = io_msg_copy_hdr(req, iomsg, &msg, ITER_SOURCE, NULL);
/* save msg_control as sys_sendmsg() overwrites it */
sr->msg_control = iomsg->msg.msg_control_user;
return ret;
@@ -719,27 +721,18 @@ static int io_recvmsg_copy_hdr(struct io_kiocb *req,
if (io_is_compat(req->ctx)) {
struct compat_msghdr cmsg;
- ret = io_compat_msg_copy_hdr(req, iomsg, &cmsg, ITER_DEST);
+ ret = io_compat_msg_copy_hdr(req, iomsg, &cmsg, ITER_DEST,
+ &iomsg->uaddr);
if (unlikely(ret))
return ret;
-
- ret = __get_compat_msghdr(&iomsg->msg, &cmsg, &iomsg->uaddr);
- if (unlikely(ret))
- return ret;
-
return io_recvmsg_mshot_prep(req, iomsg, cmsg.msg_namelen,
cmsg.msg_controllen);
}
#endif
- ret = io_msg_copy_hdr(req, iomsg, &msg, ITER_DEST);
+ ret = io_msg_copy_hdr(req, iomsg, &msg, ITER_DEST, &iomsg->uaddr);
if (unlikely(ret))
return ret;
-
- ret = __copy_msghdr(&iomsg->msg, &msg, &iomsg->uaddr);
- if (unlikely(ret))
- return ret;
-
return io_recvmsg_mshot_prep(req, iomsg, msg.msg_namelen,
msg.msg_controllen);
}
--
2.48.1
next prev parent reply other threads:[~2025-02-26 11:40 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-02-26 11:41 [PATCH 0/7] improve net msghdr / iovec handlng Pavel Begunkov
2025-02-26 11:41 ` [PATCH 1/7] io_uring/net: remove unnecessary REQ_F_NEED_CLEANUP Pavel Begunkov
2025-02-26 11:41 ` [PATCH 2/7] io_uring/net: simplify compat selbuf iov parsing Pavel Begunkov
2025-02-26 11:41 ` [PATCH 3/7] io_uring/net: isolate msghdr copying code Pavel Begunkov
2025-02-26 11:41 ` Pavel Begunkov [this message]
2025-02-26 11:41 ` [PATCH 5/7] io_uring/net: derive iovec storage later Pavel Begunkov
2025-02-26 11:41 ` [PATCH 6/7] io_uring/net: unify *mshot_prep calls with compat Pavel Begunkov
2025-02-26 11:41 ` [PATCH 7/7] io_uring/net: extract iovec import into a helper Pavel Begunkov
2025-02-26 17:41 ` [PATCH 0/7] improve net msghdr / iovec handlng Jens Axboe
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=cd35dc1b48d4e6e31f59ae7304c037fbe8a3fd3d.1740569495.git.asml.silence@gmail.com \
[email protected] \
[email protected] \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox