Skip to content

Commit

Permalink
bareudp: Fix invalid read beyond skb's linear data
Browse files Browse the repository at this point in the history
Data beyond the UDP header might not be part of the skb's linear data.
Use skb_copy_bits() instead of direct access to skb->data+X, so that
we read the correct bytes even on a fragmented skb.

Fixes: 4b5f672 ("net: Special handling for IP & MPLS.")
Signed-off-by: Guillaume Nault <gnault@redhat.com>
Link: https://lore.kernel.org/r/7741c46545c6ef02e70c80a9b32814b22d9616b3.1628264975.git.gnault@redhat.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  • Loading branch information
Guillaume Nault authored and kuba-moo committed Aug 9, 2021
1 parent d6e712a commit 143a852
Showing 1 changed file with 11 additions and 5 deletions.
16 changes: 11 additions & 5 deletions drivers/net/bareudp.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,18 @@ static int bareudp_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
family = AF_INET6;

if (bareudp->ethertype == htons(ETH_P_IP)) {
struct iphdr *iphdr;
__u8 ipversion;

iphdr = (struct iphdr *)(skb->data + BAREUDP_BASE_HLEN);
if (iphdr->version == 4) {
proto = bareudp->ethertype;
} else if (bareudp->multi_proto_mode && (iphdr->version == 6)) {
if (skb_copy_bits(skb, BAREUDP_BASE_HLEN, &ipversion,
sizeof(ipversion))) {
bareudp->dev->stats.rx_dropped++;
goto drop;
}
ipversion >>= 4;

if (ipversion == 4) {
proto = htons(ETH_P_IP);
} else if (ipversion == 6 && bareudp->multi_proto_mode) {
proto = htons(ETH_P_IPV6);
} else {
bareudp->dev->stats.rx_dropped++;
Expand Down

0 comments on commit 143a852

Please sign in to comment.