X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;ds=sidebyside;f=net%2Fipv4%2Fraw.c;h=e5effedd1ac78a609f7abc4cc7b284af93b02213;hb=97bf2856c6014879bd04983a3e9dfcdac1e7fe85;hp=a4db06cb15a43b59daf58a5d16cb7bce2534cad7;hpb=43bc926fffd92024b46cafaf7350d669ba9ca884;p=linux-2.6.git diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index a4db06cb1..e5effedd1 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c @@ -38,8 +38,7 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ - -#include + #include #include #include @@ -124,7 +123,7 @@ static inline int raw_addr_match ( } struct sock *__raw_v4_lookup(struct sock *sk, unsigned short num, - unsigned long raddr, unsigned long laddr, + __be32 raddr, __be32 laddr, int dif) { struct hlist_node *node; @@ -336,7 +335,7 @@ static int raw_send_hdrinc(struct sock *sk, void *from, size_t length, } err = -EPERM; - if (!vx_check(0, VX_ADMIN) && !capable(CAP_NET_RAW) + if (!nx_check(0, VS_ADMIN) && !capable(CAP_NET_RAW) && (!addr_in_nx_info(sk->sk_nx_info, iph->saddr))) goto error_free; @@ -358,7 +357,7 @@ error: return err; } -static void raw_probe_proto_opt(struct flowi *fl, struct msghdr *msg) +static int raw_probe_proto_opt(struct flowi *fl, struct msghdr *msg) { struct iovec *iov; u8 __user *type = NULL; @@ -367,7 +366,7 @@ static void raw_probe_proto_opt(struct flowi *fl, struct msghdr *msg) unsigned int i; if (!msg->msg_iov) - return; + return 0; for (i = 0; i < msg->msg_iovlen; i++) { iov = &msg->msg_iov[i]; @@ -389,8 +388,9 @@ static void raw_probe_proto_opt(struct flowi *fl, struct msghdr *msg) code = iov->iov_base; if (type && code) { - get_user(fl->fl_icmp_type, type); - get_user(fl->fl_icmp_code, code); + if (get_user(fl->fl_icmp_type, type) || + get_user(fl->fl_icmp_code, code)) + return -EFAULT; probed = 1; } break; @@ -401,6 +401,7 @@ static void raw_probe_proto_opt(struct flowi *fl, struct msghdr *msg) if (probed) break; } + return 0; } static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, @@ -410,8 +411,8 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, struct ipcm_cookie ipc; struct rtable *rt = NULL; int free = 0; - u32 daddr; - u32 saddr; + __be32 daddr; + __be32 saddr; u8 tos; int err; @@ -509,9 +510,13 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, .proto = inet->hdrincl ? IPPROTO_RAW : sk->sk_protocol, }; - if (!inet->hdrincl) - raw_probe_proto_opt(&fl, msg); + if (!inet->hdrincl) { + err = raw_probe_proto_opt(&fl, msg); + if (err) + goto done; + } + security_sk_classify_flow(sk, &fl); if (sk->sk_nx_info) { err = ip_find_src(sk->sk_nx_info, &rt, &fl); @@ -643,6 +648,7 @@ static int raw_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, if (sin) { sin->sin_family = AF_INET; sin->sin_addr.s_addr = skb->nh.iph->saddr; + sin->sin_port = 0; memset(&sin->sin_zero, 0, sizeof(sin->sin_zero)); } if (inet->cmsg_flags) @@ -822,7 +828,7 @@ static struct sock *raw_get_first(struct seq_file *seq) sk_for_each(sk, node, &raw_v4_htable[state->bucket]) if (sk->sk_family == PF_INET && - vx_check(sk->sk_xid, VX_IDENT|VX_WATCH)) + nx_check(sk->sk_nid, VS_WATCH_P|VS_IDENT)) goto found; } sk = NULL; @@ -839,7 +845,7 @@ static struct sock *raw_get_next(struct seq_file *seq, struct sock *sk) try_again: ; } while (sk && (sk->sk_family != PF_INET || - !vx_check(sk->sk_xid, VX_IDENT|VX_WATCH))); + !nx_check(sk->sk_nid, VS_WATCH_P|VS_IDENT))); if (!sk && ++state->bucket < RAWV4_HTABLE_SIZE) { sk = sk_head(&raw_v4_htable[state->bucket]); @@ -884,8 +890,8 @@ static void raw_seq_stop(struct seq_file *seq, void *v) static __inline__ char *get_raw_sock(struct sock *sp, char *tmpbuf, int i) { struct inet_sock *inet = inet_sk(sp); - unsigned int dest = inet->daddr, - src = inet->rcv_saddr; + __be32 dest = inet->daddr, + src = inet->rcv_saddr; __u16 destp = 0, srcp = inet->num;