lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <20101224090141.GJ5544@angua.secretlab.ca>
Date:	Fri, 24 Dec 2010 02:01:41 -0700
From:	Grant Likely <grant.likely@...retlab.ca>
To:	Thomas Gleixner <tglx@...utronix.de>
Cc:	LKML <linux-kernel@...r.kernel.org>,
	Kristoffer Glembo <kristoffer@...sler.com>,
	Greg Kroah-Hartman <gregkh@...e.de>,
	Ingo Molnar <mingo@...e.hu>
Subject: Re: [patch] drivers: serial: apbuart: Handle OF failures gracefully

On Thu, Dec 16, 2010 at 01:06:35PM -0000, Thomas Gleixner wrote:
> The apbuart driver depends on OF and relies on everything being
> available. So if it's probed on a platform which has OF support, but
> no device tree is available it crashes. Triggered by the upcoming x86
> OF support in randconfig testing.
> 
> Further it's inconsistent vs. the probing and exiting from the
> of_match loop.
> 
> Make it robust and consistent:
> 
>  - check the availablility of OF nodes before dereferencing
>  - return -ENODEV when the device tree lookup fails
>  - return -ENODEV when no uart port configuration is found
>  - return -ENODEV when invalid uart port configuration is found
> 
> Remove the enum_done check while at it. Driver init functions are only
> called once. Remove the pointless vendor and device queries as well.
> 
> Reported-by: Ingo Molnar <mingo.elte.hu>
> Signed-off-by: Thomas Gleixner <tglx@...utronix.de>
> Cc: Grant Likely <grant.likely@...retlab.ca>
> Cc: Kristoffer Glembo <kristoffer@...sler.com>
> Cc: Greg Kroah-Hartman <gregkh@...e.de>
> 

Acked-by: Grant Likely <grant.likely@...retlab.ca>

> ---
>  drivers/serial/apbuart.c |   48 ++++++++++++++++++-----------------------------
>  1 file changed, 19 insertions(+), 29 deletions(-)
> 
> Index: linux-2.6-tip/drivers/serial/apbuart.c
> ===================================================================
> --- linux-2.6-tip.orig/drivers/serial/apbuart.c
> +++ linux-2.6-tip/drivers/serial/apbuart.c
> @@ -593,54 +593,44 @@ static struct of_platform_driver grlib_a
>  };
>  
>  
> -static void grlib_apbuart_configure(void)
> +static int grlib_apbuart_configure(void)
>  {
> -	static int enum_done;
>  	struct device_node *np, *rp;
> -	struct uart_port *port = NULL;
>  	const u32 *prop;
> -	int freq_khz;
> -	int v = 0, d = 0;
> -	unsigned int addr;
> -	int irq, line;
> -	struct amba_prom_registers *regs;
> -
> -	if (enum_done)
> -		return;
> +	int freq_khz, line = 0;
>  
>  	/* Get bus frequency */
>  	rp = of_find_node_by_path("/");
> +	if (!rp)
> +		return -ENODEV;
>  	rp = of_get_next_child(rp, NULL);
> +	if (!rp)
> +		return -ENODEV;
>  	prop = of_get_property(rp, "clock-frequency", NULL);
> +	if (!prop)
> +		return -ENODEV;
>  	freq_khz = *prop;
>  
> -	line = 0;
>  	for_each_matching_node(np, apbuart_match) {
> +		const int *irqs = of_get_property(np, "interrupts", NULL);
> +		const struct amba_prom_registers *regs;
> +		struct uart_port *port;
> +		unsigned long addr;
>  
> -		int *vendor = (int *) of_get_property(np, "vendor", NULL);
> -		int *device = (int *) of_get_property(np, "device", NULL);
> -		int *irqs = (int *) of_get_property(np, "interrupts", NULL);
> -		regs = (struct amba_prom_registers *)
> -		    of_get_property(np, "reg", NULL);
> -
> -		if (vendor)
> -			v = *vendor;
> -		if (device)
> -			d = *device;
> +		regs = of_get_property(np, "reg", NULL);
>  
>  		if (!irqs || !regs)
> -			return;
> +			return -ENODEV;
>  
>  		grlib_apbuart_nodes[line] = np;
>  
>  		addr = regs->phys_addr;
> -		irq = *irqs;
>  
>  		port = &grlib_apbuart_ports[line];
>  
>  		port->mapbase = addr;
>  		port->membase = ioremap(addr, sizeof(struct grlib_apbuart_regs_map));
> -		port->irq = irq;
> +		port->irq = *irqs;
>  		port->iotype = UPIO_MEM;
>  		port->ops = &grlib_apbuart_ops;
>  		port->flags = UPF_BOOT_AUTOCONF;
> @@ -652,12 +642,10 @@ static void grlib_apbuart_configure(void
>  		/* We support maximum UART_NR uarts ... */
>  		if (line == UART_NR)
>  			break;
> -
>  	}
>  
> -	enum_done = 1;
> -
>  	grlib_apbuart_driver.nr = grlib_apbuart_port_nr = line;
> +	return line ? 0 : -ENODEV;
>  }
>  
>  static int __init grlib_apbuart_init(void)
> @@ -665,7 +653,9 @@ static int __init grlib_apbuart_init(voi
>  	int ret;
>  
>  	/* Find all APBUARTS in device the tree and initialize their ports */
> -	grlib_apbuart_configure();
> +	ret = grlib_apbuart_configure();
> +	if (ret)
> +		return ret;
>  
>  	printk(KERN_INFO "Serial: GRLIB APBUART driver\n");
>  
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