On Mon, May 6, 2024 at 6:37 AM Ales Musil <[email protected]> wrote:
>
> Avoid use after free in scenario when controller received LB deletion
> after the DB was reconnected. The reconnect led to idl clearing up
> the "old" structs, one of them being the LB. However, during recompute
> the struct was referenced when it was already gone.
>
> Clear the whole objdep_mgr instead of going one-by-one during recompute.
>
> ==143949==ERROR: AddressSanitizer: heap-use-after-free
> READ of size 4 at 0x5130000280d0 thread T0
> 0 0x61c3c9 in lb_data_local_lb_remove controller/ovn-controller.c:2978:5
> 1 0x5fd4df in en_lb_data_run controller/ovn-controller.c:3063:9
> 2 0x6fe0d9 in engine_recompute lib/inc-proc-eng.c:415:5
> 3 0x6fbdc2 in engine_run_node lib/inc-proc-eng.c:477:9
> 4 0x6fbdc2 in engine_run lib/inc-proc-eng.c:528:9
> 5 0x5f39a0 in main controller/ovn-controller.c
>
> Fixes: 8382127186bf ("controller: Store load balancer data in separate node")
> Reported-at: https://issues.redhat.com/browse/FDP-610
> Signed-off-by: Ales Musil <[email protected]>
Thanks. Applied the patch to main and backported until 23.03
Numan
> ---
> controller/ovn-controller.c | 20 +++++++++----------
> tests/ovn-controller.at | 38 +++++++++++++++++++++++++++++++++++++
> 2 files changed, 48 insertions(+), 10 deletions(-)
>
> diff --git a/controller/ovn-controller.c b/controller/ovn-controller.c
> index 23269af83..65b9ba8e5 100644
> --- a/controller/ovn-controller.c
> +++ b/controller/ovn-controller.c
> @@ -2972,7 +2972,7 @@ lb_data_local_lb_add(struct ed_type_lb_data *lb_data,
>
> static void
> lb_data_local_lb_remove(struct ed_type_lb_data *lb_data,
> - struct ovn_controller_lb *lb, bool tracked)
> + struct ovn_controller_lb *lb)
> {
> const struct uuid *uuid = &lb->slb->header_.uuid;
>
> @@ -2981,12 +2981,8 @@ lb_data_local_lb_remove(struct ed_type_lb_data
> *lb_data,
>
> lb_data_removed_five_tuples_add(lb_data, lb);
>
> - if (tracked) {
> - hmap_insert(&lb_data->old_lbs, &lb->hmap_node, uuid_hash(uuid));
> - uuidset_insert(&lb_data->deleted, uuid);
> - } else {
> - ovn_controller_lb_destroy(lb);
> - }
> + hmap_insert(&lb_data->old_lbs, &lb->hmap_node, uuid_hash(uuid));
> + uuidset_insert(&lb_data->deleted, uuid);
> }
>
> static bool
> @@ -3011,7 +3007,7 @@ lb_data_handle_changed_ref(enum objdep_type type, const
> char *res_name,
> continue;
> }
>
> - lb_data_local_lb_remove(lb_data, lb, true);
> + lb_data_local_lb_remove(lb_data, lb);
>
> const struct sbrec_load_balancer *sbrec_lb =
> sbrec_load_balancer_table_get_for_uuid(ctx_in->lb_table, uuid);
> @@ -3057,9 +3053,13 @@ en_lb_data_run(struct engine_node *node, void *data)
> const struct sbrec_load_balancer_table *lb_table =
> EN_OVSDB_GET(engine_get_input("SB_load_balancer", node));
>
> + objdep_mgr_clear(&lb_data->deps_mgr);
> +
> struct ovn_controller_lb *lb;
> HMAP_FOR_EACH_SAFE (lb, hmap_node, &lb_data->local_lbs) {
> - lb_data_local_lb_remove(lb_data, lb, false);
> + hmap_remove(&lb_data->local_lbs, &lb->hmap_node);
> + lb_data_removed_five_tuples_add(lb_data, lb);
> + ovn_controller_lb_destroy(lb);
> }
>
> const struct sbrec_load_balancer *sbrec_lb;
> @@ -3097,7 +3097,7 @@ lb_data_sb_load_balancer_handler(struct engine_node
> *node, void *data)
> continue;
> }
>
> - lb_data_local_lb_remove(lb_data, lb, true);
> + lb_data_local_lb_remove(lb_data, lb);
> }
>
> if (sbrec_load_balancer_is_deleted(sbrec_lb) ||
> diff --git a/tests/ovn-controller.at b/tests/ovn-controller.at
> index 27cec2aec..cecbc190b 100644
> --- a/tests/ovn-controller.at
> +++ b/tests/ovn-controller.at
> @@ -2973,3 +2973,41 @@
> priority=1100,ip,reg15=0x1,metadata=0x1,nw_src=10.0.0.4
> actions=load:0x1->OXM_OF
>
> OVN_CLEANUP([hv1])
> AT_CLEANUP
> +
> +AT_SETUP([ovn-controller - LB remove after disconnect])
> +ovn_start
> +
> +net_add n1
> +sim_add hv1
> +as hv1
> +check ovs-vsctl add-br br-phys
> +ovn_attach n1 br-phys 192.168.0.1
> +check ovs-vsctl -- add-port br-int vif1 -- \
> + set interface vif1 external-ids:iface-id=lsp
> +
> +check ovs-vsctl set Open_vSwitch .
> external-ids:ovn-remote-probe-interval="5000"
> +
> +check ovn-nbctl ls-add ls
> +check ovn-nbctl lsp-add ls lsp \
> +-- lsp-set-addresses lsp "f0:00:00:00:00:01 172.16.0.10"
> +
> +check ovn-nbctl lb-add lb 192.168.100.100 172.16.0.10
> +check ovn-nbctl ls-lb-add ls lb
> +
> +wait_for_ports_up
> +check ovn-nbctl --wait=hv sync
> +
> +sleep_sb
> +OVS_WAIT_UNTIL([grep -q 'OVNSB commit failed' hv1/ovn-controller.log])
> +
> +sleep_controller hv1
> +wake_up_sb
> +
> +ovn-nbctl lb-del lb
> +
> +wake_up_controller hv1
> +check ovn-nbctl --wait=hv sync
> +
> +OVN_CLEANUP([hv1
> +/no response to inactivity probe after .* seconds, disconnecting/d])
> +AT_CLEANUP
> --
> 2.44.0
>
> _______________________________________________
> dev mailing list
> [email protected]
> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
>
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev