[PATCH 1/2] wifi: p54: validate curve data length in p54_parse_eeprom()

From: Shengzhuo Wei

Date: Wed Aug 26 2026 - 13:09:35 EST


p54_convert_rev0() and p54_convert_rev1() walk
channels * (2 + points_per_channel * sizeof(sample)) bytes of the
curve data entry, with both counts taken verbatim from the
device-supplied EEPROM. An entry that declares channels=255,
points_per_channel=255 but carries only the 4-byte header drives a
~191 KB slab-out-of-bounds read past the EEPROM buffer (verified with
a KASAN reproducer of the conversion loop). The sibling converters
p54_convert_output_limits() and p54_convert_db() already validate
their counts against the entry length; this path was missed.

Reject the entry when the counts do not fit in the entry data.

Fixes: eff1a59c48e3 ("[P54]: add mac80211-based driver for prism54 softmac hardware")
Cc: stable@xxxxxxxxxxxxxxx
Assisted-by: GLM:5.3
Signed-off-by: Shengzhuo Wei <me@xxxxxxxx>
---
drivers/net/wireless/intersil/p54/eeprom.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)

diff --git a/drivers/net/wireless/intersil/p54/eeprom.c b/drivers/net/wireless/intersil/p54/eeprom.c
index 95580921d933827c5eac55b79404e26bd7a57ba4..968ce9a411358e0e6b83117b1a077becc3207090 100644
--- a/drivers/net/wireless/intersil/p54/eeprom.c
+++ b/drivers/net/wireless/intersil/p54/eeprom.c
@@ -763,6 +763,8 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
case PDR_PRISM_PA_CAL_CURVE_DATA: {
struct pda_pa_curve_data *curve_data =
(struct pda_pa_curve_data *)entry->data;
+ size_t needed;
+
if (data_len < sizeof(*curve_data)) {
err = -EINVAL;
goto err;
@@ -770,9 +772,23 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)

switch (curve_data->cal_method_rev) {
case 0:
+ needed = curve_data->channels *
+ (sizeof(struct pda_pa_curve_data_sample_rev0) *
+ curve_data->points_per_channel + 2);
+ if (data_len - sizeof(*curve_data) < needed) {
+ err = -EINVAL;
+ goto err;
+ }
err = p54_convert_rev0(dev, curve_data);
break;
case 1:
+ needed = curve_data->channels *
+ (sizeof(struct pda_pa_curve_data_sample_rev1) *
+ curve_data->points_per_channel + 3);
+ if (data_len - sizeof(*curve_data) < needed) {
+ err = -EINVAL;
+ goto err;
+ }
err = p54_convert_rev1(dev, curve_data);
break;
default:

--
2.47.3