On Sat Sep 19 07:41:09 2026 +0530, Rohinthan P wrote:
> The V4L2 control framework is designed to allow drivers to instantiate
> controls and clusters without checking for errors after each call,
> checking hdl->error only once at the end.
>
> However, if allocating the master control (controls[0]) fails, e.g. due to
> memory allocation failure, v4l2_ctrl_cluster() triggers a WARNING:
>
> ncontrols == 0 || controls[0] == NULL
> WARNING: drivers/media/v4l2-core/v4l2-ctrls-core.c:2525 at
> v4l2_ctrl_cluster
>
> Additionally, v4l2_ctrl_auto_cluster() attempts to dereference
> master->minimum without checking if controls[0] is NULL, leading to a
> NULL pointer dereference when master control creation fails.
>
> Update both v4l2_ctrl_cluster() and v4l2_ctrl_auto_cluster() to silently
> return if controls[0] is NULL, preserving the design that control
> creation errors are caught at the end when the driver checks hdl->error.
> Also update function documentation in include/media/v4l2-ctrls.h.
>
> Fixes: 71c689dc2e73 ("media: v4l2-ctrls: split up into four source files")
> Cc: [email protected]
> Reported-by: [email protected]
> Closes: https://syzkaller.appspot.com/bug?extid=cf896de36144391bcde1
> Suggested-by: Hans Verkuil <[email protected]>
> Signed-off-by: Rohinthan P <[email protected]>
> Signed-off-by: Hans Verkuil <[email protected]>
> [hverkuil: simplified the v4l2_ctrl_auto_cluster code a bit]
Patch committed.
Thanks,
Hans Verkuil
drivers/media/v4l2-core/v4l2-ctrls-core.c | 12 ++++++++++--
include/media/v4l2-ctrls.h | 6 ++++++
2 files changed, 16 insertions(+), 2 deletions(-)
---
diff --git a/drivers/media/v4l2-core/v4l2-ctrls-core.c
b/drivers/media/v4l2-core/v4l2-ctrls-core.c
index 9caca56478d1..661a3a25da52 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls-core.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls-core.c
@@ -2529,7 +2529,10 @@ void v4l2_ctrl_cluster(unsigned ncontrols, struct
v4l2_ctrl **controls)
int i;
/* The first control is the master control and it must not be NULL */
- if (WARN_ON(ncontrols == 0 || controls[0] == NULL))
+ if (WARN_ON(ncontrols == 0))
+ return;
+
+ if (!controls[0])
return;
for (i = 0; i < ncontrols; i++) {
@@ -2551,8 +2554,13 @@ void v4l2_ctrl_auto_cluster(unsigned ncontrols, struct
v4l2_ctrl **controls,
u32 flag = 0;
int i;
+ if (WARN_ON(ncontrols <= 1))
+ return;
+
+ if (!master)
+ return;
+
v4l2_ctrl_cluster(ncontrols, controls);
- WARN_ON(ncontrols <= 1);
WARN_ON(manual_val < master->minimum || manual_val > master->maximum);
WARN_ON(set_volatile && !has_op(master, g_volatile_ctrl));
master->is_auto = true;
diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h
index 327976b14d50..cec9217d97ac 100644
--- a/include/media/v4l2-ctrls.h
+++ b/include/media/v4l2-ctrls.h
@@ -834,6 +834,9 @@ bool v4l2_ctrl_radio_filter(const struct v4l2_ctrl *ctrl);
*
* @ncontrols: The number of controls in this cluster.
* @controls: The cluster control array of size @ncontrols.
+ *
+ * If controls[0] is NULL, then this function does nothing and just
+ * returns.
*/
void v4l2_ctrl_cluster(unsigned int ncontrols, struct v4l2_ctrl **controls);
@@ -845,6 +848,9 @@ void v4l2_ctrl_cluster(unsigned int ncontrols, struct
v4l2_ctrl **controls);
* @ncontrols: The number of controls in this cluster.
* @controls: The cluster control array of size @ncontrols. The first control
* must be the 'auto' control (e.g. autogain, autoexposure, etc.)
+ *
+ * If controls[0] is NULL, then this function does nothing and just
+ * returns.
* @manual_val: The value for the first control in the cluster that equals the
* manual setting.
* @set_volatile: If true, then all controls except the first auto control will
_______________________________________________
linuxtv-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]