Commit bcc6d99a authored by Bartosz Golaszewski's avatar Bartosz Golaszewski
Browse files

gpiolib: sanitize flags before allocating memory in lineevent_create()



Move all the flags sanitization before any memory allocation in
lineevent_create() in order to remove a couple unneeded gotos.

Signed-off-by: default avatarBartosz Golaszewski <bgolaszewski@baylibre.com>
parent c8f3d144
Loading
Loading
Loading
Loading
+18 −24
Original line number Diff line number Diff line
@@ -894,6 +894,24 @@ static int lineevent_create(struct gpio_device *gdev, void __user *ip)
	if (copy_from_user(&eventreq, ip, sizeof(eventreq)))
		return -EFAULT;

	offset = eventreq.lineoffset;
	lflags = eventreq.handleflags;
	eflags = eventreq.eventflags;

	if (offset >= gdev->ngpio)
		return -EINVAL;

	/* Return an error if a unknown flag is set */
	if ((lflags & ~GPIOHANDLE_REQUEST_VALID_FLAGS) ||
	    (eflags & ~GPIOEVENT_REQUEST_VALID_FLAGS))
		return -EINVAL;

	/* This is just wrong: we don't look for events on output lines */
	if ((lflags & GPIOHANDLE_REQUEST_OUTPUT) ||
	    (lflags & GPIOHANDLE_REQUEST_OPEN_DRAIN) ||
	    (lflags & GPIOHANDLE_REQUEST_OPEN_SOURCE))
		return -EINVAL;

	le = kzalloc(sizeof(*le), GFP_KERNEL);
	if (!le)
		return -ENOMEM;
@@ -911,30 +929,6 @@ static int lineevent_create(struct gpio_device *gdev, void __user *ip)
		}
	}

	offset = eventreq.lineoffset;
	lflags = eventreq.handleflags;
	eflags = eventreq.eventflags;

	if (offset >= gdev->ngpio) {
		ret = -EINVAL;
		goto out_free_label;
	}

	/* Return an error if a unknown flag is set */
	if ((lflags & ~GPIOHANDLE_REQUEST_VALID_FLAGS) ||
	    (eflags & ~GPIOEVENT_REQUEST_VALID_FLAGS)) {
		ret = -EINVAL;
		goto out_free_label;
	}

	/* This is just wrong: we don't look for events on output lines */
	if ((lflags & GPIOHANDLE_REQUEST_OUTPUT) ||
	    (lflags & GPIOHANDLE_REQUEST_OPEN_DRAIN) ||
	    (lflags & GPIOHANDLE_REQUEST_OPEN_SOURCE)) {
		ret = -EINVAL;
		goto out_free_label;
	}

	desc = &gdev->descs[offset];
	ret = gpiod_request(desc, le->label);
	if (ret)