Messages in this thread Patch in this message | | | From | Greg Kroah-Hartman <> | Subject | [PATCH 5.8 034/177] soundwire: fix double free of dangling pointer | Date | Tue, 15 Sep 2020 16:11:45 +0200 |
| |
From: Tom Rix <trix@redhat.com>
[ Upstream commit 3fbbf2148a406b3e350fe91e6fdd78eb42ecad24 ]
clang static analysis flags this problem
stream.c:844:9: warning: Use of memory after it is freed kfree(bus->defer_msg.msg->buf); ^~~~~~~~~~~~~~~~~~~~~~~
This happens in an error handler cleaning up memory allocated for elements in a list.
list_for_each_entry(m_rt, &stream->master_list, stream_node) { bus = m_rt->bus;
kfree(bus->defer_msg.msg->buf); kfree(bus->defer_msg.msg); }
And is triggered when the call to sdw_bank_switch() fails. There are a two problems.
First, when sdw_bank_switch() fails, though it frees memory it does not clear bus's reference 'defer_msg.msg' to that memory.
The second problem is the freeing msg->buf. In some cases msg will be NULL so this will dereference a null pointer. Need to check before freeing.
Fixes: 99b8a5d608a6 ("soundwire: Add bank switch routine") Signed-off-by: Tom Rix <trix@redhat.com> Reviewed-by: Nick Desaulniers <ndesaulniers@google.com> Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Link: https://lore.kernel.org/r/20200902202650.14189-1-trix@redhat.com Signed-off-by: Vinod Koul <vkoul@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org> --- drivers/soundwire/stream.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/soundwire/stream.c b/drivers/soundwire/stream.c index a9a72574b34ab..684761e86d4fc 100644 --- a/drivers/soundwire/stream.c +++ b/drivers/soundwire/stream.c @@ -716,6 +716,7 @@ error: kfree(wbuf); error_1: kfree(wr_msg); + bus->defer_msg.msg = NULL; return ret; } @@ -839,9 +840,10 @@ static int do_bank_switch(struct sdw_stream_runtime *stream) error: list_for_each_entry(m_rt, &stream->master_list, stream_node) { bus = m_rt->bus; - - kfree(bus->defer_msg.msg->buf); - kfree(bus->defer_msg.msg); + if (bus->defer_msg.msg) { + kfree(bus->defer_msg.msg->buf); + kfree(bus->defer_msg.msg); + } } msg_unlock: -- 2.25.1
| |