diff options
| author | Biren Pandya <birenpandya@gmail.com> | 2026-06-21 10:04:37 +0530 |
|---|---|---|
| committer | Hans Verkuil <hverkuil+cisco@kernel.org> | 2026-06-29 16:10:36 +0200 |
| commit | 0fbd5c2327020858c45b2d1c65775d64cdeca523 (patch) | |
| tree | 6c4dcd0911cb4eaf13f5acd67f3768d53abc05d1 | |
| parent | abac9820b26b5cfcb01eb79efe2abdd0ac7e07c3 (diff) | |
| download | linux-0fbd5c2327020858c45b2d1c65775d64cdeca523.tar.gz linux-0fbd5c2327020858c45b2d1c65775d64cdeca523.zip | |
media: cec: disable delayed work before freeing an interrupted transmit
cec_transmit_msg_fh() drops adap->lock to wait for a blocking transmit in
wait_for_completion_killable(). If that wait is interrupted by a signal,
cancel_delayed_work_sync() can run before the CEC kthread arms the reply
timeout via schedule_delayed_work(&data->work) in cec_transmit_done_ts().
The work is then armed after the cancel, and the data is freed with its
delayed_work still pending:
ODEBUG: free active (active state 0) object: ... hint: cec_wait_timeout
Use disable_delayed_work_sync(): it cancels the work and disables it, so
the later schedule_delayed_work() becomes a no-op and the work cannot be
re-armed. The data is freed right after, so it need not be re-enabled.
Fixes: 490d84f6d73c ("media: cec: forgot to cancel delayed work")
Reported-by: syzbot+051024d603432b4ab395@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=051024d603432b4ab395
Suggested-by: Hillf Danton <hdanton@sina.com>
Cc: stable@vger.kernel.org
Signed-off-by: Biren Pandya <birenpandya@gmail.com>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
| -rw-r--r-- | drivers/media/cec/core/cec-adap.c | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/drivers/media/cec/core/cec-adap.c b/drivers/media/cec/core/cec-adap.c index a90cb84a4b4d..829ee4861bf7 100644 --- a/drivers/media/cec/core/cec-adap.c +++ b/drivers/media/cec/core/cec-adap.c @@ -965,7 +965,7 @@ int cec_transmit_msg_fh(struct cec_adapter *adap, struct cec_msg *msg, */ mutex_unlock(&adap->lock); err = wait_for_completion_killable(&data->c); - cancel_delayed_work_sync(&data->work); + disable_delayed_work_sync(&data->work); mutex_lock(&adap->lock); if (err) |
