diff options
| author | Pengpeng Hou <pengpeng@iscas.ac.cn> | 2026-08-30 21:44:28 +0800 |
|---|---|---|
| committer | Mark Brown <broonie@kernel.org> | 2026-09-09 12:38:08 +0100 |
| commit | af0f4f7a042e39bf70fa7406351b26efead18dff (patch) | |
| tree | fd6252b1507d0de7e0ac21e1b8e590a4694a29f7 | |
| parent | 8fa5ce4e95bda6d3a90761d07d171f9e3f2f9328 (diff) | |
| download | linux-next-af0f4f7a042e39bf70fa7406351b26efead18dff.tar.gz linux-next-af0f4f7a042e39bf70fa7406351b26efead18dff.zip | |
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 <pengpeng@iscas.ac.cn>
Link: https://patch.msgid.link/20260830134428.9550-1-pengpeng@iscas.ac.cn
Signed-off-by: Mark Brown <broonie@kernel.org>
| -rw-r--r-- | sound/soc/codecs/sma1307.c | 14 |
1 files 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, |
