summaryrefslogtreecommitdiffstats
path: root/net-ipv4-fix-for-a-race-condition-in-raw_sendmsg.patch
diff options
context:
space:
mode:
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.patch81
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);
+