linux/net
Sean Tranchetti 0ecebdfb2e net: udp: fix handling of CHECKSUM_COMPLETE packets
[ Upstream commit db4f1be3ca ]

Current handling of CHECKSUM_COMPLETE packets by the UDP stack is
incorrect for any packet that has an incorrect checksum value.

udp4/6_csum_init() will both make a call to
__skb_checksum_validate_complete() to initialize/validate the csum
field when receiving a CHECKSUM_COMPLETE packet. When this packet
fails validation, skb->csum will be overwritten with the pseudoheader
checksum so the packet can be fully validated by software, but the
skb->ip_summed value will be left as CHECKSUM_COMPLETE so that way
the stack can later warn the user about their hardware spewing bad
checksums. Unfortunately, leaving the SKB in this state can cause
problems later on in the checksum calculation.

Since the the packet is still marked as CHECKSUM_COMPLETE,
udp_csum_pull_header() will SUBTRACT the checksum of the UDP header
from skb->csum instead of adding it, leaving us with a garbage value
in that field. Once we try to copy the packet to userspace in the
udp4/6_recvmsg(), we'll make a call to skb_copy_and_csum_datagram_msg()
to checksum the packet data and add it in the garbage skb->csum value
to perform our final validation check.

Since the value we're validating is not the proper checksum, it's possible
that the folded value could come out to 0, causing us not to drop the
packet. Instead, we believe that the packet was checksummed incorrectly
by hardware since skb->ip_summed is still CHECKSUM_COMPLETE, and we attempt
to warn the user with netdev_rx_csum_fault(skb->dev);

Unfortunately, since this is the UDP path, skb->dev has been overwritten
by skb->dev_scratch and is no longer a valid pointer, so we end up
reading invalid memory.

This patch addresses this problem in two ways:
	1) Do not use the dev pointer when calling netdev_rx_csum_fault()
	   from skb_copy_and_csum_datagram_msg(). Since this gets called
	   from the UDP path where skb->dev has been overwritten, we have
	   no way of knowing if the pointer is still valid. Also for the
	   sake of consistency with the other uses of
	   netdev_rx_csum_fault(), don't attempt to call it if the
	   packet was checksummed by software.

	2) Add better CHECKSUM_COMPLETE handling to udp4/6_csum_init().
	   If we receive a packet that's CHECKSUM_COMPLETE that fails
	   verification (i.e. skb->csum_valid == 0), check who performed
	   the calculation. It's possible that the checksum was done in
	   software by the network stack earlier (such as Netfilter's
	   CONNTRACK module), and if that says the checksum is bad,
	   we can drop the packet immediately instead of waiting until
	   we try and copy it to userspace. Otherwise, we need to
	   mark the SKB as CHECKSUM_NONE, since the skb->csum field
	   no longer contains the full packet checksum after the
	   call to __skb_checksum_validate_complete().

