Re: [patch 2.6.13-rc6] watchdog: fix oops in softdog driver

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

 



On Iau, 2005-08-18 at 01:09 -0400, Chuck Ebbert wrote:
> Wim,
>   The softdog watchdog timer has a bug that can create an oops:
> 
>   1.  Load the module without the nowayout option.
>   2.  Open the driver and close it without writing 'V' before close.
>   3.  Unload the module.  The timer will continue to run...
>   4.  Oops happens when timer fires.
> 
>   Reported Sun, 10 Oct 2004, by Michael Schierl <[email protected]>
> 
>   Fix is easy: always take a reference on the module on open.
> Release it only when the device is closed and no timer is running.
> Tested on 2.6.13-rc6 using the soft_noboot option.  While the
> timer is running and the device is closed, the module use count
> stays at 1.  After the timer fires, it drops to 0.  Repeatedly
> opening and closing the driver caused no problems.  Please apply.
> 
> 
> Signed-off-by: Chuck Ebbert <[email protected]>
> 
>  drivers/char/watchdog/softdog.c |   13 +++++++++----
>  1 files changed, 9 insertions(+), 4 deletions(-)
> 
> --- 2.6.13-rc6c.orig/drivers/char/watchdog/softdog.c
> +++ 2.6.13-rc6c/drivers/char/watchdog/softdog.c
> @@ -77,7 +77,7 @@ static void watchdog_fire(unsigned long)
>  
>  static struct timer_list watchdog_ticktock =
>  		TIMER_INITIALIZER(watchdog_fire, 0, 0);
> -static unsigned long timer_alive;
> +static unsigned long driver_open, orphan_timer;
>  static char expect_close;
>  
> 
> @@ -87,6 +87,9 @@ static char expect_close;
>  
>  static void watchdog_fire(unsigned long data)
>  {
> +	if (test_and_clear_bit(0, &orphan_timer))
> +		module_put(THIS_MODULE);
> +
>  	if (soft_noboot)
>  		printk(KERN_CRIT PFX "Triggered - Reboot ignored.\n");
>  	else
> @@ -128,9 +131,9 @@ static int softdog_set_heartbeat(int t)
>  
>  static int softdog_open(struct inode *inode, struct file *file)
>  {
> -	if(test_and_set_bit(0, &timer_alive))
> +	if (test_and_set_bit(0, &driver_open))
>  		return -EBUSY;
> -	if (nowayout)
> +	if (!test_and_clear_bit(0, &orphan_timer))
>  		__module_get(THIS_MODULE);
>  	/*
>  	 *	Activate timer
> @@ -147,11 +150,13 @@ static int softdog_release(struct inode 
>  	 */
>  	if (expect_close == 42) {
>  		softdog_stop();
> +		module_put(THIS_MODULE);
>  	} else {
>  		printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n");
> +		set_bit(0, &orphan_timer);
>  		softdog_keepalive();
>  	}
> -	clear_bit(0, &timer_alive);
> +	clear_bit(0, &driver_open);
>  	expect_close = 0;
>  	return 0;
>  }
> __
> Chuck
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]
  Powered by Linux