From: "Cen Zhang (Microsoft)" <blbllhy@gmail.com>
To: mchehab@kernel.org, linux-media@vger.kernel.org
Cc: kees@kernel.org, linux-kernel@vger.kernel.org,
AutonomousCodeSecurity@microsoft.com,
tgopinath@linux.microsoft.com, kys@microsoft.com,
blbllhy@gmail.com, stable@vger.kernel.org
Subject: [PATCH v2] media: v4l2-event: limit number of event subscriptions per file handle
Date: Wed, 22 Jul 2026 00:23:08 -0400 [thread overview]
Message-ID: <20260722042308.75939-1-blbllhy@gmail.com> (raw)
v4l2_event_subscribe() allows an unbounded number of event subscriptions
per file handle. Since the subscription id field is fully user-controlled
(32-bit), an unprivileged user with access to a V4L2 device node can
create up to 2^32 distinct subscriptions, each pinning a kernel
allocation (~200 bytes). This can exhaust kernel memory, causing an OOM
condition and kernel panic.
An unprivileged local user can trigger this by issuing repeated
VIDIOC_SUBSCRIBE_EVENT ioctls with incrementing id values. The allocated
objects reside in kernel slab (not accounted to the process cgroup), so
existing memory limits (ulimit, memcg) do not prevent this. Most V4L2
drivers are affected because the framework function v4l2_event_subscribe()
enforces no limit, such as uvcvideo (USB webcams) and the vicodec test
driver used to reproduce this issue. This leads to:
Kernel panic - not syncing: Out of memory: compulsory panic_on_oom
is enabled
Fix by adding a per-filehandle subscription counter and capping it at 256.
Fixes: 6e239399e580 ("[media] v4l2-ctrls: add control events")
Cc: stable@vger.kernel.org
Reported-by: Autonomous Code Security <AutonomousCodeSecurity@microsoft.com>
Link: https://lore.kernel.org/all/20260722004818.72310-1-blbllhy@gmail.com
Signed-off-by: Cen Zhang (Microsoft) <blbllhy@gmail.com>
---
v2:
- Add Cc: stable@vger.kernel.org
- Add Link: to v1
- Wrap long line in commit message
drivers/media/v4l2-core/v4l2-event.c | 14 +++++++++++++-
include/media/v4l2-fh.h | 2 ++
2 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/drivers/media/v4l2-core/v4l2-event.c b/drivers/media/v4l2-core/v4l2-event.c
index 9dd2aaa95a67..fcd8ce4addc1 100644
--- a/drivers/media/v4l2-core/v4l2-event.c
+++ b/drivers/media/v4l2-core/v4l2-event.c
@@ -18,6 +18,9 @@
#include <linux/slab.h>
#include <linux/export.h>
+/* Per-filehandle limit on the number of event subscriptions. */
+#define V4L2_MAX_EVENT_SUBSCRIPTIONS 256
+
static unsigned int sev_pos(const struct v4l2_subscribed_event *sev, unsigned int idx)
{
idx += sev->first;
@@ -218,6 +221,7 @@ static void __v4l2_event_unsubscribe(struct v4l2_subscribed_event *sev)
fh->navailable--;
}
list_del(&sev->list);
+ fh->nsubscribed--;
}
int v4l2_event_subscribe(struct v4l2_fh *fh,
@@ -251,8 +255,16 @@ int v4l2_event_subscribe(struct v4l2_fh *fh,
spin_lock_irqsave(&fh->vdev->fh_lock, flags);
found_ev = v4l2_event_subscribed(fh, sub->type, sub->id);
- if (!found_ev)
+ if (!found_ev) {
+ if (fh->nsubscribed >= V4L2_MAX_EVENT_SUBSCRIPTIONS) {
+ spin_unlock_irqrestore(&fh->vdev->fh_lock, flags);
+ kvfree(sev);
+ mutex_unlock(&fh->subscribe_lock);
+ return -ENOSPC;
+ }
list_add(&sev->list, &fh->subscribed);
+ fh->nsubscribed++;
+ }
spin_unlock_irqrestore(&fh->vdev->fh_lock, flags);
if (found_ev) {
diff --git a/include/media/v4l2-fh.h b/include/media/v4l2-fh.h
index aad4b3689d7e..65a7f31af889 100644
--- a/include/media/v4l2-fh.h
+++ b/include/media/v4l2-fh.h
@@ -33,6 +33,7 @@ struct v4l2_ctrl_handler;
* @subscribe_lock: serialise changes to the subscribed list; guarantee that
* the add and del event callbacks are orderly called
* @subscribed: list of subscribed events
+ * @nsubscribed: number of subscribed events at @subscribed list
* @available: list of events waiting to be dequeued
* @navailable: number of available events at @available list
* @sequence: event sequence number
@@ -49,6 +50,7 @@ struct v4l2_fh {
wait_queue_head_t wait;
struct mutex subscribe_lock;
struct list_head subscribed;
+ unsigned int nsubscribed;
struct list_head available;
unsigned int navailable;
u32 sequence;
--
2.53.0
next reply other threads:[~2026-07-22 4:23 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-22 4:23 Cen Zhang (Microsoft) [this message]
2026-07-27 14:58 ` [PATCH v2] media: v4l2-event: limit number of event subscriptions per file handle Hans Verkuil
2026-07-30 22:27 ` Cen Zhang (Microsoft)
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260722042308.75939-1-blbllhy@gmail.com \
--to=blbllhy@gmail.com \
--cc=AutonomousCodeSecurity@microsoft.com \
--cc=kees@kernel.org \
--cc=kys@microsoft.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-media@vger.kernel.org \
--cc=mchehab@kernel.org \
--cc=stable@vger.kernel.org \
--cc=tgopinath@linux.microsoft.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.