Commit 1235f504aaba2ebeabc863fdb3ceac764a317d47
Committed by
David S. Miller
1 parent
7b5e078cf0
Exists in
master
and in
39 other branches
netlink: netlink_recvmsg() fix
commit 1dacc76d0014 (net/compat/wext: send different messages to compat tasks) introduced a race condition on netlink, in case MSG_PEEK is used. An skb given by skb_recv_datagram() might be shared, we must copy it before any modification, or risk fatal corruption. Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Showing 1 changed file with 16 additions and 6 deletions Side-by-side Diff
net/netlink/af_netlink.c
... | ... | @@ -1406,7 +1406,7 @@ |
1406 | 1406 | struct netlink_sock *nlk = nlk_sk(sk); |
1407 | 1407 | int noblock = flags&MSG_DONTWAIT; |
1408 | 1408 | size_t copied; |
1409 | - struct sk_buff *skb, *frag __maybe_unused = NULL; | |
1409 | + struct sk_buff *skb; | |
1410 | 1410 | int err; |
1411 | 1411 | |
1412 | 1412 | if (flags&MSG_OOB) |
... | ... | @@ -1441,7 +1441,21 @@ |
1441 | 1441 | kfree_skb(skb); |
1442 | 1442 | skb = compskb; |
1443 | 1443 | } else { |
1444 | - frag = skb_shinfo(skb)->frag_list; | |
1444 | + /* | |
1445 | + * Before setting frag_list to NULL, we must get a | |
1446 | + * private copy of skb if shared (because of MSG_PEEK) | |
1447 | + */ | |
1448 | + if (skb_shared(skb)) { | |
1449 | + struct sk_buff *nskb; | |
1450 | + | |
1451 | + nskb = pskb_copy(skb, GFP_KERNEL); | |
1452 | + kfree_skb(skb); | |
1453 | + skb = nskb; | |
1454 | + err = -ENOMEM; | |
1455 | + if (!skb) | |
1456 | + goto out; | |
1457 | + } | |
1458 | + kfree_skb(skb_shinfo(skb)->frag_list); | |
1445 | 1459 | skb_shinfo(skb)->frag_list = NULL; |
1446 | 1460 | } |
1447 | 1461 | } |
... | ... | @@ -1477,10 +1491,6 @@ |
1477 | 1491 | siocb->scm->creds = *NETLINK_CREDS(skb); |
1478 | 1492 | if (flags & MSG_TRUNC) |
1479 | 1493 | copied = skb->len; |
1480 | - | |
1481 | -#ifdef CONFIG_COMPAT_NETLINK_MESSAGES | |
1482 | - skb_shinfo(skb)->frag_list = frag; | |
1483 | -#endif | |
1484 | 1494 | |
1485 | 1495 | skb_free_datagram(sk, skb); |
1486 | 1496 |