[PATCH] most: cdev: Initialize channel state before registering cdev
From: Runyu Xiao
Date: Thu Sep 10 2026 - 05:26:37 EST
comp_probe() registers the channel cdev before initializing c->cfg,
c->io_mutex, and the other state used by channel_fops. cdev_add() makes
the cdev live immediately, so an open through the registered device can
reach comp_open() while the channel is only partially initialized.
Initialize the channel state and allocate its FIFO before calling
cdev_add(). Release the FIFO if registering the cdev fails.
Fixes: ceea93444808 ("drivers: most: add character device interface driver")
Cc: stable@xxxxxxxxxxxxxxx
Assisted-by: LLM Codex
Signed-off-by: Runyu Xiao <runyu.xiao@xxxxxxxxxx>
---
drivers/most/most_cdev.c | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/drivers/most/most_cdev.c b/drivers/most/most_cdev.c
index 5df508d8d..75b413359 100644
--- a/drivers/most/most_cdev.c
+++ b/drivers/most/most_cdev.c
@@ -441,20 +441,22 @@ static int comp_probe(struct most_interface *iface, int channel_id,
c->devno = MKDEV(comp.major, current_minor);
cdev_init(&c->cdev, &channel_fops);
c->cdev.owner = THIS_MODULE;
- retval = cdev_add(&c->cdev, c->devno, 1);
- if (retval < 0)
- goto err_free_c;
c->iface = iface;
c->cfg = cfg;
c->channel_id = channel_id;
c->access_ref = 0;
spin_lock_init(&c->unlink);
INIT_KFIFO(c->fifo);
- retval = kfifo_alloc(&c->fifo, cfg->num_buffers, GFP_KERNEL);
- if (retval)
- goto err_del_cdev_and_free_channel;
init_waitqueue_head(&c->wq);
mutex_init(&c->io_mutex);
+ retval = kfifo_alloc(&c->fifo, cfg->num_buffers, GFP_KERNEL);
+ if (retval)
+ goto err_free_c;
+ retval = cdev_add(&c->cdev, c->devno, 1);
+ if (retval < 0) {
+ kfifo_free(&c->fifo);
+ goto err_free_c;
+ }
spin_lock_irqsave(&ch_list_lock, cl_flags);
list_add_tail(&c->list, &channel_list);
spin_unlock_irqrestore(&ch_list_lock, cl_flags);
@@ -470,7 +472,6 @@ static int comp_probe(struct most_interface *iface, int channel_id,
err_free_kfifo_and_del_list:
kfifo_free(&c->fifo);
list_del(&c->list);
-err_del_cdev_and_free_channel:
cdev_del(&c->cdev);
err_free_c:
kfree(c);
--
2.34.1