netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net v2 0/2] net: fix issues when uncloning an skb dst+metadata
@ 2022-02-07 17:13 Antoine Tenart
  2022-02-07 17:13 ` [PATCH net v2 1/2] net: do not keep the dst cache when uncloning an skb dst and its metadata Antoine Tenart
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Antoine Tenart @ 2022-02-07 17:13 UTC (permalink / raw)
  To: davem, kuba; +Cc: Antoine Tenart, netdev, vladbu, pabeni, pshelar, daniel

Hi,

This fixes two issues when uncloning an skb dst+metadata in
tun_dst_unclone; this was initially reported by Vlad Buslov[1]. Because
of the memory leak fixed by patch 2, the issue in patch 1 never happened
in practice.

tun_dst_unclone is called from two different places, one in geneve/vxlan
to handle PMTU and one in net/openvswitch/actions.c where it is used to
retrieve tunnel information. While both Vlad and I tested the former, we
could not for the latter. I did spend quite some time trying to, but
that code path is not easy to trigger. Code inspection shows this should
be fine, the tunnel information (dst+metadata) is uncloned and the skb
it is referenced from is only consumed after all accesses to the tunnel
information are done:

  do_execute_actions
    output_userspace
      dev_fill_metadata_dst         <- dst+metadata is uncloned
      ovs_dp_upcall
        queue_userspace_packet
          ovs_nla_put_tunnel_info   <- metadata (tunnel info) is accessed
    consume_skb                     <- dst+metadata is freed

Since v1:
- Only allocate a dst cache if there is one already.
- Use metadata_dst_free in the dst_cache_init error path. This is OK as
  the dst_cache is zeroed on error.
- Protect the ret variable definition with CONFIG_DST_CACHE.
- Kept Vlad's Tested-by as the changes are minor.

Thanks!
Antoine

Antoine Tenart (2):
  net: do not keep the dst cache when uncloning an skb dst and its
    metadata
  net: fix a memleak when uncloning an skb dst and its metadata

 include/net/dst_metadata.h | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

-- 
2.34.1


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH net v2 1/2] net: do not keep the dst cache when uncloning an skb dst and its metadata
  2022-02-07 17:13 [PATCH net v2 0/2] net: fix issues when uncloning an skb dst+metadata Antoine Tenart
@ 2022-02-07 17:13 ` Antoine Tenart
  2022-02-07 18:17   ` Paolo Abeni
  2022-02-07 17:13 ` [PATCH net v2 2/2] net: fix a memleak " Antoine Tenart
  2022-02-09 12:00 ` [PATCH net v2 0/2] net: fix issues when uncloning an skb dst+metadata patchwork-bot+netdevbpf
  2 siblings, 1 reply; 5+ messages in thread
From: Antoine Tenart @ 2022-02-07 17:13 UTC (permalink / raw)
  To: davem, kuba; +Cc: Antoine Tenart, netdev, vladbu, pabeni, pshelar, daniel

When uncloning an skb dst and its associated metadata a new dst+metadata
is allocated and the tunnel information from the old metadata is copied
over there.

The issue is the tunnel metadata has references to cached dst, which are
copied along the way. When a dst+metadata refcount drops to 0 the
metadata is freed including the cached dst entries. As they are also
referenced in the initial dst+metadata, this ends up in UaFs.

In practice the above did not happen because of another issue, the
dst+metadata was never freed because its refcount never dropped to 0
(this will be fixed in a subsequent patch).

Fix this by initializing the dst cache after copying the tunnel
information from the old metadata to also unshare the dst cache.

Fixes: d71785ffc7e7 ("net: add dst_cache to ovs vxlan lwtunnel")
Cc: Paolo Abeni <pabeni@redhat.com>
Reported-by: Vlad Buslov <vladbu@nvidia.com>
Tested-by: Vlad Buslov <vladbu@nvidia.com>
Signed-off-by: Antoine Tenart <atenart@kernel.org>
---
 include/net/dst_metadata.h | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/include/net/dst_metadata.h b/include/net/dst_metadata.h
index 14efa0ded75d..b997e0c1e362 100644
--- a/include/net/dst_metadata.h
+++ b/include/net/dst_metadata.h
@@ -123,6 +123,19 @@ static inline struct metadata_dst *tun_dst_unclone(struct sk_buff *skb)
 
 	memcpy(&new_md->u.tun_info, &md_dst->u.tun_info,
 	       sizeof(struct ip_tunnel_info) + md_size);
+#ifdef CONFIG_DST_CACHE
+	/* Unclone the dst cache if there is one */
+	if (new_md->u.tun_info.dst_cache.cache) {
+		int ret;
+
+		ret = dst_cache_init(&new_md->u.tun_info.dst_cache, GFP_ATOMIC);
+		if (ret) {
+			metadata_dst_free(new_md);
+			return ERR_PTR(ret);
+		}
+	}
+#endif
+
 	skb_dst_drop(skb);
 	dst_hold(&new_md->dst);
 	skb_dst_set(skb, &new_md->dst);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH net v2 2/2] net: fix a memleak when uncloning an skb dst and its metadata
  2022-02-07 17:13 [PATCH net v2 0/2] net: fix issues when uncloning an skb dst+metadata Antoine Tenart
  2022-02-07 17:13 ` [PATCH net v2 1/2] net: do not keep the dst cache when uncloning an skb dst and its metadata Antoine Tenart
