@@ -3291,19 +3291,25 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv
32913291
32923292 if (optlen != sizeof (val ))
32933293 return - EINVAL ;
3294- if (po -> rx_ring .pg_vec || po -> tx_ring .pg_vec )
3295- return - EBUSY ;
32963294 if (copy_from_user (& val , optval , sizeof (val )))
32973295 return - EFAULT ;
32983296 switch (val ) {
32993297 case TPACKET_V1 :
33003298 case TPACKET_V2 :
33013299 case TPACKET_V3 :
3302- po -> tp_version = val ;
3303- return 0 ;
3300+ break ;
33043301 default :
33053302 return - EINVAL ;
33063303 }
3304+ lock_sock (sk );
3305+ if (po -> rx_ring .pg_vec || po -> tx_ring .pg_vec ) {
3306+ ret = - EBUSY ;
3307+ } else {
3308+ po -> tp_version = val ;
3309+ ret = 0 ;
3310+ }
3311+ release_sock (sk );
3312+ return ret ;
33073313 }
33083314 case PACKET_RESERVE :
33093315 {
@@ -3766,6 +3772,7 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u,
37663772 /* Added to avoid minimal code churn */
37673773 struct tpacket_req * req = & req_u -> req ;
37683774
3775+ lock_sock (sk );
37693776 /* Opening a Tx-ring is NOT supported in TPACKET_V3 */
37703777 if (!closing && tx_ring && (po -> tp_version > TPACKET_V2 )) {
37713778 WARN (1 , "Tx-ring is not supported.\n" );
@@ -3847,7 +3854,6 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u,
38473854 goto out ;
38483855 }
38493856
3850- lock_sock (sk );
38513857
38523858 /* Detach socket from network */
38533859 spin_lock (& po -> bind_lock );
@@ -3896,11 +3902,11 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u,
38963902 if (!tx_ring )
38973903 prb_shutdown_retire_blk_timer (po , tx_ring , rb_queue );
38983904 }
3899- release_sock (sk );
39003905
39013906 if (pg_vec )
39023907 free_pg_vec (pg_vec , order , req -> tp_block_nr );
39033908out :
3909+ release_sock (sk );
39043910 return err ;
39053911}
39063912
0 commit comments