Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

tcp: only release congestion control if it has been initialized

Currently, when cleaning up congestion control, we always call the
release regardless of whether it has been initialized. There is no
need to release when closing TCP_LISTEN and TCP_CLOSE (close
immediately after socket()).

In this case, tcp_cdg calls kfree(NULL) in release without causing
an exception, but for some customized ca, this could lead to
unexpected exceptions. We need to ensure that init and release are
called in pairs.

Signed-off-by: Pengcheng Yang <yangpc@wangsu.com>
Link: https://patch.msgid.link/1729845944-6003-1-git-send-email-yangpc@wangsu.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Pengcheng Yang and committed by
Jakub Kicinski
cf44bd08 5b1c9659

+3 -2
+1 -1
net/ipv4/tcp.c
··· 3336 3336 tp->window_clamp = 0; 3337 3337 tp->delivered = 0; 3338 3338 tp->delivered_ce = 0; 3339 - if (icsk->icsk_ca_ops->release) 3339 + if (icsk->icsk_ca_initialized && icsk->icsk_ca_ops->release) 3340 3340 icsk->icsk_ca_ops->release(sk); 3341 3341 memset(icsk->icsk_ca_priv, 0, sizeof(icsk->icsk_ca_priv)); 3342 3342 icsk->icsk_ca_initialized = 0;
+2 -1
net/ipv4/tcp_cong.c
··· 270 270 { 271 271 struct inet_connection_sock *icsk = inet_csk(sk); 272 272 273 - if (icsk->icsk_ca_ops->release) 273 + if (icsk->icsk_ca_initialized && icsk->icsk_ca_ops->release) 274 274 icsk->icsk_ca_ops->release(sk); 275 + icsk->icsk_ca_initialized = 0; 275 276 bpf_module_put(icsk->icsk_ca_ops, icsk->icsk_ca_ops->owner); 276 277 } 277 278