@ 2022-02-07 17:13 ` Antoine Tenart
  2022-02-09 12:00 ` [PATCH net v2 0/2] net: fix issues when uncloning an skb dst+metadata patchwork-bot+netdevbpf
  2 siblings, 0 replies; 5+ messages in thread
From: Antoine Tenart @ 2022-02-07 17:13 UTC (permalink / raw)
  To: davem, kuba; +Cc: Antoine Tenart, netdev, vladbu, pabeni, pshelar, daniel

When uncloning an skb dst and its associated metadata, a new
dst+metadata is allocated and later replaces the old one in the skb.
This is helpful to have a non-shared dst+metadata attached to a specific
skb.

The issue is the uncloned dst+metadata is initialized with a refcount of
1, which is increased to 2 before attaching it to the skb. When
tun_dst_unclone returns, the dst+metadata is only referenced from a
single place (the skb) while its refcount is 2. Its refcount will never
drop to 0 (when the skb is consumed), leading to a memory leak.

Fix this by removing the call to dst_hold in tun_dst_unclone, as the
dst+metadata refcount is already 1.

Fixes: fc4099f17240 ("openvswitch: Fix egress tunnel info.")
Cc: Pravin B Shelar <pshelar@ovn.org>
Reported-by: Vlad Buslov <vladbu@nvidia.com>
Tested-by: Vlad Buslov <vladbu@nvidia.com>
Signed-off-by: Antoine Tenart <atenart@kernel.org>
---
 include/net/dst_metadata.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/include/net/dst_metadata.h b/include/net/dst_metadata.h
index b997e0c1e362..adab27ba1ecb 100644
--- a/include/net/dst_metadata.h
+++ b/include/net/dst_metadata.h
@@ -137,7 +137,6 @@ static inline struct metadata_dst *tun_dst_unclone(struct sk_buff *skb)
 #endif
 
 	skb_dst_drop(skb);
-	dst_hold(&new_md->dst);
 	skb_dst_set(skb, &new_md->dst);
 	return new_md;
 }
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH net v2 1/2] net: do not keep the dst cache when uncloning an skb dst and its metadata
  2022-02-07 17:13 ` [PATCH net v2 1/2] net: do not keep the dst cache when uncloning an skb dst and its metadata Antoine Tenart
@ 2022-02-07 18:17   ` Paolo Abeni
  0 siblings, 0 replies; 5+ messages in thread
From: Paolo Abeni @ 2022-02-07 18:17 UTC (permalink / raw)
  To: Antoine Tenart, davem, kuba; +Cc: netdev, vladbu, pshelar, daniel

