aboutsummaryrefslogtreecommitdiffstats
path: root/net/packet/af_packet.c
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 fab9bbfdead5..89f2e8c1f4dc 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -3593,19 +3593,25 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv
3593 3593
3594 if (optlen != sizeof(val)) 3594 if (optlen != sizeof(val))
3595 return -EINVAL; 3595 return -EINVAL;
3596 if (po->rx_ring.pg_vec || po->tx_ring.pg_vec)
3597 return -EBUSY;
3598 if (copy_from_user(&val, optval, sizeof(val))) 3596 if (copy_from_user(&val, optval, sizeof(val)))
3599 return -EFAULT; 3597 return -EFAULT;
3600 switch (val) { 3598 switch (val) {
3601 case TPACKET_V1: 3599 case TPACKET_V1:
3602 case TPACKET_V2: 3600 case TPACKET_V2:
3603 case TPACKET_V3: 3601 case TPACKET_V3:
3604 po->tp_version = val; 3602 break;
3605 return 0;
3606 default: 3603 default:
3607 return -EINVAL; 3604 return -EINVAL;
3608 } 3605 }
3606 lock_sock(sk);
3607 if (po->rx_ring.pg_vec || po->tx_ring.pg_vec) {
3608 ret = -EBUSY;
3609 } else {
3610 po->tp_version = val;
3611 ret = 0;
3612 }
3613 release_sock(sk);
3614 return ret;
3609 } 3615 }
3610 case PACKET_RESERVE: 3616 case PACKET_RESERVE:
3611 { 3617 {
@@ -4109,6 +4115,7 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u,
4109 /* Added to avoid minimal code churn */ 4115 /* Added to avoid minimal code churn */
4110 struct tpacket_req *req = &req_u->req; 4116 struct tpacket_req *req = &req_u->req;
4111 4117
4118 lock_sock(sk);
4112 /* Opening a Tx-ring is NOT supported in TPACKET_V3 */ 4119 /* Opening a Tx-ring is NOT supported in TPACKET_V3 */
4113 if (!closing && tx_ring && (po->tp_version > TPACKET_V2)) { 4120 if (!closing && tx_ring && (po->tp_version > TPACKET_V2)) {
4114 net_warn_ratelimited("Tx-ring is not supported.\n"); 4121 net_warn_ratelimited("Tx-ring is not supported.\n");
@@ -4190,7 +4197,6 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u,
4190 goto out; 4197 goto out;
4191 } 4198 }
4192 4199
4193 lock_sock(sk);
4194 4200
4195 /* Detach socket from network */ 4201 /* Detach socket from network */
4196 spin_lock(&po->bind_lock); 4202 spin_lock(&po->bind_lock);
@@ -4239,11 +4245,11 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u,
4239 if (!tx_ring) 4245 if (!tx_ring)
4240 prb_shutdown_retire_blk_timer(po, rb_queue); 4246 prb_shutdown_retire_blk_timer(po, rb_queue);
4241 } 4247 }
4242 release_sock(sk);
4243 4248
4244 if (pg_vec) 4249 if (pg_vec)
4245 free_pg_vec(pg_vec, order, req->tp_block_nr); 4250 free_pg_vec(pg_vec, order, req->tp_block_nr);
4246out: 4251out:
4252 release_sock(sk);
4247 return err; 4253 return err;
4248} 4254}
4249 4255