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: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20200223104259.GE14067@amd>
Date:   Sun, 23 Feb 2020 11:42:59 +0100
From:   Pavel Machek <pavel@...x.de>
To:     Greg Kroah-Hartman <gregkh@...uxfoundation.org>
Cc:     linux-kernel@...r.kernel.org, stable@...r.kernel.org,
        Jia-Ju Bai <baijiaju1990@...il.com>,
        Linus Walleij <linus.walleij@...aro.org>,
        Sasha Levin <sashal@...nel.org>
Subject: Re: [PATCH 4.19 023/191] gpio: gpio-grgpio: fix possible
 sleep-in-atomic-context bugs in grgpio_irq_map/unmap()

Hi!

> From: Jia-Ju Bai <baijiaju1990@...il.com>
> 
> [ Upstream commit e36eaf94be8f7bc4e686246eed3cf92d845e2ef8 ]
> 
> The driver may sleep while holding a spinlock.

True.

But you can't fix the bug by simply removing the locking, as now
nothing prevents grgpio_irq_unmap() from running while
grgpio_irq_map() is proceeding.

grgpio_irq_map()
	lirq->irq = irq;
	(drops the lock)

grgpio_irq_unmap()
	(gets the lock)
 	if (lirq->irq == irq) {
	 	...
		(proceeds to work with half-initialized structure)

Best regards,
							Pavel


> index 60a1556c570a4..c1be299e5567b 100644
> --- a/drivers/gpio/gpio-grgpio.c
> +++ b/drivers/gpio/gpio-grgpio.c
> @@ -258,17 +258,16 @@ static int grgpio_irq_map(struct irq_domain *d, unsigned int irq,
>  	lirq->irq = irq;
>  	uirq = &priv->uirqs[lirq->index];
>  	if (uirq->refcnt == 0) {
> +		spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);
>  		ret = request_irq(uirq->uirq, grgpio_irq_handler, 0,
>  				  dev_name(priv->dev), priv);
>  		if (ret) {
>  			dev_err(priv->dev,
>  				"Could not request underlying irq %d\n",
>  				uirq->uirq);
> -
> -			spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);
> -
>  			return ret;
>  		}
> +		spin_lock_irqsave(&priv->gc.bgpio_lock, flags);
>  	}
>  	uirq->refcnt++;
>  
> @@ -314,8 +313,11 @@ static void grgpio_irq_unmap(struct irq_domain *d, unsigned int irq)
>  	if (index >= 0) {
>  		uirq = &priv->uirqs[lirq->index];
>  		uirq->refcnt--;
> -		if (uirq->refcnt == 0)
> +		if (uirq->refcnt == 0) {
> +			spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);
>  			free_irq(uirq->uirq, priv);
> +			return;
> +		}
>  	}
>  
>  	spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);

-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

Download attachment "signature.asc" of type "application/pgp-signature" (182 bytes)

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