summaryrefslogtreecommitdiffstats
path: root/src/plugins/linux-cp/lcp_interface.c
diff options
context:
space:
mode:
authorVladislav Grishenko <themiron@yandex-team.ru>2022-03-20 15:55:25 +0500
committerMatthew Smith <mgsmith@netgate.com>2022-03-29 15:24:58 +0000
commitfbc4ad5fd4a48c49c492912fe75e33a2dbb41dab (patch)
tree49fd7ff04715a39d79552652a27060abb62c6705 /src/plugins/linux-cp/lcp_interface.c
parentbf82a66de7653921e3c25ae444d372d2eddeee9f (diff)
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 <themiron@yandex-team.ru> Change-Id: I21ea46d146d11060bb9bedc77377ab17ae9e22e8
Diffstat (limited to 'src/plugins/linux-cp/lcp_interface.c')
-rw-r--r--src/plugins/linux-cp/lcp_interface.c34
1 files changed, 16 insertions, 18 deletions
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);