History

ASoC: qcom: common: validate cpu dai id during parsing

lpass ports numbers have been added but the afe/apm driver never got updated with new max port value that it uses to store dai specific data. There are more than one places these values are cached and always become out of sync. This will result in array out of bounds and weird driver behaviour. To catch such issues, first add a single place where we can define max port and second add a check in common parsing code which can error out before corrupting the memory with out of bounds array access. This should help both avoid and catch these type of mistakes in future.

Srinivas Kandagatla committed 7 months ago

Commit d49ee8f1 parent e46957f5 files · +15 −3Browse files

Unified · Split

5 files
  1. sound/soc/qcom/common.c +6 −0
  2. sound/soc/qcom/common.h +3 −0
  3. sound/soc/qcom/lpass.h +2 −1
  4. sound/soc/qcom/qdsp6/q6afe.h +2 −1
  5. sound/soc/qcom/qdsp6/q6apm.h +2 −1
sound/soc/qcom/common.c+6−0
@@ -120,6 +120,12 @@ int qcom_snd_parse_of(struct snd_soc_card *card) · 119 unmodified lines
120 120
121 link->id = args.args[0];121 link->id = args.args[0];
122 122
123 if (link->id >= LPASS_MAX_PORT) {
124 dev_err(dev, "%s: Invalid cpu dai id %d\n", link->name, link->id);
125 ret = -EINVAL;
126 goto err;
127 }
128
123 if (platform) {129 if (platform) {
124 link->platforms->of_node = of_parse_phandle(platform,130 link->platforms->of_node = of_parse_phandle(platform,
125 "sound-dai",131 "sound-dai",
sound/soc/qcom/common.h+3−0
@@ -4,8 +4,11 @@ · 3 unmodified lines
4#ifndef __QCOM_SND_COMMON_H__4#ifndef __QCOM_SND_COMMON_H__
5#define __QCOM_SND_COMMON_H__5#define __QCOM_SND_COMMON_H__
6 6
7#include <dt-bindings/sound/qcom,q6afe.h>
7#include <sound/soc.h>8#include <sound/soc.h>
8 9
10#define LPASS_MAX_PORT (SENARY_MI2S_TX + 1)
11
9int qcom_snd_parse_of(struct snd_soc_card *card);12int qcom_snd_parse_of(struct snd_soc_card *card);
10int qcom_snd_wcd_jack_setup(struct snd_soc_pcm_runtime *rtd,13int qcom_snd_wcd_jack_setup(struct snd_soc_pcm_runtime *rtd,
11 struct snd_soc_jack *jack, bool *jack_setup);14 struct snd_soc_jack *jack, bool *jack_setup);
sound/soc/qcom/lpass.h+2−1
@@ -14,10 +14,11 @@ · 13 unmodified lines
14#include <linux/regmap.h>14#include <linux/regmap.h>
15#include <dt-bindings/sound/qcom,lpass.h>15#include <dt-bindings/sound/qcom,lpass.h>
16#include <dt-bindings/sound/qcom,q6afe.h>16#include <dt-bindings/sound/qcom,q6afe.h>
17#include "common.h"
17#include "lpass-hdmi.h"18#include "lpass-hdmi.h"
18 19
19#define LPASS_AHBIX_CLOCK_FREQUENCY 13107200020#define LPASS_AHBIX_CLOCK_FREQUENCY 131072000
20#define LPASS_MAX_PORTS (DISPLAY_PORT_RX_7 + 1)21#define LPASS_MAX_PORTS (LPASS_MAX_PORT)
21#define LPASS_MAX_MI2S_PORTS (8)22#define LPASS_MAX_MI2S_PORTS (8)
22#define LPASS_MAX_DMA_CHANNELS (8)23#define LPASS_MAX_DMA_CHANNELS (8)
23#define LPASS_MAX_HDMI_DMA_CHANNELS (4)24#define LPASS_MAX_HDMI_DMA_CHANNELS (4)
sound/soc/qcom/qdsp6/q6afe.h+2−1
@@ -2,8 +2,9 @@ · 1 unmodified line
2 2
3#ifndef __Q6AFE_H__3#ifndef __Q6AFE_H__
4#define __Q6AFE_H__4#define __Q6AFE_H__
5#include "../common.h"
5 6
6#define AFE_PORT_MAX 1377#define AFE_PORT_MAX (LPASS_MAX_PORT)
7 8
8#define MSM_AFE_PORT_TYPE_RX 09#define MSM_AFE_PORT_TYPE_RX 0
9#define MSM_AFE_PORT_TYPE_TX 110#define MSM_AFE_PORT_TYPE_TX 1
sound/soc/qcom/qdsp6/q6apm.h+2−1
@@ -14,9 +14,10 @@ · 13 unmodified lines
14#include <linux/of_platform.h>14#include <linux/of_platform.h>
15#include <linux/jiffies.h>15#include <linux/jiffies.h>
16#include <linux/soc/qcom/apr.h>16#include <linux/soc/qcom/apr.h>
17#include "../common.h"
17#include "audioreach.h"18#include "audioreach.h"
18 19
19#define APM_PORT_MAX 12720#define APM_PORT_MAX LPASS_MAX_PORT
20#define APM_PORT_MAX_AUDIO_CHAN_CNT 821#define APM_PORT_MAX_AUDIO_CHAN_CNT 8
21#define PCM_CHANNEL_NULL 022#define PCM_CHANNEL_NULL 0
22#define PCM_CHANNEL_FL 1 /* Front left channel. */23#define PCM_CHANNEL_FL 1 /* Front left channel. */