Skip to contentSkip to conversation

media: subdev: Add v4l2_subdev_call_state_try() macro

bug report Dan Carpenter 2 participants 2 messages Aug 7, 2025 – Aug 8, 2025 Media (V4L/DVB)

lore
Share & tools
lore
#0 lore raw

Hello Tomi Valkeinen,

Commit 982c0487185b ("media: subdev: Add v4l2_subdev_call_state_try() macro") from Jul 1, 2022 (linux-next), leads to the following Smatch static checker warning:

	drivers/media/platform/st/stm32/stm32-dcmi.c:995 dcmi_try_fmt()
	error: 'state' dereferencing possible ERR_PTR()

drivers/media/platform/st/stm32/stm32-dcmi.c

    993 
    994         v4l2_fill_mbus_format(&format.format, pix, sd_fmt->mbus_code);

--> 995 ret = v4l2_subdev_call_state_try(dcmi->source, pad, set_fmt, &format);

The problem is the v4l2_subdev_call_state_try() macro:

  1965  #define v4l2_subdev_call_state_try(sd, o, f, args...)                 \
  1966          ({                                                            \
  1967                  int __result;                                         \
  1968                  static struct lock_class_key __key;                   \
  1969                  const char *name = KBUILD_BASENAME                    \
  1970                          ":" __stringify(__LINE__) ":state->lock";     \
  1971                  struct v4l2_subdev_state *state =                     \
  1972                          __v4l2_subdev_state_alloc(sd, name, &__key);  \
                                ^^^^^^^^^^^^^^^^^^^^^^^^^

If this fails

  1973                  v4l2_subdev_lock_state(state);                        \
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

then it leads to a crash.

  1974                  __result = v4l2_subdev_call(sd, o, f, state, ##args); \
  1975                  v4l2_subdev_unlock_state(state);                      \
  1976                  __v4l2_subdev_state_free(state);                      \
  1977                  __result;                                             \

1978 })

regards,
dan carpenter

#1 lore raw

Hi,

Quoted 29 lines · Dan Carpenter

Hello Tomi Valkeinen,

Commit 982c0487185b ("media: subdev: Add v4l2_subdev_call_state_try() macro") from Jul 1, 2022 (linux-next), leads to the following Smatch static checker warning:

	drivers/media/platform/st/stm32/stm32-dcmi.c:995 dcmi_try_fmt()
	error: 'state' dereferencing possible ERR_PTR()

drivers/media/platform/st/stm32/stm32-dcmi.c

    993 
    994         v4l2_fill_mbus_format(&format.format, pix, sd_fmt->mbus_code);

--> 995 ret = v4l2_subdev_call_state_try(dcmi->source, pad, set_fmt, &format);

The problem is the v4l2_subdev_call_state_try() macro:

  1965  #define v4l2_subdev_call_state_try(sd, o, f, args...)                 \
  1966          ({                                                            \
  1967                  int __result;                                         \
  1968                  static struct lock_class_key __key;                   \
  1969                  const char *name = KBUILD_BASENAME                    \
  1970                          ":" __stringify(__LINE__) ":state->lock";     \
  1971                  struct v4l2_subdev_state *state =                     \
  1972                          __v4l2_subdev_state_alloc(sd, name, &__key);  \
                                ^^^^^^^^^^^^^^^^^^^^^^^^^

If this fails

  1973                  v4l2_subdev_lock_state(state);                        \
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Quoted 8 lines

then it leads to a crash.

  1974                  __result = v4l2_subdev_call(sd, o, f, state, ##args); \
  1975                  v4l2_subdev_unlock_state(state);                      \
  1976                  __v4l2_subdev_state_free(state);                      \
  1977                  __result;                                             \

1978 })

Thanks. For some reason I can't reproduce the error with smatch. However, it looks clear to me. We need:

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;

Tomi