Skip to content

Commit e5cfd18

Browse files
committed
rpmsg: char: Add lock to avoid race when rpmsg device is released
JIRA: https://issues.redhat.com/browse/RHEL-78824 commit 17b88a2 Author: Deepak Kumar Singh <quic_deesin@quicinc.com> Date: Mon Sep 19 16:23:59 2022 +0530 rpmsg: char: Add lock to avoid race when rpmsg device is released When remote host goes down glink char device channel is freed and associated rpdev is destroyed through rpmsg_chrdev_eptdev_destroy(), At the same time user space apps can still try to open/poll rpmsg char device which will result in calling rpmsg_create_ept()/rpmsg_poll(). These functions will try to reference rpdev which has already been freed through rpmsg_chrdev_eptdev_destroy(). File operation functions and device removal function must be protected with lock. This patch adds existing ept lock in remove function as well. Signed-off-by: Deepak Kumar Singh <quic_deesin@quicinc.com> Signed-off-by: Bjorn Andersson <andersson@kernel.org> Link: https://lore.kernel.org/r/1663584840-15762-2-git-send-email-quic_deesin@quicinc.com Signed-off-by: Jared Kangas <jkangas@redhat.com>
1 parent d28f3b5 commit e5cfd18

File tree

1 file changed

+8
-0
lines changed

1 file changed

+8
-0
lines changed

drivers/rpmsg/rpmsg_char.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ int rpmsg_chrdev_eptdev_destroy(struct device *dev, void *data)
7575
struct rpmsg_eptdev *eptdev = dev_to_eptdev(dev);
7676

7777
mutex_lock(&eptdev->ept_lock);
78+
eptdev->rpdev = NULL;
7879
if (eptdev->ept) {
7980
/* The default endpoint is released by the rpmsg core */
8081
if (!eptdev->default_ept)
@@ -128,6 +129,11 @@ static int rpmsg_eptdev_open(struct inode *inode, struct file *filp)
128129
return -EBUSY;
129130
}
130131

132+
if (!eptdev->rpdev) {
133+
mutex_unlock(&eptdev->ept_lock);
134+
return -ENETRESET;
135+
}
136+
131137
get_device(dev);
132138

133139
/*
@@ -279,7 +285,9 @@ static __poll_t rpmsg_eptdev_poll(struct file *filp, poll_table *wait)
279285
if (!skb_queue_empty(&eptdev->queue))
280286
mask |= EPOLLIN | EPOLLRDNORM;
281287

288+
mutex_lock(&eptdev->ept_lock);
282289
mask |= rpmsg_poll(eptdev->ept, filp, wait);
290+
mutex_unlock(&eptdev->ept_lock);
283291

284292
return mask;
285293
}

0 commit comments

Comments
 (0)