lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening linux-cve-announce PHC | |
Open Source and information security mailing list archives
| ||
|
Message-Id: <20220418044339.127545-3-liuhangbin@gmail.com> Date: Mon, 18 Apr 2022 12:43:39 +0800 From: Hangbin Liu <liuhangbin@...il.com> To: netdev@...r.kernel.org Cc: "Michael S . Tsirkin" <mst@...hat.com>, Jason Wang <jasowang@...hat.com>, "David S . Miller" <davem@...emloft.net>, Jakub Kicinski <kuba@...nel.org>, Paolo Abeni <pabeni@...hat.com>, Maxim Mikityanskiy <maximmi@...lanox.com>, Willem de Bruijn <willemb@...gle.com>, virtualization@...ts.linux-foundation.org, Balazs Nemeth <bnemeth@...hat.com>, Mike Pattrick <mailmpattric@...hat.com>, Eric Dumazet <edumazet@...gle.com>, Hangbin Liu <liuhangbin@...il.com> Subject: [PATCH net 2/2] virtio_net: check L3 protocol for VLAN packets For gso packets, virtio_net_hdr_to_skb() will check the protocol via virtio_net_hdr_match_proto(). But a packet may come from a raw socket with a VLAN tag. Checking the VLAN protocol for virtio net_hdr makes no sense. Let's check the L3 protocol if it's a VLAN packet. Make the virtio_net_hdr_match_proto() checking for all skbs instead of only skb without protocol setting. Also update the data, protocol parameter for skb_flow_dissect_flow_keys_basic() as the skb->protocol may not IP or IPv6. Fixes: 7e5cced9ca84 ("net: accept UFOv6 packages in virtio_net_hdr_to_skb") Signed-off-by: Hangbin Liu <liuhangbin@...il.com> --- include/linux/virtio_net.h | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/include/linux/virtio_net.h b/include/linux/virtio_net.h index a960de68ac69..97b4f9680786 100644 --- a/include/linux/virtio_net.h +++ b/include/linux/virtio_net.h @@ -3,6 +3,7 @@ #define _LINUX_VIRTIO_NET_H #include <linux/if_vlan.h> +#include <uapi/linux/if_arp.h> #include <uapi/linux/tcp.h> #include <uapi/linux/udp.h> #include <uapi/linux/virtio_net.h> @@ -102,25 +103,36 @@ static inline int virtio_net_hdr_to_skb(struct sk_buff *skb, */ if (gso_type && skb->network_header) { struct flow_keys_basic keys; + __be16 protocol; if (!skb->protocol) { - __be16 protocol = dev_parse_header_protocol(skb); + protocol = dev_parse_header_protocol(skb); if (!protocol) virtio_net_hdr_set_proto(skb, hdr); - else if (!virtio_net_hdr_match_proto(protocol, hdr->gso_type)) - return -EINVAL; else skb->protocol = protocol; + } else { + protocol = skb->protocol; } + + /* Get L3 protocol if current protocol is VLAN */ + if (likely(skb->dev->type == ARPHRD_ETHER) && + eth_type_vlan(protocol)) + protocol = vlan_get_protocol(skb); + + if (!virtio_net_hdr_match_proto(protocol, hdr->gso_type)) + return -EINVAL; + retry: if (!skb_flow_dissect_flow_keys_basic(NULL, skb, &keys, - NULL, 0, 0, 0, - 0)) { + skb->data, protocol, + skb_network_offset(skb), + skb_headlen(skb), 0)) { /* UFO does not specify ipv4 or 6: try both */ if (gso_type & SKB_GSO_UDP && - skb->protocol == htons(ETH_P_IP)) { - skb->protocol = htons(ETH_P_IPV6); + protocol == htons(ETH_P_IP)) { + protocol = htons(ETH_P_IPV6); goto retry; } return -EINVAL; -- 2.35.1
Powered by blists - more mailing lists