Re: [Linux Kernel Bugs] KASAN: slab-use-after-free Read in cec_queue_msg_fh and 4 other crashes in the cec device (`cec_ioctl`)

From: Hans Verkuil
Date: Thu Jan 25 2024 - 05:35:35 EST


Hi Chenyuan,

On 24/01/2024 14:33, Yang, Chenyuan wrote:
> Hi Hans,
>
> Thanks for your prompt response!
>
> After applying the new patch, the system hang issue persists. I also tested with the latest Linux version, but the problem remains. The error displayed is 'INFO: task syz-executor372:16736 blocked for more than 143 seconds.' Could it be that the timeout setting for the CEC is too extensive, contributing to this hang?

Again, thank you for testing this.

After investigation I suspect the issue is elsewhere.

Can you test with the patch below instead?

Thank you!

Hans

Signed-off-by: Hans Verkuil <hverkuil-cisco@xxxxxxxxx>
---
diff --git a/drivers/media/cec/core/cec-adap.c b/drivers/media/cec/core/cec-adap.c
index 079c3b142d91..e5c86bc5ed93 100644
--- a/drivers/media/cec/core/cec-adap.c
+++ b/drivers/media/cec/core/cec-adap.c
@@ -1562,10 +1562,12 @@ static int cec_config_thread_func(void *arg)
cec_transmit_msg_fh(adap, &msg, NULL, false);
}
}
+ mutex_unlock(&adap->lock);
+ call_void_op(adap, configured);
+ mutex_lock(&adap->lock);
adap->kthread_config = NULL;
complete(&adap->config_completion);
mutex_unlock(&adap->lock);
- call_void_op(adap, configured);
return 0;

unconfigure:
@@ -1591,6 +1593,12 @@ static void cec_claim_log_addrs(struct cec_adapter *adap, bool block)
if (WARN_ON(adap->is_configuring || adap->is_configured))
return;

+ if (adap->kthread_config) {
+ mutex_unlock(&adap->lock);
+ wait_for_completion(&adap->config_completion);
+ mutex_lock(&adap->lock);
+ }
+
init_completion(&adap->config_completion);

/* Ready to kick off the thread */
@@ -1598,8 +1606,8 @@ static void cec_claim_log_addrs(struct cec_adapter *adap, bool block)
adap->kthread_config = kthread_run(cec_config_thread_func, adap,
"ceccfg-%s", adap->name);
if (IS_ERR(adap->kthread_config)) {
- adap->kthread_config = NULL;
adap->is_configuring = false;
+ adap->kthread_config = NULL;
} else if (block) {
mutex_unlock(&adap->lock);
wait_for_completion(&adap->config_completion);