aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/raw.c
diff options
context:
space:
mode:
authorHeiko Carstens <heiko.carstens@de.ibm.com>2006-10-30 18:06:12 -0500
committerDavid S. Miller <davem@sunset.davemloft.net>2006-10-30 18:24:41 -0500
commita27b58fed90cc5654e2daf1d292cc5bc61be4dd7 (patch)
tree4f01c7b0bc168b9a73cd9d5406e7fbf426ab169c /net/ipv4/raw.c
parent28cd7752734563d5b0967b96a6bade7a1dc89c7f (diff)
[NET]: fix uaccess handling
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/raw.c')
-rw-r--r--net/ipv4/raw.c17
1 files changed, 11 insertions, 6 deletions
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index b430cf2a4f66..5c31dead2bdc 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -329,7 +329,7 @@ error:
329 return err; 329 return err;
330} 330}
331 331
332static void raw_probe_proto_opt(struct flowi *fl, struct msghdr *msg) 332static int raw_probe_proto_opt(struct flowi *fl, struct msghdr *msg)
333{ 333{
334 struct iovec *iov; 334 struct iovec *iov;
335 u8 __user *type = NULL; 335 u8 __user *type = NULL;
@@ -338,7 +338,7 @@ static void raw_probe_proto_opt(struct flowi *fl, struct msghdr *msg)
338 unsigned int i; 338 unsigned int i;
339 339
340 if (!msg->msg_iov) 340 if (!msg->msg_iov)
341 return; 341 return 0;
342 342
343 for (i = 0; i < msg->msg_iovlen; i++) { 343 for (i = 0; i < msg->msg_iovlen; i++) {
344 iov = &msg->msg_iov[i]; 344 iov = &msg->msg_iov[i];
@@ -360,8 +360,9 @@ static void raw_probe_proto_opt(struct flowi *fl, struct msghdr *msg)
360 code = iov->iov_base; 360 code = iov->iov_base;
361 361
362 if (type && code) { 362 if (type && code) {
363 get_user(fl->fl_icmp_type, type); 363 if (get_user(fl->fl_icmp_type, type) ||
364 get_user(fl->fl_icmp_code, code); 364 get_user(fl->fl_icmp_code, code))
365 return -EFAULT;
365 probed = 1; 366 probed = 1;
366 } 367 }
367 break; 368 break;
@@ -372,6 +373,7 @@ static void raw_probe_proto_opt(struct flowi *fl, struct msghdr *msg)
372 if (probed) 373 if (probed)
373 break; 374 break;
374 } 375 }
376 return 0;
375} 377}
376 378
377static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, 379static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
@@ -480,8 +482,11 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
480 .proto = inet->hdrincl ? IPPROTO_RAW : 482 .proto = inet->hdrincl ? IPPROTO_RAW :
481 sk->sk_protocol, 483 sk->sk_protocol,
482 }; 484 };
483 if (!inet->hdrincl) 485 if (!inet->hdrincl) {
484 raw_probe_proto_opt(&fl, msg); 486 err = raw_probe_proto_opt(&fl, msg);
487 if (err)
488 goto done;
489 }
485 490
486 security_sk_classify_flow(sk, &fl); 491 security_sk_classify_flow(sk, &fl);
487 err = ip_route_output_flow(&rt, &fl, sk, !(msg->msg_flags&MSG_DONTWAIT)); 492 err = ip_route_output_flow(&rt, &fl, sk, !(msg->msg_flags&MSG_DONTWAIT));