From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
To: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Cc: Andy Walls <awalls@md.metrocast.net>,
Mauro Carvalho Chehab <mchehab@kernel.org>,
Hans Verkuil <hverkuil+cisco@kernel.org>,
Dan Carpenter <dan.carpenter@linaro.org>,
stable@vger.kernel.org, linux-media@vger.kernel.org,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH 1/2] media: cx18: Fix invalid access to file *
Date: Mon, 18 Aug 2025 16:11:14 +0300 [thread overview]
Message-ID: <20250818131114.GD5862@pendragon.ideasonboard.com> (raw)
In-Reply-To: <20250818-cx18-v4l2-fh-v1-1-6fe153760bce@ideasonboard.com>
On Mon, Aug 18, 2025 at 02:40:11PM +0200, Jacopo Mondi wrote:
> Sice commit 7b9eb53e8591 ("media: cx18: Access v4l2_fh from file")
> all ioctl handlers have been ported to operate on the file * first
> function argument.
>
> The cx18 DVB layer calls cx18_init_on_first_open() when the driver needs
> to start streaming. This function calls the s_input(), s_std() and
> s_frequency() ioctl handlers directly, but being called from the driver
> context, it doesn't have a valid file * to pass them. This causes
> the ioctl handlers to deference an invalid pointer.
>
> Fix this by wrapping the ioctl handlers implementation in helper
> functions which accepts a cx18_open_id pointer as first argument
> and make the cx18_init_on_first_open() function call the helpers
> without going through the ioctl handlers.
>
> The bug has been reported by Smatch:
>
> --> 1223 cx18_s_input(NULL, &fh, video_input);
> The patch adds a new dereference of "file" but some of the callers pass a
> NULL pointer.
>
> Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
> Closes: https://lore.kernel.org/all/aKL4OMWsESUdX8KQ@stanley.mountain/
> Fixes: 7b9eb53e8591 ("media: cx18: Access v4l2_fh from file")
> Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
> ---
> drivers/media/pci/cx18/cx18-driver.c | 6 +++---
> drivers/media/pci/cx18/cx18-ioctl.c | 26 ++++++++++++++++++++------
> drivers/media/pci/cx18/cx18-ioctl.h | 8 +++++---
> 3 files changed, 28 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/media/pci/cx18/cx18-driver.c b/drivers/media/pci/cx18/cx18-driver.c
> index 743fcc9613744bfc1edeffc51e908fe88520405a..e1798850ff78a50d7930148622c87d9303033c45 100644
> --- a/drivers/media/pci/cx18/cx18-driver.c
> +++ b/drivers/media/pci/cx18/cx18-driver.c
> @@ -1220,14 +1220,14 @@ int cx18_init_on_first_open(struct cx18 *cx)
>
> video_input = cx->active_input;
> cx->active_input++; /* Force update of input */
> - cx18_s_input(NULL, &fh, video_input);
> + cx18_do_s_input(&fh, video_input);
>
> /* Let the VIDIOC_S_STD ioctl do all the work, keeps the code
> in one place. */
> cx->std++; /* Force full standard initialization */
> std = (cx->tuner_std == V4L2_STD_ALL) ? V4L2_STD_NTSC_M : cx->tuner_std;
> - cx18_s_std(NULL, &fh, std);
> - cx18_s_frequency(NULL, &fh, &vf);
> + cx18_do_s_std(&fh, std);
> + cx18_do_s_frequency(&fh, &vf);
> return 0;
> }
>
> diff --git a/drivers/media/pci/cx18/cx18-ioctl.c b/drivers/media/pci/cx18/cx18-ioctl.c
> index bf16d36448f888d9326b5f4a8f9c8f0e13d0c3a1..507df0d885e0dd2df7446aaef9e066592496d215 100644
> --- a/drivers/media/pci/cx18/cx18-ioctl.c
> +++ b/drivers/media/pci/cx18/cx18-ioctl.c
> @@ -521,9 +521,8 @@ static int cx18_g_input(struct file *file, void *fh, unsigned int *i)
> return 0;
> }
>
> -int cx18_s_input(struct file *file, void *fh, unsigned int inp)
> +int cx18_do_s_input(struct cx18_open_id *id, unsigned int inp)
As id is only used to access id->cx, I would pass a cx18 pointer to this
function. Same for cx18_do_s_std() and cx18_do_s_frequency(). This will
allow dropping the fake fh variable from cx18_init_on_first_open().
> {
> - struct cx18_open_id *id = file2id(file);
> struct cx18 *cx = id->cx;
> v4l2_std_id std = V4L2_STD_ALL;
> const struct cx18_card_video_input *card_input =
> @@ -558,6 +557,11 @@ int cx18_s_input(struct file *file, void *fh, unsigned int inp)
> return 0;
> }
>
> +static int cx18_s_input(struct file *file, void *fh, unsigned int inp)
> +{
> + return cx18_do_s_input(file2id(file), inp);
> +}
> +
> static int cx18_g_frequency(struct file *file, void *fh,
> struct v4l2_frequency *vf)
> {
> @@ -570,9 +574,9 @@ static int cx18_g_frequency(struct file *file, void *fh,
> return 0;
> }
>
> -int cx18_s_frequency(struct file *file, void *fh, const struct v4l2_frequency *vf)
> +int cx18_do_s_frequency(struct cx18_open_id *id,
> + const struct v4l2_frequency *vf)
> {
> - struct cx18_open_id *id = file2id(file);
> struct cx18 *cx = id->cx;
>
> if (vf->tuner != 0)
> @@ -585,6 +589,12 @@ int cx18_s_frequency(struct file *file, void *fh, const struct v4l2_frequency *v
> return 0;
> }
>
> +static int cx18_s_frequency(struct file *file, void *fh,
> + const struct v4l2_frequency *vf)
> +{
> + return cx18_do_s_frequency(file2id(file), vf);
> +}
> +
> static int cx18_g_std(struct file *file, void *fh, v4l2_std_id *std)
> {
> struct cx18 *cx = file2id(file)->cx;
> @@ -593,9 +603,8 @@ static int cx18_g_std(struct file *file, void *fh, v4l2_std_id *std)
> return 0;
> }
>
> -int cx18_s_std(struct file *file, void *fh, v4l2_std_id std)
> +int cx18_do_s_std(struct cx18_open_id *id, v4l2_std_id std)
> {
> - struct cx18_open_id *id = file2id(file);
> struct cx18 *cx = id->cx;
>
> if ((std & V4L2_STD_ALL) == 0)
> @@ -642,6 +651,11 @@ int cx18_s_std(struct file *file, void *fh, v4l2_std_id std)
> return 0;
> }
>
> +static int cx18_s_std(struct file *file, void *fh, v4l2_std_id std)
> +{
> + return cx18_do_s_std(file2id(file), std);
> +}
> +
> static int cx18_s_tuner(struct file *file, void *fh, const struct v4l2_tuner *vt)
> {
> struct cx18_open_id *id = file2id(file);
> diff --git a/drivers/media/pci/cx18/cx18-ioctl.h b/drivers/media/pci/cx18/cx18-ioctl.h
> index 221e2400fb3e2d817eaff7515fa89eb94f2d7f8a..bd0e6e5ac4e4a66f747789fd45b1d026c6905601 100644
> --- a/drivers/media/pci/cx18/cx18-ioctl.h
> +++ b/drivers/media/pci/cx18/cx18-ioctl.h
> @@ -12,6 +12,8 @@ u16 cx18_service2vbi(int type);
> void cx18_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal);
> u16 cx18_get_service_set(struct v4l2_sliced_vbi_format *fmt);
> void cx18_set_funcs(struct video_device *vdev);
> -int cx18_s_std(struct file *file, void *fh, v4l2_std_id std);
> -int cx18_s_frequency(struct file *file, void *fh, const struct v4l2_frequency *vf);
> -int cx18_s_input(struct file *file, void *fh, unsigned int inp);
> +
> +struct cx18_open_id;
> +int cx18_do_s_std(struct cx18_open_id *id, v4l2_std_id std);
> +int cx18_do_s_frequency(struct cx18_open_id *id, const struct v4l2_frequency *vf);
> +int cx18_do_s_input(struct cx18_open_id *id, unsigned int inp);
>
--
Regards,
Laurent Pinchart
next prev parent reply other threads:[~2025-08-18 13:11 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-08-18 12:40 [PATCH 0/2] media: pci: Fix invalid access to file * Jacopo Mondi
2025-08-18 12:40 ` [PATCH 1/2] media: cx18: " Jacopo Mondi
2025-08-18 12:42 ` kernel test robot
2025-08-18 13:11 ` Laurent Pinchart [this message]
2025-08-18 12:40 ` [PATCH 2/2] media: ivtv: " Jacopo Mondi
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=20250818131114.GD5862@pendragon.ideasonboard.com \
--to=laurent.pinchart@ideasonboard.com \
--cc=awalls@md.metrocast.net \
--cc=dan.carpenter@linaro.org \
--cc=hverkuil+cisco@kernel.org \
--cc=jacopo.mondi@ideasonboard.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-media@vger.kernel.org \
--cc=mchehab@kernel.org \
--cc=stable@vger.kernel.org \
/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.