| From 252785cb658e4262ecd1b5310e2830f48fd7433e Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Thu, 3 Mar 2022 10:24:40 +0800 |
| Subject: tuntap: add sanity checks about msg_controllen in sendmsg |
| |
| From: Harold Huang <baymaxhuang@gmail.com> |
| |
| [ Upstream commit 74a335a07a17d131b9263bfdbdcb5e40673ca9ca ] |
| |
| In patch [1], tun_msg_ctl was added to allow pass batched xdp buffers to |
| tun_sendmsg. Although we donot use msg_controllen in this path, we should |
| check msg_controllen to make sure the caller pass a valid msg_ctl. |
| |
| [1]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=fe8dd45bb7556246c6b76277b1ba4296c91c2505 |
| |
| Reported-by: Eric Dumazet <eric.dumazet@gmail.com> |
| Suggested-by: Jason Wang <jasowang@redhat.com> |
| Signed-off-by: Harold Huang <baymaxhuang@gmail.com> |
| Acked-by: Jason Wang <jasowang@redhat.com> |
| Link: https://lore.kernel.org/r/20220303022441.383865-1-baymaxhuang@gmail.com |
| Signed-off-by: Jakub Kicinski <kuba@kernel.org> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/net/tap.c | 3 ++- |
| drivers/net/tun.c | 3 ++- |
| drivers/vhost/net.c | 1 + |
| 3 files changed, 5 insertions(+), 2 deletions(-) |
| |
| diff --git a/drivers/net/tap.c b/drivers/net/tap.c |
| index 8e3a28ba6b28..ba2ef5437e16 100644 |
| --- a/drivers/net/tap.c |
| +++ b/drivers/net/tap.c |
| @@ -1198,7 +1198,8 @@ static int tap_sendmsg(struct socket *sock, struct msghdr *m, |
| struct xdp_buff *xdp; |
| int i; |
| |
| - if (ctl && (ctl->type == TUN_MSG_PTR)) { |
| + if (m->msg_controllen == sizeof(struct tun_msg_ctl) && |
| + ctl && ctl->type == TUN_MSG_PTR) { |
| for (i = 0; i < ctl->num; i++) { |
| xdp = &((struct xdp_buff *)ctl->ptr)[i]; |
| tap_get_user_xdp(q, xdp); |
| diff --git a/drivers/net/tun.c b/drivers/net/tun.c |
| index 45a67e72a02c..02de8d998bfa 100644 |
| --- a/drivers/net/tun.c |
| +++ b/drivers/net/tun.c |
| @@ -2489,7 +2489,8 @@ static int tun_sendmsg(struct socket *sock, struct msghdr *m, size_t total_len) |
| if (!tun) |
| return -EBADFD; |
| |
| - if (ctl && (ctl->type == TUN_MSG_PTR)) { |
| + if (m->msg_controllen == sizeof(struct tun_msg_ctl) && |
| + ctl && ctl->type == TUN_MSG_PTR) { |
| struct tun_page tpage; |
| int n = ctl->num; |
| int flush = 0; |
| diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c |
| index 28ef323882fb..792ab5f23647 100644 |
| --- a/drivers/vhost/net.c |
| +++ b/drivers/vhost/net.c |
| @@ -473,6 +473,7 @@ static void vhost_tx_batch(struct vhost_net *net, |
| goto signal_used; |
| |
| msghdr->msg_control = &ctl; |
| + msghdr->msg_controllen = sizeof(ctl); |
| err = sock->ops->sendmsg(sock, msghdr, 0); |
| if (unlikely(err < 0)) { |
| vq_err(&nvq->vq, "Fail to batch sending packets\n"); |
| -- |
| 2.35.1 |
| |