diff options
Diffstat (limited to 'net/ipv4/raw.c')
| -rw-r--r-- | net/ipv4/raw.c | 17 |
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 | ||
| 332 | static void raw_probe_proto_opt(struct flowi *fl, struct msghdr *msg) | 332 | static 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 | ||
| 377 | static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | 379 | static 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)); |
