X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=net%2Fpacket%2Faf_packet.c;h=271d2eed0699b93c01440d7d193725c5d8b010ca;hb=05e00cbf5036929355020dab4837b637203a0742;hp=f9cef3671593efaf7a513efacc3097fc27743507;hpb=6ab3d5624e172c553004ecc862bfeac16d9d68b7;p=powerpc.git diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index f9cef36715..271d2eed06 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -201,7 +201,7 @@ struct packet_sock { spinlock_t bind_lock; char running; /* prot_hook is attached*/ int ifindex; /* bound device */ - unsigned short num; + __be16 num; #ifdef CONFIG_PACKET_MULTICAST struct packet_mclist *mclist; #endif @@ -331,7 +331,7 @@ static int packet_sendmsg_spkt(struct kiocb *iocb, struct socket *sock, struct sockaddr_pkt *saddr=(struct sockaddr_pkt *)msg->msg_name; struct sk_buff *skb; struct net_device *dev; - unsigned short proto=0; + __be16 proto=0; int err; /* @@ -427,21 +427,24 @@ out_unlock: } #endif -static inline unsigned run_filter(struct sk_buff *skb, struct sock *sk, unsigned res) +static inline int run_filter(struct sk_buff *skb, struct sock *sk, + unsigned *snaplen) { struct sk_filter *filter; + int err = 0; - bh_lock_sock(sk); - filter = sk->sk_filter; - /* - * Our caller already checked that filter != NULL but we need to - * verify that under bh_lock_sock() to be safe - */ - if (likely(filter != NULL)) - res = sk_run_filter(skb, filter->insns, filter->len); - bh_unlock_sock(sk); + rcu_read_lock_bh(); + filter = rcu_dereference(sk->sk_filter); + if (filter != NULL) { + err = sk_run_filter(skb, filter->insns, filter->len); + if (!err) + err = -EPERM; + else if (*snaplen > err) + *snaplen = err; + } + rcu_read_unlock_bh(); - return res; + return err; } /* @@ -491,13 +494,8 @@ static int packet_rcv(struct sk_buff *skb, struct net_device *dev, struct packet snaplen = skb->len; - if (sk->sk_filter) { - unsigned res = run_filter(skb, sk, snaplen); - if (res == 0) - goto drop_n_restore; - if (snaplen > res) - snaplen = res; - } + if (run_filter(skb, sk, &snaplen) < 0) + goto drop_n_restore; if (atomic_read(&sk->sk_rmem_alloc) + skb->truesize >= (unsigned)sk->sk_rcvbuf) @@ -586,20 +584,15 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, struct packe else if (skb->pkt_type == PACKET_OUTGOING) { /* Special case: outgoing packets have ll header at head */ skb_pull(skb, skb->nh.raw - skb->data); - if (skb->ip_summed == CHECKSUM_HW) + if (skb->ip_summed == CHECKSUM_PARTIAL) status |= TP_STATUS_CSUMNOTREADY; } } snaplen = skb->len; - if (sk->sk_filter) { - unsigned res = run_filter(skb, sk, snaplen); - if (res == 0) - goto drop_n_restore; - if (snaplen > res) - snaplen = res; - } + if (run_filter(skb, sk, &snaplen) < 0) + goto drop_n_restore; if (sk->sk_type == SOCK_DGRAM) { macoff = netoff = TPACKET_ALIGN(TPACKET_HDRLEN) + 16; @@ -626,8 +619,6 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, struct packe if ((int)snaplen < 0) snaplen = 0; } - if (snaplen > skb->len-skb->data_len) - snaplen = skb->len-skb->data_len; spin_lock(&sk->sk_receive_queue.lock); h = (struct tpacket_hdr *)packet_lookup_frame(po, po->head); @@ -644,7 +635,7 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, struct packe status &= ~TP_STATUS_LOSING; spin_unlock(&sk->sk_receive_queue.lock); - memcpy((u8*)h + macoff, skb->data, snaplen); + skb_copy_bits(skb, 0, (u8*)h + macoff, snaplen); h->tp_len = skb->len; h->tp_snaplen = snaplen; @@ -713,7 +704,7 @@ static int packet_sendmsg(struct kiocb *iocb, struct socket *sock, struct sockaddr_ll *saddr=(struct sockaddr_ll *)msg->msg_name; struct sk_buff *skb; struct net_device *dev; - unsigned short proto; + __be16 proto; unsigned char *addr; int ifindex, err, reserve = 0; @@ -867,7 +858,7 @@ static int packet_release(struct socket *sock) * Attach a packet hook. */ -static int packet_do_bind(struct sock *sk, struct net_device *dev, int protocol) +static int packet_do_bind(struct sock *sk, struct net_device *dev, __be16 protocol) { struct packet_sock *po = pkt_sk(sk); /* @@ -992,6 +983,7 @@ static int packet_create(struct socket *sock, int protocol) { struct sock *sk; struct packet_sock *po; + __be16 proto = (__force __be16)protocol; /* weird, but documented */ int err; if (!capable(CAP_NET_RAW)) @@ -1019,7 +1011,7 @@ static int packet_create(struct socket *sock, int protocol) po = pkt_sk(sk); sk->sk_family = PF_PACKET; - po->num = protocol; + po->num = proto; sk->sk_destruct = packet_sock_destruct; atomic_inc(&packet_socks_nr); @@ -1036,8 +1028,8 @@ static int packet_create(struct socket *sock, int protocol) #endif po->prot_hook.af_packet_priv = sk; - if (protocol) { - po->prot_hook.type = protocol; + if (proto) { + po->prot_hook.type = proto; dev_add_pack(&po->prot_hook); sock_hold(sk); po->running = 1; @@ -1633,7 +1625,8 @@ static int packet_set_ring(struct sock *sk, struct tpacket_req *req, int closing { char **pg_vec = NULL; struct packet_sock *po = pkt_sk(sk); - int was_running, num, order = 0; + int was_running, order = 0; + __be16 num; int err = 0; if (req->tp_block_nr) {