@@ -262,12 +262,17 @@ static bool j1939_sk_match_dst(struct j1939_sock *jsk,
262
262
static bool j1939_sk_match_filter (struct j1939_sock * jsk ,
263
263
const struct j1939_sk_buff_cb * skcb )
264
264
{
265
- const struct j1939_filter * f = jsk -> filters ;
266
- int nfilter = jsk -> nfilters ;
265
+ const struct j1939_filter * f ;
266
+ int nfilter ;
267
+
268
+ spin_lock_bh (& jsk -> filters_lock );
269
+
270
+ f = jsk -> filters ;
271
+ nfilter = jsk -> nfilters ;
267
272
268
273
if (!nfilter )
269
274
/* receive all when no filters are assigned */
270
- return true ;
275
+ goto filter_match_found ;
271
276
272
277
for (; nfilter ; ++ f , -- nfilter ) {
273
278
if ((skcb -> addr .pgn & f -> pgn_mask ) != f -> pgn )
@@ -276,9 +281,15 @@ static bool j1939_sk_match_filter(struct j1939_sock *jsk,
276
281
continue ;
277
282
if ((skcb -> addr .src_name & f -> name_mask ) != f -> name )
278
283
continue ;
279
- return true ;
284
+ goto filter_match_found ;
280
285
}
286
+
287
+ spin_unlock_bh (& jsk -> filters_lock );
281
288
return false;
289
+
290
+ filter_match_found :
291
+ spin_unlock_bh (& jsk -> filters_lock );
292
+ return true;
282
293
}
283
294
284
295
static bool j1939_sk_recv_match_one (struct j1939_sock * jsk ,
@@ -401,6 +412,7 @@ static int j1939_sk_init(struct sock *sk)
401
412
atomic_set (& jsk -> skb_pending , 0 );
402
413
spin_lock_init (& jsk -> sk_session_queue_lock );
403
414
INIT_LIST_HEAD (& jsk -> sk_session_queue );
415
+ spin_lock_init (& jsk -> filters_lock );
404
416
405
417
/* j1939_sk_sock_destruct() depends on SOCK_RCU_FREE flag */
406
418
sock_set_flag (sk , SOCK_RCU_FREE );
@@ -703,9 +715,11 @@ static int j1939_sk_setsockopt(struct socket *sock, int level, int optname,
703
715
}
704
716
705
717
lock_sock (& jsk -> sk );
718
+ spin_lock_bh (& jsk -> filters_lock );
706
719
ofilters = jsk -> filters ;
707
720
jsk -> filters = filters ;
708
721
jsk -> nfilters = count ;
722
+ spin_unlock_bh (& jsk -> filters_lock );
709
723
release_sock (& jsk -> sk );
710
724
kfree (ofilters );
711
725
return 0 ;
0 commit comments