]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
media: v4l2-subdev: Fix alloc failure check in v4l2_subdev_call_state_try()
authorTomi Valkeinen <tomi.valkeinen@ideasonboard.com>
Fri, 8 Aug 2025 08:59:15 +0000 (11:59 +0300)
committerHans Verkuil <hverkuil+cisco@kernel.org>
Mon, 25 Aug 2025 13:40:40 +0000 (15:40 +0200)
v4l2_subdev_call_state_try() macro allocates a subdev state with
__v4l2_subdev_state_alloc(), but does not check the returned value. If
__v4l2_subdev_state_alloc fails, it returns an ERR_PTR, and that would
cause v4l2_subdev_call_state_try() to crash.

Add proper error handling to v4l2_subdev_call_state_try().

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
Fixes: 982c0487185b ("media: subdev: Add v4l2_subdev_call_state_try() macro")
Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
Closes: https://lore.kernel.org/all/aJTNtpDUbTz7eyJc%40stanley.mountain/
Cc: stable@vger.kernel.org
Reviewed-by: Dan Carpenter <dan.carpenter@linaro.org>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
include/media/v4l2-subdev.h

index 8f54fd0d90ad899b5d78310631958358ea632171..4b28086808c96a7982361aa94606a991053c2ec2 100644 (file)
@@ -1939,19 +1939,23 @@ extern const struct v4l2_subdev_ops v4l2_subdev_call_wrappers;
  *
  * Note: only legacy non-MC drivers may need this macro.
  */
-#define v4l2_subdev_call_state_try(sd, o, f, args...)                 \
-       ({                                                            \
-               int __result;                                         \
-               static struct lock_class_key __key;                   \
-               const char *name = KBUILD_BASENAME                    \
-                       ":" __stringify(__LINE__) ":state->lock";     \
-               struct v4l2_subdev_state *state =                     \
-                       __v4l2_subdev_state_alloc(sd, name, &__key);  \
-               v4l2_subdev_lock_state(state);                        \
-               __result = v4l2_subdev_call(sd, o, f, state, ##args); \
-               v4l2_subdev_unlock_state(state);                      \
-               __v4l2_subdev_state_free(state);                      \
-               __result;                                             \
+#define v4l2_subdev_call_state_try(sd, o, f, args...)                         \
+       ({                                                                    \
+               int __result;                                                 \
+               static struct lock_class_key __key;                           \
+               const char *name = KBUILD_BASENAME                            \
+                       ":" __stringify(__LINE__) ":state->lock";             \
+               struct v4l2_subdev_state *state =                             \
+                       __v4l2_subdev_state_alloc(sd, name, &__key);          \
+               if (IS_ERR(state)) {                                          \
+                       __result = PTR_ERR(state);                            \
+               } else {                                                      \
+                       v4l2_subdev_lock_state(state);                        \
+                       __result = v4l2_subdev_call(sd, o, f, state, ##args); \
+                       v4l2_subdev_unlock_state(state);                      \
+                       __v4l2_subdev_state_free(state);                      \
+               }                                                             \
+               __result;                                                     \
        })
 
 /**