aboutsummaryrefslogtreecommitdiff
path: root/net/ipv6/raw.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-10-31 08:08:31 -0800
committerLinus Torvalds <torvalds@g5.osdl.org>2006-10-31 08:08:31 -0800
commit612b322ade7954a1d984fa410a70d4ae50f75c0d (patch)
tree1e8d6cf698148c5fa23870d81a51eb5a460662e3 /net/ipv6/raw.c
parentd2c59a22dd7c0a59dfff60a8e9910f76f308b9f2 (diff)
parent1b7c2dbc07bf0663a41e3dc838992930019f08fd (diff)
Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6: [IPV6]: fix flowlabel seqfile handling [IPV6]: return EINVAL for invalid address with flowlabel lease request [SCTP]: Remove temporary associations from backlog and hash. [SCTP]: Correctly set IP id for SCTP traffic [NetLabel]: protect the CIPSOv4 socket option from setsockopt() [NETFILTER]: ip_tables: compat code module refcounting fix [NETFILTER]: nf_conntrack: add missing unlock in get_next_corpse() [NETFILTER]: ip_tables: compat error way cleanup [NETFILTER]: Missed and reordered checks in {arp,ip,ip6}_tables [NETFILTER]: remove masq/NAT from ip6tables Kconfig help [IPV6]: fix lockup via /proc/net/ip6_flowlabel [NET]: fix uaccess handling [SCTP]: Always linearise packet on input [ETH1394]: Fix unaligned accesses. [DCCP]: fix printk format warnings [NET]: Fix segmentation of linear packets [XFRM] xfrm_user: Fix unaligned accesses. [APPLETALK]: Fix potential OOPS in atalk_sendmsg(). [NET] sealevel: uses arp_broken_ops
Diffstat (limited to 'net/ipv6/raw.c')
-rw-r--r--net/ipv6/raw.c17
1 files changed, 11 insertions, 6 deletions
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index d09329ca326..d6dedc4aec7 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -604,7 +604,7 @@ error:
return err;
}
-static void rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg)
+static int rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg)
{
struct iovec *iov;
u8 __user *type = NULL;
@@ -616,7 +616,7 @@ static void rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg)
int i;
if (!msg->msg_iov)
- return;
+ return 0;
for (i = 0; i < msg->msg_iovlen; i++) {
iov = &msg->msg_iov[i];
@@ -638,8 +638,9 @@ static void rawv6_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;
@@ -650,7 +651,8 @@ static void rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg)
/* check if type field is readable or not. */
if (iov->iov_len > 2 - len) {
u8 __user *p = iov->iov_base;
- get_user(fl->fl_mh_type, &p[2 - len]);
+ if (get_user(fl->fl_mh_type, &p[2 - len]))
+ return -EFAULT;
probed = 1;
} else
len += iov->iov_len;
@@ -664,6 +666,7 @@ static void rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg)
if (probed)
break;
}
+ return 0;
}
static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
@@ -787,7 +790,9 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
opt = ipv6_fixup_options(&opt_space, opt);
fl.proto = proto;
- rawv6_probe_proto_opt(&fl, msg);
+ err = rawv6_probe_proto_opt(&fl, msg);
+ if (err)
+ goto out;
ipv6_addr_copy(&fl.fl6_dst, daddr);
if (ipv6_addr_any(&fl.fl6_src) && !ipv6_addr_any(&np->saddr))