@@ -158,14 +158,15 @@ struct isotp_sock {
158158 canid_t rxid ;
159159 ktime_t tx_gap ;
160160 ktime_t lastrxcf_tstamp ;
161- struct hrtimer rxtimer , txtimer , txfrtimer ;
161+ struct hrtimer rxtimer , txtimer , txfrtimer , echotimer ;
162162 struct can_isotp_options opt ;
163163 struct can_isotp_fc_options rxfc , txfc ;
164164 struct can_isotp_ll_options ll ;
165165 u32 frame_txtime ;
166166 u32 force_tx_stmin ;
167167 u32 force_rx_stmin ;
168168 u32 cfecho ; /* consecutive frame echo tag */
169+ u32 tx_gen ; /* generation, bumped per new tx transfer */
169170 struct tpcon rx , tx ;
170171 struct list_head notifier ;
171172 wait_queue_head_t wait ;
@@ -378,6 +379,15 @@ static int isotp_rcv_fc(struct isotp_sock *so, struct canfd_frame *cf, int ae)
378379
379380 hrtimer_cancel (& so -> txtimer );
380381
382+ /* isotp_tx_timeout() may have given up on this job while
383+ * hrtimer_cancel() above waited for it to finish; so->rx_lock
384+ * (held by our caller isotp_rcv()) rules out a concurrent claim,
385+ * so a plain recheck is enough here.
386+ */
387+ if (so -> tx .state != ISOTP_WAIT_FC &&
388+ so -> tx .state != ISOTP_WAIT_FIRST_FC )
389+ return 1 ;
390+
381391 if ((cf -> len < ae + FC_CONTENT_SZ ) ||
382392 ((so -> opt .flags & ISOTP_CHECK_PADDING ) &&
383393 check_pad (so , cf , ae + FC_CONTENT_SZ , so -> opt .rxpad_content ))) {
@@ -424,7 +434,7 @@ static int isotp_rcv_fc(struct isotp_sock *so, struct canfd_frame *cf, int ae)
424434 so -> tx .bs = 0 ;
425435 so -> tx .state = ISOTP_SENDING ;
426436 /* send CF frame and enable echo timeout handling */
427- hrtimer_start (& so -> txtimer , ktime_set (ISOTP_ECHO_TIMEOUT , 0 ),
437+ hrtimer_start (& so -> echotimer , ktime_set (ISOTP_ECHO_TIMEOUT , 0 ),
428438 HRTIMER_MODE_REL_SOFT );
429439 isotp_send_cframe (so );
430440 break ;
@@ -577,6 +587,14 @@ static int isotp_rcv_cf(struct sock *sk, struct canfd_frame *cf, int ae,
577587
578588 hrtimer_cancel (& so -> rxtimer );
579589
590+ /* isotp_rx_timer_handler() may have raced us for so->rx.state
591+ * while hrtimer_cancel() above waited for it to finish, already
592+ * reporting ETIMEDOUT and resetting the reception; don't process
593+ * this CF into a reassembly that has already been given up on.
594+ */
595+ if (so -> rx .state != ISOTP_WAIT_DATA )
596+ return 1 ;
597+
580598 /* CFs are never longer than the FF */
581599 if (cf -> len > so -> rx .ll_dl )
582600 return 1 ;
@@ -872,74 +890,120 @@ static void isotp_rcv_echo(struct sk_buff *skb, void *data)
872890 struct canfd_frame * cf = (struct canfd_frame * )skb -> data ;
873891
874892 /* only handle my own local echo CF/SF skb's (no FF!) */
875- if (skb -> sk != sk || so -> cfecho != * ( u32 * ) cf -> data )
893+ if (skb -> sk != sk )
876894 return ;
877895
896+ /* unlike isotp_rcv_fc()/isotp_rcv_cf(), not already under so->rx_lock
897+ * (no isotp_rcv() caller here), so take it ourselves
898+ */
899+ spin_lock (& so -> rx_lock );
900+
901+ /* so->cfecho may since belong to a new transfer; recheck under lock */
902+ if (so -> cfecho != * (u32 * )cf -> data )
903+ goto out_unlock ;
904+
878905 /* cancel local echo timeout */
879- hrtimer_cancel (& so -> txtimer );
906+ hrtimer_cancel (& so -> echotimer );
880907
881908 /* local echo skb with consecutive frame has been consumed */
882909 so -> cfecho = 0 ;
883910
911+ /* claiming a transfer also takes so->rx_lock, so a plain recheck
912+ * is enough: so->tx.state can't have flipped to ISOTP_SENDING for
913+ * a new claim while we're still in here
914+ */
915+ if (so -> tx .state != ISOTP_SENDING )
916+ goto out_unlock ;
917+
884918 if (so -> tx .idx >= so -> tx .len ) {
885919 /* we are done */
886920 so -> tx .state = ISOTP_IDLE ;
887921 wake_up_interruptible (& so -> wait );
888- return ;
922+ goto out_unlock ;
889923 }
890924
891925 if (so -> txfc .bs && so -> tx .bs >= so -> txfc .bs ) {
892926 /* stop and wait for FC with timeout */
893927 so -> tx .state = ISOTP_WAIT_FC ;
894928 hrtimer_start (& so -> txtimer , ktime_set (ISOTP_FC_TIMEOUT , 0 ),
895929 HRTIMER_MODE_REL_SOFT );
896- return ;
930+ goto out_unlock ;
897931 }
898932
899933 /* no gap between data frames needed => use burst mode */
900934 if (!so -> tx_gap ) {
901935 /* enable echo timeout handling */
902- hrtimer_start (& so -> txtimer , ktime_set (ISOTP_ECHO_TIMEOUT , 0 ),
936+ hrtimer_start (& so -> echotimer , ktime_set (ISOTP_ECHO_TIMEOUT , 0 ),
903937 HRTIMER_MODE_REL_SOFT );
904938 isotp_send_cframe (so );
905- return ;
939+ goto out_unlock ;
906940 }
907941
908942 /* start timer to send next consecutive frame with correct delay */
909943 hrtimer_start (& so -> txfrtimer , so -> tx_gap , HRTIMER_MODE_REL_SOFT );
944+
945+ out_unlock :
946+ spin_unlock (& so -> rx_lock );
910947}
911948
912- static enum hrtimer_restart isotp_tx_timer_handler (struct hrtimer * hrtimer )
949+ /* shared by so->txtimer's and so->echotimer's callbacks. Both timers get
950+ * cancelled under so->rx_lock elsewhere, so this must stay lock-free to
951+ * avoid deadlocking with that; uses so->tx_gen instead to avoid tainting
952+ * a new transfer with an error from the one that just timed out.
953+ */
954+ static enum hrtimer_restart isotp_tx_timeout (struct isotp_sock * so )
913955{
914- struct isotp_sock * so = container_of (hrtimer , struct isotp_sock ,
915- txtimer );
916956 struct sock * sk = & so -> sk ;
957+ u32 gen = READ_ONCE (so -> tx_gen );
958+ u32 old_state = READ_ONCE (so -> tx .state );
917959
918960 /* don't handle timeouts in IDLE or SHUTDOWN state */
919- if (so -> tx .state == ISOTP_IDLE || so -> tx .state == ISOTP_SHUTDOWN )
961+ if (old_state == ISOTP_IDLE || old_state == ISOTP_SHUTDOWN )
962+ return HRTIMER_NORESTART ;
963+
964+ /* only claim the timeout if the state is still unchanged */
965+ if (cmpxchg (& so -> tx .state , old_state , ISOTP_IDLE ) != old_state )
920966 return HRTIMER_NORESTART ;
921967
922968 /* we did not get any flow control or echo frame in time */
923969
924- /* report 'communication error on send' */
925- sk -> sk_err = ECOMM ;
926- if (!sock_flag (sk , SOCK_DEAD ))
927- sk_error_report (sk );
970+ if (READ_ONCE (so -> tx_gen ) == gen ) {
971+ /* report 'communication error on send' */
972+ sk -> sk_err = ECOMM ;
973+ if (!sock_flag (sk , SOCK_DEAD ))
974+ sk_error_report (sk );
975+ }
928976
929- /* reset tx state */
930- so -> tx .state = ISOTP_IDLE ;
931977 wake_up_interruptible (& so -> wait );
932978
933979 return HRTIMER_NORESTART ;
934980}
935981
982+ /* so->txtimer: fires when a Flow Control frame does not arrive in time */
983+ static enum hrtimer_restart isotp_tx_timer_handler (struct hrtimer * hrtimer )
984+ {
985+ struct isotp_sock * so = container_of (hrtimer , struct isotp_sock ,
986+ txtimer );
987+
988+ return isotp_tx_timeout (so );
989+ }
990+
991+ /* so->echotimer: fires when a sent CF/SF's local echo does not arrive */
992+ static enum hrtimer_restart isotp_echo_timer_handler (struct hrtimer * hrtimer )
993+ {
994+ struct isotp_sock * so = container_of (hrtimer , struct isotp_sock ,
995+ echotimer );
996+
997+ return isotp_tx_timeout (so );
998+ }
999+
9361000static enum hrtimer_restart isotp_txfr_timer_handler (struct hrtimer * hrtimer )
9371001{
9381002 struct isotp_sock * so = container_of (hrtimer , struct isotp_sock ,
9391003 txfrtimer );
9401004
9411005 /* start echo timeout handling and cover below protocol error */
942- hrtimer_start (& so -> txtimer , ktime_set (ISOTP_ECHO_TIMEOUT , 0 ),
1006+ hrtimer_start (& so -> echotimer , ktime_set (ISOTP_ECHO_TIMEOUT , 0 ),
9431007 HRTIMER_MODE_REL_SOFT );
9441008
9451009 /* cfecho should be consumed by isotp_rcv_echo() here */
@@ -960,13 +1024,24 @@ static int isotp_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
9601024 int ae = (so -> opt .flags & CAN_ISOTP_EXTEND_ADDR ) ? 1 : 0 ;
9611025 int wait_tx_done = (so -> opt .flags & CAN_ISOTP_WAIT_TX_DONE ) ? 1 : 0 ;
9621026 s64 hrtimer_sec = ISOTP_ECHO_TIMEOUT ;
1027+ struct hrtimer * tx_hrt = & so -> echotimer ;
1028+ u32 new_state = ISOTP_SENDING ;
9631029 int off ;
9641030 int err ;
9651031
9661032 if (!so -> bound || so -> tx .state == ISOTP_SHUTDOWN )
9671033 return - EADDRNOTAVAIL ;
9681034
969- while (cmpxchg (& so -> tx .state , ISOTP_IDLE , ISOTP_SENDING ) != ISOTP_IDLE ) {
1035+ /* claim the socket under so->rx_lock: this serializes the claim
1036+ * with the RX path and with sendmsg()'s own error paths below, so
1037+ * none of them can ever see a transfer mid-claim
1038+ */
1039+ for (;;) {
1040+ spin_lock_bh (& so -> rx_lock );
1041+ if (READ_ONCE (so -> tx .state ) == ISOTP_IDLE )
1042+ break ;
1043+ spin_unlock_bh (& so -> rx_lock );
1044+
9701045 /* we do not support multiple buffers - for now */
9711046 if (msg -> msg_flags & MSG_DONTWAIT )
9721047 return - EAGAIN ;
@@ -975,11 +1050,23 @@ static int isotp_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
9751050 return - EADDRNOTAVAIL ;
9761051
9771052 /* wait for complete transmission of current pdu */
978- err = wait_event_interruptible (so -> wait , so -> tx .state == ISOTP_IDLE );
1053+ err = wait_event_interruptible (so -> wait ,
1054+ so -> tx .state == ISOTP_IDLE );
9791055 if (err )
980- goto err_event_drop ;
1056+ return err ;
9811057 }
9821058
1059+ /* new transfer: bump so->tx_gen and drain the old one's timers,
1060+ * still under the so->rx_lock we just claimed the socket with
1061+ */
1062+ WRITE_ONCE (so -> tx .state , ISOTP_SENDING );
1063+ WRITE_ONCE (so -> tx_gen , READ_ONCE (so -> tx_gen ) + 1 );
1064+ hrtimer_cancel (& so -> txtimer );
1065+ hrtimer_cancel (& so -> echotimer );
1066+ hrtimer_cancel (& so -> txfrtimer );
1067+ so -> cfecho = 0 ;
1068+ spin_unlock_bh (& so -> rx_lock );
1069+
9831070 /* so->bound is only checked once above - a wakeup may have
9841071 * unbound/rebound the socket meanwhile, so re-validate it
9851072 */
@@ -1096,18 +1183,33 @@ static int isotp_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
10961183 so -> cfecho = * (u32 * )cf -> data ;
10971184 } else {
10981185 /* standard flow control check */
1099- so -> tx . state = ISOTP_WAIT_FIRST_FC ;
1186+ new_state = ISOTP_WAIT_FIRST_FC ;
11001187
11011188 /* start timeout for FC */
11021189 hrtimer_sec = ISOTP_FC_TIMEOUT ;
1190+ tx_hrt = & so -> txtimer ;
11031191
11041192 /* no CF echo tag for isotp_rcv_echo() (FF-mode) */
11051193 so -> cfecho = 0 ;
11061194 }
11071195 }
11081196
1109- hrtimer_start (& so -> txtimer , ktime_set (hrtimer_sec , 0 ),
1197+ spin_lock_bh (& so -> rx_lock );
1198+ if (so -> tx .state == ISOTP_SHUTDOWN ) {
1199+ /* isotp_release() has since taken over and already drained
1200+ * our timers - don't send into a socket that's going away
1201+ */
1202+ spin_unlock_bh (& so -> rx_lock );
1203+ kfree_skb (skb );
1204+ dev_put (dev );
1205+ wake_up_interruptible (& so -> wait );
1206+ return - EADDRNOTAVAIL ;
1207+ }
1208+ /* WAIT_FIRST_FC for standard FF, else stays ISOTP_SENDING */
1209+ so -> tx .state = new_state ;
1210+ hrtimer_start (tx_hrt , ktime_set (hrtimer_sec , 0 ),
11101211 HRTIMER_MODE_REL_SOFT );
1212+ spin_unlock_bh (& so -> rx_lock );
11111213
11121214 /* send the first or only CAN frame */
11131215 cf -> flags = so -> ll .tx_flags ;
@@ -1120,13 +1222,10 @@ static int isotp_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
11201222 pr_notice_once ("can-isotp: %s: can_send_ret %pe\n" ,
11211223 __func__ , ERR_PTR (err ));
11221224
1225+ spin_lock_bh (& so -> rx_lock );
11231226 /* no transmission -> no timeout monitoring */
1124- hrtimer_cancel (& so -> txtimer );
1125-
1126- /* reset consecutive frame echo tag */
1127- so -> cfecho = 0 ;
1128-
1129- goto err_out_drop ;
1227+ hrtimer_cancel (tx_hrt );
1228+ goto err_out_drop_locked ;
11301229 }
11311230
11321231 if (wait_tx_done ) {
@@ -1142,14 +1241,21 @@ static int isotp_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
11421241
11431242 return size ;
11441243
1244+ err_out_drop :
1245+ /* claimed but nothing sent yet - no timer to cancel */
1246+ spin_lock_bh (& so -> rx_lock );
1247+ goto err_out_drop_locked ;
11451248err_event_drop :
1146- /* got signal: force tx state machine to be idle */
1147- so -> tx . state = ISOTP_IDLE ;
1249+ /* interrupted waiting on our own transfer - drain its timers */
1250+ spin_lock_bh ( & so -> rx_lock ) ;
11481251 hrtimer_cancel (& so -> txfrtimer );
11491252 hrtimer_cancel (& so -> txtimer );
1150- err_out_drop :
1151- /* drop this PDU and unlock a potential wait queue */
1253+ hrtimer_cancel (& so -> echotimer );
1254+ err_out_drop_locked :
1255+ /* release the claim; so->rx_lock still held from above */
1256+ so -> cfecho = 0 ;
11521257 so -> tx .state = ISOTP_IDLE ;
1258+ spin_unlock_bh (& so -> rx_lock );
11531259 wake_up_interruptible (& so -> wait );
11541260
11551261 return err ;
@@ -1211,13 +1317,20 @@ static int isotp_release(struct socket *sock)
12111317 so = isotp_sk (sk );
12121318 net = sock_net (sk );
12131319
1214- /* wait for complete transmission of current pdu */
1215- while (wait_event_interruptible (so -> wait , so -> tx .state == ISOTP_IDLE ) == 0 &&
1216- cmpxchg (& so -> tx .state , ISOTP_IDLE , ISOTP_SHUTDOWN ) != ISOTP_IDLE )
1320+ /* best-effort: wait for a running pdu to finish, but don't block on
1321+ * it forever - give up after the first signal
1322+ */
1323+ while (so -> tx .state != ISOTP_IDLE &&
1324+ wait_event_interruptible (so -> wait , so -> tx .state == ISOTP_IDLE ) == 0 )
12171325 ;
12181326
1219- /* force state machines to be idle also when a signal occurred */
1327+ /* claim the socket under so->rx_lock like sendmsg() does, so its
1328+ * claim can't race the forced ISOTP_SHUTDOWN below; force it
1329+ * unconditionally, even when a signal cut the wait above short
1330+ */
1331+ spin_lock_bh (& so -> rx_lock );
12201332 so -> tx .state = ISOTP_SHUTDOWN ;
1333+ spin_unlock_bh (& so -> rx_lock );
12211334 so -> rx .state = ISOTP_IDLE ;
12221335
12231336 spin_lock (& isotp_notifier_lock );
@@ -1263,6 +1376,7 @@ static int isotp_release(struct socket *sock)
12631376
12641377 hrtimer_cancel (& so -> txfrtimer );
12651378 hrtimer_cancel (& so -> txtimer );
1379+ hrtimer_cancel (& so -> echotimer );
12661380 hrtimer_cancel (& so -> rxtimer );
12671381
12681382 sock_orphan (sk );
@@ -1702,10 +1816,14 @@ static int isotp_init(struct sock *sk)
17021816 so -> rx .buflen = ARRAY_SIZE (so -> rx .sbuf );
17031817 so -> tx .buflen = ARRAY_SIZE (so -> tx .sbuf );
17041818
1705- hrtimer_setup (& so -> rxtimer , isotp_rx_timer_handler , CLOCK_MONOTONIC , HRTIMER_MODE_REL_SOFT );
1706- hrtimer_setup (& so -> txtimer , isotp_tx_timer_handler , CLOCK_MONOTONIC , HRTIMER_MODE_REL_SOFT );
1707- hrtimer_setup (& so -> txfrtimer , isotp_txfr_timer_handler , CLOCK_MONOTONIC ,
1708- HRTIMER_MODE_REL_SOFT );
1819+ hrtimer_setup (& so -> rxtimer , isotp_rx_timer_handler ,
1820+ CLOCK_MONOTONIC , HRTIMER_MODE_REL_SOFT );
1821+ hrtimer_setup (& so -> txtimer , isotp_tx_timer_handler ,
1822+ CLOCK_MONOTONIC , HRTIMER_MODE_REL_SOFT );
1823+ hrtimer_setup (& so -> echotimer , isotp_echo_timer_handler ,
1824+ CLOCK_MONOTONIC , HRTIMER_MODE_REL_SOFT );
1825+ hrtimer_setup (& so -> txfrtimer , isotp_txfr_timer_handler ,
1826+ CLOCK_MONOTONIC , HRTIMER_MODE_REL_SOFT );
17091827
17101828 init_waitqueue_head (& so -> wait );
17111829 spin_lock_init (& so -> rx_lock );
0 commit comments