| From fff694b89df2479cd1c46076a69ac3294a602001 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Mon, 16 May 2022 17:20:35 +0800 |
| Subject: ASoC: rt5645: Fix errorenous cleanup order |
| |
| From: Lin Ma <linma@zju.edu.cn> |
| |
| [ Upstream commit 2def44d3aec59e38d2701c568d65540783f90f2f ] |
| |
| There is a logic error when removing rt5645 device as the function |
| rt5645_i2c_remove() first cancel the &rt5645->jack_detect_work and |
| delete the &rt5645->btn_check_timer latter. However, since the timer |
| handler rt5645_btn_check_callback() will re-queue the jack_detect_work, |
| this cleanup order is buggy. |
| |
| That is, once the del_timer_sync in rt5645_i2c_remove is concurrently |
| run with the rt5645_btn_check_callback, the canceled jack_detect_work |
| will be rescheduled again, leading to possible use-after-free. |
| |
| This patch fix the issue by placing the del_timer_sync function before |
| the cancel_delayed_work_sync. |
| |
| Signed-off-by: Lin Ma <linma@zju.edu.cn> |
| Link: https://lore.kernel.org/r/20220516092035.28283-1-linma@zju.edu.cn |
| Signed-off-by: Mark Brown <broonie@kernel.org> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| sound/soc/codecs/rt5645.c | 6 ++++++ |
| 1 file changed, 6 insertions(+) |
| |
| diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c |
| index 1ac96ef9ee20..703b26ec4e15 100644 |
| --- a/sound/soc/codecs/rt5645.c |
| +++ b/sound/soc/codecs/rt5645.c |
| @@ -3878,6 +3878,12 @@ static int rt5645_i2c_remove(struct i2c_client *i2c) |
| if (i2c->irq) |
| free_irq(i2c->irq, rt5645); |
| |
| + /* |
| + * Since the rt5645_btn_check_callback() can queue jack_detect_work, |
| + * the timer need to be delted first |
| + */ |
| + del_timer_sync(&rt5645->btn_check_timer); |
| + |
| cancel_delayed_work_sync(&rt5645->jack_detect_work); |
| cancel_delayed_work_sync(&rt5645->rcclock_work); |
| |
| -- |
| 2.35.1 |
| |