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

"Shengzhuo Wei" <[email protected]>
Newsgroups org.kernel.vger.linux-wireless,org.kernel.vger.linux-kernel,org.kernel.vger.stable
Message-ID <[email protected]>
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: [email protected]
Assisted-by: GLM:5.3
Signed-off-by: Shengzhuo Wei <[email protected]>
---
 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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.