aboutsummaryrefslogtreecommitdiffstats
path: root/net/packet
diff options
context:
space:
mode:
Diffstat (limited to 'net/packet')
-rw-r--r--net/packet/af_packet.c46
1 files changed, 8 insertions, 38 deletions
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 40053a08f00..0f661745df0 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -3224,10 +3224,10 @@ static int packet_getsockopt(struct socket *sock, int level, int optname,
3224 char __user *optval, int __user *optlen) 3224 char __user *optval, int __user *optlen)
3225{ 3225{
3226 int len; 3226 int len;
3227 int val; 3227 int val, lv = sizeof(val);
3228 struct sock *sk = sock->sk; 3228 struct sock *sk = sock->sk;
3229 struct packet_sock *po = pkt_sk(sk); 3229 struct packet_sock *po = pkt_sk(sk);
3230 void *data; 3230 void *data = &val;
3231 struct tpacket_stats st; 3231 struct tpacket_stats st;
3232 union tpacket_stats_u st_u; 3232 union tpacket_stats_u st_u;
3233 3233
@@ -3242,21 +3242,17 @@ static int packet_getsockopt(struct socket *sock, int level, int optname,
3242 3242
3243 switch (optname) { 3243 switch (optname) {
3244 case PACKET_STATISTICS: 3244 case PACKET_STATISTICS:
3245 if (po->tp_version == TPACKET_V3) {
3246 len = sizeof(struct tpacket_stats_v3);
3247 } else {
3248 if (len > sizeof(struct tpacket_stats))
3249 len = sizeof(struct tpacket_stats);
3250 }
3251 spin_lock_bh(&sk->sk_receive_queue.lock); 3245 spin_lock_bh(&sk->sk_receive_queue.lock);
3252 if (po->tp_version == TPACKET_V3) { 3246 if (po->tp_version == TPACKET_V3) {
3247 lv = sizeof(struct tpacket_stats_v3);
3253 memcpy(&st_u.stats3, &po->stats, 3248 memcpy(&st_u.stats3, &po->stats,
3254 sizeof(struct tpacket_stats)); 3249 sizeof(struct tpacket_stats));
3255 st_u.stats3.tp_freeze_q_cnt = 3250 st_u.stats3.tp_freeze_q_cnt =
3256 po->stats_u.stats3.tp_freeze_q_cnt; 3251 po->stats_u.stats3.tp_freeze_q_cnt;
3257 st_u.stats3.tp_packets += po->stats.tp_drops; 3252 st_u.stats3.tp_packets += po->stats.tp_drops;
3258 data = &st_u.stats3; 3253 data = &st_u.stats3;
3259 } else { 3254 } else {
3255 lv = sizeof(struct tpacket_stats);
3260 st = po->stats; 3256 st = po->stats;
3261 st.tp_packets += st.tp_drops; 3257 st.tp_packets += st.tp_drops;
3262 data = &st; 3258 data = &st;
@@ -3265,31 +3261,16 @@ static int packet_getsockopt(struct socket *sock, int level, int optname,
3265 spin_unlock_bh(&sk->sk_receive_queue.lock); 3261 spin_unlock_bh(&sk->sk_receive_queue.lock);
3266 break; 3262 break;
3267 case PACKET_AUXDATA: 3263 case PACKET_AUXDATA:
3268 if (len > sizeof(int))
3269 len = sizeof(int);
3270 val = po->auxdata; 3264 val = po->auxdata;
3271
3272 data = &val;
3273 break; 3265 break;
3274 case PACKET_ORIGDEV: 3266 case PACKET_ORIGDEV:
3275 if (len > sizeof(int))
3276 len = sizeof(int);
3277 val = po->origdev; 3267 val = po->origdev;
3278
3279 data = &val;
3280 break; 3268 break;
3281 case PACKET_VNET_HDR: 3269 case PACKET_VNET_HDR:
3282 if (len > sizeof(int))
3283 len = sizeof(int);
3284 val = po->has_vnet_hdr; 3270 val = po->has_vnet_hdr;
3285
3286 data = &val;
3287 break; 3271 break;
3288 case PACKET_VERSION: 3272 case PACKET_VERSION:
3289 if (len > sizeof(int))
3290 len = sizeof(int);
3291 val = po->tp_version; 3273 val = po->tp_version;
3292 data = &val;
3293 break; 3274 break;
3294 case PACKET_HDRLEN: 3275 case PACKET_HDRLEN:
3295 if (len > sizeof(int)) 3276 if (len > sizeof(int))
@@ -3309,39 +3290,28 @@ static int packet_getsockopt(struct socket *sock, int level, int optname,
3309 default: 3290 default:
3310 return -EINVAL; 3291 return -EINVAL;
3311 } 3292 }
3312 data = &val;
3313 break; 3293 break;
3314 case PACKET_RESERVE: 3294 case PACKET_RESERVE:
3315 if (len > sizeof(unsigned int))
3316 len = sizeof(unsigned int);
3317 val = po->tp_reserve; 3295 val = po->tp_reserve;
3318 data = &val;
3319 break; 3296 break;
3320 case PACKET_LOSS: 3297 case PACKET_LOSS:
3321 if (len > sizeof(unsigned int))
3322 len = sizeof(unsigned int);
3323 val = po->tp_loss; 3298 val = po->tp_loss;
3324 data = &val;
3325 break; 3299 break;
3326 case PACKET_TIMESTAMP: 3300 case PACKET_TIMESTAMP:
3327 if (len > sizeof(int))
3328 len = sizeof(int);
3329 val = po->tp_tstamp; 3301 val = po->tp_tstamp;
3330 data = &val;
3331 break; 3302 break;
3332 case PACKET_FANOUT: 3303 case PACKET_FANOUT:
3333 if (len > sizeof(int))
3334 len = sizeof(int);
3335 val = (po->fanout ? 3304 val = (po->fanout ?
3336 ((u32)po->fanout->id | 3305 ((u32)po->fanout->id |
3337 ((u32)po->fanout->type << 16)) : 3306 ((u32)po->fanout->type << 16)) :
3338 0); 3307 0);
3339 data = &val;
3340 break; 3308 break;
3341 default: 3309 default:
3342 return -ENOPROTOOPT; 3310 return -ENOPROTOOPT;
3343 } 3311 }
3344 3312
3313 if (len > lv)
3314 len = lv;
3345 if (put_user(len, optlen)) 3315 if (put_user(len, optlen))
3346 return -EFAULT; 3316 return -EFAULT;
3347 if (copy_to_user(optval, data, len)) 3317 if (copy_to_user(optval, data, len))