mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	net: switch to use skb_probe_transport_header()
Switch to use the new help skb_probe_transport_header() to do the l4 header probing for untrusted sources. For packets with partial csum, the header should already been set by skb_partial_csum_set(). Cc: Eric Dumazet <edumazet@google.com> Signed-off-by: Jason Wang <jasowang@redhat.com> Acked-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									5203cd28db
								
							
						
					
					
						commit
						40893fd0fd
					
				
					 4 changed files with 6 additions and 45 deletions
				
			
		| 
						 | 
					@ -21,7 +21,6 @@
 | 
				
			||||||
#include <net/rtnetlink.h>
 | 
					#include <net/rtnetlink.h>
 | 
				
			||||||
#include <net/sock.h>
 | 
					#include <net/sock.h>
 | 
				
			||||||
#include <linux/virtio_net.h>
 | 
					#include <linux/virtio_net.h>
 | 
				
			||||||
#include <net/flow_keys.h>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * A macvtap queue is the central object of this driver, it connects
 | 
					 * A macvtap queue is the central object of this driver, it connects
 | 
				
			||||||
| 
						 | 
					@ -646,7 +645,6 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m,
 | 
				
			||||||
	int vnet_hdr_len = 0;
 | 
						int vnet_hdr_len = 0;
 | 
				
			||||||
	int copylen = 0;
 | 
						int copylen = 0;
 | 
				
			||||||
	bool zerocopy = false;
 | 
						bool zerocopy = false;
 | 
				
			||||||
	struct flow_keys keys;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (q->flags & IFF_VNET_HDR) {
 | 
						if (q->flags & IFF_VNET_HDR) {
 | 
				
			||||||
		vnet_hdr_len = q->vnet_hdr_sz;
 | 
							vnet_hdr_len = q->vnet_hdr_sz;
 | 
				
			||||||
| 
						 | 
					@ -727,12 +725,7 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m,
 | 
				
			||||||
			goto err_kfree;
 | 
								goto err_kfree;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (skb->ip_summed == CHECKSUM_PARTIAL)
 | 
						skb_probe_transport_header(skb, ETH_HLEN);
 | 
				
			||||||
		skb_set_transport_header(skb, skb_checksum_start_offset(skb));
 | 
					 | 
				
			||||||
	else if (skb_flow_dissect(skb, &keys))
 | 
					 | 
				
			||||||
		skb_set_transport_header(skb, keys.thoff);
 | 
					 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		skb_set_transport_header(skb, ETH_HLEN);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rcu_read_lock_bh();
 | 
						rcu_read_lock_bh();
 | 
				
			||||||
	vlan = rcu_dereference_bh(q->vlan);
 | 
						vlan = rcu_dereference_bh(q->vlan);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -70,7 +70,6 @@
 | 
				
			||||||
#include <net/sock.h>
 | 
					#include <net/sock.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <asm/uaccess.h>
 | 
					#include <asm/uaccess.h>
 | 
				
			||||||
#include <net/flow_keys.h>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Uncomment to enable debugging */
 | 
					/* Uncomment to enable debugging */
 | 
				
			||||||
/* #define TUN_DEBUG 1 */
 | 
					/* #define TUN_DEBUG 1 */
 | 
				
			||||||
| 
						 | 
					@ -1050,7 +1049,6 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
 | 
				
			||||||
	bool zerocopy = false;
 | 
						bool zerocopy = false;
 | 
				
			||||||
	int err;
 | 
						int err;
 | 
				
			||||||
	u32 rxhash;
 | 
						u32 rxhash;
 | 
				
			||||||
	struct flow_keys keys;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!(tun->flags & TUN_NO_PI)) {
 | 
						if (!(tun->flags & TUN_NO_PI)) {
 | 
				
			||||||
		if ((len -= sizeof(pi)) > total_len)
 | 
							if ((len -= sizeof(pi)) > total_len)
 | 
				
			||||||
| 
						 | 
					@ -1205,13 +1203,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	skb_reset_network_header(skb);
 | 
						skb_reset_network_header(skb);
 | 
				
			||||||
 | 
						skb_probe_transport_header(skb, 0);
 | 
				
			||||||
	if (skb->ip_summed == CHECKSUM_PARTIAL)
 | 
					 | 
				
			||||||
		skb_set_transport_header(skb, skb_checksum_start_offset(skb));
 | 
					 | 
				
			||||||
	else if (skb_flow_dissect(skb, &keys))
 | 
					 | 
				
			||||||
		skb_set_transport_header(skb, keys.thoff);
 | 
					 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		skb_reset_transport_header(skb);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rxhash = skb_get_rxhash(skb);
 | 
						rxhash = skb_get_rxhash(skb);
 | 
				
			||||||
	netif_rx_ni(skb);
 | 
						netif_rx_ni(skb);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -39,7 +39,6 @@
 | 
				
			||||||
#include <linux/udp.h>
 | 
					#include <linux/udp.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <net/tcp.h>
 | 
					#include <net/tcp.h>
 | 
				
			||||||
#include <net/flow_keys.h>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <xen/xen.h>
 | 
					#include <xen/xen.h>
 | 
				
			||||||
#include <xen/events.h>
 | 
					#include <xen/events.h>
 | 
				
			||||||
| 
						 | 
					@ -1506,14 +1505,7 @@ static void xen_netbk_tx_submit(struct xen_netbk *netbk)
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (!skb_transport_header_was_set(skb)) {
 | 
							skb_probe_transport_header(skb, 0);
 | 
				
			||||||
			struct flow_keys keys;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			if (skb_flow_dissect(skb, &keys))
 | 
					 | 
				
			||||||
				skb_set_transport_header(skb, keys.thoff);
 | 
					 | 
				
			||||||
			else
 | 
					 | 
				
			||||||
				skb_reset_transport_header(skb);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		vif->dev->stats.rx_bytes += skb->len;
 | 
							vif->dev->stats.rx_bytes += skb->len;
 | 
				
			||||||
		vif->dev->stats.rx_packets++;
 | 
							vif->dev->stats.rx_packets++;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -88,7 +88,6 @@
 | 
				
			||||||
#include <linux/virtio_net.h>
 | 
					#include <linux/virtio_net.h>
 | 
				
			||||||
#include <linux/errqueue.h>
 | 
					#include <linux/errqueue.h>
 | 
				
			||||||
#include <linux/net_tstamp.h>
 | 
					#include <linux/net_tstamp.h>
 | 
				
			||||||
#include <net/flow_keys.h>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_INET
 | 
					#ifdef CONFIG_INET
 | 
				
			||||||
#include <net/inet_common.h>
 | 
					#include <net/inet_common.h>
 | 
				
			||||||
| 
						 | 
					@ -1413,7 +1412,6 @@ static int packet_sendmsg_spkt(struct kiocb *iocb, struct socket *sock,
 | 
				
			||||||
	__be16 proto = 0;
 | 
						__be16 proto = 0;
 | 
				
			||||||
	int err;
 | 
						int err;
 | 
				
			||||||
	int extra_len = 0;
 | 
						int extra_len = 0;
 | 
				
			||||||
	struct flow_keys keys;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 *	Get and verify the address.
 | 
						 *	Get and verify the address.
 | 
				
			||||||
| 
						 | 
					@ -1514,10 +1512,7 @@ static int packet_sendmsg_spkt(struct kiocb *iocb, struct socket *sock,
 | 
				
			||||||
	if (unlikely(extra_len == 4))
 | 
						if (unlikely(extra_len == 4))
 | 
				
			||||||
		skb->no_fcs = 1;
 | 
							skb->no_fcs = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (skb_flow_dissect(skb, &keys))
 | 
						skb_probe_transport_header(skb, 0);
 | 
				
			||||||
		skb_set_transport_header(skb, keys.thoff);
 | 
					 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		skb_reset_transport_header(skb);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dev_queue_xmit(skb);
 | 
						dev_queue_xmit(skb);
 | 
				
			||||||
	rcu_read_unlock();
 | 
						rcu_read_unlock();
 | 
				
			||||||
| 
						 | 
					@ -1925,7 +1920,6 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb,
 | 
				
			||||||
	struct page *page;
 | 
						struct page *page;
 | 
				
			||||||
	void *data;
 | 
						void *data;
 | 
				
			||||||
	int err;
 | 
						int err;
 | 
				
			||||||
	struct flow_keys keys;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ph.raw = frame;
 | 
						ph.raw = frame;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1950,11 +1944,7 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	skb_reserve(skb, hlen);
 | 
						skb_reserve(skb, hlen);
 | 
				
			||||||
	skb_reset_network_header(skb);
 | 
						skb_reset_network_header(skb);
 | 
				
			||||||
 | 
						skb_probe_transport_header(skb, 0);
 | 
				
			||||||
	if (skb_flow_dissect(skb, &keys))
 | 
					 | 
				
			||||||
		skb_set_transport_header(skb, keys.thoff);
 | 
					 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		skb_reset_transport_header(skb);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (po->tp_tx_has_off) {
 | 
						if (po->tp_tx_has_off) {
 | 
				
			||||||
		int off_min, off_max, off;
 | 
							int off_min, off_max, off;
 | 
				
			||||||
| 
						 | 
					@ -2212,7 +2202,6 @@ static int packet_snd(struct socket *sock,
 | 
				
			||||||
	unsigned short gso_type = 0;
 | 
						unsigned short gso_type = 0;
 | 
				
			||||||
	int hlen, tlen;
 | 
						int hlen, tlen;
 | 
				
			||||||
	int extra_len = 0;
 | 
						int extra_len = 0;
 | 
				
			||||||
	struct flow_keys keys;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 *	Get and verify the address.
 | 
						 *	Get and verify the address.
 | 
				
			||||||
| 
						 | 
					@ -2365,12 +2354,7 @@ static int packet_snd(struct socket *sock,
 | 
				
			||||||
		len += vnet_hdr_len;
 | 
							len += vnet_hdr_len;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (skb->ip_summed == CHECKSUM_PARTIAL)
 | 
						skb_probe_transport_header(skb, reserve);
 | 
				
			||||||
		skb_set_transport_header(skb, skb_checksum_start_offset(skb));
 | 
					 | 
				
			||||||
	else if (skb_flow_dissect(skb, &keys))
 | 
					 | 
				
			||||||
		skb_set_transport_header(skb, keys.thoff);
 | 
					 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		skb_set_transport_header(skb, reserve);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (unlikely(extra_len == 4))
 | 
						if (unlikely(extra_len == 4))
 | 
				
			||||||
		skb->no_fcs = 1;
 | 
							skb->no_fcs = 1;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue