Skip to content

Commit 64d9b03

Browse files
akodanevgregkh
authored andcommitted
dccp: fix undefined behavior with 'cwnd' shift in ccid2_cwnd_restart()
[ Upstream commit 61ef4b0 ] The shift of 'cwnd' with '(now - hc->tx_lsndtime) / hc->tx_rto' value can lead to undefined behavior [1]. In order to fix this use a gradual shift of the window with a 'while' loop, similar to what tcp_cwnd_restart() is doing. When comparing delta and RTO there is a minor difference between TCP and DCCP, the last one also invokes dccp_cwnd_restart() and reduces 'cwnd' if delta equals RTO. That case is preserved in this change. [1]: [40850.963623] UBSAN: Undefined behaviour in net/dccp/ccids/ccid2.c:237:7 [40851.043858] shift exponent 67 is too large for 32-bit type 'unsigned int' [40851.127163] CPU: 3 PID: 15940 Comm: netstress Tainted: G W E 4.18.0-rc7.x86_64 #1 ... [40851.377176] Call Trace: [40851.408503] dump_stack+0xf1/0x17b [40851.451331] ? show_regs_print_info+0x5/0x5 [40851.503555] ubsan_epilogue+0x9/0x7c [40851.548363] __ubsan_handle_shift_out_of_bounds+0x25b/0x2b4 [40851.617109] ? __ubsan_handle_load_invalid_value+0x18f/0x18f [40851.686796] ? xfrm4_output_finish+0x80/0x80 [40851.739827] ? lock_downgrade+0x6d0/0x6d0 [40851.789744] ? xfrm4_prepare_output+0x160/0x160 [40851.845912] ? ip_queue_xmit+0x810/0x1db0 [40851.895845] ? ccid2_hc_tx_packet_sent+0xd36/0x10a0 [dccp] [40851.963530] ccid2_hc_tx_packet_sent+0xd36/0x10a0 [dccp] [40852.029063] dccp_xmit_packet+0x1d3/0x720 [dccp] [40852.086254] dccp_write_xmit+0x116/0x1d0 [dccp] [40852.142412] dccp_sendmsg+0x428/0xb20 [dccp] [40852.195454] ? inet_dccp_listen+0x200/0x200 [dccp] [40852.254833] ? sched_clock+0x5/0x10 [40852.298508] ? sched_clock+0x5/0x10 [40852.342194] ? inet_create+0xdf0/0xdf0 [40852.388988] sock_sendmsg+0xd9/0x160 ... Fixes: 113ced1 ("dccp ccid-2: Perform congestion-window validation") Signed-off-by: Alexey Kodanev <alexey.kodanev@oracle.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 4cea13b commit 64d9b03

File tree

1 file changed

+4
-2
lines changed

1 file changed

+4
-2
lines changed

net/dccp/ccids/ccid2.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -228,14 +228,16 @@ static void ccid2_cwnd_restart(struct sock *sk, const u32 now)
228228
struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk);
229229
u32 cwnd = hc->tx_cwnd, restart_cwnd,
230230
iwnd = rfc3390_bytes_to_packets(dccp_sk(sk)->dccps_mss_cache);
231+
s32 delta = now - hc->tx_lsndtime;
231232

232233
hc->tx_ssthresh = max(hc->tx_ssthresh, (cwnd >> 1) + (cwnd >> 2));
233234

234235
/* don't reduce cwnd below the initial window (IW) */
235236
restart_cwnd = min(cwnd, iwnd);
236-
cwnd >>= (now - hc->tx_lsndtime) / hc->tx_rto;
237-
hc->tx_cwnd = max(cwnd, restart_cwnd);
238237

238+
while ((delta -= hc->tx_rto) >= 0 && cwnd > restart_cwnd)
239+
cwnd >>= 1;
240+
hc->tx_cwnd = max(cwnd, restart_cwnd);
239241
hc->tx_cwnd_stamp = now;
240242
hc->tx_cwnd_used = 0;
241243

0 commit comments

Comments
 (0)