aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'net/packet/af_packet.c')
-rw-r--r--net/packet/af_packet.c18
1 files changed, 12 insertions, 6 deletions
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index a3654d929814..b9d1baaa8bdc 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -3344,19 +3344,25 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv
3344 3344
3345 if (optlen != sizeof(val)) 3345 if (optlen != sizeof(val))
3346 return -EINVAL; 3346 return -EINVAL;
3347 if (po->rx_ring.pg_vec || po->tx_ring.pg_vec)
3348 return -EBUSY;
3349 if (copy_from_user(&val, optval, sizeof(val))) 3347 if (copy_from_user(&val, optval, sizeof(val)))
3350 return -EFAULT; 3348 return -EFAULT;
3351 switch (val) { 3349 switch (val) {
3352 case TPACKET_V1: 3350 case TPACKET_V1:
3353 case TPACKET_V2: 3351 case TPACKET_V2:
3354 case TPACKET_V3: 3352 case TPACKET_V3:
3355 po->tp_version = val; 3353 break;
3356 return 0;
3357 default: 3354 default:
3358 return -EINVAL; 3355 return -EINVAL;
3359 } 3356 }
3357 lock_sock(sk);
3358 if (po->rx_ring.pg_vec || po->tx_ring.pg_vec) {
3359 ret = -EBUSY;
3360 } else {
3361 po->tp_version = val;
3362 ret = 0;
3363 }
3364 release_sock(sk);
3365 return ret;
3360 } 3366 }
3361 case PACKET_RESERVE: 3367 case PACKET_RESERVE:
3362 { 3368 {
@@ -3819,6 +3825,7 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u,
3819 /* Added to avoid minimal code churn */ 3825 /* Added to avoid minimal code churn */
3820 struct tpacket_req *req = &req_u->req; 3826 struct tpacket_req *req = &req_u->req;
3821 3827
3828 lock_sock(sk);
3822 /* Opening a Tx-ring is NOT supported in TPACKET_V3 */ 3829 /* Opening a Tx-ring is NOT supported in TPACKET_V3 */
3823 if (!closing && tx_ring && (po->tp_version > TPACKET_V2)) { 3830 if (!closing && tx_ring && (po->tp_version > TPACKET_V2)) {
3824 WARN(1, "Tx-ring is not supported.\n"); 3831 WARN(1, "Tx-ring is not supported.\n");
@@ -3900,7 +3907,6 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u,
3900 goto out; 3907 goto out;
3901 } 3908 }
3902 3909
3903 lock_sock(sk);
3904 3910
3905 /* Detach socket from network */ 3911 /* Detach socket from network */
3906 spin_lock(&po->bind_lock); 3912 spin_lock(&po->bind_lock);
@@ -3949,11 +3955,11 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u,
3949 if (!tx_ring) 3955 if (!tx_ring)
3950 prb_shutdown_retire_blk_timer(po, tx_ring, rb_queue); 3956 prb_shutdown_retire_blk_timer(po, tx_ring, rb_queue);
3951 } 3957 }
3952 release_sock(sk);
3953 3958
3954 if (pg_vec) 3959 if (pg_vec)
3955 free_pg_vec(pg_vec, order, req->tp_block_nr); 3960 free_pg_vec(pg_vec, order, req->tp_block_nr);
3956out: 3961out:
3962 release_sock(sk);
3957 return err; 3963 return err;
3958} 3964}
3959 3965