tcp: fix refcnt leak with ebpf congestion control
authorSabrina Dubroca <sd@queasysnail.net>
Fri, 25 Aug 2017 11:10:12 +0000 (13:10 +0200)
committerDavid S. Miller <davem@davemloft.net>
Sat, 26 Aug 2017 00:16:27 +0000 (17:16 -0700)
commitebfa00c5745660fe7f0a91eea88d4dff658486c4
tree70f899bdadb25a073dc98f97bac41e60a149077a
parent3614364527daa870264f6dde77f02853cdecd02c
tcp: fix refcnt leak with ebpf congestion control

There are a few bugs around refcnt handling in the new BPF congestion
control setsockopt:

 - The new ca is assigned to icsk->icsk_ca_ops even in the case where we
   cannot get a reference on it. This would lead to a use after free,
   since that ca is going away soon.

 - Changing the congestion control case doesn't release the refcnt on
   the previous ca.

 - In the reinit case, we first leak a reference on the old ca, then we
   call tcp_reinit_congestion_control on the ca that we have just
   assigned, leading to deinitializing the wrong ca (->release of the
   new ca on the old ca's data) and releasing the refcount on the ca
   that we actually want to use.

This is visible by building (for example) BIC as a module and setting
net.ipv4.tcp_congestion_control=bic, and using tcp_cong_kern.c from
samples/bpf.

This patch fixes the refcount issues, and moves reinit back into tcp
core to avoid passing a ca pointer back to BPF.

Fixes: 91b5b21c7c16 ("bpf: Add support for changing congestion control")
Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
Acked-by: Lawrence Brakmo <brakmo@fb.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/tcp.h
net/core/filter.c
net/ipv4/tcp.c
net/ipv4/tcp_cong.c