ipv6: add complete rcu protection around np->opt
This patch addresses multiple problems : UDP/RAW sendmsg() need to get a stable struct ipv6_txoptions while socket is not locked : Other threads can change np->opt concurrently. Dmitry posted a syzkaller (http://github.com/google/syzkaller) program desmonstrating use-after-free. Starting with TCP/DCCP lockless listeners, tcp_v6_syn_recv_sock() and dccp_v6_request_recv_sock() also need to use RCU protection to dereference np->opt once (before calling ipv6_dup_options()) This patch adds full RCU protection to np->opt Reported-by: Dmitry Vyukov <dvyukov@google.com> Signed-off-by: Eric Dumazet <edumazet@google.com> Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:

committed by
David S. Miller

parent
01b3f52157
commit
45f6fad84c
@@ -1110,6 +1110,7 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
|
||||
DECLARE_SOCKADDR(struct sockaddr_in6 *, sin6, msg->msg_name);
|
||||
struct in6_addr *daddr, *final_p, final;
|
||||
struct ipv6_txoptions *opt = NULL;
|
||||
struct ipv6_txoptions *opt_to_free = NULL;
|
||||
struct ip6_flowlabel *flowlabel = NULL;
|
||||
struct flowi6 fl6;
|
||||
struct dst_entry *dst;
|
||||
@@ -1263,8 +1264,10 @@ do_udp_sendmsg:
|
||||
opt = NULL;
|
||||
connected = 0;
|
||||
}
|
||||
if (!opt)
|
||||
opt = np->opt;
|
||||
if (!opt) {
|
||||
opt = txopt_get(np);
|
||||
opt_to_free = opt;
|
||||
}
|
||||
if (flowlabel)
|
||||
opt = fl6_merge_options(&opt_space, flowlabel, opt);
|
||||
opt = ipv6_fixup_options(&opt_space, opt);
|
||||
@@ -1373,6 +1376,7 @@ release_dst:
|
||||
out:
|
||||
dst_release(dst);
|
||||
fl6_sock_release(flowlabel);
|
||||
txopt_put(opt_to_free);
|
||||
if (!err)
|
||||
return len;
|
||||
/*
|
||||
|
Reference in New Issue
Block a user