Re: [PATCH net] tcp/dccp: remove reqsk_put() from inet_child_forget()
From: David Miller <davem@davemloft.net>
Date: 2017-09-13 03:39:14
From: Eric Dumazet <redacted> Date: Mon, 11 Sep 2017 15:58:38 -0700
From: Eric Dumazet <edumazet@google.com>
Back in linux-4.4, I inadvertently put a call to reqsk_put() in
inet_child_forget(), forgetting it could be called from two different
points.
In the case it is called from inet_csk_reqsk_queue_add(), we want to
keep the reference on the request socket, since it is released later by
the caller (tcp_v{4|6}_rcv())
This bug never showed up because atomic_dec_and_test() was not signaling
the underflow, and SLAB_DESTROY_BY RCU semantic for request sockets
prevented the request to be put in quarantine.
Recent conversion of socket refcount from atomic_t to refcount_t finally
exposed the bug.
So move the reqsk_put() to inet_csk_listen_stop() to fix this.
Thanks to Shankara Pailoor for using syzkaller and providing
a nice set of .config and C repro....
Fixes: ebb516af60e1 ("tcp/dccp: fix race at listener dismantle phase")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reported-by: Shankara Pailoor <redacted>
Tested-by: Shankara Pailoor <redacted>Applied and queued up for -stable. Thanks.