Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 29c68526 authored by Eric Dumazet's avatar Eric Dumazet Committed by David S. Miller
Browse files

inet: fix races in reqsk_queue_hash_req()



Before allowing lockless LISTEN processing, we need to make
sure to arm the SYN_RECV timer before the req socket is visible
in hash tables.

Also, req->rsk_hash should be written before we set rsk_refcnt
to a non zero value.

Fixes: fa76ce73 ("inet: get rid of central tcp/dccp listener timer")
Signed-off-by: default avatarEric Dumazet <edumazet@google.com>
Cc: Ying Cai <ycai@google.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ed2e9239
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -685,20 +685,20 @@ void reqsk_queue_hash_req(struct request_sock_queue *queue,
	req->num_timeout = 0;
	req->sk = NULL;

	setup_timer(&req->rsk_timer, reqsk_timer_handler, (unsigned long)req);
	mod_timer_pinned(&req->rsk_timer, jiffies + timeout);
	req->rsk_hash = hash;

	/* before letting lookups find us, make sure all req fields
	 * are committed to memory and refcnt initialized.
	 */
	smp_wmb();
	atomic_set(&req->rsk_refcnt, 2);
	setup_timer(&req->rsk_timer, reqsk_timer_handler, (unsigned long)req);
	req->rsk_hash = hash;

	spin_lock(&queue->syn_wait_lock);
	req->dl_next = lopt->syn_table[hash];
	lopt->syn_table[hash] = req;
	spin_unlock(&queue->syn_wait_lock);

	mod_timer_pinned(&req->rsk_timer, jiffies + timeout);
}
EXPORT_SYMBOL(reqsk_queue_hash_req);