On 8/15/26 5:17 PM, Ruoyu Wang wrote:
> ovs_ct_init() acquires a connlabels reference before initializing the
> conntrack limit state. If ovs_ct_limit_init() fails, its error is returned
> directly. The pernet core does not invoke the exit callback for the
> operation whose initialization failed, so ovs_ct_exit() cannot drop the
> reference.
> 
> This leaves labels_used elevated when Open vSwitch pernet registration
> fails for an existing network namespace. Subsequent conntrack entries in
> that namespace may allocate label extensions even though Open vSwitch
> failed to register.
> 
> Drop the connlabels reference before returning a conntrack limit
> initialization error. ovs_ct_limit_init() already releases its partial
> state, and the original error remains unchanged.
> 
> This issue was found by a static analysis checker and confirmed by
> manual source review.
> 
> Fixes: 11efd5cb04a1 ("openvswitch: Support conntrack zone limit")
> Cc: [email protected]
> Assisted-by: unnamed:gpt-5.5 typestate
> Signed-off-by: Ruoyu Wang <[email protected]>
> 
> ---
> Changes in v2:
> - Initialize err unconditionally and use one return path.
> - Add the stable Cc and Assisted-by tag.
> 
> v1: https://lore.kernel.org/r/[email protected]/
> ---
>  net/openvswitch/conntrack.c | 8 +++++---
>  1 file changed, 5 insertions(+), 3 deletions(-)

Reviewed-by: Ilya Maximets <[email protected]>

Note:
"contest" reports a conflict with the other fix, presumably:
  
https://lore.kernel.org/r/6cb36cfa28844b05919ca7c45c6c2bc812d3dc2e.1786936669.git.xuyuqi...@gmail.com
However, there is no real conflict, patches do not touch the same functions.
'git am -3' applies them just fine.

> 
> diff --git a/net/openvswitch/conntrack.c b/net/openvswitch/conntrack.c
> index 95697d4e16e64e..38c6f34776c280 100644
> --- a/net/openvswitch/conntrack.c
> +++ b/net/openvswitch/conntrack.c
> @@ -2001,6 +2001,7 @@ int ovs_ct_init(struct net *net)
>  {
>       unsigned int n_bits = sizeof(struct ovs_key_ct_labels) * BITS_PER_BYTE;
>       struct ovs_net *ovs_net = net_generic(net, ovs_net_id);
> +     int err = 0;
>  
>       if (nf_connlabels_get(net, n_bits - 1)) {
>               ovs_net->xt_label = false;
> @@ -2010,10 +2011,11 @@ int ovs_ct_init(struct net *net)
>       }
>  
>  #if  IS_ENABLED(CONFIG_NETFILTER_CONNCOUNT)
> -     return ovs_ct_limit_init(net, ovs_net);
> -#else
> -     return 0;
> +     err = ovs_ct_limit_init(net, ovs_net);
> +     if (err && ovs_net->xt_label)
> +             nf_connlabels_put(net);
>  #endif
> +     return err;
>  }
>  
>  void ovs_ct_exit(struct net *net)

_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to