[PATCH v3 1/6] ethdev: fix out-of-bounds read of SFF-8636 thresholds
Roman Khromenok
roma55592 at yandex.ru
Tue Sep 29 09:07:29 CEST 2026
The SFF-8636 decoder reads the alarm and warning thresholds
from page 03h (offsets 0x200 to 0x247) unconditionally,
but they are printed only if the EEPROM data is 640 bytes long.
The telemetry command /ethdev/module_eeprom allocates exactly
the length reported by the driver, and several drivers report
256 bytes for QSFP modules, for example i40e for SFF-8436
and bnxt for flat memory QSFP28.
On such ports, the command reads past the end of the heap buffer.
Read the thresholds only when they are going to be printed.
Fixes: c42754fd581a ("ethdev: support SFF-8636 module telemetry")
Cc: stable at dpdk.org
Signed-off-by: Roman Khromenok <roma55592 at yandex.ru>
---
v3: new patch, split from the length checks to be backported
.mailmap | 1 +
lib/ethdev/sff_8636.c | 52 ++++++++++++++++++++++---------------------
2 files changed, 28 insertions(+), 25 deletions(-)
diff --git a/.mailmap b/.mailmap
index 57f7a9f87a..45d4e92fbd 100644
--- a/.mailmap
+++ b/.mailmap
@@ -1445,6 +1445,7 @@ Romain Delhomel <romain.delhomel at 6wind.com>
Roman Dementiev <roman.dementiev at intel.com>
Roman Fridlyand <roman.fridlyand at intel.com>
Roman Kapl <rka at sysgo.com>
+Roman Khromenok <roma55592 at yandex.ru>
Roman Korynkevych <romanx.korynkevych at intel.com>
Roman Storozhenko <roman.storozhenko at intel.com>
Roman Zhukov <roman.zhukov at arknetworks.am> <roman.zhukov at oktetlabs.ru>
diff --git a/lib/ethdev/sff_8636.c b/lib/ethdev/sff_8636.c
index 6b65f47efe..9dfff41a3b 100644
--- a/lib/ethdev/sff_8636.c
+++ b/lib/ethdev/sff_8636.c
@@ -600,34 +600,36 @@ static void sff_8636_dom_parse(const uint8_t *data, struct sff_diags *sd)
{
int i = 0;
- /* Monitoring Thresholds for Alarms and Warnings */
sd->sfp_voltage[SFF_MCURR] = SFF_OFFSET_TO_U16(SFF_8636_VCC_CURR);
- sd->sfp_voltage[SFF_HALRM] = SFF_OFFSET_TO_U16(SFF_8636_VCC_HALRM);
- sd->sfp_voltage[SFF_LALRM] = SFF_OFFSET_TO_U16(SFF_8636_VCC_LALRM);
- sd->sfp_voltage[SFF_HWARN] = SFF_OFFSET_TO_U16(SFF_8636_VCC_HWARN);
- sd->sfp_voltage[SFF_LWARN] = SFF_OFFSET_TO_U16(SFF_8636_VCC_LWARN);
-
sd->sfp_temp[SFF_MCURR] = SFF_8636_OFFSET_TO_TEMP(SFF_8636_TEMP_CURR);
- sd->sfp_temp[SFF_HALRM] = SFF_8636_OFFSET_TO_TEMP(SFF_8636_TEMP_HALRM);
- sd->sfp_temp[SFF_LALRM] = SFF_8636_OFFSET_TO_TEMP(SFF_8636_TEMP_LALRM);
- sd->sfp_temp[SFF_HWARN] = SFF_8636_OFFSET_TO_TEMP(SFF_8636_TEMP_HWARN);
- sd->sfp_temp[SFF_LWARN] = SFF_8636_OFFSET_TO_TEMP(SFF_8636_TEMP_LWARN);
-
- sd->bias_cur[SFF_HALRM] = SFF_OFFSET_TO_U16(SFF_8636_TX_BIAS_HALRM);
- sd->bias_cur[SFF_LALRM] = SFF_OFFSET_TO_U16(SFF_8636_TX_BIAS_LALRM);
- sd->bias_cur[SFF_HWARN] = SFF_OFFSET_TO_U16(SFF_8636_TX_BIAS_HWARN);
- sd->bias_cur[SFF_LWARN] = SFF_OFFSET_TO_U16(SFF_8636_TX_BIAS_LWARN);
-
- sd->tx_power[SFF_HALRM] = SFF_OFFSET_TO_U16(SFF_8636_TX_PWR_HALRM);
- sd->tx_power[SFF_LALRM] = SFF_OFFSET_TO_U16(SFF_8636_TX_PWR_LALRM);
- sd->tx_power[SFF_HWARN] = SFF_OFFSET_TO_U16(SFF_8636_TX_PWR_HWARN);
- sd->tx_power[SFF_LWARN] = SFF_OFFSET_TO_U16(SFF_8636_TX_PWR_LWARN);
-
- sd->rx_power[SFF_HALRM] = SFF_OFFSET_TO_U16(SFF_8636_RX_PWR_HALRM);
- sd->rx_power[SFF_LALRM] = SFF_OFFSET_TO_U16(SFF_8636_RX_PWR_LALRM);
- sd->rx_power[SFF_HWARN] = SFF_OFFSET_TO_U16(SFF_8636_RX_PWR_HWARN);
- sd->rx_power[SFF_LWARN] = SFF_OFFSET_TO_U16(SFF_8636_RX_PWR_LWARN);
+ /* Monitoring Thresholds for Alarms and Warnings are in page 03h */
+ if (sd->supports_alarms) {
+ sd->sfp_voltage[SFF_HALRM] = SFF_OFFSET_TO_U16(SFF_8636_VCC_HALRM);
+ sd->sfp_voltage[SFF_LALRM] = SFF_OFFSET_TO_U16(SFF_8636_VCC_LALRM);
+ sd->sfp_voltage[SFF_HWARN] = SFF_OFFSET_TO_U16(SFF_8636_VCC_HWARN);
+ sd->sfp_voltage[SFF_LWARN] = SFF_OFFSET_TO_U16(SFF_8636_VCC_LWARN);
+
+ sd->sfp_temp[SFF_HALRM] = SFF_8636_OFFSET_TO_TEMP(SFF_8636_TEMP_HALRM);
+ sd->sfp_temp[SFF_LALRM] = SFF_8636_OFFSET_TO_TEMP(SFF_8636_TEMP_LALRM);
+ sd->sfp_temp[SFF_HWARN] = SFF_8636_OFFSET_TO_TEMP(SFF_8636_TEMP_HWARN);
+ sd->sfp_temp[SFF_LWARN] = SFF_8636_OFFSET_TO_TEMP(SFF_8636_TEMP_LWARN);
+
+ sd->bias_cur[SFF_HALRM] = SFF_OFFSET_TO_U16(SFF_8636_TX_BIAS_HALRM);
+ sd->bias_cur[SFF_LALRM] = SFF_OFFSET_TO_U16(SFF_8636_TX_BIAS_LALRM);
+ sd->bias_cur[SFF_HWARN] = SFF_OFFSET_TO_U16(SFF_8636_TX_BIAS_HWARN);
+ sd->bias_cur[SFF_LWARN] = SFF_OFFSET_TO_U16(SFF_8636_TX_BIAS_LWARN);
+
+ sd->tx_power[SFF_HALRM] = SFF_OFFSET_TO_U16(SFF_8636_TX_PWR_HALRM);
+ sd->tx_power[SFF_LALRM] = SFF_OFFSET_TO_U16(SFF_8636_TX_PWR_LALRM);
+ sd->tx_power[SFF_HWARN] = SFF_OFFSET_TO_U16(SFF_8636_TX_PWR_HWARN);
+ sd->tx_power[SFF_LWARN] = SFF_OFFSET_TO_U16(SFF_8636_TX_PWR_LWARN);
+
+ sd->rx_power[SFF_HALRM] = SFF_OFFSET_TO_U16(SFF_8636_RX_PWR_HALRM);
+ sd->rx_power[SFF_LALRM] = SFF_OFFSET_TO_U16(SFF_8636_RX_PWR_LALRM);
+ sd->rx_power[SFF_HWARN] = SFF_OFFSET_TO_U16(SFF_8636_RX_PWR_HWARN);
+ sd->rx_power[SFF_LWARN] = SFF_OFFSET_TO_U16(SFF_8636_RX_PWR_LWARN);
+ }
/* Channel Specific Data */
for (i = 0; i < SFF_MAX_CHANNEL_NUM; i++) {
--
2.47.3
More information about the stable
mailing list