Fixes: e6afc8ace6 ("udp: remove headers from UDP packets before queueing")
Fixes: c84d949057 ("udp: copy skb->truesize in the first cache line")
Cc: Sam Kumar <samanthakumar@google.com>
Cc: Eric Dumazet <edumazet@google.com>
Signed-off-by: Sean Tranchetti <stranche@codeaurora.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2018-11-04 14:52:49 +01:00
..
6lowpan 6lowpan: iphc: reset mac_header after decompress to fix panic 2018-10-03 17:00:47 -07:00
9p net/9p: fix error path of p9_virtio_probe 2018-09-15 09:45:29 +02:00
802 License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
8021q net: fix use-after-free in GRO with ESP 2018-07-22 14:28:44 +02:00
appletalk License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
atm atm: Preserve value of skb->truesize when accounting to vcc 2018-07-22 14:28:43 +02:00
ax25 License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
batman-adv batman-adv: fix hardif_neigh refcount on queue_work() failure 2018-10-20 09:48:49 +02:00
bluetooth Bluetooth: SMP: fix crash in unpairing 2018-11-04 14:52:39 +01:00
bpf
bridge net: bridge: remove ipv6 zero address check in mcast queries 2018-11-04 14:52:48 +01:00
caif net: caif: Add a missing rcu_read_unlock() in caif_flow_cb 2018-09-05 09:26:27 +02:00
can can: af_can: canfd_rcv(): replace WARN_ONCE by pr_warn_once 2018-01-23 19:58:17 +01:00
ceph libceph, ceph: avoid memory leak when specifying same option several times 2018-05-30 07:52:04 +02:00
core net: udp: fix handling of CHECKSUM_COMPLETE packets 2018-11-04 14:52:49 +01:00
dcb net: dcb: For wild-card lookups, use priority -1, not 0 2018-09-19 22:43:43 +02:00
dccp inet: make sure to grab rcu_read_lock before using ireq->ireq_opt 2018-10-18 09:16:21 +02:00
decnet dn_getsockoptdecnet: move nf_{get/set}sockopt outside sock lock 2018-02-25 11:07:52 +01:00
dns_resolver KEYS: DNS: fix parsing multiple options 2018-07-22 14:28:49 +02:00
dsa net: dsa: Do not suspend/resume closed slave_dev 2018-08-06 16:20:48 +02:00
ethernet networking: make skb_push & __skb_push return void pointers 2017-06-16 11:48:40 -04:00
hsr net/hsr: Check skb_put_padto() return value 2017-08-22 13:40:23 -07:00
ieee802154 inet: frags: fix ip6frag_low_thresh boundary 2018-09-19 22:43:47 +02:00
ife net: sched: ife: check on metadata length 2018-04-29 11:33:13 +02:00
ipv4 net: udp: fix handling of CHECKSUM_COMPLETE packets 2018-11-04 14:52:49 +01:00
ipv6 net: udp: fix handling of CHECKSUM_COMPLETE packets 2018-11-04 14:52:49 +01:00
ipx License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
iucv net/iucv: Free memory obtained by kzalloc 2018-03-31 18:10:41 +02:00
kcm kcm: Fix use-after-free caused by clonned sockets 2018-06-11 22:49:19 +02:00
key af_key: Always verify length of provided sadb_key 2018-06-16 09:45:14 +02:00
l2tp l2tp: remove configurable payload offset 2018-11-04 14:52:43 +01:00
l3mdev
lapb net, lapb: convert lapb_cb.refcnt from atomic_t to refcount_t 2017-07-04 22:35:16 +01:00
llc llc: set SOCK_RCU_FREE in llc_sap_add_socket() 2018-11-04 14:52:48 +01:00
mac80211 mac80211: fix TX status reporting for ieee80211s 2018-11-04 14:52:37 +01:00
mac802154 net: mac802154: tx: expand tailroom if necessary 2018-09-09 19:55:52 +02:00
mpls mpls, nospec: Sanitize array index in mpls_label_ok() 2018-02-22 15:42:28 +01:00
ncsi net/ncsi: Fix length of GVI response packet 2017-10-21 01:56:38 +01:00
netfilter netfilter: nf_tables: release chain in flushing set 2018-10-10 08:54:23 +02:00
netlabel netlabel: check for IPV4MASK in addrinfo_get 2018-10-18 09:16:18 +02:00
netlink netlink: Don't shift on 64 for ngroups 2018-08-09 12:16:38 +02:00
netrom net, netrom: convert nr_node.refcount from atomic_t to refcount_t 2017-07-04 22:35:17 +01:00
nfc NFC: Fix possible memory corruption when handling SHDLC I-Frame commands 2018-09-29 03:06:01 -07:00
nsh nsh: set mac len based on inner packet 2018-07-22 14:28:49 +02:00
openvswitch openvswitch: Don't swap table in nlattr_set() after OVS_ATTR_NESTED is found 2018-05-19 10:20:24 +02:00
packet net/packet: fix packet drop as of virtio gso 2018-10-18 09:16:19 +02:00
phonet License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
psample MAINTAINERS: Update Yotam's E-mail 2017-11-01 12:19:03 +09:00
qrtr net: qrtr: Broadcast messages only from control port 2018-08-24 13:09:13 +02:00
rds rds: rds_ib_recv_alloc_cache() should call alloc_percpu_gfp() instead 2018-10-13 09:27:29 +02:00
rfkill rfkill: gpio: fix memory leak in probe error path 2018-05-16 10:10:26 +02:00
rose
rxrpc rxrpc: Fix connection-level abort handling 2018-11-04 14:52:46 +01:00
sched net: sched: gred: pass the right attribute to gred_change_table_def() 2018-11-04 14:52:48 +01:00
sctp sctp: update dst pmtu with the correct daddr 2018-10-18 09:16:19 +02:00
smc net/smc: no shutdown in state SMC_LISTEN 2018-08-24 13:09:22 +02:00
strparser strparser: Remove early eaten to fix full tcp receive buffer stall 2018-07-22 14:28:47 +02:00
sunrpc sunrpc: Don't use stack buffer with scatterlist 2018-09-15 09:45:26 +02:00
switchdev net: switchdev: Remove bridge bypass support from switchdev 2017-08-07 14:48:48 -07:00
tipc tipc: fix flow control accounting for implicit connect 2018-10-18 09:16:19 +02:00
tls tls: possible hang when do_tcp_sendpages hits sndbuf is full case 2018-10-03 17:00:58 -07:00
unix License cleanup: add SPDX license identifiers to some files 2017-11-02 10:04:46 -07:00
vmw_vsock vsock: split dwork to avoid reinitializations 2018-08-22 07:46:08 +02:00
wimax License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
wireless cfg80211: fix use-after-free in reg_process_hint() 2018-11-04 14:52:40 +01:00
x25 License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
xfrm xfrm: validate template mode 2018-11-04 14:52:38 +01:00
compat.c net: support compat 64-bit time in {s,g}etsockopt 2018-05-19 10:20:24 +02:00
Kconfig net: Remove CONFIG_NETFILTER_DEBUG and _ASSERT() macros. 2017-09-04 13:25:20 +02:00
Makefile License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
socket.c net: socket: fix a missing-check bug 2018-11-04 14:52:49 +01:00
sysctl_net.c