X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=net%2Fpacket%2Faf_packet.c;h=1b441a628b718d853b5cae01fa7ce1e69b08dfdf;hb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;hp=7ebb64d522820df855e5ec71685df0c0752e041c;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 7ebb64d52..1b441a628 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -65,6 +65,8 @@ #include #include #include +#include +#include #include #include #include @@ -172,7 +174,7 @@ struct packet_opt { struct tpacket_stats stats; #ifdef CONFIG_PACKET_MMAP - unsigned long *pg_vec; + char * *pg_vec; unsigned int head; unsigned int frames_per_block; unsigned int frame_size; @@ -197,15 +199,15 @@ struct packet_opt #ifdef CONFIG_PACKET_MMAP -static inline unsigned long packet_lookup_frame(struct packet_opt *po, unsigned int position) +static inline char *packet_lookup_frame(struct packet_opt *po, unsigned int position) { unsigned int pg_vec_pos, frame_offset; - unsigned long frame; + char *frame; pg_vec_pos = position / po->frames_per_block; frame_offset = position % po->frames_per_block; - frame = (unsigned long) (po->pg_vec[pg_vec_pos] + (frame_offset * po->frame_size)); + frame = po->pg_vec[pg_vec_pos] + (frame_offset * po->frame_size); return frame; } @@ -784,11 +786,13 @@ out: static int packet_release(struct socket *sock) { struct sock *sk = sock->sk; - struct packet_opt *po = pkt_sk(sk); + struct packet_opt *po; if (!sk) return 0; + po = pkt_sk(sk); + write_lock_bh(&packet_sklist_lock); sk_del_node_init(sk); write_unlock_bh(&packet_sklist_lock); @@ -1037,7 +1041,7 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock, int copied, err; err = -EINVAL; - if (flags & ~(MSG_PEEK|MSG_DONTWAIT|MSG_TRUNC)) + if (flags & ~(MSG_PEEK|MSG_DONTWAIT|MSG_TRUNC|MSG_CMSG_COMPAT)) goto out; #if 0 @@ -1292,7 +1296,7 @@ static void packet_flush_mclist(struct sock *sk) #endif static int -packet_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen) +packet_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen) { struct sock *sk = sock->sk; int ret; @@ -1347,7 +1351,7 @@ packet_setsockopt(struct socket *sock, int level, int optname, char *optval, int } int packet_getsockopt(struct socket *sock, int level, int optname, - char *optval, int *optlen) + char __user *optval, int __user *optlen) { int len; struct sock *sk = sock->sk; @@ -1450,7 +1454,7 @@ static int packet_ioctl(struct socket *sock, unsigned int cmd, case SIOCOUTQ: { int amount = atomic_read(&sk->sk_wmem_alloc); - return put_user(amount, (int *)arg); + return put_user(amount, (int __user *)arg); } case SIOCINQ: { @@ -1462,10 +1466,10 @@ static int packet_ioctl(struct socket *sock, unsigned int cmd, if (skb) amount = skb->len; spin_unlock_bh(&sk->sk_receive_queue.lock); - return put_user(amount, (int *)arg); + return put_user(amount, (int __user *)arg); } case SIOCGSTAMP: - return sock_get_timestamp(sk, (struct timeval *)arg); + return sock_get_timestamp(sk, (struct timeval __user *)arg); #ifdef CONFIG_INET case SIOCADDRT: @@ -1486,7 +1490,7 @@ static int packet_ioctl(struct socket *sock, unsigned int cmd, #endif default: - return dev_ioctl(cmd, (void *)arg); + return dev_ioctl(cmd, (void __user *)arg); } return 0; } @@ -1548,7 +1552,12 @@ static struct vm_operations_struct packet_mmap_ops = { .close =packet_mm_close, }; -static void free_pg_vec(unsigned long *pg_vec, unsigned order, unsigned len) +static inline struct page *pg_vec_endpage(char *one_pg_vec, unsigned int order) +{ + return virt_to_page(one_pg_vec + (PAGE_SIZE << order) - 1); +} + +static void free_pg_vec(char **pg_vec, unsigned order, unsigned len) { int i; @@ -1556,10 +1565,10 @@ static void free_pg_vec(unsigned long *pg_vec, unsigned order, unsigned len) if (pg_vec[i]) { struct page *page, *pend; - pend = virt_to_page(pg_vec[i] + (PAGE_SIZE << order) - 1); + pend = pg_vec_endpage(pg_vec[i], order); for (page = virt_to_page(pg_vec[i]); page <= pend; page++) ClearPageReserved(page); - free_pages(pg_vec[i], order); + free_pages((unsigned long)pg_vec[i], order); } } kfree(pg_vec); @@ -1568,7 +1577,7 @@ static void free_pg_vec(unsigned long *pg_vec, unsigned order, unsigned len) static int packet_set_ring(struct sock *sk, struct tpacket_req *req, int closing) { - unsigned long *pg_vec = NULL; + char **pg_vec = NULL; struct packet_opt *po = pkt_sk(sk); int was_running, num, order = 0; int err = 0; @@ -1603,18 +1612,18 @@ static int packet_set_ring(struct sock *sk, struct tpacket_req *req, int closing err = -ENOMEM; - pg_vec = kmalloc(req->tp_block_nr*sizeof(unsigned long*), GFP_KERNEL); + pg_vec = kmalloc(req->tp_block_nr*sizeof(char *), GFP_KERNEL); if (pg_vec == NULL) goto out; - memset(pg_vec, 0, req->tp_block_nr*sizeof(unsigned long*)); + memset(pg_vec, 0, req->tp_block_nr*sizeof(char **)); for (i=0; itp_block_nr; i++) { struct page *page, *pend; - pg_vec[i] = __get_free_pages(GFP_KERNEL, order); + pg_vec[i] = (char *)__get_free_pages(GFP_KERNEL, order); if (!pg_vec[i]) goto out_free_pgvec; - pend = virt_to_page(pg_vec[i] + (PAGE_SIZE << order) - 1); + pend = pg_vec_endpage(pg_vec[i], order); for (page = virt_to_page(pg_vec[i]); page <= pend; page++) SetPageReserved(page); } @@ -1622,7 +1631,7 @@ static int packet_set_ring(struct sock *sk, struct tpacket_req *req, int closing l = 0; for (i=0; itp_block_nr; i++) { - unsigned long ptr = pg_vec[i]; + char *ptr = pg_vec[i]; struct tpacket_hdr *header; int k;