[PATCH] Fix tuner_warn() induced kernel Ooops in simple_tuner_attach()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sat, 2008-05-24 at 22:33 -0400, Andy Walls wrote:
> On Sat, 2008-05-24 at 18:17 +0200, Jose Alberto Reguero wrote:
> > Work well with kernel 2.6.25
> > 
> > Jose Alberto


> It looks like something about the "tuner_warn()" macro is causing
> references to be made to very low memory addresses.  That is probably
> not right.
> 
> So let's look further: here is the same section of
> tuner-simple.c:simple_tuner_attach() after preprocessing, but before
> conversion to assembly:
> 
>     if (fe->ops.i2c_gate_ctrl)
>      fe->ops.i2c_gate_ctrl(fe, 1);
> 
>     if (1 != i2c_transfer(i2c_adap, &msg, 1))
>      do { do { printk("<4>" "%s %d-%04x: " "unable to probe %s,
> proceeding anyway.", priv->i2c_props.name, priv->i2c_props.adap ?
> i2c_adapter_id(priv->i2c_props.adap) : -1, priv->i2c_props.addr,
> tuners[type].name); } while (0); } while (0);
> 
> 
>     if (fe->ops.i2c_gate_ctrl)
>      fe->ops.i2c_gate_ctrl(fe, 0);
>  

> Hmmm. Lots of dereferences of something called "priv".  Looking at the
> top of tuner-simple.c:simple_tuner_attach() we find:
> 
> 1032         struct tuner_simple_priv *priv = NULL;
> 1033         int instance;
> 
> With no other operations on "priv" before the "tuner_warn()"
> invocation.
> 
> So tuner-simple.c:simple_tuner_attach() has a hard coded NULL pointer
> dereference buried in a macro that only sometimes gets executed.


Patch attached.  It compiles.  I assume it works.

I did a search through the rest of tuner-simple.c and did not see any
other instances of tuner_warn() being called without "priv" being
defined.

Regards,
Andy

# HG changeset patch
# User Andy Walls <awalls@xxxxxxxxx>
# Date 1211765477 14400
# Node ID c49fbcb74feefa8af911236978f42fcc2e18de8e
# Parent  9d04bba82511bd8576a4e3304d507d84ae3522ca
Fix tuner_warn() induced kernel Ooops in simple_tuner_attach()

From: Andy Walls <awalls@xxxxxxxxx>


The tuner_warn() macro relies on the local variable "priv" to be a valid
pointer.  There was a case in simple_tuner_attach() where this cannot be the
case yet, so tuner_warn() would dereference a NULL "priv" pointer.  Changed
the tuner_warn() to a printk() with the originally intended output format.


Signed-off-by: Andy Walls <awalls@xxxxxxxxx>

diff -r 9d04bba82511 -r c49fbcb74fee linux/drivers/media/common/tuners/tuner-simple.c
--- a/linux/drivers/media/common/tuners/tuner-simple.c	Wed May 14 23:14:04 2008 +0000
+++ b/linux/drivers/media/common/tuners/tuner-simple.c	Sun May 25 21:31:17 2008 -0400
@@ -1053,8 +1053,10 @@ struct dvb_frontend *simple_tuner_attach
 			fe->ops.i2c_gate_ctrl(fe, 1);
 
 		if (1 != i2c_transfer(i2c_adap, &msg, 1))
-			tuner_warn("unable to probe %s, proceeding anyway.",
-				   tuners[type].name);
+			printk(KERN_WARNING "%s %d-%04x: "
+				"unable to probe %s, proceeding anyway.",
+				"tuner-simple", i2c_adapter_id(i2c_adap),
+				i2c_addr, tuners[type].name);
 
 		if (fe->ops.i2c_gate_ctrl)
 			fe->ops.i2c_gate_ctrl(fe, 0);
_______________________________________________
linux-dvb mailing list
linux-dvb@xxxxxxxxxxx
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb

[Index of Archives]     [Linux Media]     [Video 4 Linux]     [Asterisk]     [Samba]     [Xorg]     [Xfree86]     [Linux USB]

  Powered by Linux