Message ID | 1624589330-2579-5-git-send-email-wujianguo106@163.com (mailing list archive) |
---|---|
State | Superseded, archived |
Headers | show |
Series | Fix some mptcp syncookie process bugs | expand |
Hi, Thank you for the patch! Yet something to improve: [auto build test ERROR on mptcp/export] [also build test ERROR on next-20210624] [cannot apply to kselftest/next linus/master v5.13-rc7] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch] url: https://github.com/0day-ci/linux/commits/wujianguo106-163-com/Fix-some-mptcp-syncookie-process-bugs/20210625-110557 base: https://github.com/multipath-tcp/mptcp_net-next.git export config: i386-randconfig-a011-20210622 (attached as .config) compiler: gcc-9 (Debian 9.3.0-22) 9.3.0 reproduce (this is a W=1 build): # https://github.com/0day-ci/linux/commit/8bac278b64d6949fede4d0f383ca5f01fca11ef7 git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review wujianguo106-163-com/Fix-some-mptcp-syncookie-process-bugs/20210625-110557 git checkout 8bac278b64d6949fede4d0f383ca5f01fca11ef7 # save the attached .config to linux build tree make W=1 ARCH=i386 If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot <lkp@intel.com> All errors (new ones prefixed by >>): net/ipv4/tcp_input.c: In function 'tcp_data_queue': >> net/ipv4/tcp_input.c:4950:25: error: invalid use of void expression 4950 | if (sk_is_mptcp(sk) && !mptcp_incoming_options(sk, skb)) { | ^ net/ipv4/tcp_input.c: In function 'tcp_rcv_state_process': net/ipv4/tcp_input.c:6537:27: error: invalid use of void expression 6537 | if (sk_is_mptcp(sk) && !mptcp_incoming_options(sk, skb)) | ^ vim +4950 net/ipv4/tcp_input.c 4940 4941 static void tcp_data_queue(struct sock *sk, struct sk_buff *skb) 4942 { 4943 struct tcp_sock *tp = tcp_sk(sk); 4944 bool fragstolen; 4945 int eaten; 4946 4947 /* If a subflow has been reset, the packet should not continue 4948 * to be processed, drop the packet. 4949 */ > 4950 if (sk_is_mptcp(sk) && !mptcp_incoming_options(sk, skb)) { 4951 __kfree_skb(skb); 4952 return; 4953 } 4954 4955 if (TCP_SKB_CB(skb)->seq == TCP_SKB_CB(skb)->end_seq) { 4956 __kfree_skb(skb); 4957 return; 4958 } 4959 skb_dst_drop(skb); 4960 __skb_pull(skb, tcp_hdr(skb)->doff * 4); 4961 4962 tp->rx_opt.dsack = 0; 4963 4964 /* Queue data for delivery to the user. 4965 * Packets in sequence go to the receive queue. 4966 * Out of sequence packets to the out_of_order_queue. 4967 */ 4968 if (TCP_SKB_CB(skb)->seq == tp->rcv_nxt) { 4969 if (tcp_receive_window(tp) == 0) { 4970 NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPZEROWINDOWDROP); 4971 goto out_of_window; 4972 } 4973 4974 /* Ok. In sequence. In window. */ 4975 queue_and_out: 4976 if (skb_queue_len(&sk->sk_receive_queue) == 0) 4977 sk_forced_mem_schedule(sk, skb->truesize); 4978 else if (tcp_try_rmem_schedule(sk, skb, skb->truesize)) { 4979 NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPRCVQDROP); 4980 sk->sk_data_ready(sk); 4981 goto drop; 4982 } 4983 4984 eaten = tcp_queue_rcv(sk, skb, &fragstolen); 4985 if (skb->len) 4986 tcp_event_data_recv(sk, skb); 4987 if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) 4988 tcp_fin(sk); 4989 4990 if (!RB_EMPTY_ROOT(&tp->out_of_order_queue)) { 4991 tcp_ofo_queue(sk); 4992 4993 /* RFC5681. 4.2. SHOULD send immediate ACK, when 4994 * gap in queue is filled. 4995 */ 4996 if (RB_EMPTY_ROOT(&tp->out_of_order_queue)) 4997 inet_csk(sk)->icsk_ack.pending |= ICSK_ACK_NOW; 4998 } 4999 5000 if (tp->rx_opt.num_sacks) 5001 tcp_sack_remove(tp); 5002 5003 tcp_fast_path_check(sk); 5004 5005 if (eaten > 0) 5006 kfree_skb_partial(skb, fragstolen); 5007 if (!sock_flag(sk, SOCK_DEAD)) 5008 tcp_data_ready(sk); 5009 return; 5010 } 5011 5012 if (!after(TCP_SKB_CB(skb)->end_seq, tp->rcv_nxt)) { 5013 tcp_rcv_spurious_retrans(sk, skb); 5014 /* A retransmit, 2nd most common case. Force an immediate ack. */ 5015 NET_INC_STATS(sock_net(sk), LINUX_MIB_DELAYEDACKLOST); 5016 tcp_dsack_set(sk, TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->end_seq); 5017 5018 out_of_window: 5019 tcp_enter_quickack_mode(sk, TCP_MAX_QUICKACKS); 5020 inet_csk_schedule_ack(sk); 5021 drop: 5022 tcp_drop(sk, skb); 5023 return; 5024 } 5025 5026 /* Out of window. F.e. zero window probe. */ 5027 if (!before(TCP_SKB_CB(skb)->seq, tp->rcv_nxt + tcp_receive_window(tp))) 5028 goto out_of_window; 5029 5030 if (before(TCP_SKB_CB(skb)->seq, tp->rcv_nxt)) { 5031 /* Partial packet, seq < rcv_next < end_seq */ 5032 tcp_dsack_set(sk, TCP_SKB_CB(skb)->seq, tp->rcv_nxt); 5033 5034 /* If window is closed, drop tail of packet. But after 5035 * remembering D-SACK for its head made in previous line. 5036 */ 5037 if (!tcp_receive_window(tp)) { 5038 NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPZEROWINDOWDROP); 5039 goto out_of_window; 5040 } 5041 goto queue_and_out; 5042 } 5043 5044 tcp_data_queue_ofo(sk, skb); 5045 } 5046 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
Sorry for the mistake, please ignore this series, I will send v7. On 2021/6/25 14:40, kernel test robot wrote: > Hi, > > Thank you for the patch! Yet something to improve: > > [auto build test ERROR on mptcp/export] > [also build test ERROR on next-20210624] > [cannot apply to kselftest/next linus/master v5.13-rc7] > [If your patch is applied to the wrong git tree, kindly drop us a note. > And when submitting patch, we suggest to use '--base' as documented in > https://git-scm.com/docs/git-format-patch] > > url: https://github.com/0day-ci/linux/commits/wujianguo106-163-com/Fix-some-mptcp-syncookie-process-bugs/20210625-110557 > base: https://github.com/multipath-tcp/mptcp_net-next.git export > config: i386-randconfig-a011-20210622 (attached as .config) > compiler: gcc-9 (Debian 9.3.0-22) 9.3.0 > reproduce (this is a W=1 build): > # https://github.com/0day-ci/linux/commit/8bac278b64d6949fede4d0f383ca5f01fca11ef7 > git remote add linux-review https://github.com/0day-ci/linux > git fetch --no-tags linux-review wujianguo106-163-com/Fix-some-mptcp-syncookie-process-bugs/20210625-110557 > git checkout 8bac278b64d6949fede4d0f383ca5f01fca11ef7 > # save the attached .config to linux build tree > make W=1 ARCH=i386 > > If you fix the issue, kindly add following tag as appropriate > Reported-by: kernel test robot <lkp@intel.com> > > All errors (new ones prefixed by >>): > > net/ipv4/tcp_input.c: In function 'tcp_data_queue': >>> net/ipv4/tcp_input.c:4950:25: error: invalid use of void expression > 4950 | if (sk_is_mptcp(sk) && !mptcp_incoming_options(sk, skb)) { > | ^ > net/ipv4/tcp_input.c: In function 'tcp_rcv_state_process': > net/ipv4/tcp_input.c:6537:27: error: invalid use of void expression > 6537 | if (sk_is_mptcp(sk) && !mptcp_incoming_options(sk, skb)) > | ^ > > > vim +4950 net/ipv4/tcp_input.c > > 4940 > 4941 static void tcp_data_queue(struct sock *sk, struct sk_buff *skb) > 4942 { > 4943 struct tcp_sock *tp = tcp_sk(sk); > 4944 bool fragstolen; > 4945 int eaten; > 4946 > 4947 /* If a subflow has been reset, the packet should not continue > 4948 * to be processed, drop the packet. > 4949 */ >> 4950 if (sk_is_mptcp(sk) && !mptcp_incoming_options(sk, skb)) { > 4951 __kfree_skb(skb); > 4952 return; > 4953 } > 4954 > 4955 if (TCP_SKB_CB(skb)->seq == TCP_SKB_CB(skb)->end_seq) { > 4956 __kfree_skb(skb); > 4957 return; > 4958 } > 4959 skb_dst_drop(skb); > 4960 __skb_pull(skb, tcp_hdr(skb)->doff * 4); > 4961 > 4962 tp->rx_opt.dsack = 0; > 4963 > 4964 /* Queue data for delivery to the user. > 4965 * Packets in sequence go to the receive queue. > 4966 * Out of sequence packets to the out_of_order_queue. > 4967 */ > 4968 if (TCP_SKB_CB(skb)->seq == tp->rcv_nxt) { > 4969 if (tcp_receive_window(tp) == 0) { > 4970 NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPZEROWINDOWDROP); > 4971 goto out_of_window; > 4972 } > 4973 > 4974 /* Ok. In sequence. In window. */ > 4975 queue_and_out: > 4976 if (skb_queue_len(&sk->sk_receive_queue) == 0) > 4977 sk_forced_mem_schedule(sk, skb->truesize); > 4978 else if (tcp_try_rmem_schedule(sk, skb, skb->truesize)) { > 4979 NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPRCVQDROP); > 4980 sk->sk_data_ready(sk); > 4981 goto drop; > 4982 } > 4983 > 4984 eaten = tcp_queue_rcv(sk, skb, &fragstolen); > 4985 if (skb->len) > 4986 tcp_event_data_recv(sk, skb); > 4987 if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) > 4988 tcp_fin(sk); > 4989 > 4990 if (!RB_EMPTY_ROOT(&tp->out_of_order_queue)) { > 4991 tcp_ofo_queue(sk); > 4992 > 4993 /* RFC5681. 4.2. SHOULD send immediate ACK, when > 4994 * gap in queue is filled. > 4995 */ > 4996 if (RB_EMPTY_ROOT(&tp->out_of_order_queue)) > 4997 inet_csk(sk)->icsk_ack.pending |= ICSK_ACK_NOW; > 4998 } > 4999 > 5000 if (tp->rx_opt.num_sacks) > 5001 tcp_sack_remove(tp); > 5002 > 5003 tcp_fast_path_check(sk); > 5004 > 5005 if (eaten > 0) > 5006 kfree_skb_partial(skb, fragstolen); > 5007 if (!sock_flag(sk, SOCK_DEAD)) > 5008 tcp_data_ready(sk); > 5009 return; > 5010 } > 5011 > 5012 if (!after(TCP_SKB_CB(skb)->end_seq, tp->rcv_nxt)) { > 5013 tcp_rcv_spurious_retrans(sk, skb); > 5014 /* A retransmit, 2nd most common case. Force an immediate ack. */ > 5015 NET_INC_STATS(sock_net(sk), LINUX_MIB_DELAYEDACKLOST); > 5016 tcp_dsack_set(sk, TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->end_seq); > 5017 > 5018 out_of_window: > 5019 tcp_enter_quickack_mode(sk, TCP_MAX_QUICKACKS); > 5020 inet_csk_schedule_ack(sk); > 5021 drop: > 5022 tcp_drop(sk, skb); > 5023 return; > 5024 } > 5025 > 5026 /* Out of window. F.e. zero window probe. */ > 5027 if (!before(TCP_SKB_CB(skb)->seq, tp->rcv_nxt + tcp_receive_window(tp))) > 5028 goto out_of_window; > 5029 > 5030 if (before(TCP_SKB_CB(skb)->seq, tp->rcv_nxt)) { > 5031 /* Partial packet, seq < rcv_next < end_seq */ > 5032 tcp_dsack_set(sk, TCP_SKB_CB(skb)->seq, tp->rcv_nxt); > 5033 > 5034 /* If window is closed, drop tail of packet. But after > 5035 * remembering D-SACK for its head made in previous line. > 5036 */ > 5037 if (!tcp_receive_window(tp)) { > 5038 NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPZEROWINDOWDROP); > 5039 goto out_of_window; > 5040 } > 5041 goto queue_and_out; > 5042 } > 5043 > 5044 tcp_data_queue_ofo(sk, skb); > 5045 } > 5046 > > --- > 0-DAY CI Kernel Test Service, Intel Corporation > https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org >
diff --git a/include/net/mptcp.h b/include/net/mptcp.h index d61bbbf11979..b32333f95738 100644 --- a/include/net/mptcp.h +++ b/include/net/mptcp.h @@ -104,7 +104,7 @@ bool mptcp_synack_options(const struct request_sock *req, unsigned int *size, bool mptcp_established_options(struct sock *sk, struct sk_buff *skb, unsigned int *size, unsigned int remaining, struct mptcp_out_options *opts); -void mptcp_incoming_options(struct sock *sk, struct sk_buff *skb); +int mptcp_incoming_options(struct sock *sk, struct sk_buff *skb); void mptcp_write_options(__be32 *ptr, const struct tcp_sock *tp, struct mptcp_out_options *opts); diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 7d5e59f688de..4bacd7d2abd7 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -4247,6 +4247,9 @@ void tcp_reset(struct sock *sk, struct sk_buff *skb) { trace_tcp_receive_reset(sk); + /* mptcp can't tell us to ignore reset pkts, + * so just ignore the return value of mptcp_incoming_options(). + */ if (sk_is_mptcp(sk)) mptcp_incoming_options(sk, skb); @@ -4941,8 +4944,13 @@ static void tcp_data_queue(struct sock *sk, struct sk_buff *skb) bool fragstolen; int eaten; - if (sk_is_mptcp(sk)) - mptcp_incoming_options(sk, skb); + /* If a subflow has been reset, the packet should not continue + * to be processed, drop the packet. + */ + if (sk_is_mptcp(sk) && !mptcp_incoming_options(sk, skb)) { + __kfree_skb(skb); + return; + } if (TCP_SKB_CB(skb)->seq == TCP_SKB_CB(skb)->end_seq) { __kfree_skb(skb); @@ -6523,8 +6531,11 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb) case TCP_CLOSING: case TCP_LAST_ACK: if (!before(TCP_SKB_CB(skb)->seq, tp->rcv_nxt)) { - if (sk_is_mptcp(sk)) - mptcp_incoming_options(sk, skb); + /* If a subflow has been reset, the packet should not + * continue to be processed, drop the packet. + */ + if (sk_is_mptcp(sk) && !mptcp_incoming_options(sk, skb)) + goto discard; break; } fallthrough; diff --git a/net/mptcp/options.c b/net/mptcp/options.c index 1aec01686c1a..8a386556a23c 100644 --- a/net/mptcp/options.c +++ b/net/mptcp/options.c @@ -847,7 +847,8 @@ bool mptcp_synack_options(const struct request_sock *req, unsigned int *size, static bool check_fully_established(struct mptcp_sock *msk, struct sock *ssk, struct mptcp_subflow_context *subflow, struct sk_buff *skb, - struct mptcp_options_received *mp_opt) + struct mptcp_options_received *mp_opt, + bool *subflow_is_rst) { /* here we can process OoO, in-window pkts, only in-sequence 4th ack * will make the subflow fully established @@ -926,6 +927,7 @@ static bool check_fully_established(struct mptcp_sock *msk, struct sock *ssk, return true; reset: + *subflow_is_rst = true; mptcp_subflow_reset(ssk); return false; } @@ -1022,12 +1024,14 @@ static bool add_addr_hmac_valid(struct mptcp_sock *msk, return hmac == mp_opt->ahmac; } -void mptcp_incoming_options(struct sock *sk, struct sk_buff *skb) +/* Return 0 if a subflow has been reset, else return 1 */ +int mptcp_incoming_options(struct sock *sk, struct sk_buff *skb) { struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk); struct mptcp_sock *msk = mptcp_sk(subflow->conn); struct mptcp_options_received mp_opt; struct mptcp_ext *mpext; + bool subflow_is_rst = false; if (__mptcp_check_fallback(msk)) { /* Keep it simple and unconditionally trigger send data cleanup and @@ -1040,12 +1044,12 @@ void mptcp_incoming_options(struct sock *sk, struct sk_buff *skb) __mptcp_check_push(subflow->conn, sk); __mptcp_data_acked(subflow->conn); mptcp_data_unlock(subflow->conn); - return; + return 1; } mptcp_get_options(sk, skb, &mp_opt); - if (!check_fully_established(msk, sk, subflow, skb, &mp_opt)) - return; + if (!check_fully_established(msk, sk, subflow, skb, &mp_opt, &subflow_is_rst)) + return subflow_is_rst ? 0 : 1; if (mp_opt.fastclose && msk->local_key == mp_opt.rcvr_key) { @@ -1087,7 +1091,7 @@ void mptcp_incoming_options(struct sock *sk, struct sk_buff *skb) } if (!mp_opt.dss) - return; + return 1; /* we can't wait for recvmsg() to update the ack_seq, otherwise * monodirectional flows will stuck @@ -1106,12 +1110,12 @@ void mptcp_incoming_options(struct sock *sk, struct sk_buff *skb) schedule_work(&msk->work)) sock_hold(subflow->conn); - return; + return 1; } mpext = skb_ext_add(skb, SKB_EXT_MPTCP); if (!mpext) - return; + return 1; memset(mpext, 0, sizeof(*mpext)); @@ -1140,6 +1144,8 @@ void mptcp_incoming_options(struct sock *sk, struct sk_buff *skb) if (mpext->csum_reqd) mpext->csum = mp_opt.csum; } + + return 1; } static void mptcp_set_rwin(const struct tcp_sock *tp)