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.c30
1 files changed, 15 insertions, 15 deletions
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index da73e8a8c18d..594c078c5ebc 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -428,24 +428,18 @@ out_unlock:
428} 428}
429#endif 429#endif
430 430
431static inline int run_filter(struct sk_buff *skb, struct sock *sk, 431static inline unsigned int run_filter(struct sk_buff *skb, struct sock *sk,
432 unsigned *snaplen) 432 unsigned int res)
433{ 433{
434 struct sk_filter *filter; 434 struct sk_filter *filter;
435 int err = 0;
436 435
437 rcu_read_lock_bh(); 436 rcu_read_lock_bh();
438 filter = rcu_dereference(sk->sk_filter); 437 filter = rcu_dereference(sk->sk_filter);
439 if (filter != NULL) { 438 if (filter != NULL)
440 err = sk_run_filter(skb, filter->insns, filter->len); 439 res = sk_run_filter(skb, filter->insns, filter->len);
441 if (!err)
442 err = -EPERM;
443 else if (*snaplen > err)
444 *snaplen = err;
445 }
446 rcu_read_unlock_bh(); 440 rcu_read_unlock_bh();
447 441
448 return err; 442 return res;
449} 443}
450 444
451/* 445/*
@@ -467,7 +461,7 @@ static int packet_rcv(struct sk_buff *skb, struct net_device *dev, struct packet
467 struct packet_sock *po; 461 struct packet_sock *po;
468 u8 * skb_head = skb->data; 462 u8 * skb_head = skb->data;
469 int skb_len = skb->len; 463 int skb_len = skb->len;
470 unsigned snaplen; 464 unsigned int snaplen, res;
471 465
472 if (skb->pkt_type == PACKET_LOOPBACK) 466 if (skb->pkt_type == PACKET_LOOPBACK)
473 goto drop; 467 goto drop;
@@ -495,8 +489,11 @@ static int packet_rcv(struct sk_buff *skb, struct net_device *dev, struct packet
495 489
496 snaplen = skb->len; 490 snaplen = skb->len;
497 491
498 if (run_filter(skb, sk, &snaplen) < 0) 492 res = run_filter(skb, sk, snaplen);
493 if (!res)
499 goto drop_n_restore; 494 goto drop_n_restore;
495 if (snaplen > res)
496 snaplen = res;
500 497
501 if (atomic_read(&sk->sk_rmem_alloc) + skb->truesize >= 498 if (atomic_read(&sk->sk_rmem_alloc) + skb->truesize >=
502 (unsigned)sk->sk_rcvbuf) 499 (unsigned)sk->sk_rcvbuf)
@@ -568,7 +565,7 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, struct packe
568 struct tpacket_hdr *h; 565 struct tpacket_hdr *h;
569 u8 * skb_head = skb->data; 566 u8 * skb_head = skb->data;
570 int skb_len = skb->len; 567 int skb_len = skb->len;
571 unsigned snaplen; 568 unsigned int snaplen, res;
572 unsigned long status = TP_STATUS_LOSING|TP_STATUS_USER; 569 unsigned long status = TP_STATUS_LOSING|TP_STATUS_USER;
573 unsigned short macoff, netoff; 570 unsigned short macoff, netoff;
574 struct sk_buff *copy_skb = NULL; 571 struct sk_buff *copy_skb = NULL;
@@ -592,8 +589,11 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, struct packe
592 589
593 snaplen = skb->len; 590 snaplen = skb->len;
594 591
595 if (run_filter(skb, sk, &snaplen) < 0) 592 res = run_filter(skb, sk, snaplen);
593 if (!res)
596 goto drop_n_restore; 594 goto drop_n_restore;
595 if (snaplen > res)
596 snaplen = res;
597 597
598 if (sk->sk_type == SOCK_DGRAM) { 598 if (sk->sk_type == SOCK_DGRAM) {
599 macoff = netoff = TPACKET_ALIGN(TPACKET_HDRLEN) + 16; 599 macoff = netoff = TPACKET_ALIGN(TPACKET_HDRLEN) + 16;