[Bug 263896] Interger overflow in buffer size calculation in sys/dev/e1000/if_em.c

From: <bugzilla-noreply_at_freebsd.org>
Date: Tue, 10 May 2022 13:13:36 UTC
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=263896

            Bug ID: 263896
           Summary: Interger overflow in buffer size calculation in
                    sys/dev/e1000/if_em.c
           Product: Base System
           Version: Unspecified
          Hardware: Any
                OS: Any
            Status: New
          Severity: Affects Some People
          Priority: ---
         Component: kern
          Assignee: bugs@FreeBSD.org
          Reporter: hannula@gmail.com

In sys/dev/e1000/if_em.c the RX buffer is defined as:
u16 rx_buffer_size

so max value is 65535.

Later it is used to calculate the buffer water levels:
rx_buffer_size = (pba & 0xffff) << 10;
hw->fc.high_water = rx_buffer_size - roundup2(hw->mac.max_frame_size, 1024);

This is ok for example for 36KB when pba is 0x36 fc.high_water is calculated as
36864-2048=34816.

But for I350 when only 2 ports are used PBA size can be set as 72KB (see
datasheet RXPbsize or e1000_rxpbs_adjust_82580 function in e1000_82575.c).
In this case calculating the rx_buffer_size overflows as 0x0048 << 10 = 73728
or 0x12000 pushed into u16. It is then set as 0x2000 or 8192.

Tested on my dual port I350 vs quad port I350:
On quad port the PBA size is 36KB and is calculated correctly 36864-2048=34816:
dev.igb.0.fc_low_water: 34800
dev.igb.0.fc_high_water: 34816

On dual port the PBA size is 72KB and totally wrong values are set
corresponding to 8192-2048=6144:
dev.igb.0.fc_low_water: 6128
dev.igb.0.fc_high_water: 6144

One can verify what PBA is set in hardware with enabling verbose boot:
kernel: em_reset: pba=36K
kernel: em_reset: pba=72K

-- 
You are receiving this mail because:
You are the assignee for the bug.