----- On Jun 30, 2020, at 7:41 PM, Eric Dumazet eduma...@google.com wrote:

> MD5 keys are read with RCU protection, and tcp_md5_do_add()
> might update in-place a prior key.
> 
> Normally, typical RCU updates would allocate a new piece
> of memory. In this case only key->key and key->keylen might
> be updated, and we do not care if an incoming packet could
> see the old key, the new one, or some intermediate value,
> since changing the key on a live flow is known to be problematic
> anyway.

What makes it acceptable to observe an intermediate bogus key during the
transition ?

Thanks,

Mathieu

> 
> We only want to make sure that in the case key->keylen
> is changed, cpus in tcp_md5_hash_key() wont try to use
> uninitialized data, or crash because key->keylen was
> read twice to feed sg_init_one() and ahash_request_set_crypt()
> 
> Fixes: 9ea88a153001 ("tcp: md5: check md5 signature without socket lock")
> Signed-off-by: Eric Dumazet <eduma...@google.com>
> Cc: Mathieu Desnoyers <mathieu.desnoy...@efficios.com>
> ---
> net/ipv4/tcp.c      | 7 +++++--
> net/ipv4/tcp_ipv4.c | 3 +++
> 2 files changed, 8 insertions(+), 2 deletions(-)
> 
> diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
> index
> 810cc164f795f8e1e8ca747ed5df51bb20fec8a2..f111660453241692a17c881dd6dc2910a1236263
> 100644
> --- a/net/ipv4/tcp.c
> +++ b/net/ipv4/tcp.c
> @@ -4033,10 +4033,13 @@ EXPORT_SYMBOL(tcp_md5_hash_skb_data);
> 
> int tcp_md5_hash_key(struct tcp_md5sig_pool *hp, const struct tcp_md5sig_key
> *key)
> {
> +     u8 keylen = key->keylen;
>       struct scatterlist sg;
> 
> -     sg_init_one(&sg, key->key, key->keylen);
> -     ahash_request_set_crypt(hp->md5_req, &sg, NULL, key->keylen);
> +     smp_rmb(); /* paired with smp_wmb() in tcp_md5_do_add() */
> +
> +     sg_init_one(&sg, key->key, keylen);
> +     ahash_request_set_crypt(hp->md5_req, &sg, NULL, keylen);
>       return crypto_ahash_update(hp->md5_req);
> }
> EXPORT_SYMBOL(tcp_md5_hash_key);
> diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
> index
> ad6435ba6d72ffd8caf783bb25cad7ec151d6909..99916fcc15ca0be12c2c133ff40516f79e6fdf7f
> 100644
> --- a/net/ipv4/tcp_ipv4.c
> +++ b/net/ipv4/tcp_ipv4.c
> @@ -1113,6 +1113,9 @@ int tcp_md5_do_add(struct sock *sk, const union
> tcp_md5_addr *addr,
>       if (key) {
>               /* Pre-existing entry - just update that one. */
>               memcpy(key->key, newkey, newkeylen);
> +
> +             smp_wmb(); /* pairs with smp_rmb() in tcp_md5_hash_key() */
> +
>               key->keylen = newkeylen;
>               return 0;
>       }
> --
> 2.27.0.212.ge8ba1cc988-goog

-- 
Mathieu Desnoyers
EfficiOS Inc.
http://www.efficios.com

Reply via email to