aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-10-25 00:19:07 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-10-25 00:19:07 -0400
commit1ce5bdb8312b6e9629029340063ea1e5cfac435d (patch)
treec47706ca6b30ff50ec204e5abfb5ee22dc841e48
parentaa34e07e457ed13b44d680b5b605e3e5a585f611 (diff)
parentd71cf15b865bdd45925f7b094d169aaabd705145 (diff)
Merge tag 'gpio-v4.9-2' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio
Pull GPIO fixes from Linus Walleij: "Here is a set of GPIO fixes for the v4.9 kernel series: - Fix up off-by one and line offset validation, info leak to userspace, and reject invalid flags. Those are especially valuable hardening patches from Lars-Peter Clausen, all tagged for stable. - Fix module autoload for TS4800 and ATH79. - Correct the IRQ handler for MPC8xxx to use handle_level_irq() as it (a) reacts to edges not levels and (b) even implements .irq_ack(). We were missing IRQs here. - Fix the error path for acpi_dev_gpio_irq_get() - Fix a memory leak in the MXS driver. - Fix an annoying typo in the STMPE driver. - Put a dependency on sysfs to the mockup driver" * tag 'gpio-v4.9-2' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio: gpio: mpc8xxx: Correct irq handler function gpio: ath79: Fix module autoload gpio: ts4800: Fix module autoload gpio: GPIO_GET_LINEEVENT_IOCTL: Reject invalid line and event flags gpio: GPIO_GET_LINEHANDLE_IOCTL: Reject invalid line flags gpio: GPIOHANDLE_GET_LINE_VALUES_IOCTL: Fix information leak gpio: GPIO_GET_LINEEVENT_IOCTL: Validate line offset gpio: GPIOHANDLE_GET_LINE_VALUES_IOCTL: Fix information leak gpio: GPIO_GET_LINEHANDLE_IOCTL: Validate line offset gpio: GPIO_GET_CHIPINFO_IOCTL: Fix information leak gpio: GPIO_GET_CHIPINFO_IOCTL: Fix line offset validation gpio / ACPI: fix returned error from acpi_dev_gpio_irq_get() gpio: mockup: add sysfs dependency gpio: stmpe: || vs && typo gpio: mxs: Unmap region obtained by of_iomap gpio/board.txt: point to gpiod_set_value
-rw-r--r--Documentation/gpio/board.txt11
-rw-r--r--drivers/gpio/Kconfig2
-rw-r--r--drivers/gpio/gpio-ath79.c1
-rw-r--r--drivers/gpio/gpio-mpc8xxx.c2
-rw-r--r--drivers/gpio/gpio-mxs.c8
-rw-r--r--drivers/gpio/gpio-stmpe.c2
-rw-r--r--drivers/gpio/gpio-ts4800.c1
-rw-r--r--drivers/gpio/gpiolib-acpi.c7
-rw-r--r--drivers/gpio/gpiolib.c42
9 files changed, 64 insertions, 12 deletions
diff --git a/Documentation/gpio/board.txt b/Documentation/gpio/board.txt
index 40884c4fe40c..a0f61898d493 100644
--- a/Documentation/gpio/board.txt
+++ b/Documentation/gpio/board.txt
@@ -6,7 +6,7 @@ Note that it only applies to the new descriptor-based interface. For a
6description of the deprecated integer-based GPIO interface please refer to 6description of the deprecated integer-based GPIO interface please refer to
7gpio-legacy.txt (actually, there is no real mapping possible with the old 7gpio-legacy.txt (actually, there is no real mapping possible with the old
8interface; you just fetch an integer from somewhere and request the 8interface; you just fetch an integer from somewhere and request the
9corresponding GPIO. 9corresponding GPIO).
10 10
11All platforms can enable the GPIO library, but if the platform strictly 11All platforms can enable the GPIO library, but if the platform strictly
12requires GPIO functionality to be present, it needs to select GPIOLIB from its 12requires GPIO functionality to be present, it needs to select GPIOLIB from its
@@ -162,6 +162,9 @@ The driver controlling "foo.0" will then be able to obtain its GPIOs as follows:
162 162
163Since the "led" GPIOs are mapped as active-high, this example will switch their 163Since the "led" GPIOs are mapped as active-high, this example will switch their
164signals to 1, i.e. enabling the LEDs. And for the "power" GPIO, which is mapped 164signals to 1, i.e. enabling the LEDs. And for the "power" GPIO, which is mapped
165as active-low, its actual signal will be 0 after this code. Contrary to the legacy 165as active-low, its actual signal will be 0 after this code. Contrary to the
166integer GPIO interface, the active-low property is handled during mapping and is 166legacy integer GPIO interface, the active-low property is handled during
167thus transparent to GPIO consumers. 167mapping and is thus transparent to GPIO consumers.
168
169A set of functions such as gpiod_set_value() is available to work with
170the new descriptor-oriented interface.
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 26ee00f6bd58..d011cb89d25e 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -284,7 +284,7 @@ config GPIO_MM_LANTIQ
284 284
285config GPIO_MOCKUP 285config GPIO_MOCKUP
286 tristate "GPIO Testing Driver" 286 tristate "GPIO Testing Driver"
287 depends on GPIOLIB 287 depends on GPIOLIB && SYSFS
288 select GPIO_SYSFS 288 select GPIO_SYSFS
289 help 289 help
290 This enables GPIO Testing driver, which provides a way to test GPIO 290 This enables GPIO Testing driver, which provides a way to test GPIO
diff --git a/drivers/gpio/gpio-ath79.c b/drivers/gpio/gpio-ath79.c
index 9457e2022bf6..dc37dbe4b46d 100644
--- a/drivers/gpio/gpio-ath79.c
+++ b/drivers/gpio/gpio-ath79.c
@@ -219,6 +219,7 @@ static const struct of_device_id ath79_gpio_of_match[] = {
219 { .compatible = "qca,ar9340-gpio" }, 219 { .compatible = "qca,ar9340-gpio" },
220 {}, 220 {},
221}; 221};
222MODULE_DEVICE_TABLE(of, ath79_gpio_of_match);
222 223
223static int ath79_gpio_probe(struct platform_device *pdev) 224static int ath79_gpio_probe(struct platform_device *pdev)
224{ 225{
diff --git a/drivers/gpio/gpio-mpc8xxx.c b/drivers/gpio/gpio-mpc8xxx.c
index 425501c39527..793518a30afe 100644
--- a/drivers/gpio/gpio-mpc8xxx.c
+++ b/drivers/gpio/gpio-mpc8xxx.c
@@ -239,7 +239,7 @@ static int mpc8xxx_gpio_irq_map(struct irq_domain *h, unsigned int irq,
239 irq_hw_number_t hwirq) 239 irq_hw_number_t hwirq)
240{ 240{
241 irq_set_chip_data(irq, h->host_data); 241 irq_set_chip_data(irq, h->host_data);
242 irq_set_chip_and_handler(irq, &mpc8xxx_irq_chip, handle_level_irq); 242 irq_set_chip_and_handler(irq, &mpc8xxx_irq_chip, handle_edge_irq);
243 243
244 return 0; 244 return 0;
245} 245}
diff --git a/drivers/gpio/gpio-mxs.c b/drivers/gpio/gpio-mxs.c
index b9daa0bf32a4..ee1724806f46 100644
--- a/drivers/gpio/gpio-mxs.c
+++ b/drivers/gpio/gpio-mxs.c
@@ -308,8 +308,10 @@ static int mxs_gpio_probe(struct platform_device *pdev)
308 writel(~0U, port->base + PINCTRL_IRQSTAT(port) + MXS_CLR); 308 writel(~0U, port->base + PINCTRL_IRQSTAT(port) + MXS_CLR);
309 309
310 irq_base = irq_alloc_descs(-1, 0, 32, numa_node_id()); 310 irq_base = irq_alloc_descs(-1, 0, 32, numa_node_id());
311 if (irq_base < 0) 311 if (irq_base < 0) {
312 return irq_base; 312 err = irq_base;
313 goto out_iounmap;
314 }
313 315
314 port->domain = irq_domain_add_legacy(np, 32, irq_base, 0, 316 port->domain = irq_domain_add_legacy(np, 32, irq_base, 0,
315 &irq_domain_simple_ops, NULL); 317 &irq_domain_simple_ops, NULL);
@@ -349,6 +351,8 @@ out_irqdomain_remove:
349 irq_domain_remove(port->domain); 351 irq_domain_remove(port->domain);
350out_irqdesc_free: 352out_irqdesc_free:
351 irq_free_descs(irq_base, 32); 353 irq_free_descs(irq_base, 32);
354out_iounmap:
355 iounmap(port->base);
352 return err; 356 return err;
353} 357}
354 358
diff --git a/drivers/gpio/gpio-stmpe.c b/drivers/gpio/gpio-stmpe.c
index e7d422a6b90b..5b0042776ec7 100644
--- a/drivers/gpio/gpio-stmpe.c
+++ b/drivers/gpio/gpio-stmpe.c
@@ -409,7 +409,7 @@ static irqreturn_t stmpe_gpio_irq(int irq, void *dev)
409 * 801/1801/1600, bits are cleared when read. 409 * 801/1801/1600, bits are cleared when read.
410 * Edge detect register is not present on 801/1600/1801 410 * Edge detect register is not present on 801/1600/1801
411 */ 411 */
412 if (stmpe->partnum != STMPE801 || stmpe->partnum != STMPE1600 || 412 if (stmpe->partnum != STMPE801 && stmpe->partnum != STMPE1600 &&
413 stmpe->partnum != STMPE1801) { 413 stmpe->partnum != STMPE1801) {
414 stmpe_reg_write(stmpe, statmsbreg + i, status[i]); 414 stmpe_reg_write(stmpe, statmsbreg + i, status[i]);
415 stmpe_reg_write(stmpe, 415 stmpe_reg_write(stmpe,
diff --git a/drivers/gpio/gpio-ts4800.c b/drivers/gpio/gpio-ts4800.c
index 99256115bea5..c2a80b4cbf32 100644
--- a/drivers/gpio/gpio-ts4800.c
+++ b/drivers/gpio/gpio-ts4800.c
@@ -66,6 +66,7 @@ static const struct of_device_id ts4800_gpio_of_match[] = {
66 { .compatible = "technologic,ts4800-gpio", }, 66 { .compatible = "technologic,ts4800-gpio", },
67 {}, 67 {},
68}; 68};
69MODULE_DEVICE_TABLE(of, ts4800_gpio_of_match);
69 70
70static struct platform_driver ts4800_gpio_driver = { 71static struct platform_driver ts4800_gpio_driver = {
71 .driver = { 72 .driver = {
diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c
index 58ece201b8e6..72a4b326fd0d 100644
--- a/drivers/gpio/gpiolib-acpi.c
+++ b/drivers/gpio/gpiolib-acpi.c
@@ -653,14 +653,17 @@ int acpi_dev_gpio_irq_get(struct acpi_device *adev, int index)
653{ 653{
654 int idx, i; 654 int idx, i;
655 unsigned int irq_flags; 655 unsigned int irq_flags;
656 int ret = -ENOENT;
656 657
657 for (i = 0, idx = 0; idx <= index; i++) { 658 for (i = 0, idx = 0; idx <= index; i++) {
658 struct acpi_gpio_info info; 659 struct acpi_gpio_info info;
659 struct gpio_desc *desc; 660 struct gpio_desc *desc;
660 661
661 desc = acpi_get_gpiod_by_index(adev, NULL, i, &info); 662 desc = acpi_get_gpiod_by_index(adev, NULL, i, &info);
662 if (IS_ERR(desc)) 663 if (IS_ERR(desc)) {
664 ret = PTR_ERR(desc);
663 break; 665 break;
666 }
664 if (info.gpioint && idx++ == index) { 667 if (info.gpioint && idx++ == index) {
665 int irq = gpiod_to_irq(desc); 668 int irq = gpiod_to_irq(desc);
666 669
@@ -679,7 +682,7 @@ int acpi_dev_gpio_irq_get(struct acpi_device *adev, int index)
679 } 682 }
680 683
681 } 684 }
682 return -ENOENT; 685 return ret;
683} 686}
684EXPORT_SYMBOL_GPL(acpi_dev_gpio_irq_get); 687EXPORT_SYMBOL_GPL(acpi_dev_gpio_irq_get);
685 688
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index f0fc3a0d37c8..20e09b7c2de3 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -333,6 +333,13 @@ struct linehandle_state {
333 u32 numdescs; 333 u32 numdescs;
334}; 334};
335 335
336#define GPIOHANDLE_REQUEST_VALID_FLAGS \
337 (GPIOHANDLE_REQUEST_INPUT | \
338 GPIOHANDLE_REQUEST_OUTPUT | \
339 GPIOHANDLE_REQUEST_ACTIVE_LOW | \
340 GPIOHANDLE_REQUEST_OPEN_DRAIN | \
341 GPIOHANDLE_REQUEST_OPEN_SOURCE)
342
336static long linehandle_ioctl(struct file *filep, unsigned int cmd, 343static long linehandle_ioctl(struct file *filep, unsigned int cmd,
337 unsigned long arg) 344 unsigned long arg)
338{ 345{
@@ -344,6 +351,8 @@ static long linehandle_ioctl(struct file *filep, unsigned int cmd,
344 if (cmd == GPIOHANDLE_GET_LINE_VALUES_IOCTL) { 351 if (cmd == GPIOHANDLE_GET_LINE_VALUES_IOCTL) {
345 int val; 352 int val;
346 353
354 memset(&ghd, 0, sizeof(ghd));
355
347 /* TODO: check if descriptors are really input */ 356 /* TODO: check if descriptors are really input */
348 for (i = 0; i < lh->numdescs; i++) { 357 for (i = 0; i < lh->numdescs; i++) {
349 val = gpiod_get_value_cansleep(lh->descs[i]); 358 val = gpiod_get_value_cansleep(lh->descs[i]);
@@ -444,6 +453,17 @@ static int linehandle_create(struct gpio_device *gdev, void __user *ip)
444 u32 lflags = handlereq.flags; 453 u32 lflags = handlereq.flags;
445 struct gpio_desc *desc; 454 struct gpio_desc *desc;
446 455
456 if (offset >= gdev->ngpio) {
457 ret = -EINVAL;
458 goto out_free_descs;
459 }
460
461 /* Return an error if a unknown flag is set */
462 if (lflags & ~GPIOHANDLE_REQUEST_VALID_FLAGS) {
463 ret = -EINVAL;
464 goto out_free_descs;
465 }
466
447 desc = &gdev->descs[offset]; 467 desc = &gdev->descs[offset];
448 ret = gpiod_request(desc, lh->label); 468 ret = gpiod_request(desc, lh->label);
449 if (ret) 469 if (ret)
@@ -536,6 +556,10 @@ struct lineevent_state {
536 struct mutex read_lock; 556 struct mutex read_lock;
537}; 557};
538 558
559#define GPIOEVENT_REQUEST_VALID_FLAGS \
560 (GPIOEVENT_REQUEST_RISING_EDGE | \
561 GPIOEVENT_REQUEST_FALLING_EDGE)
562
539static unsigned int lineevent_poll(struct file *filep, 563static unsigned int lineevent_poll(struct file *filep,
540 struct poll_table_struct *wait) 564 struct poll_table_struct *wait)
541{ 565{
@@ -623,6 +647,8 @@ static long lineevent_ioctl(struct file *filep, unsigned int cmd,
623 if (cmd == GPIOHANDLE_GET_LINE_VALUES_IOCTL) { 647 if (cmd == GPIOHANDLE_GET_LINE_VALUES_IOCTL) {
624 int val; 648 int val;
625 649
650 memset(&ghd, 0, sizeof(ghd));
651
626 val = gpiod_get_value_cansleep(le->desc); 652 val = gpiod_get_value_cansleep(le->desc);
627 if (val < 0) 653 if (val < 0)
628 return val; 654 return val;
@@ -726,6 +752,18 @@ static int lineevent_create(struct gpio_device *gdev, void __user *ip)
726 lflags = eventreq.handleflags; 752 lflags = eventreq.handleflags;
727 eflags = eventreq.eventflags; 753 eflags = eventreq.eventflags;
728 754
755 if (offset >= gdev->ngpio) {
756 ret = -EINVAL;
757 goto out_free_label;
758 }
759
760 /* Return an error if a unknown flag is set */
761 if ((lflags & ~GPIOHANDLE_REQUEST_VALID_FLAGS) ||
762 (eflags & ~GPIOEVENT_REQUEST_VALID_FLAGS)) {
763 ret = -EINVAL;
764 goto out_free_label;
765 }
766
729 /* This is just wrong: we don't look for events on output lines */ 767 /* This is just wrong: we don't look for events on output lines */
730 if (lflags & GPIOHANDLE_REQUEST_OUTPUT) { 768 if (lflags & GPIOHANDLE_REQUEST_OUTPUT) {
731 ret = -EINVAL; 769 ret = -EINVAL;
@@ -823,6 +861,8 @@ static long gpio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
823 if (cmd == GPIO_GET_CHIPINFO_IOCTL) { 861 if (cmd == GPIO_GET_CHIPINFO_IOCTL) {
824 struct gpiochip_info chipinfo; 862 struct gpiochip_info chipinfo;
825 863
864 memset(&chipinfo, 0, sizeof(chipinfo));
865
826 strncpy(chipinfo.name, dev_name(&gdev->dev), 866 strncpy(chipinfo.name, dev_name(&gdev->dev),
827 sizeof(chipinfo.name)); 867 sizeof(chipinfo.name));
828 chipinfo.name[sizeof(chipinfo.name)-1] = '\0'; 868 chipinfo.name[sizeof(chipinfo.name)-1] = '\0';
@@ -839,7 +879,7 @@ static long gpio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
839 879
840 if (copy_from_user(&lineinfo, ip, sizeof(lineinfo))) 880 if (copy_from_user(&lineinfo, ip, sizeof(lineinfo)))
841 return -EFAULT; 881 return -EFAULT;
842 if (lineinfo.line_offset > gdev->ngpio) 882 if (lineinfo.line_offset >= gdev->ngpio)
843 return -EINVAL; 883 return -EINVAL;
844 884
845 desc = &gdev->descs[lineinfo.line_offset]; 885 desc = &gdev->descs[lineinfo.line_offset];