Skip to content

Commit 8f659a0

Browse files
0x36davem330
authored andcommitted
net: ipv4: fix for a race condition in raw_sendmsg
inet->hdrincl is racy, and could lead to uninitialized stack pointer usage, so its value should be read only once. Fixes: c008ba5 ("ipv4: Avoid reading user iov twice after raw_probe_proto_opt") Signed-off-by: Mohamed Ghannam <simo.ghannam@gmail.com> Reviewed-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 93c6476 commit 8f659a0

File tree

1 file changed

+10
-5
lines changed

1 file changed

+10
-5
lines changed

Diff for: net/ipv4/raw.c

+10-5
Original file line numberDiff line numberDiff line change
@@ -513,11 +513,16 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
513513
int err;
514514
struct ip_options_data opt_copy;
515515
struct raw_frag_vec rfv;
516+
int hdrincl;
516517

517518
err = -EMSGSIZE;
518519
if (len > 0xFFFF)
519520
goto out;
520521

522+
/* hdrincl should be READ_ONCE(inet->hdrincl)
523+
* but READ_ONCE() doesn't work with bit fields
524+
*/
525+
hdrincl = inet->hdrincl;
521526
/*
522527
* Check the flags.
523528
*/
@@ -593,7 +598,7 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
593598
/* Linux does not mangle headers on raw sockets,
594599
* so that IP options + IP_HDRINCL is non-sense.
595600
*/
596-
if (inet->hdrincl)
601+
if (hdrincl)
597602
goto done;
598603
if (ipc.opt->opt.srr) {
599604
if (!daddr)
@@ -615,12 +620,12 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
615620

616621
flowi4_init_output(&fl4, ipc.oif, sk->sk_mark, tos,
617622
RT_SCOPE_UNIVERSE,
618-
inet->hdrincl ? IPPROTO_RAW : sk->sk_protocol,
623+
hdrincl ? IPPROTO_RAW : sk->sk_protocol,
619624
inet_sk_flowi_flags(sk) |
620-
(inet->hdrincl ? FLOWI_FLAG_KNOWN_NH : 0),
625+
(hdrincl ? FLOWI_FLAG_KNOWN_NH : 0),
621626
daddr, saddr, 0, 0, sk->sk_uid);
622627

623-
if (!inet->hdrincl) {
628+
if (!hdrincl) {
624629
rfv.msg = msg;
625630
rfv.hlen = 0;
626631

@@ -645,7 +650,7 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
645650
goto do_confirm;
646651
back_from_confirm:
647652

648-
if (inet->hdrincl)
653+
if (hdrincl)
649654
err = raw_send_hdrinc(sk, &fl4, msg, len,
650655
&rt, msg->msg_flags, &ipc.sockc);
651656

0 commit comments

Comments
 (0)