|
|
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; | struct iovec *iov; |
u8 __user *type = NULL; | u8 __user *type = NULL; |
|
Lines 338-344
static void raw_probe_proto_opt(struct f
|
Link Here
|
|---|
|
unsigned int i; | unsigned int i; |
| |
if (!msg->msg_iov) | if (!msg->msg_iov) |
return; |
return 0; |
| |
for (i = 0; i < msg->msg_iovlen; i++) { | for (i = 0; i < msg->msg_iovlen; i++) { |
iov = &msg->msg_iov[i]; | iov = &msg->msg_iov[i]; |
|
Lines 360-367
static void raw_probe_proto_opt(struct f
|
Link Here
|
|---|
|
code = iov->iov_base; | code = iov->iov_base; |
| |
if (type && code) { | if (type && code) { |
get_user(fl->fl_icmp_type, type); |
if (get_user(fl->fl_icmp_type, type) || |
get_user(fl->fl_icmp_code, code); |
get_user(fl->fl_icmp_code, code)) |
|
return -EFAULT; |
probed = 1; | probed = 1; |
} | } |
break; | break; |
|
Lines 372-377
static void raw_probe_proto_opt(struct f
|
Link Here
|
|---|
|
if (probed) | if (probed) |
break; | break; |
} | } |
|
return 0; |
} | } |
| |
static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, |
|
Lines 480-487
static int raw_sendmsg(struct kiocb *ioc
|
Link Here
|
|---|
|
.proto = inet->hdrincl ? IPPROTO_RAW : | .proto = inet->hdrincl ? IPPROTO_RAW : |
sk->sk_protocol, | sk->sk_protocol, |
}; | }; |
if (!inet->hdrincl) |
if (!inet->hdrincl) { |
raw_probe_proto_opt(&fl, msg); |
err = raw_probe_proto_opt(&fl, msg); |
|
if (err) |
|
goto done; |
|
} |
| |
security_sk_classify_flow(sk, &fl); | 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, !(msg->msg_flags&MSG_DONTWAIT)); |
|
|
return err; | 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; | struct iovec *iov; |
u8 __user *type = NULL; | u8 __user *type = NULL; |
|
Lines 616-622
static void rawv6_probe_proto_opt(struct
|
Link Here
|
|---|
|
int i; | int i; |
| |
if (!msg->msg_iov) | if (!msg->msg_iov) |
return; |
return 0; |
| |
for (i = 0; i < msg->msg_iovlen; i++) { | for (i = 0; i < msg->msg_iovlen; i++) { |
iov = &msg->msg_iov[i]; | iov = &msg->msg_iov[i]; |
|
Lines 638-645
static void rawv6_probe_proto_opt(struct
|
Link Here
|
|---|
|
code = iov->iov_base; | code = iov->iov_base; |
| |
if (type && code) { | if (type && code) { |
get_user(fl->fl_icmp_type, type); |
if (get_user(fl->fl_icmp_type, type) || |
get_user(fl->fl_icmp_code, code); |
get_user(fl->fl_icmp_code, code)) |
|
return -EFAULT; |
probed = 1; | probed = 1; |
} | } |
break; | break; |
|
Lines 650-656
static void rawv6_probe_proto_opt(struct
|
Link Here
|
|---|
|
/* check if type field is readable or not. */ | /* check if type field is readable or not. */ |
if (iov->iov_len > 2 - len) { | if (iov->iov_len > 2 - len) { |
u8 __user *p = iov->iov_base; | 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; | probed = 1; |
} else | } else |
len += iov->iov_len; | len += iov->iov_len; |
|
Lines 664-669
static void rawv6_probe_proto_opt(struct
|
Link Here
|
|---|
|
if (probed) | if (probed) |
break; | break; |
} | } |
|
return 0; |
} | } |
| |
static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, | static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, |
|
Lines 787-793
static int rawv6_sendmsg(struct kiocb *i
|
Link Here
|
|---|
|
opt = ipv6_fixup_options(&opt_space, opt); | opt = ipv6_fixup_options(&opt_space, opt); |
| |
fl.proto = proto; | 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); | ipv6_addr_copy(&fl.fl6_dst, daddr); |
if (ipv6_addr_any(&fl.fl6_src) && !ipv6_addr_any(&np->saddr)) | if (ipv6_addr_any(&fl.fl6_src) && !ipv6_addr_any(&np->saddr)) |
|
Lines 1075-1082
static int netlink_getsockopt(struct soc
|
Link Here
|
|---|
|
return -EINVAL; | return -EINVAL; |
len = sizeof(int); | len = sizeof(int); |
val = nlk->flags & NETLINK_RECV_PKTINFO ? 1 : 0; | val = nlk->flags & NETLINK_RECV_PKTINFO ? 1 : 0; |
put_user(len, optlen); |
if (put_user(len, optlen) || |
put_user(val, optval); |
put_user(val, optval)) |
|
return -EFAULT; |
err = 0; | err = 0; |
break; | break; |
default: | default: |