diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 27140e5cdc06..292435dbec06 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -1168,6 +1168,14 @@ struct tcp_md5sig_key *tcp_v4_md5_lookup(const struct sock *sk, } EXPORT_SYMBOL(tcp_v4_md5_lookup); +static void tcp_md5sig_info_free(struct rcu_head *head) +{ + struct tcp_md5sig_info *md5sig = + container_of(head, struct tcp_md5sig_info, rcu); + + kfree_sensitive(md5sig); +} + static int tcp_md5sig_info_add(struct sock *sk, gfp_t gfp) { struct tcp_sock *tp = tcp_sk(sk); @@ -1180,9 +1188,18 @@ static int tcp_md5sig_info_add(struct sock *sk, gfp_t gfp) sk_gso_disable(sk); INIT_HLIST_HEAD(&md5sig->head); rcu_assign_pointer(tp->md5sig_info, md5sig); + call_rcu(&md5sig->rcu, tcp_md5sig_info_free); return 0; } +static void tcp_md5sig_key_free(struct rcu_head *head) +{ + struct tcp_md5sig_key *key = + container_of(head, struct tcp_md5sig_key, rcu); + + kfree_sensitive(key); +} + /* This can be called on a newly created socket, from other files */ static int __tcp_md5_do_add(struct sock *sk, const union tcp_md5_addr *addr, int family, u8 prefixlen, int l3index, u8 flags, @@ -1234,6 +1251,7 @@ static int __tcp_md5_do_add(struct sock *sk, const union tcp_md5_addr *addr, (IS_ENABLED(CONFIG_IPV6) && family == AF_INET6) ? sizeof(struct in6_addr) : sizeof(struct in_addr)); hlist_add_head_rcu(&key->node, &md5sig->head); + call_rcu(&key->rcu, tcp_md5sig_key_free); return 0; }