[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <1488461281.9415.327.camel@edumazet-glaptop3.roam.corp.google.com>
Date: Thu, 02 Mar 2017 05:28:01 -0800
From: Eric Dumazet <eric.dumazet@...il.com>
To: Daniel J Blueman <daniel@...ra.org>
Cc: Netdev <netdev@...r.kernel.org>,
David Miller <davem@...emloft.net>,
Stephen Hemminger <shemminger@...tta.com>
Subject: Re: [4.9.13] use after free in ipv4_mtu
On Thu, 2017-03-02 at 05:08 -0800, Eric Dumazet wrote:
> Thanks for the report !
>
> This patch should solve this precise issue, but we need more work.
>
> We need to audit all __sk_dst_get() and make sure they are inside an
> rcu_read_lock()/rcu_read_unlock() section.
>
> diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
> index 22548b5f05cbe5a655e0c53df2d31c5cc2e8a702..517963e1cb6eb9d70fcd71f44262813c3378759f 100644
> --- a/net/ipv4/tcp_output.c
> +++ b/net/ipv4/tcp_output.c
> @@ -1459,7 +1459,7 @@ EXPORT_SYMBOL(tcp_sync_mss);
> unsigned int tcp_current_mss(struct sock *sk)
> {
> const struct tcp_sock *tp = tcp_sk(sk);
> - const struct dst_entry *dst = __sk_dst_get(sk);
> + const struct dst_entry *dst;
> u32 mss_now;
> unsigned int header_len;
> struct tcp_out_options opts;
> @@ -1467,11 +1467,14 @@ unsigned int tcp_current_mss(struct sock *sk)
>
> mss_now = tp->mss_cache;
>
> + rcu_read_lock();
> + dst = __sk_dst_get(sk);
> if (dst) {
> u32 mtu = dst_mtu(dst);
> if (mtu != inet_csk(sk)->icsk_pmtu_cookie)
> mss_now = tcp_sync_mss(sk, mtu);
> }
> + rcu_read_unlock();
>
> header_len = tcp_established_options(sk, NULL, &opts, &md5) +
> sizeof(struct tcphdr);
>
Normally TCP sockets sk_dst_cache can only be changed if the thread
doing the change owns the socket.
I have not yet understood which point was breaking the rule yet.
Powered by blists - more mailing lists