diff options
Diffstat (limited to 'net/ipv4/raw.c')
-rw-r--r-- | net/ipv4/raw.c | 15 |
1 files changed, 10 insertions, 5 deletions
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index 33b70bfd1122..125c1eab3eaa 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c | |||
@@ -513,11 +513,16 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) | |||
513 | int err; | 513 | int err; |
514 | struct ip_options_data opt_copy; | 514 | struct ip_options_data opt_copy; |
515 | struct raw_frag_vec rfv; | 515 | struct raw_frag_vec rfv; |
516 | int hdrincl; | ||
516 | 517 | ||
517 | err = -EMSGSIZE; | 518 | err = -EMSGSIZE; |
518 | if (len > 0xFFFF) | 519 | if (len > 0xFFFF) |
519 | goto out; | 520 | goto out; |
520 | 521 | ||
522 | /* hdrincl should be READ_ONCE(inet->hdrincl) | ||
523 | * but READ_ONCE() doesn't work with bit fields | ||
524 | */ | ||
525 | hdrincl = inet->hdrincl; | ||
521 | /* | 526 | /* |
522 | * Check the flags. | 527 | * Check the flags. |
523 | */ | 528 | */ |
@@ -593,7 +598,7 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) | |||
593 | /* Linux does not mangle headers on raw sockets, | 598 | /* Linux does not mangle headers on raw sockets, |
594 | * so that IP options + IP_HDRINCL is non-sense. | 599 | * so that IP options + IP_HDRINCL is non-sense. |
595 | */ | 600 | */ |
596 | if (inet->hdrincl) | 601 | if (hdrincl) |
597 | goto done; | 602 | goto done; |
598 | if (ipc.opt->opt.srr) { | 603 | if (ipc.opt->opt.srr) { |
599 | if (!daddr) | 604 | if (!daddr) |
@@ -615,12 +620,12 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) | |||
615 | 620 | ||
616 | flowi4_init_output(&fl4, ipc.oif, sk->sk_mark, tos, | 621 | flowi4_init_output(&fl4, ipc.oif, sk->sk_mark, tos, |
617 | RT_SCOPE_UNIVERSE, | 622 | RT_SCOPE_UNIVERSE, |
618 | inet->hdrincl ? IPPROTO_RAW : sk->sk_protocol, | 623 | hdrincl ? IPPROTO_RAW : sk->sk_protocol, |
619 | inet_sk_flowi_flags(sk) | | 624 | inet_sk_flowi_flags(sk) | |
620 | (inet->hdrincl ? FLOWI_FLAG_KNOWN_NH : 0), | 625 | (hdrincl ? FLOWI_FLAG_KNOWN_NH : 0), |
621 | daddr, saddr, 0, 0, sk->sk_uid); | 626 | daddr, saddr, 0, 0, sk->sk_uid); |
622 | 627 | ||
623 | if (!inet->hdrincl) { | 628 | if (!hdrincl) { |
624 | rfv.msg = msg; | 629 | rfv.msg = msg; |
625 | rfv.hlen = 0; | 630 | rfv.hlen = 0; |
626 | 631 | ||
@@ -645,7 +650,7 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) | |||
645 | goto do_confirm; | 650 | goto do_confirm; |
646 | back_from_confirm: | 651 | back_from_confirm: |
647 | 652 | ||
648 | if (inet->hdrincl) | 653 | if (hdrincl) |
649 | err = raw_send_hdrinc(sk, &fl4, msg, len, | 654 | err = raw_send_hdrinc(sk, &fl4, msg, len, |
650 | &rt, msg->msg_flags, &ipc.sockc); | 655 | &rt, msg->msg_flags, &ipc.sockc); |
651 | 656 | ||