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:
committed by
Matthew Smith
parent
bf82a66de7
commit
fbc4ad5fd4
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user