From fbc4ad5fd4a48c49c492912fe75e33a2dbb41dab Mon Sep 17 00:00:00 2001 From: Vladislav Grishenko Date: Sun, 20 Mar 2022 15:55:25 +0500 Subject: linux-cp: fix tap interface attrs in case the sw pool realloc'd Creating tap interface / sub interface causes allocation of a new software interface with possible sw interface pool reallocation. In such case accessing L3 MTU and interface flags by obsolete sw pointer is UAF. Instead, keep desired tap interface MTU value before sw intreface creation and refetch sw pointer right before sw flags inheritance. Type: fix Fixes: b89c1ddcb3b4f9138ca3ebefb2115f896ff3e1bd Signed-off-by: Vladislav Grishenko Change-Id: I21ea46d146d11060bb9bedc77377ab17ae9e22e8 --- src/plugins/linux-cp/lcp_interface.c | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) (limited to 'src/plugins/linux-cp') diff --git a/src/plugins/linux-cp/lcp_interface.c b/src/plugins/linux-cp/lcp_interface.c index bcd8ac7c20e..be73372e374 100644 --- a/src/plugins/linux-cp/lcp_interface.c +++ b/src/plugins/linux-cp/lcp_interface.c @@ -981,6 +981,7 @@ lcp_itf_pair_create (u32 phy_sw_if_index, u8 *host_if_name, .host_namespace = 0, }; ethernet_interface_t *ei; + u32 host_sw_mtu_size; if (host_if_type == LCP_ITF_HOST_TUN) args.tap_flags |= TAP_FLAG_TUN; @@ -990,18 +991,28 @@ lcp_itf_pair_create (u32 phy_sw_if_index, u8 *host_if_name, mac_address_copy (&args.host_mac_addr, &ei->address.mac); } - if (sw->mtu[VNET_MTU_L3]) + /* + * The TAP interface does copy forward the host MTU based on the VPP + * interface's L3 MTU, but it should also ensure that the VPP tap + * interface has an MTU that is greater-or-equal to those. Considering + * users can set the interfaces at runtime (set interface mtu packet ...) + * ensure that the tap MTU is large enough, taking the VPP interface L3 + * if it's set, and otherwise a sensible default. + */ + host_sw_mtu_size = sw->mtu[VNET_MTU_L3]; + if (host_sw_mtu_size) { args.host_mtu_set = 1; - args.host_mtu_size = sw->mtu[VNET_MTU_L3]; + args.host_mtu_size = host_sw_mtu_size; } + else + host_sw_mtu_size = ETHERNET_MAX_PACKET_BYTES; if (ns && ns[0] != 0) args.host_namespace = ns; vm = vlib_get_main (); tap_create_if (vm, &args); - if (args.rv < 0) { LCP_ITF_PAIR_ERR ("pair_create: could not create tap, retval:%d", @@ -1009,20 +1020,7 @@ lcp_itf_pair_create (u32 phy_sw_if_index, u8 *host_if_name, return args.rv; } - /* - * The TAP interface does copy forward the host MTU based on the VPP - * interface's L3 MTU, but it should also ensure that the VPP tap - * interface has an MTU that is greater-or-equal to those. Considering - * users can set the interfaces at runtime (set interface mtu packet ...) - * ensure that the tap MTU is large enough, taking the VPP interface L3 - * if it's set, and otherwise a sensible default. - */ - if (sw->mtu[VNET_MTU_L3]) - vnet_sw_interface_set_mtu (vnm, args.sw_if_index, - sw->mtu[VNET_MTU_L3]); - else - vnet_sw_interface_set_mtu (vnm, args.sw_if_index, - ETHERNET_MAX_PACKET_BYTES); + vnet_sw_interface_set_mtu (vnm, args.sw_if_index, host_sw_mtu_size); /* * get the hw and ethernet of the tap @@ -1068,7 +1066,7 @@ lcp_itf_pair_create (u32 phy_sw_if_index, u8 *host_if_name, * The TAP is shared by many interfaces, always keep it up. * This controls whether the host can RX/TX. */ - + sw = vnet_get_sw_interface (vnm, phy_sw_if_index); lip = lcp_itf_pair_get (lcp_itf_pair_find_by_vif (vif_index)); LCP_ITF_PAIR_INFO ("pair create: %U sw-flags %u hw-flags %u", format_lcp_itf_pair, lip, sw->flags, hw->flags); -- cgit 1.2.3-korg