aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio/gpiolib.c
diff options
context:
space:
mode:
authorAlexandre Courbot <acourbot@nvidia.com>2013-02-15 00:46:14 -0500
committerGrant Likely <grant.likely@secretlab.ca>2013-03-02 08:20:19 -0500
commitbcabdef12da49878789464ad7239e97d83ea5ef5 (patch)
tree9ecc37897f165bdd812551f4696cd3ed7f78de65 /drivers/gpio/gpiolib.c
parentb0af9cd9aab60ceb17d3ebabb9fdf4ff0a99cf50 (diff)
gpiolib: check descriptors validity before use
Some functions dereferenced their GPIO descriptor argument without checking its validity first, potentially leading to an oops when given an invalid argument. This patch also makes gpio_get_value() more resilient when given an invalid GPIO, returning 0 instead of silently crashing. Signed-off-by: Alexandre Courbot <acourbot@nvidia.com> Cc: Ryan Mallon <rmallon@gmail.com> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Diffstat (limited to 'drivers/gpio/gpiolib.c')
-rw-r--r--drivers/gpio/gpiolib.c112
1 files changed, 65 insertions, 47 deletions
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index fff9786cdc64..1a8a7a8f803f 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -174,7 +174,7 @@ static int gpio_ensure_requested(struct gpio_desc *desc)
174/* caller holds gpio_lock *OR* gpio is marked as requested */ 174/* caller holds gpio_lock *OR* gpio is marked as requested */
175static struct gpio_chip *gpiod_to_chip(struct gpio_desc *desc) 175static struct gpio_chip *gpiod_to_chip(struct gpio_desc *desc)
176{ 176{
177 return desc->chip; 177 return desc ? desc->chip : NULL;
178} 178}
179 179
180struct gpio_chip *gpio_to_chip(unsigned gpio) 180struct gpio_chip *gpio_to_chip(unsigned gpio)
@@ -654,6 +654,11 @@ static ssize_t export_store(struct class *class,
654 goto done; 654 goto done;
655 655
656 desc = gpio_to_desc(gpio); 656 desc = gpio_to_desc(gpio);
657 /* reject invalid GPIOs */
658 if (!desc) {
659 pr_warn("%s: invalid GPIO %ld\n", __func__, gpio);
660 return -EINVAL;
661 }
657 662
658 /* No extra locking here; FLAG_SYSFS just signifies that the 663 /* No extra locking here; FLAG_SYSFS just signifies that the
659 * request and export were done by on behalf of userspace, so 664 * request and export were done by on behalf of userspace, so
@@ -690,12 +695,14 @@ static ssize_t unexport_store(struct class *class,
690 if (status < 0) 695 if (status < 0)
691 goto done; 696 goto done;
692 697
693 status = -EINVAL;
694
695 desc = gpio_to_desc(gpio); 698 desc = gpio_to_desc(gpio);
696 /* reject bogus commands (gpio_unexport ignores them) */ 699 /* reject bogus commands (gpio_unexport ignores them) */
697 if (!desc) 700 if (!desc) {
698 goto done; 701 pr_warn("%s: invalid GPIO %ld\n", __func__, gpio);
702 return -EINVAL;
703 }
704
705 status = -EINVAL;
699 706
700 /* No extra locking here; FLAG_SYSFS just signifies that the 707 /* No extra locking here; FLAG_SYSFS just signifies that the
701 * request and export were done by on behalf of userspace, so 708 * request and export were done by on behalf of userspace, so
@@ -846,8 +853,10 @@ static int gpiod_export_link(struct device *dev, const char *name,
846{ 853{
847 int status = -EINVAL; 854 int status = -EINVAL;
848 855
849 if (!desc) 856 if (!desc) {
850 goto done; 857 pr_warn("%s: invalid GPIO\n", __func__);
858 return -EINVAL;
859 }
851 860
852 mutex_lock(&sysfs_lock); 861 mutex_lock(&sysfs_lock);
853 862
@@ -865,7 +874,6 @@ static int gpiod_export_link(struct device *dev, const char *name,
865 874
866 mutex_unlock(&sysfs_lock); 875 mutex_unlock(&sysfs_lock);
867 876
868done:
869 if (status) 877 if (status)
870 pr_debug("%s: gpio%d status %d\n", __func__, desc_to_gpio(desc), 878 pr_debug("%s: gpio%d status %d\n", __func__, desc_to_gpio(desc),
871 status); 879 status);
@@ -896,8 +904,10 @@ static int gpiod_sysfs_set_active_low(struct gpio_desc *desc, int value)
896 struct device *dev = NULL; 904 struct device *dev = NULL;
897 int status = -EINVAL; 905 int status = -EINVAL;
898 906
899 if (!desc) 907 if (!desc) {
900 goto done; 908 pr_warn("%s: invalid GPIO\n", __func__);
909 return -EINVAL;
910 }
901 911
902 mutex_lock(&sysfs_lock); 912 mutex_lock(&sysfs_lock);
903 913
@@ -914,7 +924,6 @@ static int gpiod_sysfs_set_active_low(struct gpio_desc *desc, int value)
914unlock: 924unlock:
915 mutex_unlock(&sysfs_lock); 925 mutex_unlock(&sysfs_lock);
916 926
917done:
918 if (status) 927 if (status)
919 pr_debug("%s: gpio%d status %d\n", __func__, desc_to_gpio(desc), 928 pr_debug("%s: gpio%d status %d\n", __func__, desc_to_gpio(desc),
920 status); 929 status);
@@ -940,8 +949,8 @@ static void gpiod_unexport(struct gpio_desc *desc)
940 struct device *dev = NULL; 949 struct device *dev = NULL;
941 950
942 if (!desc) { 951 if (!desc) {
943 status = -EINVAL; 952 pr_warn("%s: invalid GPIO\n", __func__);
944 goto done; 953 return;
945 } 954 }
946 955
947 mutex_lock(&sysfs_lock); 956 mutex_lock(&sysfs_lock);
@@ -962,7 +971,7 @@ static void gpiod_unexport(struct gpio_desc *desc)
962 device_unregister(dev); 971 device_unregister(dev);
963 put_device(dev); 972 put_device(dev);
964 } 973 }
965done: 974
966 if (status) 975 if (status)
967 pr_debug("%s: gpio%d status %d\n", __func__, desc_to_gpio(desc), 976 pr_debug("%s: gpio%d status %d\n", __func__, desc_to_gpio(desc),
968 status); 977 status);
@@ -1384,12 +1393,13 @@ static int gpiod_request(struct gpio_desc *desc, const char *label)
1384 int status = -EPROBE_DEFER; 1393 int status = -EPROBE_DEFER;
1385 unsigned long flags; 1394 unsigned long flags;
1386 1395
1387 spin_lock_irqsave(&gpio_lock, flags);
1388
1389 if (!desc) { 1396 if (!desc) {
1390 status = -EINVAL; 1397 pr_warn("%s: invalid GPIO\n", __func__);
1391 goto done; 1398 return -EINVAL;
1392 } 1399 }
1400
1401 spin_lock_irqsave(&gpio_lock, flags);
1402
1393 chip = desc->chip; 1403 chip = desc->chip;
1394 if (chip == NULL) 1404 if (chip == NULL)
1395 goto done; 1405 goto done;
@@ -1432,8 +1442,7 @@ static int gpiod_request(struct gpio_desc *desc, const char *label)
1432done: 1442done:
1433 if (status) 1443 if (status)
1434 pr_debug("_gpio_request: gpio-%d (%s) status %d\n", 1444 pr_debug("_gpio_request: gpio-%d (%s) status %d\n",
1435 desc ? desc_to_gpio(desc) : -1, 1445 desc_to_gpio(desc), label ? : "?", status);
1436 label ? : "?", status);
1437 spin_unlock_irqrestore(&gpio_lock, flags); 1446 spin_unlock_irqrestore(&gpio_lock, flags);
1438 return status; 1447 return status;
1439} 1448}
@@ -1616,10 +1625,13 @@ static int gpiod_direction_input(struct gpio_desc *desc)
1616 int status = -EINVAL; 1625 int status = -EINVAL;
1617 int offset; 1626 int offset;
1618 1627
1628 if (!desc) {
1629 pr_warn("%s: invalid GPIO\n", __func__);
1630 return -EINVAL;
1631 }
1632
1619 spin_lock_irqsave(&gpio_lock, flags); 1633 spin_lock_irqsave(&gpio_lock, flags);
1620 1634
1621 if (!desc)
1622 goto fail;
1623 chip = desc->chip; 1635 chip = desc->chip;
1624 if (!chip || !chip->get || !chip->direction_input) 1636 if (!chip || !chip->get || !chip->direction_input)
1625 goto fail; 1637 goto fail;
@@ -1655,13 +1667,9 @@ lose:
1655 return status; 1667 return status;
1656fail: 1668fail:
1657 spin_unlock_irqrestore(&gpio_lock, flags); 1669 spin_unlock_irqrestore(&gpio_lock, flags);
1658 if (status) { 1670 if (status)
1659 int gpio = -1; 1671 pr_debug("%s: gpio-%d status %d\n", __func__,
1660 if (desc) 1672 desc_to_gpio(desc), status);
1661 gpio = desc_to_gpio(desc);
1662 pr_debug("%s: gpio-%d status %d\n",
1663 __func__, gpio, status);
1664 }
1665 return status; 1673 return status;
1666} 1674}
1667 1675
@@ -1678,6 +1686,11 @@ static int gpiod_direction_output(struct gpio_desc *desc, int value)
1678 int status = -EINVAL; 1686 int status = -EINVAL;
1679 int offset; 1687 int offset;
1680 1688
1689 if (!desc) {
1690 pr_warn("%s: invalid GPIO\n", __func__);
1691 return -EINVAL;
1692 }
1693
1681 /* Open drain pin should not be driven to 1 */ 1694 /* Open drain pin should not be driven to 1 */
1682 if (value && test_bit(FLAG_OPEN_DRAIN, &desc->flags)) 1695 if (value && test_bit(FLAG_OPEN_DRAIN, &desc->flags))
1683 return gpiod_direction_input(desc); 1696 return gpiod_direction_input(desc);
@@ -1688,8 +1701,6 @@ static int gpiod_direction_output(struct gpio_desc *desc, int value)
1688 1701
1689 spin_lock_irqsave(&gpio_lock, flags); 1702 spin_lock_irqsave(&gpio_lock, flags);
1690 1703
1691 if (!desc)
1692 goto fail;
1693 chip = desc->chip; 1704 chip = desc->chip;
1694 if (!chip || !chip->set || !chip->direction_output) 1705 if (!chip || !chip->set || !chip->direction_output)
1695 goto fail; 1706 goto fail;
@@ -1725,13 +1736,9 @@ lose:
1725 return status; 1736 return status;
1726fail: 1737fail:
1727 spin_unlock_irqrestore(&gpio_lock, flags); 1738 spin_unlock_irqrestore(&gpio_lock, flags);
1728 if (status) { 1739 if (status)
1729 int gpio = -1; 1740 pr_debug("%s: gpio-%d status %d\n", __func__,
1730 if (desc) 1741 desc_to_gpio(desc), status);
1731 gpio = desc_to_gpio(desc);
1732 pr_debug("%s: gpio-%d status %d\n",
1733 __func__, gpio, status);
1734 }
1735 return status; 1742 return status;
1736} 1743}
1737 1744
@@ -1753,10 +1760,13 @@ static int gpiod_set_debounce(struct gpio_desc *desc, unsigned debounce)
1753 int status = -EINVAL; 1760 int status = -EINVAL;
1754 int offset; 1761 int offset;
1755 1762
1763 if (!desc) {
1764 pr_warn("%s: invalid GPIO\n", __func__);
1765 return -EINVAL;
1766 }
1767
1756 spin_lock_irqsave(&gpio_lock, flags); 1768 spin_lock_irqsave(&gpio_lock, flags);
1757 1769
1758 if (!desc)
1759 goto fail;
1760 chip = desc->chip; 1770 chip = desc->chip;
1761 if (!chip || !chip->set || !chip->set_debounce) 1771 if (!chip || !chip->set || !chip->set_debounce)
1762 goto fail; 1772 goto fail;
@@ -1776,13 +1786,9 @@ static int gpiod_set_debounce(struct gpio_desc *desc, unsigned debounce)
1776 1786
1777fail: 1787fail:
1778 spin_unlock_irqrestore(&gpio_lock, flags); 1788 spin_unlock_irqrestore(&gpio_lock, flags);
1779 if (status) { 1789 if (status)
1780 int gpio = -1; 1790 pr_debug("%s: gpio-%d status %d\n", __func__,
1781 if (desc) 1791 desc_to_gpio(desc), status);
1782 gpio = desc_to_gpio(desc);
1783 pr_debug("%s: gpio-%d status %d\n",
1784 __func__, gpio, status);
1785 }
1786 1792
1787 return status; 1793 return status;
1788} 1794}
@@ -1830,6 +1836,8 @@ static int gpiod_get_value(struct gpio_desc *desc)
1830 int value; 1836 int value;
1831 int offset; 1837 int offset;
1832 1838
1839 if (!desc)
1840 return 0;
1833 chip = desc->chip; 1841 chip = desc->chip;
1834 offset = gpio_chip_hwgpio(desc); 1842 offset = gpio_chip_hwgpio(desc);
1835 /* Should be using gpio_get_value_cansleep() */ 1843 /* Should be using gpio_get_value_cansleep() */
@@ -1912,6 +1920,8 @@ static void gpiod_set_value(struct gpio_desc *desc, int value)
1912{ 1920{
1913 struct gpio_chip *chip; 1921 struct gpio_chip *chip;
1914 1922
1923 if (!desc)
1924 return;
1915 chip = desc->chip; 1925 chip = desc->chip;
1916 /* Should be using gpio_set_value_cansleep() */ 1926 /* Should be using gpio_set_value_cansleep() */
1917 WARN_ON(chip->can_sleep); 1927 WARN_ON(chip->can_sleep);
@@ -1940,6 +1950,8 @@ EXPORT_SYMBOL_GPL(__gpio_set_value);
1940 */ 1950 */
1941static int gpiod_cansleep(struct gpio_desc *desc) 1951static int gpiod_cansleep(struct gpio_desc *desc)
1942{ 1952{
1953 if (!desc)
1954 return 0;
1943 /* only call this on GPIOs that are valid! */ 1955 /* only call this on GPIOs that are valid! */
1944 return desc->chip->can_sleep; 1956 return desc->chip->can_sleep;
1945} 1957}
@@ -1964,6 +1976,8 @@ static int gpiod_to_irq(struct gpio_desc *desc)
1964 struct gpio_chip *chip; 1976 struct gpio_chip *chip;
1965 int offset; 1977 int offset;
1966 1978
1979 if (!desc)
1980 return -EINVAL;
1967 chip = desc->chip; 1981 chip = desc->chip;
1968 offset = gpio_chip_hwgpio(desc); 1982 offset = gpio_chip_hwgpio(desc);
1969 return chip->to_irq ? chip->to_irq(chip, offset) : -ENXIO; 1983 return chip->to_irq ? chip->to_irq(chip, offset) : -ENXIO;
@@ -1987,6 +2001,8 @@ static int gpiod_get_value_cansleep(struct gpio_desc *desc)
1987 int offset; 2001 int offset;
1988 2002
1989 might_sleep_if(extra_checks); 2003 might_sleep_if(extra_checks);
2004 if (!desc)
2005 return 0;
1990 chip = desc->chip; 2006 chip = desc->chip;
1991 offset = gpio_chip_hwgpio(desc); 2007 offset = gpio_chip_hwgpio(desc);
1992 value = chip->get ? chip->get(chip, offset) : 0; 2008 value = chip->get ? chip->get(chip, offset) : 0;
@@ -2005,6 +2021,8 @@ static void gpiod_set_value_cansleep(struct gpio_desc *desc, int value)
2005 struct gpio_chip *chip; 2021 struct gpio_chip *chip;
2006 2022
2007 might_sleep_if(extra_checks); 2023 might_sleep_if(extra_checks);
2024 if (!desc)
2025 return;
2008 chip = desc->chip; 2026 chip = desc->chip;
2009 trace_gpio_value(desc_to_gpio(desc), 0, value); 2027 trace_gpio_value(desc_to_gpio(desc), 0, value);
2010 if (test_bit(FLAG_OPEN_DRAIN, &desc->flags)) 2028 if (test_bit(FLAG_OPEN_DRAIN, &desc->flags))