mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] HSI: hsi_char: Fix use-after-free on device removal
@ 2026-08-26 20:43 Shengzhuo Wei
  2026-08-27  4:48 ` Greg KH
  0 siblings, 1 reply; 6+ messages in thread
From: Shengzhuo Wei @ 2026-08-26 20:43 UTC (permalink / raw)
  To: sre, kees, linux-kernel, Andras Domokos, Carlos Chinea
  Cc: stable, Shengzhuo Wei

hsc_open() stores a pointer to a channel embedded in the hsc_client_data
in file->private_data, but hsc_remove() frees the whole hsc_client_data
right after cdev_del(). If the HSI client device is removed while a
channel is open, the next access from the file descriptor (a read, an
ioctl or the final close) dereferences freed memory:

CPU0                                CPU1
hsc_remove                          hsc_read
  cdev_del(&cl_data->cdev);           channel->cl->rx_cfg ...
  kfree(cl_data);                     // use after free

Fix it by tracking the hsc_client_data with a kref: each open file
descriptor takes a reference, and hsc_remove() drops the initial one,
so the object is freed only after the last descriptor is closed.

Fixes: 4e69fc22753f ("HSI: hsi_char: Add HSI char device driver")
Cc: stable@vger.kernel.org
Signed-off-by: Shengzhuo Wei <me@cherr.cc>
---
 drivers/hsi/clients/hsi_char.c | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/hsi/clients/hsi_char.c b/drivers/hsi/clients/hsi_char.c
index a31cc1466dd3ddf73762ce3d0213c96d64a190fd..479e5d6e94c8c03489464c4b39d81d697d104ce0 100644
--- a/drivers/hsi/clients/hsi_char.c
+++ b/drivers/hsi/clients/hsi_char.c
@@ -96,6 +96,7 @@ struct hsc_channel {
  * @usecnt: Use count for claiming the HSI port (mutex protected)
  * @cl: Referece to the HSI client
  * @channels: Array of channels accessible by the client
+ * @kref: Reference count for the client data lifetime
  */
 struct hsc_client_data {
 	struct cdev		cdev;
@@ -104,6 +105,7 @@ struct hsc_client_data {
 	unsigned int		usecnt;
 	struct hsi_client	*cl;
 	struct hsc_channel	channels[HSC_DEVS];
+	struct kref		kref;
 };
 
 /* Stores the major number dynamically allocated for hsi_char */
@@ -576,6 +578,11 @@ static long hsc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 	return ret;
 }
 
+static void hsc_client_data_release(struct kref *kref)
+{
+	kfree(container_of(kref, struct hsc_client_data, kref));
+}
+
 static inline void __hsc_port_release(struct hsc_client_data *cl_data)
 {
 	BUG_ON(cl_data->usecnt == 0);
@@ -613,10 +620,12 @@ static int hsc_open(struct inode *inode, struct file *file)
 		hsi_setup(cl_data->cl);
 	}
 	cl_data->usecnt++;
+	kref_get(&cl_data->kref);
 
 	ret = hsc_msgs_alloc(channel);
 	if (ret < 0) {
 		__hsc_port_release(cl_data);
+		kref_put(&cl_data->kref, hsc_client_data_release);
 		goto out;
 	}
 
@@ -650,6 +659,8 @@ static int hsc_release(struct inode *inode __maybe_unused, struct file *file)
 	wake_up(&channel->tx_wait);
 	mutex_unlock(&cl_data->lock);
 
+	kref_put(&cl_data->kref, hsc_client_data_release);
+
 	return 0;
 }
 
@@ -703,6 +714,7 @@ static int hsc_probe(struct device *dev)
 		goto out1;
 	}
 	mutex_init(&cl_data->lock);
+	kref_init(&cl_data->kref);
 	hsi_client_set_drvdata(cl, cl_data);
 	cdev_init(&cl_data->cdev, &hsc_fops);
 	cl_data->cdev.owner = THIS_MODULE;
@@ -739,7 +751,7 @@ static int hsc_remove(struct device *dev)
 	cdev_del(&cl_data->cdev);
 	unregister_chrdev_region(hsc_dev, HSC_DEVS);
 	hsi_client_set_drvdata(cl, NULL);
-	kfree(cl_data);
+	kref_put(&cl_data->kref, hsc_client_data_release);
 
 	return 0;
 }

---
base-commit: 45c13f3f9e3bb15fd89ff2864c6f627a3b4b4229
change-id: 20260827-hsi-char-uaf-4013a742dcd9

Best regards,
-- 
Shengzhuo Wei <me@cherr.cc>

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2026-08-27  5:45 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-08-26 20:43 [PATCH] HSI: hsi_char: Fix use-after-free on device removal Shengzhuo Wei
2026-08-27  4:48 ` Greg KH
2026-08-27  5:09   ` Shengzhuo Wei
2026-08-27  5:15     ` Greg KH
2026-08-27  5:40       ` Shengzhuo Wei
2026-08-27  5:43         ` Greg KH

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®