summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJustin M. Forbes <jforbes@redhat.com>2015-10-05 09:53:15 -0500
committerJustin M. Forbes <jforbes@redhat.com>2015-10-05 09:53:15 -0500
commit8ad49d88de7e7c53e142a8d6e5dcd191dbf6c914 (patch)
tree1a0865ec0379a6e72c83194de661126a9fbb92fb
parent77add2b3df0e0a184fba301465f7f73a7a873dfe (diff)
downloadkernel-8ad49d88de7e7c53e142a8d6e5dcd191dbf6c914.tar.gz
kernel-8ad49d88de7e7c53e142a8d6e5dcd191dbf6c914.tar.xz
kernel-8ad49d88de7e7c53e142a8d6e5dcd191dbf6c914.zip
Netdev fix race in resq_queue_unlink
-rw-r--r--kernel.spec5
-rw-r--r--net-inet-fix-race-in-reqsk_queue_unlink.patch76
2 files changed, 81 insertions, 0 deletions
diff --git a/kernel.spec b/kernel.spec
index 320e3c0ff..110cafdcc 100644
--- a/kernel.spec
+++ b/kernel.spec
@@ -636,6 +636,8 @@ Patch529: vfs-Test-for-and-handle-paths-that-are-unreachable-f.patch
#CVE-2015-7613 rhbz 1268270 1268273
Patch532: Initialize-msg-shm-IPC-objects-before-doing-ipc_addi.patch
+Patch533: net-inet-fix-race-in-reqsk_queue_unlink.patch
+
# END OF PATCH DEFINITIONS
%endif
@@ -1391,6 +1393,8 @@ ApplyPatch vfs-Test-for-and-handle-paths-that-are-unreachable-f.patch
#CVE-2015-7613 rhbz 1268270 1268273
ApplyPatch Initialize-msg-shm-IPC-objects-before-doing-ipc_addi.patch
+ApplyPatch net-inet-fix-race-in-reqsk_queue_unlink.patch
+
# END OF PATCH APPLICATIONS
%endif
@@ -2243,6 +2247,7 @@ fi
%changelog
* Mon Oct 05 2015 Justin M. Forbes <jforbes@fedoraproject.org>
- Linux v4.2.3
+- Netdev fix race in resq_queue_unlink
* Fri Oct 02 2015 Josh Boyer <jwboyer@fedoraproject.org>
- CVE-2015-7613 Unauthorized access to IPC via SysV shm (rhbz 1268270 1268273)
diff --git a/net-inet-fix-race-in-reqsk_queue_unlink.patch b/net-inet-fix-race-in-reqsk_queue_unlink.patch
new file mode 100644
index 000000000..744084314
--- /dev/null
+++ b/net-inet-fix-race-in-reqsk_queue_unlink.patch
@@ -0,0 +1,76 @@
+From patchwork Thu Oct 1 12:39:26 2015
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+Subject: [net] inet: fix race in reqsk_queue_unlink()
+From: Eric Dumazet <eric.dumazet@gmail.com>
+X-Patchwork-Id: 524966
+Message-Id: <1443703166.32531.47.camel@edumazet-glaptop2.roam.corp.google.com>
+To: David Miller <davem@davemloft.net>
+Cc: netdev <netdev@vger.kernel.org>, Yuchung Cheng <ycheng@google.com>
+Date: Thu, 01 Oct 2015 05:39:26 -0700
+
+From: Eric Dumazet <edumazet@google.com>
+
+reqsk_timer_handler() tests if icsk_accept_queue.listen_opt
+is NULL at its beginning.
+
+By the time it calls inet_csk_reqsk_queue_drop() and
+reqsk_queue_unlink(), listener might have been closed and
+inet_csk_listen_stop() had called reqsk_queue_yank_acceptq()
+which sets icsk_accept_queue.listen_opt to NULL
+
+We therefore need to correctly check listen_opt being NULL
+after holding syn_wait_lock for proper synchronization.
+
+Fixes: fa76ce7328b2 ("inet: get rid of central tcp/dccp listener timer")
+Fixes: b357a364c57c ("inet: fix possible panic in reqsk_queue_unlink()")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Yuchung Cheng <ycheng@google.com>
+---
+ net/ipv4/inet_connection_sock.c | 19 ++++++++++---------
+ 1 file changed, 10 insertions(+), 9 deletions(-)
+
+
+
+--
+To unsubscribe from this list: send the line "unsubscribe netdev" in
+the body of a message to majordomo@vger.kernel.org
+More majordomo info at http://vger.kernel.org/majordomo-info.html
+
+diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
+index 7bb9c39e0a4d..61b45a17fc73 100644
+--- a/net/ipv4/inet_connection_sock.c
++++ b/net/ipv4/inet_connection_sock.c
+@@ -577,21 +577,22 @@ EXPORT_SYMBOL(inet_rtx_syn_ack);
+ static bool reqsk_queue_unlink(struct request_sock_queue *queue,
+ struct request_sock *req)
+ {
+- struct listen_sock *lopt = queue->listen_opt;
+ struct request_sock **prev;
++ struct listen_sock *lopt;
+ bool found = false;
+
+ spin_lock(&queue->syn_wait_lock);
+-
+- for (prev = &lopt->syn_table[req->rsk_hash]; *prev != NULL;
+- prev = &(*prev)->dl_next) {
+- if (*prev == req) {
+- *prev = req->dl_next;
+- found = true;
+- break;
++ lopt = queue->listen_opt;
++ if (lopt) {
++ for (prev = &lopt->syn_table[req->rsk_hash]; *prev != NULL;
++ prev = &(*prev)->dl_next) {
++ if (*prev == req) {
++ *prev = req->dl_next;
++ found = true;
++ break;
++ }
+ }
+ }
+-
+ spin_unlock(&queue->syn_wait_lock);
+ if (timer_pending(&req->rsk_timer) && del_timer_sync(&req->rsk_timer))
+ reqsk_put(req);