Skip to content

Commit 121d57a

Browse files
wdebruijdavem330
authored andcommitted
gso: validate gso_type in GSO handlers
Validate gso_type during segmentation as SKB_GSO_DODGY sources may pass packets where the gso_type does not match the contents. Syzkaller was able to enter the SCTP gso handler with a packet of gso_type SKB_GSO_TCPV4. On entry of transport layer gso handlers, verify that the gso_type matches the transport protocol. Fixes: 90017ac ("sctp: Add GSO support") Link: http://lkml.kernel.org/r/<[email protected]> Reported-by: [email protected] Signed-off-by: Willem de Bruijn <[email protected]> Acked-by: Jason Wang <[email protected]> Reviewed-by: Marcelo Ricardo Leitner <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 7c68d1a commit 121d57a

File tree

7 files changed

+21
-0
lines changed

7 files changed

+21
-0
lines changed

net/ipv4/esp4_offload.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,9 @@ static struct sk_buff *esp4_gso_segment(struct sk_buff *skb,
122122
if (!xo)
123123
goto out;
124124

125+
if (!(skb_shinfo(skb)->gso_type & SKB_GSO_ESP))
126+
goto out;
127+
125128
seq = xo->seq.low;
126129

127130
x = skb->sp->xvec[skb->sp->len - 1];

net/ipv4/tcp_offload.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ static void tcp_gso_tstamp(struct sk_buff *skb, unsigned int ts_seq,
3232
static struct sk_buff *tcp4_gso_segment(struct sk_buff *skb,
3333
netdev_features_t features)
3434
{
35+
if (!(skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4))
36+
return ERR_PTR(-EINVAL);
37+
3538
if (!pskb_may_pull(skb, sizeof(struct tcphdr)))
3639
return ERR_PTR(-EINVAL);
3740

net/ipv4/udp_offload.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,9 @@ static struct sk_buff *udp4_ufo_fragment(struct sk_buff *skb,
203203
goto out;
204204
}
205205

206+
if (!(skb_shinfo(skb)->gso_type & SKB_GSO_UDP))
207+
goto out;
208+
206209
if (!pskb_may_pull(skb, sizeof(struct udphdr)))
207210
goto out;
208211

net/ipv6/esp6_offload.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,9 @@ static struct sk_buff *esp6_gso_segment(struct sk_buff *skb,
149149
if (!xo)
150150
goto out;
151151

152+
if (!(skb_shinfo(skb)->gso_type & SKB_GSO_ESP))
153+
goto out;
154+
152155
seq = xo->seq.low;
153156

154157
x = skb->sp->xvec[skb->sp->len - 1];

net/ipv6/tcpv6_offload.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ static struct sk_buff *tcp6_gso_segment(struct sk_buff *skb,
4646
{
4747
struct tcphdr *th;
4848

49+
if (!(skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6))
50+
return ERR_PTR(-EINVAL);
51+
4952
if (!pskb_may_pull(skb, sizeof(*th)))
5053
return ERR_PTR(-EINVAL);
5154

net/ipv6/udp_offload.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb,
4242
const struct ipv6hdr *ipv6h;
4343
struct udphdr *uh;
4444

45+
if (!(skb_shinfo(skb)->gso_type & SKB_GSO_UDP))
46+
goto out;
47+
4548
if (!pskb_may_pull(skb, sizeof(struct udphdr)))
4649
goto out;
4750

net/sctp/offload.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ static struct sk_buff *sctp_gso_segment(struct sk_buff *skb,
4545
struct sk_buff *segs = ERR_PTR(-EINVAL);
4646
struct sctphdr *sh;
4747

48+
if (!(skb_shinfo(skb)->gso_type & SKB_GSO_SCTP))
49+
goto out;
50+
4851
sh = sctp_hdr(skb);
4952
if (!pskb_may_pull(skb, sizeof(*sh)))
5053
goto out;

0 commit comments

Comments
 (0)