| From f730a46b931d894816af34a0ff8e4ad51565b39f Mon Sep 17 00:00:00 2001 |
| From: Xiaomeng Tong <xiam0nd.tong@gmail.com> |
| Date: Tue, 29 Mar 2022 09:21:34 +0800 |
| Subject: ASoC: soc-dapm: fix two incorrect uses of list iterator |
| |
| From: Xiaomeng Tong <xiam0nd.tong@gmail.com> |
| |
| commit f730a46b931d894816af34a0ff8e4ad51565b39f upstream. |
| |
| These two bug are here: |
| list_for_each_entry_safe_continue(w, n, list, |
| power_list); |
| list_for_each_entry_safe_continue(w, n, list, |
| power_list); |
| |
| After the list_for_each_entry_safe_continue() exits, the list iterator |
| will always be a bogus pointer which point to an invalid struct objdect |
| containing HEAD member. The funciton poniter 'w->event' will be a |
| invalid value which can lead to a control-flow hijack if the 'w' can be |
| controlled. |
| |
| The original intention was to continue the outer list_for_each_entry_safe() |
| loop with the same entry if w->event is NULL, but misunderstanding the |
| meaning of list_for_each_entry_safe_continue(). |
| |
| So just add a 'continue;' to fix the bug. |
| |
| Cc: stable@vger.kernel.org |
| Fixes: 163cac061c973 ("ASoC: Factor out DAPM sequence execution") |
| Signed-off-by: Xiaomeng Tong <xiam0nd.tong@gmail.com> |
| Link: https://lore.kernel.org/r/20220329012134.9375-1-xiam0nd.tong@gmail.com |
| Signed-off-by: Mark Brown <broonie@kernel.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| sound/soc/soc-dapm.c | 6 ++---- |
| 1 file changed, 2 insertions(+), 4 deletions(-) |
| |
| --- a/sound/soc/soc-dapm.c |
| +++ b/sound/soc/soc-dapm.c |
| @@ -1569,8 +1569,7 @@ static void dapm_seq_run(struct snd_soc_ |
| switch (w->id) { |
| case snd_soc_dapm_pre: |
| if (!w->event) |
| - list_for_each_entry_safe_continue(w, n, list, |
| - power_list); |
| + continue; |
| |
| if (event == SND_SOC_DAPM_STREAM_START) |
| ret = w->event(w, |
| @@ -1582,8 +1581,7 @@ static void dapm_seq_run(struct snd_soc_ |
| |
| case snd_soc_dapm_post: |
| if (!w->event) |
| - list_for_each_entry_safe_continue(w, n, list, |
| - power_list); |
| + continue; |
| |
| if (event == SND_SOC_DAPM_STREAM_START) |
| ret = w->event(w, |