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] [thread-next>] [day] [month] [year] [list]
Date:	Tue,  2 Dec 2014 23:15:05 +0900
From:	Alexandre Courbot <acourbot@...dia.com>
To:	Linus Walleij <linus.walleij@...aro.org>,
	Geert Uytterhoeven <geert@...ux-m68k.org>
Cc:	linux-gpio@...r.kernel.org, linux-kernel@...r.kernel.org,
	gnurou@...il.com, Alexandre Courbot <acourbot@...dia.com>
Subject: [PATCH v2] gpio: fix deferred probe detection for legacy API

Commit 14e85c0e69d5 ("gpio: remove gpio_descs global array") changed
gpio_to_desc()'s behavior to return NULL not only for GPIOs numbers
not in the valid range, but also for all GPIOs whose controller has not
been probed yet. Although this behavior is more correct (nothing hints
that these GPIO numbers will be populated later), this affects
gpio_request() and gpio_request_one() which call gpiod_request() with a
NULL descriptor, causing it to return -EINVAL instead of the expected
-EPROBE_DEFER for a non-probed GPIO.

gpiod_request() is only called with a descriptor obtained from
gpio_to_desc() from these two functions, so address the issue there.

Other ways to obtain GPIOs rely on well-defined mappings and can thus
return -EPROBE_DEFER only for relevant GPIOs, and are thus not affected
by this issue.

Reported-by: Geert Uytterhoeven <geert@...ux-m68k.org>
Signed-off-by: Alexandre Courbot <acourbot@...dia.com>
---
v2:
- Add Geert's Tested-by
- Only display scary warning on gpio_to_desc() is the GPIO is outside
  the valid range (pre gpio_desc array removal behavior)

 drivers/gpio/gpiolib-legacy.c | 12 +++++++++++-
 drivers/gpio/gpiolib.c        |  4 +++-
 2 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/drivers/gpio/gpiolib-legacy.c b/drivers/gpio/gpiolib-legacy.c
index 078ae6c..8b83099 100644
--- a/drivers/gpio/gpiolib-legacy.c
+++ b/drivers/gpio/gpiolib-legacy.c
@@ -24,6 +24,10 @@ int gpio_request_one(unsigned gpio, unsigned long flags, const char *label)
 
 	desc = gpio_to_desc(gpio);
 
+	/* Compatibility: assume unavailable "valid" GPIOs will appear later */
+	if (!desc && gpio_is_valid(gpio))
+		return -EPROBE_DEFER;
+
 	err = gpiod_request(desc, label);
 	if (err)
 		return err;
@@ -62,7 +66,13 @@ EXPORT_SYMBOL_GPL(gpio_request_one);
 
 int gpio_request(unsigned gpio, const char *label)
 {
-	return gpiod_request(gpio_to_desc(gpio), label);
+	struct gpio_desc *desc = gpio_to_desc(gpio);
+
+	/* Compatibility: assume unavailable "valid" GPIOs will appear later */
+	if (!desc && gpio_is_valid(gpio))
+		return -EPROBE_DEFER;
+
+	return gpiod_request(desc, label);
 }
 EXPORT_SYMBOL_GPL(gpio_request);
 
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 0b271ef8..56b7c5d 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -77,7 +77,9 @@ struct gpio_desc *gpio_to_desc(unsigned gpio)
 
 	spin_unlock_irqrestore(&gpio_lock, flags);
 
-	WARN(1, "invalid GPIO %d\n", gpio);
+	if (!gpio_is_valid(gpio))
+		WARN(1, "invalid GPIO %d\n", gpio);
+
 	return NULL;
 }
 EXPORT_SYMBOL_GPL(gpio_to_desc);
-- 
2.1.3

--
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