From af0f4f7a042e39bf70fa7406351b26efead18dff Mon Sep 17 00:00:00 2001 From: Pengpeng Hou Date: Sun, 30 Aug 2026 21:44:28 +0800 Subject: ASoC: codecs: sma1307: validate setting firmware layout sma1307_setting_loaded() checks a byte count against an element count, then reads an eight-int header and a fixed default table from the firmware. It also trusts the mode count while indexing a five-entry mode_set array. Validate the byte-to-int conversion, fixed header/default extent, mode count, and exact mode table layout before parsing the setting file. Fixes: 576c57e6b4c1 ("ASoC: sma1307: Add driver for Iron Device SMA1307") Signed-off-by: Pengpeng Hou Link: https://patch.msgid.link/20260830134428.9550-1-pengpeng@iscas.ac.cn Signed-off-by: Mark Brown --- sound/soc/codecs/sma1307.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/sma1307.c b/sound/soc/codecs/sma1307.c index adb369a29b9d..653cbafee23e 100644 --- a/sound/soc/codecs/sma1307.c +++ b/sound/soc/codecs/sma1307.c @@ -1701,7 +1701,9 @@ static void sma1307_setting_loaded(struct sma1307_priv *sma1307, const char *fil __func__, setting_file, ERR_PTR(ret)); sma1307->set.status = false; return; - } else if ((fw->size) < SMA1307_SETTING_HEADER_SIZE) { + } else if (fw->size % sizeof(int) || + fw->size < (SMA1307_SETTING_HEADER_SIZE + + SMA1307_SETTING_DEFAULT_SIZE) * sizeof(int)) { dev_err(sma1307->dev, "%s: Invalid file\n", __func__); sma1307->set.status = false; return; @@ -1720,6 +1722,10 @@ static void sma1307_setting_loaded(struct sma1307_priv *sma1307, const char *fil sma1307->set.checksum = data[sma1307->set.header_size - 2]; sma1307->set.num_mode = data[sma1307->set.header_size - 1]; num_mode = sma1307->set.num_mode; + if (num_mode < 0 || num_mode > ARRAY_SIZE(sma1307->set.mode_set)) { + sma1307->set.status = false; + return; + } sma1307->set.header = devm_kmalloc_array(sma1307->dev, sma1307->set.header_size, sizeof(int), @@ -1755,7 +1761,11 @@ static void sma1307_setting_loaded(struct sma1307_priv *sma1307, const char *fil /* MODE */ offset = sma1307->set.header_size + sma1307->set.def_size; - sma1307->set.mode_size = DIV_ROUND_CLOSEST(size - offset, num_mode + 1); + if ((size - offset) % (num_mode + 1)) { + sma1307->set.status = false; + return; + } + sma1307->set.mode_size = (size - offset) / (num_mode + 1); for (int i = 0; i < num_mode; i++) { sma1307->set.mode_set[i] = devm_kzalloc(sma1307->dev, -- cgit v1.2.3