On Mon, 2022-02-07 at 18:13 +0100, Antoine Tenart wrote:
> When uncloning an skb dst and its associated metadata a new dst+metadata
> is allocated and the tunnel information from the old metadata is copied
> over there.
> 
> The issue is the tunnel metadata has references to cached dst, which are
> copied along the way. When a dst+metadata refcount drops to 0 the
> metadata is freed including the cached dst entries. As they are also
> referenced in the initial dst+metadata, this ends up in UaFs.
> 
> In practice the above did not happen because of another issue, the
> dst+metadata was never freed because its refcount never dropped to 0
> (this will be fixed in a subsequent patch).
> 
> Fix this by initializing the dst cache after copying the tunnel
> information from the old metadata to also unshare the dst cache.
> 
> Fixes: d71785ffc7e7 ("net: add dst_cache to ovs vxlan lwtunnel")
> Cc: Paolo Abeni <pabeni@redhat.com>
> Reported-by: Vlad Buslov <vladbu@nvidia.com>
> Tested-by: Vlad Buslov <vladbu@nvidia.com>
> Signed-off-by: Antoine Tenart <atenart@kernel.org>
> ---
>  include/net/dst_metadata.h | 13 +++++++++++++
>  1 file changed, 13 insertions(+)
> 
> diff --git a/include/net/dst_metadata.h b/include/net/dst_metadata.h
> index 14efa0ded75d..b997e0c1e362 100644
> --- a/include/net/dst_metadata.h
> +++ b/include/net/dst_metadata.h
> @@ -123,6 +123,19 @@ static inline struct metadata_dst *tun_dst_unclone(struct sk_buff *skb)
>  
>  	memcpy(&new_md->u.tun_info, &md_dst->u.tun_info,
>  	       sizeof(struct ip_tunnel_info) + md_size);
> +#ifdef CONFIG_DST_CACHE
> +	/* Unclone the dst cache if there is one */
> +	if (new_md->u.tun_info.dst_cache.cache) {
> +		int ret;
> +
> +		ret = dst_cache_init(&new_md->u.tun_info.dst_cache, GFP_ATOMIC);
> +		if (ret) {
> +			metadata_dst_free(new_md);
> +			return ERR_PTR(ret);
> +		}
> +	}
> +#endif
> +
>  	skb_dst_drop(skb);
>  	dst_hold(&new_md->dst);
>  	skb_dst_set(skb, &new_md->dst);

LGTM, thanks!

Acked-by: Paolo Abeni <pabeni@redhat.com>


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH net v2 0/2] net: fix issues when uncloning an skb dst+metadata
  2022-02-07 17:13 [PATCH net v2 0/2] net: fix issues when uncloning an skb dst+metadata Antoine Tenart
  2022-02-07 17:13 ` [PATCH net v2 1/2] net: do not keep the dst cache when uncloning an skb dst and its metadata Antoine Tenart
  2022-02-07 17:13 ` [PATCH net v2 2/2] net: fix a memleak " Antoine Tenart
@ 2022-02-09 12:00 ` patchwork-bot+netdevbpf
  2 siblings, 0 replies; 5+ messages in thread
From: patchwork-bot+netdevbpf @ 2022-02-09 12:00 UTC (permalink / raw)
  To: Antoine Tenart; +Cc: davem, kuba, netdev, vladbu, pabeni, pshelar, daniel

Hello:

This series was applied to netdev/net.git (master)
by David S. Miller <davem@davemloft.net>:

On Mon,  7 Feb 2022 18:13:17 +0100 you wrote:
> Hi,
> 
> This fixes two issues when uncloning an skb dst+metadata in
> tun_dst_unclone; this was initially reported by Vlad Buslov[1]. Because
> of the memory leak fixed by patch 2, the issue in patch 1 never happened
> in practice.
> 
> [...]

Here is the summary with links:
  - [net,v2,1/2] net: do not keep the dst cache when uncloning an skb dst and its metadata
    https://git.kernel.org/netdev/net/c/cfc56f85e72f
  - [net,v2,2/2] net: fix a memleak when uncloning an skb dst and its metadata
    https://git.kernel.org/netdev/net/c/9eeabdf17fa0

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2022-02-09 12:15 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-02-07 17:13 [PATCH net v2 0/2] net: fix issues when uncloning an skb dst+metadata Antoine Tenart
2022-02-07 17:13 ` [PATCH net v2 1/2] net: do not keep the dst cache when uncloning an skb dst and its metadata Antoine Tenart
2022-02-07 18:17   ` Paolo Abeni
2022-02-07 17:13 ` [PATCH net v2 2/2] net: fix a memleak " Antoine Tenart
2022-02-09 12:00 ` [PATCH net v2 0/2] net: fix issues when uncloning an skb dst+metadata patchwork-bot+netdevbpf

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).