public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Hans Verkuil <hverkuil+cisco@kernel.org>
To: Philipp Matthias Hahn <pmhahn@pmhahn.de>,
	Hans Verkuil <hverkuil@kernel.org>,
	Mauro Carvalho Chehab <mchehab@kernel.org>
Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH v3] media: gspca: Handle SENSOR_HV7131R
Date: Tue, 5 May 2026 15:34:56 +0200	[thread overview]
Message-ID: <9cc0ef80-8f2b-4206-b305-d68f8f0cc1ff@kernel.org> (raw)
In-Reply-To: <a36c41b3f1a4d9c8d5e6b264ce848df01fac8344.1776693140.git.pmhahn@pmhahn.de>

Hi Philipp,

On 4/20/26 15:54, Philipp Matthias Hahn wrote:
> I found an old USB webcam 0c45:602d Microdia VideoCAM ExpressII. `vlc`
> triggered an OOPS as soon as I opened the device:
> 
>> BUG: kernel NULL pointer dereference, address: 0000000000000068
>> #PF: supervisor read access in kernel mode
>> #PF: error_code(0x0000) - not-present page
>> PGD 0 P4D 0
>> Oops: Oops: 0000 [#1] PREEMPT SMP NOPTI
>> CPU: 8 UID: 1000 PID: 19655 Comm: vlc Tainted: G O 7.0.0+ #1 Debian
>> Tainted: [O]=OOT_MODULE
>> RIP: 0010:do_autogain+0x7d/0x100 [gspca_sonixb]
>> Code: 74 21 0f af 90 c4 00 00 00 89 d0 48 63 d2 48 69 d2 09 04 02 81
>> 48 c1 ea 20 01 c2 c1 f8 1f c1 fa 06 29 c2 48 8b 83 48 06 00 00 <48>
>> 81 78 68 f3 01 00 00 7f 34 48 89 df e8 41 f1 3b 00 85 c0 74 07
> 
> (The out-of-tree-module is v4l2-loopback.)
> 
> Adding addition debug information I found out, that the cam is based on
> an SENSOR_HV7131R:
> 
>> gspca_main: sonixb-2.14.0 probing 0c45:602d
>> sonixb 1-3:1.0: sd_config(sensor=01 bridge=00)
> 
> In case of an SENSOR_HV7131R `gspca_dev->exposure` is not setup.
> Enabling auto-gain will result in the above OOPS.
> 
> 1. Check for `gspca_dev->exposure != NULL` before dereferencing it.
> 
> Even after that there's 2nd OOPS:
> 
>> BUG: kernel NULL pointer dereference, address: 0000000000000034
>> #PF: supervisor read access in kernel mode
>> #PF: error_code(0x0000) - not-present page
>> PGD 0 P4D 0
>> Oops: Oops: 0000 [#1] SMP NOPTI
>> CPU: 1 UID: 1000 PID: 709 Comm: vlc Tainted: G E 7.0.0+ #6 Debian
>> Tainted: [E]=UNSIGNED_MODULE
>> RIP: 0010:v4l2_ctrl_g_ctrl+0x36/0x80 [videodev]
>> Code: 20 65 48 8b 05 63 17 b1 c8 48 89 44 24 18 31 c0 c7 44 24 14 00
>> 00 00 00 48 c7 44 24 04 00 00 00 00 48 c7 44 24 0c 00 00 00 00 <f6>
>> 47 34 20 74 2e 48 8d 74 24 04 c7 44 24 10 00 00 00 00 e8 72 fd
> 
> This is caused by v4l2_ctrl_g_ctrl() dereferencing gspca_dev->autogain,
> which remains NULL as gspca_dev->exposure is NULL.
> 
> Check for `gspca_dev->autogain != NULL` before dereferencing it via
> gspca_expo_autogain().

I see no sign of adding that check in gspca_expo_autogain(): I think you
missed that in your patch.

> 
> Signed-off-by: Philipp Matthias Hahn <pmhahn@pmhahn.de>
> ---
>  drivers/media/usb/gspca/sonixb.c | 12 ++++++++----
>  1 file changed, 8 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/media/usb/gspca/sonixb.c b/drivers/media/usb/gspca/sonixb.c
> index 4d655e2da9cb..09725d62d904 100644
> --- a/drivers/media/usb/gspca/sonixb.c
> +++ b/drivers/media/usb/gspca/sonixb.c
> @@ -900,11 +900,11 @@ static void do_autogain(struct gspca_dev *gspca_dev)
>  	if (sd->brightness)
>  		desired_avg_lum = sd->brightness->val * desired_avg_lum / 127;
>  
> -	if (gspca_dev->exposure->maximum < 500) {
> +	if (gspca_dev->exposure && gspca_dev->exposure->maximum < 500) {
>  		if (gspca_coarse_grained_expo_autogain(gspca_dev, avg_lum,
>  				desired_avg_lum, deadzone))
>  			sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
> -	} else {
> +	} else if (gspca_dev->autogain) {
>  		int gain_knee = (s32)gspca_dev->gain->maximum * 9 / 10;
>  		if (gspca_expo_autogain(gspca_dev, avg_lum, desired_avg_lum,
>  				deadzone, gain_knee, sd->exposure_knee))
> @@ -927,6 +927,9 @@ static int sd_config(struct gspca_dev *gspca_dev,
>  	sd->sensor = id->driver_info >> 8;
>  	sd->bridge = id->driver_info & 0xff;
>  
> +	dev_info(gspca_dev->v4l2_dev.dev, "%s(sensor=%02x bridge=%02x)\n",
> +		 __func__, sd->sensor, sd->bridge);
> +
>  	cam = &gspca_dev->cam;
>  	if (!(sensor_data[sd->sensor].flags & F_SIF)) {
>  		cam->cam_mode = vga_mode;
> @@ -958,7 +961,7 @@ static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
>  
>  	gspca_dev->usb_err = 0;
>  
> -	if (ctrl->id == V4L2_CID_AUTOGAIN && ctrl->is_new && ctrl->val) {
> +	if (ctrl->id == V4L2_CID_AUTOGAIN && ctrl->is_new && ctrl->val && gspca_dev->exposure) {

Is this really needed? We should only be able to get here if the AUTOGAIN
control was added, and that's only added if the EXPOSURE control is also
present.

Does it still crash if you drop this change?

>  		/* when switching to autogain set defaults to make sure
>  		   we are on a valid point of the autogain gain /
>  		   exposure knee graph, and give this change time to
> @@ -976,7 +979,8 @@ static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
>  		setbrightness(gspca_dev);
>  		break;
>  	case V4L2_CID_AUTOGAIN:
> -		if (gspca_dev->exposure->is_new || (ctrl->is_new && ctrl->val))
> +		if ((gspca_dev->exposure && gspca_dev->exposure->is_new) ||
> +		    (ctrl->is_new && ctrl->val))

Same here.

>  			setexposure(gspca_dev);
>  		if (gspca_dev->gain->is_new || (ctrl->is_new && ctrl->val))
>  			setgain(gspca_dev);

Regards,

	Hans

  reply	other threads:[~2026-05-05 13:34 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-04-16  7:34 [PATCH] media: gspca: Handle SENSOR_HV7131R Philipp Matthias Hahn
2026-04-16  7:34 ` Philipp Matthias Hahn
2026-04-16  7:34 ` [PATCH] media: gspca: Fix comment in sd_init() Philipp Matthias Hahn
2026-04-17 12:05 ` [PATCH v2] media: gspca: Handle SENSOR_HV7131R Philipp Matthias Hahn
2026-04-17 12:05   ` Philipp Matthias Hahn
2026-04-17 12:05   ` [PATCH v2] media: gspca: Fix comment in sd_init() Philipp Matthias Hahn
2026-04-20 13:54   ` [PATCH v3] media: gspca: Handle SENSOR_HV7131R Philipp Matthias Hahn
2026-04-20 13:54     ` Philipp Matthias Hahn
2026-05-05 13:34       ` Hans Verkuil [this message]
2026-04-20 13:54     ` [PATCH v3] media: gspca: Fix comment in sd_init() Philipp Matthias Hahn

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=9cc0ef80-8f2b-4206-b305-d68f8f0cc1ff@kernel.org \
    --to=hverkuil+cisco@kernel.org \
    --cc=hverkuil@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-media@vger.kernel.org \
    --cc=mchehab@kernel.org \
    --cc=pmhahn@pmhahn.de \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox