From 8ad49d88de7e7c53e142a8d6e5dcd191dbf6c914 Mon Sep 17 00:00:00 2001 From: Justin M. Forbes Date: Oct 05 2015 14:53:15 +0000 Subject: Netdev fix race in resq_queue_unlink --- diff --git a/kernel.spec b/kernel.spec index 320e3c0..110cafd 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 - Linux v4.2.3 +- Netdev fix race in resq_queue_unlink * Fri Oct 02 2015 Josh Boyer - 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 0000000..7440843 --- /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 +X-Patchwork-Id: 524966 +Message-Id: <1443703166.32531.47.camel@edumazet-glaptop2.roam.corp.google.com> +To: David Miller +Cc: netdev , Yuchung Cheng +Date: Thu, 01 Oct 2015 05:39:26 -0700 + +From: Eric Dumazet + +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 +Cc: Yuchung Cheng +--- + 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);