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: b89c1ddcb3
Signed-off-by: Vladislav Grishenko <themiron@yandex-team.ru>
Change-Id: I21ea46d146d11060bb9bedc77377ab17ae9e22e8
This commit is contained in:
Vladislav Grishenko
2022-03-20 15:55:25 +05:00
committed by Matthew Smith
parent bf82a66de7
commit fbc4ad5fd4

View File

@@ -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,25 +991,6 @@ 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])
{
args.host_mtu_set = 1;
args.host_mtu_size = sw->mtu[VNET_MTU_L3];
}
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",
args.rv);
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
@@ -1017,12 +999,28 @@ lcp_itf_pair_create (u32 phy_sw_if_index, u8 *host_if_name,
* 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]);
host_sw_mtu_size = sw->mtu[VNET_MTU_L3];
if (host_sw_mtu_size)
{
args.host_mtu_set = 1;
args.host_mtu_size = host_sw_mtu_size;
}
else
vnet_sw_interface_set_mtu (vnm, args.sw_if_index,
ETHERNET_MAX_PACKET_BYTES);
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",
args.rv);
return args.rv;
}
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);