forked from Minki/linux
dccp: avoid deadlock in dccp_v4_ctl_send_reset
In the prep work I did before enabling BH while handling socket backlog, I missed two points in DCCP : 1) dccp_v4_ctl_send_reset() uses bh_lock_sock(), assuming BH were blocked. It is not anymore always true. 2) dccp_v4_route_skb() was using __IP_INC_STATS() instead of IP_INC_STATS() A similar fix was done for TCP, in commit47dcc20a39
("ipv4: tcp: ip_send_unicast_reply() is not BH safe") Fixes:7309f8821f
("dccp: do not assume DCCP code is non preemptible") Fixes:5413d1babe
("net: do not block BH while processing socket backlog") Signed-off-by: Eric Dumazet <edumazet@google.com> Reported-by: Dmitry Vyukov <dvyukov@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
03addc2bce
commit
95556a8838
@ -462,7 +462,7 @@ static struct dst_entry* dccp_v4_route_skb(struct net *net, struct sock *sk,
|
||||
security_skb_classify_flow(skb, flowi4_to_flowi(&fl4));
|
||||
rt = ip_route_output_flow(net, &fl4, sk);
|
||||
if (IS_ERR(rt)) {
|
||||
__IP_INC_STATS(net, IPSTATS_MIB_OUTNOROUTES);
|
||||
IP_INC_STATS(net, IPSTATS_MIB_OUTNOROUTES);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -527,17 +527,19 @@ static void dccp_v4_ctl_send_reset(const struct sock *sk, struct sk_buff *rxskb)
|
||||
rxiph->daddr);
|
||||
skb_dst_set(skb, dst_clone(dst));
|
||||
|
||||
local_bh_disable();
|
||||
bh_lock_sock(ctl_sk);
|
||||
err = ip_build_and_send_pkt(skb, ctl_sk,
|
||||
rxiph->daddr, rxiph->saddr, NULL);
|
||||
bh_unlock_sock(ctl_sk);
|
||||
|
||||
if (net_xmit_eval(err) == 0) {
|
||||
DCCP_INC_STATS(DCCP_MIB_OUTSEGS);
|
||||
DCCP_INC_STATS(DCCP_MIB_OUTRSTS);
|
||||
__DCCP_INC_STATS(DCCP_MIB_OUTSEGS);
|
||||
__DCCP_INC_STATS(DCCP_MIB_OUTRSTS);
|
||||
}
|
||||
local_bh_enable();
|
||||
out:
|
||||
dst_release(dst);
|
||||
dst_release(dst);
|
||||
}
|
||||
|
||||
static void dccp_v4_reqsk_destructor(struct request_sock *req)
|
||||
|
Loading…
Reference in New Issue
Block a user