[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CANn89iLZ1kDbpm81ftXkrtKBNx-NVHSYzP++_Jd0-xwy2J2Mpg@mail.gmail.com>
Date: Tue, 7 Jul 2020 21:43:26 -0700
From: Eric Dumazet <edumazet@...gle.com>
To: Christoph Paasch <cpaasch@...le.com>
Cc: netdev <netdev@...r.kernel.org>,
David Miller <davem@...emloft.net>,
Jakub Kicinski <kuba@...nel.org>, Wei Wang <weiwan@...gle.com>
Subject: Re: [PATCH net] tcp: Initialize ca_priv when inheriting from listener
On Tue, Jul 7, 2020 at 9:11 PM Christoph Paasch <cpaasch@...le.com> wrote:
>
> syzkaller found its way into setsockopt with TCP_CONGESTION "cdg".
> tcp_cdg_init() does a kcalloc to store the gradients. As sk_clone_lock
> just copies all the memory, the allocated pointer will be copied as
> well, if the app called setsockopt(..., TCP_CONGESTION) on the listener.
> If now the socket will be destroyed before the congestion-control
> has properly been initialized (through a call to tcp_init_transfer), we
> will end up freeing memory that does not belong to that particular
> socket, opening the door to a double-free:
>
> Wei Wang fixed a part of these CDG-malloc issues with commit c12014440750
> ("tcp: memset ca_priv data to 0 properly").
>
> This patch here fixes the listener-scenario by memsetting ca_priv to 0
> after its content has been inherited by the listener.
>
> (The issue can be reproduced at least down to v4.4.x.)
>
> Cc: Wei Wang <weiwan@...gle.com>
> Cc: Eric Dumazet <edumazet@...gle.com>
> Fixes: 2b0a8c9ee ("tcp: add CDG congestion control")
> Signed-off-by: Christoph Paasch <cpaasch@...le.com>
> ---
> net/ipv4/inet_connection_sock.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
> index afaf582a5aa9..dc9432f9248a 100644
> --- a/net/ipv4/inet_connection_sock.c
> +++ b/net/ipv4/inet_connection_sock.c
> @@ -850,6 +850,8 @@ struct sock *inet_csk_clone_lock(const struct sock *sk,
> newicsk->icsk_backoff = 0;
> newicsk->icsk_probes_out = 0;
>
> + memset(newicsk->icsk_ca_priv, 0, sizeof(newicsk->icsk_ca_priv));
> +
Could this be done instead in tcp_disconnect() ?
Thanks !
Powered by blists - more mailing lists