Skip to content
Snippets Groups Projects
  1. Nov 09, 2021
  2. Oct 05, 2021
  3. Sep 30, 2021
  4. Aug 04, 2021
  5. Jul 22, 2021
  6. Jul 12, 2021
  7. Jun 24, 2021
    • Shuah Khan's avatar
      media: Fix Media Controller API config checks · 50e7a31d
      Shuah Khan authored and Mauro Carvalho Chehab's avatar Mauro Carvalho Chehab committed
      Smatch static checker warns that "mdev" can be null:
      
      sound/usb/media.c:287 snd_media_device_create()
          warn: 'mdev' can also be NULL
      
      If CONFIG_MEDIA_CONTROLLER is disabled, this file should not be included
      in the build.
      
      The below conditions in the sound/usb/Makefile are in place to ensure that
      media.c isn't included in the build.
      
      sound/usb/Makefile:
      snd-usb-audio-$(CONFIG_SND_USB_AUDIO_USE_MEDIA_CONTROLLER) += media.o
      
      select SND_USB_AUDIO_USE_MEDIA_CONTROLLER if MEDIA_CONTROLLER &&
             (MEDIA_SUPPORT=y || MEDIA_SUPPORT=SND_USB_AUDIO)
      
      The following config check in include/media/media-dev-allocator.h is
      in place to enable the API only when CONFIG_MEDIA_CONTROLLER and
      CONFIG_USB are enabled.
      
       #if defined(CONFIG_MEDIA_CONTROLLER) && defined(CONFIG_USB)
      
      This check doesn't work as intended when CONFIG_USB=m. When CONFIG_USB=m,
      CONFIG_USB_MODULE is defined and CONFIG_USB is not. The above config check
      doesn't catch that CONFIG_USB is defined as a module and disables the API.
      This results in sound/usb enabling Media Controller specific ALSA driver
      code, while Media disables the Media Controller API.
      
      Fix the problem requires two changes:
      
      1. Change the check to use IS_ENABLED to detect when CONFIG_USB is enabled
         as a module or static. Since CONFIG_MEDIA_CONTROLLER is a bool, leave
         the check unchanged to be consistent with drivers/media/Makefile.
      
      2. Change the drivers/media/mc/Makefile to include mc-dev-allocator.o
         in mc-objs when CONFIG_USB is enabled.
      
      Link: https://lore.kernel.org/alsa-devel/YLeAvT+R22FQ%2FEyw@mwanda/
      
      
      
      Reported-by: default avatarDan Carpenter <dan.carpenter@oracle.com>
      Signed-off-by: default avatarShuah Khan <skhan@linuxfoundation.org>
      Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
      Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+huawei@kernel.org>
      50e7a31d
  8. Jun 17, 2021
    • Arnd Bergmann's avatar
      media: subdev: disallow ioctl for saa6588/davinci · 0a7790be
      Arnd Bergmann authored and Mauro Carvalho Chehab's avatar Mauro Carvalho Chehab committed
      
      The saa6588_ioctl() function expects to get called from other kernel
      functions with a 'saa6588_command' pointer, but I found nothing stops it
      from getting called from user space instead, which seems rather dangerous.
      
      The same thing happens in the davinci vpbe driver with its VENC_GET_FLD
      command.
      
      As a quick fix, add a separate .command() callback pointer for this
      driver and change the two callers over to that.  This change can easily
      get backported to stable kernels if necessary, but since there are only
      two drivers, we may want to eventually replace this with a set of more
      specialized callbacks in the long run.
      
      Fixes: c3fda7f8 ("V4L/DVB (10537): saa6588: convert to v4l2_subdev.")
      Cc: stable@vger.kernel.org
      Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
      Reviewed-by: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
      Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
      Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+huawei@kernel.org>
      0a7790be
    • Tomi Valkeinen's avatar
      media: v4l2-subdev: add subdev-wide state struct · 0d346d2a
      Tomi Valkeinen authored and Mauro Carvalho Chehab's avatar Mauro Carvalho Chehab committed
      
      We have 'struct v4l2_subdev_pad_config' which contains configuration for
      a single pad used for the TRY functionality, and an array of those
      structs is passed to various v4l2_subdev_pad_ops.
      
      I was working on subdev internal routing between pads, and realized that
      there's no way to add TRY functionality for routes, which is not pad
      specific configuration. Adding a separate struct for try-route config
      wouldn't work either, as e.g. set-fmt needs to know the try-route
      configuration to propagate the settings.
      
      This patch adds a new struct, 'struct v4l2_subdev_state' (which at the
      moment only contains the v4l2_subdev_pad_config array) and the new
      struct is used in most of the places where v4l2_subdev_pad_config was
      used. All v4l2_subdev_pad_ops functions taking v4l2_subdev_pad_config
      are changed to instead take v4l2_subdev_state.
      
      The changes to drivers/media/v4l2-core/v4l2-subdev.c and
      include/media/v4l2-subdev.h were written by hand, and all the driver
      changes were done with the semantic patch below. The spatch needs to be
      applied to a select list of directories. I used the following shell
      commands to apply the spatch:
      
      dirs="drivers/media/i2c drivers/media/platform drivers/media/usb drivers/media/test-drivers/vimc drivers/media/pci drivers/staging/media"
      for dir in $dirs; do spatch -j8 --dir --include-headers --no-show-diff --in-place --sp-file v4l2-subdev-state.cocci $dir; done
      
      Note that Coccinelle chokes on a few drivers (gcc extensions?). With
      minor changes we can make Coccinelle run fine, and these changes can be
      reverted after spatch. The diff for these changes is:
      
      For drivers/media/i2c/s5k5baf.c:
      
      	@@ -1481,7 +1481,7 @@ static int s5k5baf_set_selection(struct v4l2_subdev *sd,
      	 				&s5k5baf_cis_rect,
      	 				v4l2_subdev_get_try_crop(sd, cfg, PAD_CIS),
      	 				v4l2_subdev_get_try_compose(sd, cfg, PAD_CIS),
      	-				v4l2_subdev_get_try_crop(sd, cfg, PAD_OUT)
      	+				v4l2_subdev_get_try_crop(sd, cfg, PAD_OUT),
      	 			};
      	 		s5k5baf_set_rect_and_adjust(rects, rtype, &sel->r);
      	 		return 0;
      
      For drivers/media/platform/s3c-camif/camif-capture.c:
      
      	@@ -1230,7 +1230,7 @@ static int s3c_camif_subdev_get_fmt(struct v4l2_subdev *sd,
      	 		*mf = camif->mbus_fmt;
      	 		break;
      
      	-	case CAMIF_SD_PAD_SOURCE_C...CAMIF_SD_PAD_SOURCE_P:
      	+	case CAMIF_SD_PAD_SOURCE_C:
      	 		/* crop rectangle at camera interface input */
      	 		mf->width = camif->camif_crop.width;
      	 		mf->height = camif->camif_crop.height;
      	@@ -1332,7 +1332,7 @@ static int s3c_camif_subdev_set_fmt(struct v4l2_subdev *sd,
      	 		}
      	 		break;
      
      	-	case CAMIF_SD_PAD_SOURCE_C...CAMIF_SD_PAD_SOURCE_P:
      	+	case CAMIF_SD_PAD_SOURCE_C:
      	 		/* Pixel format can be only changed on the sink pad. */
      	 		mf->code = camif->mbus_fmt.code;
      	 		mf->width = crop->width;
      
      The semantic patch is:
      
      // <smpl>
      
      // Change function parameter
      
      @@
      identifier func;
      identifier cfg;
      @@
      
       func(...,
      -   struct v4l2_subdev_pad_config *cfg
      +   struct v4l2_subdev_state *sd_state
          , ...)
       {
       <...
      - cfg
      + sd_state
       ...>
       }
      
      // Change function declaration parameter
      
      @@
      identifier func;
      identifier cfg;
      type T;
      @@
      T func(...,
      -   struct v4l2_subdev_pad_config *cfg
      +   struct v4l2_subdev_state *sd_state
          , ...);
      
      // Change function return value
      
      @@
      identifier func;
      @@
      - struct v4l2_subdev_pad_config
      + struct v4l2_subdev_state
       *func(...)
       {
          ...
       }
      
      // Change function declaration return value
      
      @@
      identifier func;
      @@
      - struct v4l2_subdev_pad_config
      + struct v4l2_subdev_state
       *func(...);
      
      // Some drivers pass a local pad_cfg for a single pad to a called function. Wrap it
      // inside a pad_state.
      
      @@
      identifier func;
      identifier pad_cfg;
      @@
      func(...)
      {
          ...
          struct v4l2_subdev_pad_config pad_cfg;
      +   struct v4l2_subdev_state pad_state = { .pads = &pad_cfg };
      
          <+...
      
      (
          v4l2_subdev_call
      |
          sensor_call
      |
          isi_try_fse
      |
          isc_try_fse
      |
          saa_call_all
      )
          (...,
      -   &pad_cfg
      +   &pad_state
          ,...)
      
          ...+>
      }
      
      // If the function uses fields from pad_config, access via state->pads
      
      @@
      identifier func;
      identifier state;
      @@
       func(...,
          struct v4l2_subdev_state *state
          , ...)
       {
          <...
      (
      -   state->try_fmt
      +   state->pads->try_fmt
      |
      -   state->try_crop
      +   state->pads->try_crop
      |
      -   state->try_compose
      +   state->pads->try_compose
      )
          ...>
      }
      
      // If the function accesses the filehandle, use fh->state instead
      
      @@
      struct v4l2_subdev_fh *fh;
      @@
      -    fh->pad
      +    fh->state
      
      @@
      struct v4l2_subdev_fh fh;
      @@
      -    fh.pad
      +    fh.state
      
      // Start of vsp1 specific
      
      @@
      @@
      struct vsp1_entity {
          ...
      -    struct v4l2_subdev_pad_config *config;
      +    struct v4l2_subdev_state *config;
          ...
      };
      
      @@
      symbol entity;
      @@
      vsp1_entity_init(...)
      {
          ...
          entity->config =
      -    v4l2_subdev_alloc_pad_config
      +    v4l2_subdev_alloc_state
          (&entity->subdev);
          ...
      }
      
      @@
      symbol entity;
      @@
      vsp1_entity_destroy(...)
      {
          ...
      -   v4l2_subdev_free_pad_config
      +   v4l2_subdev_free_state
          (entity->config);
          ...
      }
      
      @exists@
      identifier func =~ "(^vsp1.*)|(hsit_set_format)|(sru_enum_frame_size)|(sru_set_format)|(uif_get_selection)|(uif_set_selection)|(uds_enum_frame_size)|(uds_set_format)|(brx_set_format)|(brx_get_selection)|(histo_get_selection)|(histo_set_selection)|(brx_set_selection)";
      symbol config;
      @@
      func(...) {
          ...
      -    struct v4l2_subdev_pad_config *config;
      +    struct v4l2_subdev_state *config;
          ...
      }
      
      // End of vsp1 specific
      
      // Start of rcar specific
      
      @@
      identifier sd;
      identifier pad_cfg;
      @@
       rvin_try_format(...)
       {
          ...
      -   struct v4l2_subdev_pad_config *pad_cfg;
      +   struct v4l2_subdev_state *sd_state;
          ...
      -   pad_cfg = v4l2_subdev_alloc_pad_config(sd);
      +   sd_state = v4l2_subdev_alloc_state(sd);
          <...
      -   pad_cfg
      +   sd_state
          ...>
      -   v4l2_subdev_free_pad_config(pad_cfg);
      +   v4l2_subdev_free_state(sd_state);
          ...
       }
      
      // End of rcar specific
      
      // Start of rockchip specific
      
      @@
      identifier func =~ "(rkisp1_rsz_get_pad_fmt)|(rkisp1_rsz_get_pad_crop)|(rkisp1_rsz_register)";
      symbol rsz;
      symbol pad_cfg;
      @@
      
       func(...)
       {
      +   struct v4l2_subdev_state state = { .pads = rsz->pad_cfg };
          ...
      -   rsz->pad_cfg
      +   &state
          ...
       }
      
      @@
      identifier func =~ "(rkisp1_isp_get_pad_fmt)|(rkisp1_isp_get_pad_crop)";
      symbol isp;
      symbol pad_cfg;
      @@
      
       func(...)
       {
      +   struct v4l2_subdev_state state = { .pads = isp->pad_cfg };
          ...
      -   isp->pad_cfg
      +   &state
          ...
       }
      
      @@
      symbol rkisp1;
      symbol isp;
      symbol pad_cfg;
      @@
      
       rkisp1_isp_register(...)
       {
      +   struct v4l2_subdev_state state = { .pads = rkisp1->isp.pad_cfg };
          ...
      -   rkisp1->isp.pad_cfg
      +   &state
          ...
       }
      
      // End of rockchip specific
      
      // Start of tegra-video specific
      
      @@
      identifier sd;
      identifier pad_cfg;
      @@
       __tegra_channel_try_format(...)
       {
          ...
      -   struct v4l2_subdev_pad_config *pad_cfg;
      +   struct v4l2_subdev_state *sd_state;
          ...
      -   pad_cfg = v4l2_subdev_alloc_pad_config(sd);
      +   sd_state = v4l2_subdev_alloc_state(sd);
          <...
      -   pad_cfg
      +   sd_state
          ...>
      -   v4l2_subdev_free_pad_config(pad_cfg);
      +   v4l2_subdev_free_state(sd_state);
          ...
       }
      
      @@
      identifier sd_state;
      @@
       __tegra_channel_try_format(...)
       {
          ...
          struct v4l2_subdev_state *sd_state;
          <...
      -   sd_state->try_crop
      +   sd_state->pads->try_crop
          ...>
       }
      
      // End of tegra-video specific
      
      // </smpl>
      
      Signed-off-by: default avatarTomi Valkeinen <tomi.valkeinen@ideasonboard.com>
      Acked-by: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
      Acked-by: default avatarSakari Ailus <sakari.ailus@linux.intel.com>
      Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
      Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+huawei@kernel.org>
      0d346d2a
  9. Jun 08, 2021
  10. May 23, 2021
  11. May 21, 2021
  12. May 19, 2021
  13. Apr 15, 2021
    • Hans Verkuil's avatar
      media: v4l2-ctrls: fix reference to freed memory · ac34b79d
      Hans Verkuil authored and Mauro Carvalho Chehab's avatar Mauro Carvalho Chehab committed
      
      When controls are used together with the Request API, then for
      each request a v4l2_ctrl_handler struct is allocated. This contains
      the controls that can be set in a request. If a control is *not* set in
      the request, then the value used in the most recent previous request
      must be used, or the current value if it is not found in any outstanding
      requests.
      
      The framework tried to find such a previous request and it would set
      the 'req' pointer in struct v4l2_ctrl_ref to the v4l2_ctrl_ref of the
      control in such a previous request. So far, so good. However, when that
      previous request was applied to the hardware, returned to userspace, and
      then userspace would re-init or free that request, any 'ref' pointer in
      still-queued requests would suddenly point to freed memory.
      
      This was not noticed before since the drivers that use this expected
      that each request would always have the controls set, so there was
      never any need to find a control in older requests. This requirement
      was relaxed, and now this bug surfaced.
      
      It was also made worse by changeset
      2fae4d6a ("media: v4l2-ctrls: v4l2_ctrl_request_complete() should always set ref->req")
      which increased the chance of this happening.
      
      The use of the 'req' pointer in v4l2_ctrl_ref was very fragile, so
      drop this entirely. Instead add a valid_p_req bool to indicate that
      p_req contains a valid value for this control. And if it is false,
      then just use the current value of the control.
      
      Note that VIDIOC_G_EXT_CTRLS will always return -EACCES when attempting
      to get a control from a request until the request is completed. And in
      that case, all controls in the request will have the control value set
      (i.e. valid_p_req is true). This means that the whole 'find the most
      recent previous request containing a control' idea is pointless, and
      the code can be simplified considerably.
      
      The v4l2_g_ext_ctrls_common() function was refactored a bit to make
      it more understandable. It also avoids updating volatile controls
      in a completed request since that was already done when the request
      was completed.
      
      Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
      Fixes: 2fae4d6a ("media: v4l2-ctrls: v4l2_ctrl_request_complete() should always set ref->req")
      Fixes: 6fa6f831 ("media: v4l2-ctrls: add core request support")
      Cc: <stable@vger.kernel.org>      # for v5.9 and up
      Tested-by: default avatarAlexandre Courbot <acourbot@chromium.org>
      Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+huawei@kernel.org>
      ac34b79d
  14. Apr 09, 2021
  15. Apr 06, 2021
Loading