X-Git-Url: http://git.agner.ch/gitweb/?p=linux-drm-fsl-dcu.git;a=blobdiff_plain;f=net%2Fipv4%2Fraw.c;h=931084bfb57255afe5d1676a3bcea57e29bfa86b;hp=b430cf2a4f6609db27f6ea137e3f18b0281bd442;hb=d68798374bcf5cd4a19105b86d96121651b3c8cb;hpb=946b92437e550d6ed80213bf54a1f383e141aede diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index b430cf2a4f66..931084bfb572 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c @@ -95,7 +95,7 @@ static void raw_v4_hash(struct sock *sk) static void raw_v4_unhash(struct sock *sk) { - write_lock_bh(&raw_v4_lock); + write_lock_bh(&raw_v4_lock); if (sk_del_node_init(sk)) sock_prot_dec_use(sk->sk_prot); write_unlock_bh(&raw_v4_lock); @@ -238,7 +238,7 @@ void raw_err (struct sock *sk, struct sk_buff *skb, u32 info) static int raw_rcv_skb(struct sock * sk, struct sk_buff * skb) { /* Charge it to the socket. */ - + if (sock_queue_rcv_skb(sk, skb) < 0) { /* FIXME: increment a raw drops counter here */ kfree_skb(skb); @@ -263,7 +263,7 @@ int raw_rcv(struct sock *sk, struct sk_buff *skb) } static int raw_send_hdrinc(struct sock *sk, void *from, size_t length, - struct rtable *rt, + struct rtable *rt, unsigned int flags) { struct inet_sock *inet = inet_sk(sk); @@ -285,7 +285,7 @@ static int raw_send_hdrinc(struct sock *sk, void *from, size_t length, skb = sock_alloc_send_skb(sk, length+hh_len+15, flags&MSG_DONTWAIT, &err); if (skb == NULL) - goto error; + goto error; skb_reserve(skb, hh_len); skb->priority = sk->sk_priority; @@ -326,10 +326,10 @@ error_fault: kfree_skb(skb); error: IP_INC_STATS(IPSTATS_MIB_OUTDISCARDS); - return err; + 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; @@ -338,7 +338,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]; @@ -360,8 +360,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; @@ -372,6 +373,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, @@ -397,9 +399,9 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, err = -EOPNOTSUPP; if (msg->msg_flags & MSG_OOB) /* Mirror BSD error message */ goto out; /* compatibility */ - + /* - * Get and verify the address. + * Get and verify the address. */ if (msg->msg_namelen) { @@ -424,7 +426,7 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, */ } else { err = -EDESTADDRREQ; - if (sk->sk_state != TCP_ESTABLISHED) + if (sk->sk_state != TCP_ESTABLISHED) goto out; daddr = inet->daddr; } @@ -478,13 +480,16 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, .saddr = saddr, .tos = tos } }, .proto = inet->hdrincl ? IPPROTO_RAW : - sk->sk_protocol, + 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); - err = ip_route_output_flow(&rt, &fl, sk, !(msg->msg_flags&MSG_DONTWAIT)); + err = ip_route_output_flow(&rt, &fl, sk, 1); } if (err) goto done; @@ -498,9 +503,9 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, back_from_confirm: if (inet->hdrincl) - err = raw_send_hdrinc(sk, msg->msg_iov, len, + err = raw_send_hdrinc(sk, msg->msg_iov, len, rt, msg->msg_flags); - + else { if (!ipc.addr) ipc.addr = rt->rt_dst; @@ -533,7 +538,7 @@ do_confirm: static void raw_close(struct sock *sk, long timeout) { - /* + /* * Raw sockets may have direct kernel refereneces. Kill them. */ ip_ra_control(sk, 0, NULL); @@ -849,14 +854,14 @@ 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; sprintf(tmpbuf, "%4d: %08X:%04X %08X:%04X" " %02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p", - i, src, srcp, dest, destp, sp->sk_state, + i, src, srcp, dest, destp, sp->sk_state, atomic_read(&sp->sk_wmem_alloc), atomic_read(&sp->sk_rmem_alloc), 0, 0L, 0, sock_i_uid(sp), 0, sock_i_ino(sp),