diff options
author | Wen Yang <wen.yang99@zte.com.cn> | 2019-07-10 03:25:06 -0400 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2019-07-10 11:33:49 -0400 |
commit | 724808ad556c15e9473418d082f8aae81dd267f6 (patch) | |
tree | 2f9ab6505cb421d81c85a6eea73deb4b7e20b1dc /sound/soc/generic | |
parent | 794fcee8da3c0c8a01b08ecad1c181cb0a622868 (diff) |
ASoC: simple-card: fix an use-after-free in simple_dai_link_of_dpcm()
The node variable is still being used after the of_node_put() call,
which may result in use-after-free.
Fixes: cfc652a73331 ("ASoC: simple-card: tidyup prefix for snd_soc_codec_conf")
Link: https://lore.kernel.org/r/1562743509-30496-2-git-send-email-wen.yang99@zte.com.cn
Signed-off-by: Wen Yang <wen.yang99@zte.com.cn>
Acked-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/generic')
-rw-r--r-- | sound/soc/generic/simple-card.c | 22 |
1 files changed, 11 insertions, 11 deletions
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c index e5cde0d5e63c..4117e54884e5 100644 --- a/sound/soc/generic/simple-card.c +++ b/sound/soc/generic/simple-card.c | |||
@@ -124,8 +124,6 @@ static int simple_dai_link_of_dpcm(struct asoc_simple_priv *priv, | |||
124 | 124 | ||
125 | li->link++; | 125 | li->link++; |
126 | 126 | ||
127 | of_node_put(node); | ||
128 | |||
129 | /* For single DAI link & old style of DT node */ | 127 | /* For single DAI link & old style of DT node */ |
130 | if (is_top) | 128 | if (is_top) |
131 | prefix = PREFIX; | 129 | prefix = PREFIX; |
@@ -147,17 +145,17 @@ static int simple_dai_link_of_dpcm(struct asoc_simple_priv *priv, | |||
147 | 145 | ||
148 | ret = asoc_simple_parse_cpu(np, dai_link, &is_single_links); | 146 | ret = asoc_simple_parse_cpu(np, dai_link, &is_single_links); |
149 | if (ret) | 147 | if (ret) |
150 | return ret; | 148 | goto out_put_node; |
151 | 149 | ||
152 | ret = asoc_simple_parse_clk_cpu(dev, np, dai_link, dai); | 150 | ret = asoc_simple_parse_clk_cpu(dev, np, dai_link, dai); |
153 | if (ret < 0) | 151 | if (ret < 0) |
154 | return ret; | 152 | goto out_put_node; |
155 | 153 | ||
156 | ret = asoc_simple_set_dailink_name(dev, dai_link, | 154 | ret = asoc_simple_set_dailink_name(dev, dai_link, |
157 | "fe.%s", | 155 | "fe.%s", |
158 | cpus->dai_name); | 156 | cpus->dai_name); |
159 | if (ret < 0) | 157 | if (ret < 0) |
160 | return ret; | 158 | goto out_put_node; |
161 | 159 | ||
162 | asoc_simple_canonicalize_cpu(dai_link, is_single_links); | 160 | asoc_simple_canonicalize_cpu(dai_link, is_single_links); |
163 | } else { | 161 | } else { |
@@ -180,17 +178,17 @@ static int simple_dai_link_of_dpcm(struct asoc_simple_priv *priv, | |||
180 | 178 | ||
181 | ret = asoc_simple_parse_codec(np, dai_link); | 179 | ret = asoc_simple_parse_codec(np, dai_link); |
182 | if (ret < 0) | 180 | if (ret < 0) |
183 | return ret; | 181 | goto out_put_node; |
184 | 182 | ||
185 | ret = asoc_simple_parse_clk_codec(dev, np, dai_link, dai); | 183 | ret = asoc_simple_parse_clk_codec(dev, np, dai_link, dai); |
186 | if (ret < 0) | 184 | if (ret < 0) |
187 | return ret; | 185 | goto out_put_node; |
188 | 186 | ||
189 | ret = asoc_simple_set_dailink_name(dev, dai_link, | 187 | ret = asoc_simple_set_dailink_name(dev, dai_link, |
190 | "be.%s", | 188 | "be.%s", |
191 | codecs->dai_name); | 189 | codecs->dai_name); |
192 | if (ret < 0) | 190 | if (ret < 0) |
193 | return ret; | 191 | goto out_put_node; |
194 | 192 | ||
195 | /* check "prefix" from top node */ | 193 | /* check "prefix" from top node */ |
196 | snd_soc_of_parse_node_prefix(top, cconf, codecs->of_node, | 194 | snd_soc_of_parse_node_prefix(top, cconf, codecs->of_node, |
@@ -208,19 +206,21 @@ static int simple_dai_link_of_dpcm(struct asoc_simple_priv *priv, | |||
208 | 206 | ||
209 | ret = asoc_simple_parse_tdm(np, dai); | 207 | ret = asoc_simple_parse_tdm(np, dai); |
210 | if (ret) | 208 | if (ret) |
211 | return ret; | 209 | goto out_put_node; |
212 | 210 | ||
213 | ret = asoc_simple_parse_daifmt(dev, node, codec, | 211 | ret = asoc_simple_parse_daifmt(dev, node, codec, |
214 | prefix, &dai_link->dai_fmt); | 212 | prefix, &dai_link->dai_fmt); |
215 | if (ret < 0) | 213 | if (ret < 0) |
216 | return ret; | 214 | goto out_put_node; |
217 | 215 | ||
218 | dai_link->dpcm_playback = 1; | 216 | dai_link->dpcm_playback = 1; |
219 | dai_link->dpcm_capture = 1; | 217 | dai_link->dpcm_capture = 1; |
220 | dai_link->ops = &simple_ops; | 218 | dai_link->ops = &simple_ops; |
221 | dai_link->init = asoc_simple_dai_init; | 219 | dai_link->init = asoc_simple_dai_init; |
222 | 220 | ||
223 | return 0; | 221 | out_put_node: |
222 | of_node_put(node); | ||
223 | return ret; | ||
224 | } | 224 | } |
225 | 225 | ||
226 | static int simple_dai_link_of(struct asoc_simple_priv *priv, | 226 | static int simple_dai_link_of(struct asoc_simple_priv *priv, |