Matthieu Baerts says: ==================== mptcp: misc fixes for v7.3-rc1 Here are various unrelated fixes: - Patch 1: Do not reschedule the RTX timer for sockets that fell back to TCP. A fix for v5.7. - Patch 2: Avoid copying thmac which will not be used and could be uninitialised. A fix for v5.7. - Patch 3: Re-set the request backup flag when SYN cookies are used. A fix for v5.9. - Patch 4: Drop pending ADD_ADDR when removing ID0, and avoid a WARN. A fix for v5.13. - Patch 5: Handle invalid suboptions where the checksum is requested in the MP_CAPABLE 4th ACK with data, but not added in the option. A fix for v5.14. - Patch 6: Prevent a race between mptcp_disconnect() and the retransmit timer. A fix for v5.17. - Patch 7: Fix a use-after-free in the selftests that could lead to false positive. A fix for v5.17. - Patch 8: Limit new addresses with the userspace PM to avoid an address ID overflow. A fix for v5.19. - Patch 9: Reset the ADD_ADDR retransmission counter when the timer is reused. A fix for v5.19. - Patch 10: Remove unneeded and confusing READ_ONCE() annotations. A fix for v6.13. - Patches 11-12: Get nstat counters for the current test, not since the creation of the netns. A fix for v6.19. - Patch 13: Fix an uninit-value in mptcp_write_data_fin for a corner case now that only a part of the tcp_out_options struct is reset. A fix for v7.1. - Patches 14-15: Two follow-up patches addressing minor comments discovered after the human review. A fix for v7.3-rc1. ====================
Unified · Split
| @@ -93,7 +93,8 @@ static void mptcp_parse_option(const struct sk_buff *skb, · 92 unmodified lines | ||
| 93 | 93 | * In other words, the only way for checksums not to be used |
| 94 | 94 | * is if both hosts in their SYNs set A=0." |
| 95 | 95 | */ |
| 96 | − if (flags & MPTCP_CAP_CHECKSUM_REQD) | |
| 96 | + if ((flags & MPTCP_CAP_CHECKSUM_REQD) && | |
| 97 | + opsize < TCPOLEN_MPTCP_MPC_ACK_DATA) | |
| 97 | 98 | mp_opt->suboptions |= OPTION_MPTCP_CSUMREQD; |
| 98 | 99 | |
| 99 | 100 | mp_opt->deny_join_id0 = !!(flags & MPTCP_CAP_DENY_JOIN_ID0); |
| @@ -529,7 +530,7 @@ static bool mptcp_established_options_mp(struct sock *sk, struct sk_buff *skb, · 429 unmodified lines | ||
| 529 | 530 | return false; |
| 530 | 531 | |
| 531 | 532 | /* MPC/MPJ needed only on 3rd ack packet, DATA_FIN and TCP shutdown take precedence */ |
| 532 | − if (READ_ONCE(subflow->fully_established) || snd_data_fin_enable || | |
| 533 | + if (subflow->fully_established || snd_data_fin_enable || | |
| 533 | 534 | subflow->snd_isn != TCP_SKB_CB(skb)->seq || |
| 534 | 535 | sk->sk_state != TCP_ESTABLISHED) |
| 535 | 536 | return false; |
| @@ -611,6 +612,7 @@ static void mptcp_write_data_fin(struct mptcp_subflow_context *subflow, · 75 unmodified lines | ||
| 611 | 612 | ext->data_seq = data_fin_tx_seq; |
| 612 | 613 | ext->subflow_seq = 0; |
| 613 | 614 | ext->data_len = 1; |
| 615 | + ext->csum = 0; | |
| 614 | 616 | } else if (ext->data_seq + ext->data_len == data_fin_tx_seq) { |
| 615 | 617 | /* If there's an existing DSS mapping and it is the |
| 616 | 618 | * final mapping, DATA_FIN consumes 1 additional byte of |
| @@ -980,7 +982,7 @@ static bool check_fully_established(struct mptcp_sock *msk, struct sock *ssk, · 363 unmodified lines | ||
| 980 | 982 | /* here we can process OoO, in-window pkts, only in-sequence 4th ack |
| 981 | 983 | * will make the subflow fully established |
| 982 | 984 | */ |
| 983 | − if (likely(READ_ONCE(subflow->fully_established))) { | |
| 985 | + if (likely(subflow->fully_established)) { | |
| 984 | 986 | /* on passive sockets, check for 3rd ack retransmission |
| 985 | 987 | * note that msk is always set by subflow_syn_recv_sock() |
| 986 | 988 | * for mp_join subflows |
| @@ -462,10 +462,10 @@ bool mptcp_pm_announced_alloc(struct mptcp_sock *msk, · 461 unmodified lines | ||
| 462 | 462 | |
| 463 | 463 | add_entry->addr = *addr; |
| 464 | 464 | add_entry->sock = msk; |
| 465 | − add_entry->retrans_times = 0; | |
| 466 | 465 | |
| 467 | 466 | timer_setup(&add_entry->timer, mptcp_pm_add_addr_timer, 0); |
| 468 | 467 | reset_timer: |
| 468 | + add_entry->retrans_times = 0; | |
| 469 | 469 | add_entry->timer_done = false; |
| 470 | 470 | timeout = mptcp_adjust_add_addr_timeout(msk); |
| 471 | 471 | if (timeout) |
| @@ -1137,6 +1137,8 @@ static int mptcp_nl_remove_id_zero_address(struct net *net, · 1136 unmodified lines | ||
| 1137 | 1137 | while ((msk = mptcp_token_iter_next(net, &s_slot, &s_num)) != NULL) { |
| 1138 | 1138 | struct sock *sk = (struct sock *)msk; |
| 1139 | 1139 | struct mptcp_addr_info msk_local; |
| 1140 | + struct mptcp_addr_info anno_addr; | |
| 1141 | + bool announced; | |
| 1140 | 1142 | |
| 1141 | 1143 | if (list_empty(&msk->conn_list) || mptcp_pm_is_userspace(msk)) |
| 1142 | 1144 | goto next; |
| @@ -1146,7 +1148,13 @@ static int mptcp_nl_remove_id_zero_address(struct net *net, · 3 unmodified lines | ||
| 1146 | 1148 | goto next; |
| 1147 | 1149 | |
| 1148 | 1150 | lock_sock(sk); |
| 1151 | + /* Drop a possibly pending ADD_ADDR for this address. */ | |
| 1152 | + anno_addr = msk_local; | |
| 1153 | + anno_addr.port = 0; | |
| 1154 | + announced = mptcp_pm_announced_remove(msk, &anno_addr); | |
| 1149 | 1155 | spin_lock_bh(&msk->pm.lock); |
| 1156 | + if (announced) | |
| 1157 | + msk->pm.add_addr_signaled--; | |
| 1150 | 1158 | mptcp_pm_remove_addr(msk, &list); |
| 1151 | 1159 | mptcp_pm_rm_subflow(msk, &list); |
| 1152 | 1160 | __mark_subflow_endp_available(msk, 0); |
| @@ -69,6 +69,19 @@ static int mptcp_userspace_pm_append_new_local_addr(struct mptcp_sock *msk, · 68 unmodified lines | ||
| 69 | 69 | } |
| 70 | 70 | |
| 71 | 71 | if (!addr_match && !id_match) { |
| 72 | + unsigned int id; | |
| 73 | + | |
| 74 | + if (!entry->addr.id && needs_id) { | |
| 75 | + id = find_next_zero_bit(id_bitmap, | |
| 76 | + MPTCP_PM_MAX_ADDR_ID + 1, 1); | |
| 77 | + if (id > MPTCP_PM_MAX_ADDR_ID) { | |
| 78 | + ret = -ENOSPC; | |
| 79 | + goto append_err; | |
| 80 | + } | |
| 81 | + } else { | |
| 82 | + id = entry->addr.id; | |
| 83 | + } | |
| 84 | + | |
| 72 | 85 | /* Memory for the entry is allocated from the |
| 73 | 86 | * sock option buffer. |
| 74 | 87 | */ |
| @@ -78,10 +91,7 @@ static int mptcp_userspace_pm_append_new_local_addr(struct mptcp_sock *msk, · 3 unmodified lines | ||
| 78 | 91 | goto append_err; |
| 79 | 92 | } |
| 80 | 93 | |
| 81 | − if (!e->addr.id && needs_id) | |
| 82 | − e->addr.id = find_next_zero_bit(id_bitmap, | |
| 83 | − MPTCP_PM_MAX_ADDR_ID + 1, | |
| 84 | − 1); | |
| 94 | + e->addr.id = id; | |
| 85 | 95 | list_add_tail_rcu(&e->list, &msk->pm.userspace_pm_local_addr_list); |
| 86 | 96 | msk->pm.local_addr_used++; |
| 87 | 97 | ret = e->addr.id; |
| @@ -95,6 +95,7 @@ bool __mptcp_try_fallback(struct mptcp_sock *msk, int fb_mib) · 94 unmodified lines | ||
| 95 | 95 | |
| 96 | 96 | msk->allow_subflows = false; |
| 97 | 97 | set_bit(MPTCP_FALLBACK_DONE, &msk->flags); |
| 98 | + clear_bit(MPTCP_RTX_ENABLED, &msk->flags); | |
| 98 | 99 | __MPTCP_INC_STATS(net, fb_mib); |
| 99 | 100 | spin_unlock_bh(&msk->fallback_lock); |
| 100 | 101 | return true; |
| @@ -288,8 +289,8 @@ static void mptcp_prune_ofo_queue(struct sock *sk, · 187 unmodified lines | ||
| 288 | 289 | */ |
| 289 | 290 | static bool mptcp_can_ingest(const struct sock *sk) |
| 290 | 291 | { |
| 291 | − return unlikely(sk_rmem_alloc_get(sk) <= READ_ONCE(sk->sk_rcvbuf)) || | |
| 292 | − __mptcp_check_fallback(mptcp_sk(sk)); | |
| 292 | + return likely(sk_rmem_alloc_get(sk) <= READ_ONCE(sk->sk_rcvbuf)) || | |
| 293 | + __mptcp_check_fallback(mptcp_sk(sk)); | |
| 293 | 294 | } |
| 294 | 295 | |
| 295 | 296 | static bool mptcp_try_rmem_schedule(struct sock *sk, const struct sk_buff *skb) |
| @@ -312,12 +313,6 @@ static void mptcp_data_queue_ofo(struct mptcp_sock *msk, struct sk_buff *skb) · 16 unmodified lines | ||
| 312 | 313 | u64 seq, end_seq, max_seq; |
| 313 | 314 | struct sk_buff *skb1; |
| 314 | 315 | |
| 315 | − if (!mptcp_try_rmem_schedule(sk, skb)) { | |
| 316 | − MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_RCVPRUNED); | |
| 317 | − mptcp_drop(sk, skb); | |
| 318 | − return; | |
| 319 | − } | |
| 320 | − | |
| 321 | 316 | seq = MPTCP_SKB_CB(skb)->map_seq; |
| 322 | 317 | end_seq = MPTCP_SKB_CB(skb)->end_seq; |
| 323 | 318 | max_seq = atomic64_read(&msk->rcv_wnd_sent); |
| @@ -334,6 +329,12 @@ static void mptcp_data_queue_ofo(struct mptcp_sock *msk, struct sk_buff *skb) · 10 unmodified lines | ||
| 334 | 329 | return; |
| 335 | 330 | } |
| 336 | 331 | |
| 332 | + if (!mptcp_try_rmem_schedule(sk, skb)) { | |
| 333 | + MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_RCVPRUNED); | |
| 334 | + mptcp_drop(sk, skb); | |
| 335 | + return; | |
| 336 | + } | |
| 337 | + | |
| 337 | 338 | p = &msk->out_of_order_queue.rb_node; |
| 338 | 339 | MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_OFOQUEUE); |
| 339 | 340 | if (RB_EMPTY_ROOT(&msk->out_of_order_queue)) { |
| @@ -1084,13 +1085,14 @@ static bool mptcp_rtx_timer_pending(struct sock *sk) · 744 unmodified lines | ||
| 1084 | 1085 | |
| 1085 | 1086 | static void mptcp_reset_rtx_timer(struct sock *sk) |
| 1086 | 1087 | { |
| 1088 | + struct mptcp_sock *msk = mptcp_sk(sk); | |
| 1087 | 1089 | unsigned long tout; |
| 1088 | 1090 | |
| 1089 | − /* prevent rescheduling on close */ | |
| 1090 | − if (unlikely(inet_sk_state_load(sk) == TCP_CLOSE)) | |
| 1091 | + /* Prevent rescheduling on close and in case of fallback. */ | |
| 1092 | + if (!test_bit(MPTCP_RTX_ENABLED, &msk->flags)) | |
| 1091 | 1093 | return; |
| 1092 | 1094 | |
| 1093 | − tout = mptcp_sk(sk)->timer_ival; | |
| 1095 | + tout = msk->timer_ival; | |
| 1094 | 1096 | sk_reset_timer(sk, &sk->mptcp_retransmit_timer, jiffies + tout); |
| 1095 | 1097 | } |
| 1096 | 1098 | |
| @@ -3323,6 +3325,9 @@ void mptcp_set_state(struct sock *sk, int state) · 2226 unmodified lines | ||
| 3323 | 3325 | * transition from TCP_SYN_RECV to TCP_CLOSE_WAIT. |
| 3324 | 3326 | */ |
| 3325 | 3327 | break; |
| 3328 | + case TCP_CLOSE: | |
| 3329 | + clear_bit(MPTCP_RTX_ENABLED, &mptcp_sk(sk)->flags); | |
| 3330 | + fallthrough; | |
| 3326 | 3331 | default: |
| 3327 | 3332 | if (oldstate == TCP_ESTABLISHED || oldstate == TCP_CLOSE_WAIT) |
| 3328 | 3333 | MPTCP_DEC_STATS(sock_net(sk), MPTCP_MIB_CURRESTAB); |
| @@ -3583,6 +3588,7 @@ static void mptcp_destroy_common(struct mptcp_sock *msk) · 254 unmodified lines | ||
| 3583 | 3588 | |
| 3584 | 3589 | static int mptcp_disconnect(struct sock *sk, int flags) |
| 3585 | 3590 | { |
| 3591 | + struct inet_connection_sock *icsk = inet_csk(sk); | |
| 3586 | 3592 | struct mptcp_sock *msk = mptcp_sk(sk); |
| 3587 | 3593 | |
| 3588 | 3594 | /* We are on the fastopen error path. We can't call straight into the |
| @@ -3595,8 +3601,13 @@ static int mptcp_disconnect(struct sock *sk, int flags) · 6 unmodified lines | ||
| 3595 | 3601 | mptcp_check_listen_stop(sk); |
| 3596 | 3602 | mptcp_set_state(sk, TCP_CLOSE); |
| 3597 | 3603 | |
| 3598 | − mptcp_stop_rtx_timer(sk); | |
| 3599 | − mptcp_stop_tout_timer(sk); | |
| 3604 | + /* The later subflow close can not kick again the tout timer, | |
| 3605 | + * as the msk is already in closed status. | |
| 3606 | + */ | |
| 3607 | + msk->timer_ival = icsk->icsk_rto_min; | |
| 3608 | + sk_stop_timer_sync(sk, &sk->mptcp_retransmit_timer); | |
| 3609 | + icsk->icsk_mtup.probe_timestamp = 0; | |
| 3610 | + sk_stop_timer_sync(sk, &icsk->mptcp_tout_timer); | |
| 3600 | 3611 | |
| 3601 | 3612 | mptcp_pm_connection_closed(msk); |
| 3602 | 3613 | |
| @@ -3875,7 +3886,7 @@ static void schedule_3rdack_retransmission(struct sock *ssk) · 272 unmodified lines | ||
| 3875 | 3886 | struct tcp_sock *tp = tcp_sk(ssk); |
| 3876 | 3887 | unsigned long timeout; |
| 3877 | 3888 | |
| 3878 | − if (READ_ONCE(mptcp_subflow_ctx(ssk)->fully_established)) | |
| 3889 | + if (mptcp_subflow_ctx(ssk)->fully_established) | |
| 3879 | 3890 | return; |
| 3880 | 3891 | |
| 3881 | 3892 | /* reschedule with a timeout above RTT, as we must look only for drop */ |
| @@ -4141,6 +4152,7 @@ static int mptcp_connect(struct sock *sk, struct sockaddr_unsized *uaddr, · 259 unmodified lines | ||
| 4141 | 4152 | if (IS_ERR(ssk)) |
| 4142 | 4153 | return PTR_ERR(ssk); |
| 4143 | 4154 | |
| 4155 | + set_bit(MPTCP_RTX_ENABLED, &msk->flags); | |
| 4144 | 4156 | mptcp_set_state(sk, TCP_SYN_SENT); |
| 4145 | 4157 | subflow = mptcp_subflow_ctx(ssk); |
| 4146 | 4158 | #ifdef CONFIG_TCP_MD5SIG |
| @@ -4288,6 +4300,7 @@ static int mptcp_listen(struct socket *sock, int backlog) · 141 unmodified lines | ||
| 4288 | 4300 | goto unlock; |
| 4289 | 4301 | } |
| 4290 | 4302 | |
| 4303 | + set_bit(MPTCP_RTX_ENABLED, &msk->flags); | |
| 4291 | 4304 | mptcp_set_state(sk, TCP_LISTEN); |
| 4292 | 4305 | sock_set_flag(sk, SOCK_RCU_FREE); |
| 4293 | 4306 | |
| @@ -116,6 +116,7 @@ · 115 unmodified lines | ||
| 116 | 116 | #define MPTCP_WORK_RTX 1 |
| 117 | 117 | #define MPTCP_FALLBACK_DONE 2 |
| 118 | 118 | #define MPTCP_WORK_CLOSE_SUBFLOW 3 |
| 119 | +#define MPTCP_RTX_ENABLED 4 | |
| 119 | 120 | |
| 120 | 121 | /* MPTCP socket release cb flags */ |
| 121 | 122 | #define MPTCP_PUSH_PENDING 1 |
| @@ -2084,7 +2084,6 @@ static void subflow_ulp_clone(const struct request_sock *req, · 2083 unmodified lines | ||
| 2084 | 2084 | new_ctx->request_bkup = subflow_req->request_bkup; |
| 2085 | 2085 | WRITE_ONCE(new_ctx->remote_id, subflow_req->remote_id); |
| 2086 | 2086 | new_ctx->token = subflow_req->token; |
| 2087 | − new_ctx->thmac = subflow_req->thmac; | |
| 2088 | 2087 | |
| 2089 | 2088 | /* the subflow req id is valid, fetched via subflow_check_req() |
| 2090 | 2089 | * and subflow_token_join_request() |
| @@ -26,7 +26,8 @@ struct join_entry { · 25 unmodified lines | ||
| 26 | 26 | u32 local_nonce; |
| 27 | 27 | u8 join_id; |
| 28 | 28 | u8 local_id; |
| 29 | − u8 backup; | |
| 29 | + u8 backup:1, | |
| 30 | + request_bkup:1; | |
| 30 | 31 | u8 valid; |
| 31 | 32 | }; |
| 32 | 33 | |
| @@ -63,6 +64,7 @@ static void mptcp_join_store_state(struct join_entry *entry, · 30 unmodified lines | ||
| 63 | 64 | entry->remote_nonce = subflow_req->remote_nonce; |
| 64 | 65 | entry->local_nonce = subflow_req->local_nonce; |
| 65 | 66 | entry->backup = subflow_req->backup; |
| 67 | + entry->request_bkup = subflow_req->request_bkup; | |
| 66 | 68 | entry->join_id = subflow_req->remote_id; |
| 67 | 69 | entry->local_id = subflow_req->local_id; |
| 68 | 70 | entry->valid = 1; |
| @@ -117,6 +119,7 @@ bool mptcp_token_join_cookie_init_state(struct mptcp_subflow_request_sock *subfl · 48 unmodified lines | ||
| 117 | 119 | subflow_req->remote_nonce = e->remote_nonce; |
| 118 | 120 | subflow_req->local_nonce = e->local_nonce; |
| 119 | 121 | subflow_req->backup = e->backup; |
| 122 | + subflow_req->request_bkup = e->request_bkup; | |
| 120 | 123 | subflow_req->remote_id = e->join_id; |
| 121 | 124 | subflow_req->local_id = e->local_id; |
| 122 | 125 | subflow_req->token = e->token; |
| @@ -381,6 +381,9 @@ static int sock_connect_mptcp(const char * const remoteaddr, · 380 unmodified lines | ||
| 381 | 381 | |
| 382 | 382 | hints.ai_family = pf; |
| 383 | 383 | |
| 384 | + /* Keep the resolved address alive for the whole execution: it is | |
| 385 | + * used again when reconnecting, and will be released at exit time. | |
| 386 | + */ | |
| 384 | 387 | xgetaddrinfo(remoteaddr, port, &hints, &addr); |
| 385 | 388 | for (a = addr; a; a = a->ai_next) { |
| 386 | 389 | sock = socket(a->ai_family, a->ai_socktype, proto); |
| @@ -421,7 +424,6 @@ static int sock_connect_mptcp(const char * const remoteaddr, · 34 unmodified lines | ||
| 421 | 424 | sock = -1; |
| 422 | 425 | } |
| 423 | 426 | |
| 424 | − freeaddrinfo(addr); | |
| 425 | 427 | if (sock != -1) |
| 426 | 428 | SOCK_TEST_TCPULP(sock, proto); |
| 427 | 429 | return sock; |
| @@ -108,12 +108,14 @@ mptcp_lib_pr_info() { · 107 unmodified lines | ||
| 108 | 108 | |
| 109 | 109 | mptcp_lib_pr_nstat() { |
| 110 | 110 | local ns="${1}" |
| 111 | − local hist="/tmp/${ns}.out" | |
| 111 | + local cache="/tmp/${ns}.out" | |
| 112 | + local hist="/tmp/${ns}.nstat" | |
| 112 | 113 | |
| 113 | − if [ -f "${hist}" ]; then | |
| 114 | − awk '$2 != 0 { print " "$0 }' "${hist}" | |
| 114 | + if [ -f "${cache}" ]; then | |
| 115 | + awk '$2 != 0 { print " "$0 }' "${cache}" | |
| 115 | 116 | else |
| 116 | − ip netns exec "${ns}" nstat -as | grep Tcp | |
| 117 | + NSTAT_HISTORY="${hist}" ip netns exec "${ns}" nstat -s | | |
| 118 | + grep Tcp | |
| 117 | 119 | fi |
| 118 | 120 | } |
| 119 | 121 | |
| @@ -414,19 +416,21 @@ mptcp_lib_nstat_get() { · 294 unmodified lines | ||
| 414 | 416 | } |
| 415 | 417 | |
| 416 | 418 | # $1: ns, $2: MIB counter |
| 417 | −# Get the counter from the history (mptcp_lib_nstat_{init,get}()) if available. | |
| 418 | −# If not, get the counter from nstat ignoring any history. | |
| 419 | +# Get the counter from the cache (mptcp_lib_nstat_{init,get}()) if available. | |
| 420 | +# If not, get the counter from nstat ignoring any cache, but using the history. | |
| 419 | 421 | mptcp_lib_get_counter() { |
| 420 | 422 | local ns="${1}" |
| 421 | 423 | local counter="${2}" |
| 422 | − local hist="/tmp/${ns}.out" | |
| 424 | + local cache="/tmp/${ns}.out" | |
| 425 | + local hist="/tmp/${ns}.nstat" | |
| 423 | 426 | local count |
| 424 | 427 | |
| 425 | − if [[ -s "${hist}" && "${counter}" == *"Tcp"* ]]; then | |
| 426 | − count=$(awk "/^${counter} / {print \$2; exit}" "${hist}") | |
| 428 | + if [[ -s "${cache}" && "${counter}" == *"Tcp"* ]]; then | |
| 429 | + count=$(awk "/^${counter} / {print \$2; exit}" "${cache}") | |
| 427 | 430 | else |
| 428 | − count=$(ip netns exec "${ns}" nstat -asz "${counter}" | | |
| 429 | − awk 'NR==1 {next} {print $2}') | |
| 431 | + count=$(NSTAT_HISTORY="${hist}" ip netns exec "${ns}" \ | |
| 432 | + nstat -sz "${counter}" | | |
| 433 | + awk 'NR==1 {next} {print $2}') | |
| 430 | 434 | fi |
| 431 | 435 | if [ -z "${count}" ]; then |
| 432 | 436 | mptcp_lib_fail_if_expected_feature "${counter} counter" |