[PATCH] media: mc: Fix potential media_device lifetime race

Haotian Zhang <[email protected]>
Newsgroups org.kernel.vger.linux-media,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
__media_device_get() traverses the global media_device_list under
media_device_lock and takes a reference on a matching instance with an
unconditional kref_get(). media_device_delete() drops the last
reference with kref_put() outside the lock, so the refcount can reach
zero while the instance is still on the list; if a concurrent
allocate() attempts to acquire a reference from such an instance,
kref_get() operates on a zero refcount while release() is already in
progress. The allocator may then return an instance that release()
subsequently frees, leading to a use-after-free.

Use kref_get_unless_zero() in __media_device_get() when acquiring the
reference. If the reference count has already dropped to zero, release
is in progress, so skip the entry and allocate a fresh instance
instead.

Fixes: 6e1d824e7a1d ("media: Media Device Allocator API")
Signed-off-by: Haotian Zhang <[email protected]>
---
 drivers/media/mc/mc-dev-allocator.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/media/mc/mc-dev-allocator.c b/drivers/media/mc/mc-dev-allocator.c
index ae17887dec59..8b97372adc83 100644
--- a/drivers/media/mc/mc-dev-allocator.c
+++ b/drivers/media/mc/mc-dev-allocator.c
@@ -68,7 +68,8 @@ static struct media_device *__media_device_get(struct device *dev,
 		if (mdi->mdev.dev != dev)
 			continue;
 
-		kref_get(&mdi->refcount);
+		if (!kref_get_unless_zero(&mdi->refcount))
+			continue;
 
 		/* get module reference for the media_device owner */
 		if (owner != mdi->owner && !try_module_get(mdi->owner))
-- 
2.43.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.