interface: fix overflow of link speed. 40/36140/4
authorAnton Nikolaev <anikolaev@netgate.com>
Mon, 16 May 2022 10:33:17 +0000 (10:33 +0000)
committerMatthew Smith <mgsmith@netgate.com>
Tue, 17 May 2022 19:42:17 +0000 (19:42 +0000)
Type: fix

There were several places where mbps were converted to kbps for
link_speed, but often drivers of devices set link speed to unknown
(0xFFFFFFFF) on initialization, so there was multiplication of
link_speed equal 0xFFFFFFFF(UINT32_MAX) by 1000, this provides
overflow of unsigned int, and as result link_speed was equal
4295 Gbps, but actually link_speed is unknown.

Signed-off-by: Anton Nikolaev <anikolaev@netgate.com>
Change-Id: Ib462ed6ed685654af4687041e115bfb74e640f13

src/plugins/avf/device.c
src/plugins/dpdk/device/init.c
src/plugins/vmxnet3/vmxnet3.c
src/vnet/interface_format.c

index df6d128..d12785c 100644 (file)
@@ -1169,8 +1169,9 @@ avf_process_one_device (vlib_main_t * vm, avf_device_t * ad, int is_irq)
              flags |= (VNET_HW_INTERFACE_FLAG_FULL_DUPLEX |
                        VNET_HW_INTERFACE_FLAG_LINK_UP);
              vnet_hw_interface_set_flags (vnm, ad->hw_if_index, flags);
-             vnet_hw_interface_set_link_speed (vnm, ad->hw_if_index,
-                                               mbps * 1000);
+             vnet_hw_interface_set_link_speed (
+               vnm, ad->hw_if_index,
+               (mbps == UINT32_MAX) ? UINT32_MAX : mbps * 1000);
              ad->link_speed = mbps;
            }
          else if (!link_up && (ad->flags & AVF_DEVICE_F_LINK_UP) != 0)
index 6d3b864..6b1479b 100644 (file)
@@ -1390,7 +1390,9 @@ dpdk_update_link_state (dpdk_device_t * xd, f64 now)
     }
   if (xd->link.link_speed != prev_link.link_speed)
     vnet_hw_interface_set_link_speed (vnm, xd->hw_if_index,
-                                     xd->link.link_speed * 1000);
+                                     (xd->link.link_speed == UINT32_MAX) ?
+                                             UINT32_MAX :
+                                             xd->link.link_speed * 1000);
 
   if (xd->link.link_status != prev_link.link_status)
     {
index a0c125a..770cb2d 100644 (file)
@@ -572,8 +572,9 @@ vmxnet3_event_irq_handler (vlib_main_t * vm, vlib_pci_dev_handle_t h,
     {
       vd->flags |= VMXNET3_DEVICE_F_LINK_UP;
       vd->link_speed = ret >> 16;
-      vnet_hw_interface_set_link_speed (vnm, vd->hw_if_index,
-                                       vd->link_speed * 1000);
+      vnet_hw_interface_set_link_speed (
+       vnm, vd->hw_if_index,
+       (vd->link_speed == UINT32_MAX) ? UINT32_MAX : vd->link_speed * 1000);
       vnet_hw_interface_set_flags (vnm, vd->hw_if_index,
                                   VNET_HW_INTERFACE_FLAG_LINK_UP);
     }
@@ -867,8 +868,9 @@ vmxnet3_create_if (vlib_main_t * vm, vmxnet3_create_if_args_t * args)
   vd->flags |= VMXNET3_DEVICE_F_INITIALIZED;
   vmxnet3_enable_interrupt (vd);
 
-  vnet_hw_interface_set_link_speed (vnm, vd->hw_if_index,
-                                   vd->link_speed * 1000);
+  vnet_hw_interface_set_link_speed (
+    vnm, vd->hw_if_index,
+    (vd->link_speed == UINT32_MAX) ? UINT32_MAX : vd->link_speed * 1000);
   if (vd->flags & VMXNET3_DEVICE_F_LINK_UP)
     vnet_hw_interface_set_flags (vnm, vd->hw_if_index,
                                 VNET_HW_INTERFACE_FLAG_LINK_UP);
index e34b6fb..304fbb8 100644 (file)
@@ -120,7 +120,7 @@ format_vnet_hw_interface_link_speed (u8 * s, va_list * args)
 {
   u32 link_speed = va_arg (*args, u32);
 
-  if (link_speed == 0)
+  if (link_speed == 0 || link_speed == UINT32_MAX)
     return format (s, "unknown");
 
   if (link_speed >= 1000000)