aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio/gpiolib.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpio/gpiolib.c')
-rw-r--r--drivers/gpio/gpiolib.c42
1 files changed, 41 insertions, 1 deletions
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];