On Thursday 02 June 2016 13:51:26, Linus Walleij wrote: > This adds a userspace ABI for reading and writing GPIO lines. > The mechanism returns an anonymous file handle to a request > to read/write n offsets from a gpiochip. This file handle > in turn accepts two ioctl()s: one that reads and one that > writes values to the selected lines. > [...] > +static int linehandle_create(struct gpio_device *gdev, void __user *ip) > +{ > + struct gpiohandle_request handlereq; > + struct linehandle_state *lh; > + int fd, i, ret; > + > + if (copy_from_user(&handlereq, ip, sizeof(handlereq))) > + return -EFAULT; > + if ((handlereq.lines == 0) || (handlereq.lines > GPIOHANDLES_MAX)) > + return -EINVAL; > + > + lh = kzalloc(sizeof(*lh), GFP_KERNEL); > + if (!lh) > + return -ENOMEM; > + lh->gdev = gdev; > + get_device(&gdev->dev); > + > + /* Make sure this is terminated */ > + handlereq.consumer_label[sizeof(handlereq.consumer_label)-1] = '\0'; > + if (strlen(handlereq.consumer_label)) { > + lh->label = kstrdup(handlereq.consumer_label, > + GFP_KERNEL); > + if (!lh->label) { > + ret = -ENOMEM; > + goto out_free_lh; > + } > + } > + > + /* Request each GPIO */ > + for (i = 0; i < handlereq.lines; i++) { > + u32 offset = handlereq.lineoffsets[i]; > + u32 lflags = handlereq.flags; > + struct gpio_desc *desc; > + > + desc = &gdev->descs[offset]; > + ret = gpiod_request(desc, lh->label); > + if (ret) > + goto out_free_descs; > + lh->descs[i] = desc; > + > + if (lflags & GPIOHANDLE_REQUEST_ACTIVE_LOW) > + set_bit(FLAG_ACTIVE_LOW, &desc->flags); > + if (lflags & GPIOHANDLE_REQUEST_OPEN_DRAIN) > + set_bit(FLAG_OPEN_DRAIN, &desc->flags); > + if (lflags & GPIOHANDLE_REQUEST_OPEN_SOURCE) > + set_bit(FLAG_OPEN_SOURCE, &desc->flags); > + > + /* > + * Lines have to be requested explicitly for input > + * or output, else the line will be treated "as is". > + */ > + if (lflags & GPIOHANDLE_REQUEST_OUTPUT) { > + int val = !!handlereq.default_values[i]; > + > + ret = gpiod_direction_output(desc, val); > + if (ret) > + goto out_free_descs; > + } else if (lflags & GPIOHANDLE_REQUEST_INPUT) { > + ret = gpiod_direction_input(desc); > + if (ret) > + goto out_free_descs; > + } > + dev_dbg(&gdev->dev, "registered chardev handle for line %d\n", > + offset); > + } > + lh->numdescs = handlereq.lines; > + > + fd = anon_inode_getfd("gpio-linehandle", > + &linehandle_fileops, > + lh, > + O_RDONLY | O_CLOEXEC); When will linehandle_release actually be called? When we explicitely call close(req.fd) or when application exits and all FDs will be closed anyway? > + if (fd < 0) { > + ret = fd; > + goto out_free_descs; > + } > + > + handlereq.fd = fd; > + if (copy_to_user(ip, &handlereq, sizeof(handlereq))) > + return -EFAULT; If I'm right above doesn't that then leak lh until application eventually exits? Userspace won't receive the newly created fd. The same would apply to patch 3/4. Best regards, Alexander -- To unsubscribe from this list: send the line "unsubscribe linux-gpio" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html