aboutsummaryrefslogtreecommitdiffstats
path: root/net/packet
diff options
context:
space:
mode:
Diffstat (limited to 'net/packet')
-rw-r--r--net/packet/af_packet.c41
1 files changed, 32 insertions, 9 deletions
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 91cb1d71f018..b5362e96022b 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -164,7 +164,6 @@ struct packet_mreq_max {
164static int packet_set_ring(struct sock *sk, struct tpacket_req *req, 164static int packet_set_ring(struct sock *sk, struct tpacket_req *req,
165 int closing, int tx_ring); 165 int closing, int tx_ring);
166 166
167#define PGV_FROM_VMALLOC 1
168struct pgv { 167struct pgv {
169 char *buffer; 168 char *buffer;
170}; 169};
@@ -466,7 +465,7 @@ retry:
466 */ 465 */
467 466
468 err = -EMSGSIZE; 467 err = -EMSGSIZE;
469 if (len > dev->mtu + dev->hard_header_len) 468 if (len > dev->mtu + dev->hard_header_len + VLAN_HLEN)
470 goto out_unlock; 469 goto out_unlock;
471 470
472 if (!skb) { 471 if (!skb) {
@@ -497,6 +496,19 @@ retry:
497 goto retry; 496 goto retry;
498 } 497 }
499 498
499 if (len > (dev->mtu + dev->hard_header_len)) {
500 /* Earlier code assumed this would be a VLAN pkt,
501 * double-check this now that we have the actual
502 * packet in hand.
503 */
504 struct ethhdr *ehdr;
505 skb_reset_mac_header(skb);
506 ehdr = eth_hdr(skb);
507 if (ehdr->h_proto != htons(ETH_P_8021Q)) {
508 err = -EMSGSIZE;
509 goto out_unlock;
510 }
511 }
500 512
501 skb->protocol = proto; 513 skb->protocol = proto;
502 skb->dev = dev; 514 skb->dev = dev;
@@ -523,11 +535,11 @@ static inline unsigned int run_filter(const struct sk_buff *skb,
523{ 535{
524 struct sk_filter *filter; 536 struct sk_filter *filter;
525 537
526 rcu_read_lock_bh(); 538 rcu_read_lock();
527 filter = rcu_dereference_bh(sk->sk_filter); 539 filter = rcu_dereference(sk->sk_filter);
528 if (filter != NULL) 540 if (filter != NULL)
529 res = sk_run_filter(skb, filter->insns); 541 res = sk_run_filter(skb, filter->insns);
530 rcu_read_unlock_bh(); 542 rcu_read_unlock();
531 543
532 return res; 544 return res;
533} 545}
@@ -954,7 +966,6 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb,
954 966
955static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) 967static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
956{ 968{
957 struct socket *sock;
958 struct sk_buff *skb; 969 struct sk_buff *skb;
959 struct net_device *dev; 970 struct net_device *dev;
960 __be16 proto; 971 __be16 proto;
@@ -966,8 +977,6 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
966 int len_sum = 0; 977 int len_sum = 0;
967 int status = 0; 978 int status = 0;
968 979
969 sock = po->sk.sk_socket;
970
971 mutex_lock(&po->pg_vec_lock); 980 mutex_lock(&po->pg_vec_lock);
972 981
973 err = -EBUSY; 982 err = -EBUSY;
@@ -1200,7 +1209,7 @@ static int packet_snd(struct socket *sock,
1200 } 1209 }
1201 1210
1202 err = -EMSGSIZE; 1211 err = -EMSGSIZE;
1203 if (!gso_type && (len > dev->mtu+reserve)) 1212 if (!gso_type && (len > dev->mtu + reserve + VLAN_HLEN))
1204 goto out_unlock; 1213 goto out_unlock;
1205 1214
1206 err = -ENOBUFS; 1215 err = -ENOBUFS;
@@ -1225,6 +1234,20 @@ static int packet_snd(struct socket *sock,
1225 if (err < 0) 1234 if (err < 0)
1226 goto out_free; 1235 goto out_free;
1227 1236
1237 if (!gso_type && (len > dev->mtu + reserve)) {
1238 /* Earlier code assumed this would be a VLAN pkt,
1239 * double-check this now that we have the actual
1240 * packet in hand.
1241 */
1242 struct ethhdr *ehdr;
1243 skb_reset_mac_header(skb);
1244 ehdr = eth_hdr(skb);
1245 if (ehdr->h_proto != htons(ETH_P_8021Q)) {
1246 err = -EMSGSIZE;
1247 goto out_free;
1248 }
1249 }
1250
1228 skb->protocol = proto; 1251 skb->protocol = proto;
1229 skb->dev = dev; 1252 skb->dev = dev;
1230 skb->priority = sk->sk_priority; 1253 skb->priority = sk->sk_priority;