diff options
Diffstat (limited to 'net-ipv4-fix-for-a-race-condition-in-raw_sendmsg.patch')
-rw-r--r-- | net-ipv4-fix-for-a-race-condition-in-raw_sendmsg.patch | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/net-ipv4-fix-for-a-race-condition-in-raw_sendmsg.patch b/net-ipv4-fix-for-a-race-condition-in-raw_sendmsg.patch new file mode 100644 index 000000000..41ad4af16 --- /dev/null +++ b/net-ipv4-fix-for-a-race-condition-in-raw_sendmsg.patch @@ -0,0 +1,81 @@ +From patchwork Sun Dec 10 03:50:58 2017 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Subject: net: ipv4: fix for a race condition in raw_sendmsg +X-Patchwork-Submitter: simo.ghannam@gmail.com +X-Patchwork-Id: 846641 +X-Patchwork-Delegate: davem@davemloft.net +Message-Id: <5a2caf2e.4ce61c0a.5017a.575f@mx.google.com> +To: netdev@vger.kernel.org +Cc: Mohamed Ghannam <simo.ghannam@gmail.com> +Date: Sun, 10 Dec 2017 03:50:58 +0000 +From: simo.ghannam@gmail.com +List-Id: <netdev.vger.kernel.org> + +From: Mohamed Ghannam <simo.ghannam@gmail.com> + +inet->hdrincl is racy, and could lead to uninitialized stack pointer +usage, so its value should be read only once. + +Signed-off-by: Mohamed Ghannam <simo.ghannam@gmail.com> +Reviewed-by: Eric Dumazet <edumazet@google.com> +--- + net/ipv4/raw.c | 15 ++++++++++----- + 1 file 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) + int err; + struct ip_options_data opt_copy; + struct raw_frag_vec rfv; ++ int hdrincl; + + err = -EMSGSIZE; + if (len > 0xFFFF) + goto out; + ++ /* hdrincl should be READ_ONCE(inet->hdrincl) ++ * but READ_ONCE() doesn't work with bit fields ++ */ ++ hdrincl = inet->hdrincl; + /* + * Check the flags. + */ +@@ -593,7 +598,7 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) + /* Linux does not mangle headers on raw sockets, + * so that IP options + IP_HDRINCL is non-sense. + */ +- if (inet->hdrincl) ++ if (hdrincl) + goto done; + if (ipc.opt->opt.srr) { + if (!daddr) +@@ -615,12 +620,12 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) + + flowi4_init_output(&fl4, ipc.oif, sk->sk_mark, tos, + RT_SCOPE_UNIVERSE, +- inet->hdrincl ? IPPROTO_RAW : sk->sk_protocol, ++ hdrincl ? IPPROTO_RAW : sk->sk_protocol, + inet_sk_flowi_flags(sk) | +- (inet->hdrincl ? FLOWI_FLAG_KNOWN_NH : 0), ++ (hdrincl ? FLOWI_FLAG_KNOWN_NH : 0), + daddr, saddr, 0, 0, sk->sk_uid); + +- if (!inet->hdrincl) { ++ if (!hdrincl) { + rfv.msg = msg; + rfv.hlen = 0; + +@@ -645,7 +650,7 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) + goto do_confirm; + back_from_confirm: + +- if (inet->hdrincl) ++ if (hdrincl) + err = raw_send_hdrinc(sk, &fl4, msg, len, + &rt, msg->msg_flags, &ipc.sockc); + |