All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dan Carpenter <dan.carpenter@oracle.com>
To: kbuild@lists.01.org, Kent Gibson <warthog618@gmail.com>,
	linux-kernel@vger.kernel.org, linux-gpio@vger.kernel.org,
	bgolaszewski@baylibre.com, linus.walleij@linaro.org
Cc: lkp@intel.com, kbuild-all@lists.01.org,
	Kent Gibson <warthog618@gmail.com>
Subject: Re: [PATCH 16/22] gpiolib: cdev: add V2 uAPI implementation to parity with V1
Date: Tue, 23 Jun 2020 20:44:38 +0300	[thread overview]
Message-ID: <20200623174438.GL4151@kadam> (raw)
In-Reply-To: <20200623040107.22270-17-warthog618@gmail.com>

[-- Attachment #1: Type: text/plain, Size: 15322 bytes --]

[ The copy_to_user() overflow code is weird.  Why do we need to do a
  atomic_read()?  That suggests that there is a potential time of check
  time of use bug where we do:

	if (atomic_read(&gcdev->watch_abi_version) == 2) // <<-- time of check
		event_size = sizeof(struct gpioline_info_changed_v2);

	...

	if (atomic_read(&gcdev->watch_abi_version) == 2) { // <<-- time of use
		copy_to_user(blah, blah, event_size);

  If the value for "gcdev->watch_abi_version" changes between the time
  of check and the time of use then it can read beyond the end of the
  buffer.

  -- dan ]

Hi Kent,

Thank you for the patch! Perhaps something to improve:

url:    https://github.com/0day-ci/linux/commits/Kent-Gibson/gpio-cdev-add-uAPI-V2/20200623-120634
base:   https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio.git for-next
config: openrisc-randconfig-m031-20200623 (attached as .config)
compiler: or1k-linux-gcc (GCC) 9.3.0

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>

smatch warnings:
drivers/gpio/gpiolib-cdev.c:891 line_free() error: dereferencing freed memory 'line'
drivers/gpio/gpiolib-cdev.c:949 line_create() warn: possible memory leak of 'line'
drivers/gpio/gpiolib-cdev.c:1860 lineinfo_watch_read() error: copy_to_user() '&event_v1' too small (104 vs 168)

# https://github.com/0day-ci/linux/commit/f3b3ae8752adc5ac33dcf83d49b0b02f2d7ef43b
git remote add linux-review https://github.com/0day-ci/linux
git remote update linux-review
git checkout f3b3ae8752adc5ac33dcf83d49b0b02f2d7ef43b
vim +/line +891 drivers/gpio/gpiolib-cdev.c

f3b3ae8752adc5 Kent Gibson 2020-06-23   877  static void line_free(struct line *line)
f3b3ae8752adc5 Kent Gibson 2020-06-23   878  {
f3b3ae8752adc5 Kent Gibson 2020-06-23   879  	int i;
f3b3ae8752adc5 Kent Gibson 2020-06-23   880  
f3b3ae8752adc5 Kent Gibson 2020-06-23   881  	for (i = 0; i < line->num_descs; i++) {
f3b3ae8752adc5 Kent Gibson 2020-06-23   882  		if (line->edets)
f3b3ae8752adc5 Kent Gibson 2020-06-23   883  			edge_detector_stop(&line->edets[i]);
f3b3ae8752adc5 Kent Gibson 2020-06-23   884  		if (line->descs[i])
f3b3ae8752adc5 Kent Gibson 2020-06-23   885  			gpiod_free(line->descs[i]);
f3b3ae8752adc5 Kent Gibson 2020-06-23   886  	}
f3b3ae8752adc5 Kent Gibson 2020-06-23   887  	kfifo_free(&line->events);
f3b3ae8752adc5 Kent Gibson 2020-06-23   888  	kfree(line->label);
f3b3ae8752adc5 Kent Gibson 2020-06-23   889  	kfree(line->edets);
f3b3ae8752adc5 Kent Gibson 2020-06-23   890  	kfree(line);
f3b3ae8752adc5 Kent Gibson 2020-06-23  @891  	put_device(&line->gdev->dev);
f3b3ae8752adc5 Kent Gibson 2020-06-23   892  }
f3b3ae8752adc5 Kent Gibson 2020-06-23   893  
f3b3ae8752adc5 Kent Gibson 2020-06-23   894  static int line_release(struct inode *inode, struct file *file)
f3b3ae8752adc5 Kent Gibson 2020-06-23   895  {
f3b3ae8752adc5 Kent Gibson 2020-06-23   896  	struct line *line = file->private_data;
f3b3ae8752adc5 Kent Gibson 2020-06-23   897  
f3b3ae8752adc5 Kent Gibson 2020-06-23   898  	line_free(line);
f3b3ae8752adc5 Kent Gibson 2020-06-23   899  	return 0;
f3b3ae8752adc5 Kent Gibson 2020-06-23   900  }
f3b3ae8752adc5 Kent Gibson 2020-06-23   901  
f3b3ae8752adc5 Kent Gibson 2020-06-23   902  static const struct file_operations line_fileops = {
f3b3ae8752adc5 Kent Gibson 2020-06-23   903  	.release = line_release,
f3b3ae8752adc5 Kent Gibson 2020-06-23   904  	.read = line_read,
f3b3ae8752adc5 Kent Gibson 2020-06-23   905  	.poll = line_poll,
f3b3ae8752adc5 Kent Gibson 2020-06-23   906  	.owner = THIS_MODULE,
f3b3ae8752adc5 Kent Gibson 2020-06-23   907  	.llseek = noop_llseek,
f3b3ae8752adc5 Kent Gibson 2020-06-23   908  	.unlocked_ioctl = line_ioctl,
f3b3ae8752adc5 Kent Gibson 2020-06-23   909  #ifdef CONFIG_COMPAT
f3b3ae8752adc5 Kent Gibson 2020-06-23   910  	.compat_ioctl = line_ioctl_compat,
f3b3ae8752adc5 Kent Gibson 2020-06-23   911  #endif
f3b3ae8752adc5 Kent Gibson 2020-06-23   912  };
f3b3ae8752adc5 Kent Gibson 2020-06-23   913  
f3b3ae8752adc5 Kent Gibson 2020-06-23   914  static int line_create(struct gpio_device *gdev, void __user *ip)
f3b3ae8752adc5 Kent Gibson 2020-06-23   915  {
f3b3ae8752adc5 Kent Gibson 2020-06-23   916  	struct gpioline_request linereq;
f3b3ae8752adc5 Kent Gibson 2020-06-23   917  	struct line *line;
f3b3ae8752adc5 Kent Gibson 2020-06-23   918  	struct file *file;
f3b3ae8752adc5 Kent Gibson 2020-06-23   919  	int fd, i, ret, size;
f3b3ae8752adc5 Kent Gibson 2020-06-23   920  	struct gpioline_config *lc;
f3b3ae8752adc5 Kent Gibson 2020-06-23   921  	unsigned long *vals;
f3b3ae8752adc5 Kent Gibson 2020-06-23   922  
f3b3ae8752adc5 Kent Gibson 2020-06-23   923  	if (copy_from_user(&linereq, ip, sizeof(linereq)))
f3b3ae8752adc5 Kent Gibson 2020-06-23   924  		return -EFAULT;
f3b3ae8752adc5 Kent Gibson 2020-06-23   925  	if ((linereq.num_lines == 0) || (linereq.num_lines > GPIOLINES_MAX))
f3b3ae8752adc5 Kent Gibson 2020-06-23   926  		return -EINVAL;
f3b3ae8752adc5 Kent Gibson 2020-06-23   927  
f3b3ae8752adc5 Kent Gibson 2020-06-23   928  	if (padding_not_zeroed(linereq.padding, GPIOLINE_REQUEST_PAD_SIZE))
f3b3ae8752adc5 Kent Gibson 2020-06-23   929  		return -EINVAL;
f3b3ae8752adc5 Kent Gibson 2020-06-23   930  
f3b3ae8752adc5 Kent Gibson 2020-06-23   931  	lc = &linereq.config;
f3b3ae8752adc5 Kent Gibson 2020-06-23   932  	ret = gpioline_config_validate(lc);
f3b3ae8752adc5 Kent Gibson 2020-06-23   933  	if (ret)
f3b3ae8752adc5 Kent Gibson 2020-06-23   934  		return ret;
f3b3ae8752adc5 Kent Gibson 2020-06-23   935  
f3b3ae8752adc5 Kent Gibson 2020-06-23   936  	/* event_buffer_size only valid with edge_detection */
f3b3ae8752adc5 Kent Gibson 2020-06-23   937  	if ((linereq.event_buffer_size) &&
f3b3ae8752adc5 Kent Gibson 2020-06-23   938  	    !(linereq.config.flags & GPIOLINE_FLAG_V2_EDGE_DETECTION))
f3b3ae8752adc5 Kent Gibson 2020-06-23   939  		return -EINVAL;
f3b3ae8752adc5 Kent Gibson 2020-06-23   940  
f3b3ae8752adc5 Kent Gibson 2020-06-23   941  	line = kzalloc(struct_size(line, descs, linereq.num_lines),
f3b3ae8752adc5 Kent Gibson 2020-06-23   942  		       GFP_KERNEL);
f3b3ae8752adc5 Kent Gibson 2020-06-23   943  	if (!line)
f3b3ae8752adc5 Kent Gibson 2020-06-23   944  		return -ENOMEM;
f3b3ae8752adc5 Kent Gibson 2020-06-23   945  
f3b3ae8752adc5 Kent Gibson 2020-06-23   946  	line->edets = kcalloc(linereq.num_lines, sizeof(*line->edets),
f3b3ae8752adc5 Kent Gibson 2020-06-23   947  			      GFP_KERNEL);
f3b3ae8752adc5 Kent Gibson 2020-06-23   948  	if (!line->edets)
f3b3ae8752adc5 Kent Gibson 2020-06-23  @949  		return -ENOMEM;
                                                        ^^^^^^^^^^^^^^^
kfree(line) before returning.

f3b3ae8752adc5 Kent Gibson 2020-06-23   950  
f3b3ae8752adc5 Kent Gibson 2020-06-23   951  	for (i = 0; i < linereq.num_lines; i++)
f3b3ae8752adc5 Kent Gibson 2020-06-23   952  		line->edets[i].line = line;
f3b3ae8752adc5 Kent Gibson 2020-06-23   953  
f3b3ae8752adc5 Kent Gibson 2020-06-23   954  	line->gdev = gdev;
f3b3ae8752adc5 Kent Gibson 2020-06-23   955  	get_device(&gdev->dev);
f3b3ae8752adc5 Kent Gibson 2020-06-23   956  
f3b3ae8752adc5 Kent Gibson 2020-06-23   957  	/* Make sure this is terminated */
f3b3ae8752adc5 Kent Gibson 2020-06-23   958  	linereq.consumer[sizeof(linereq.consumer)-1] = '\0';
f3b3ae8752adc5 Kent Gibson 2020-06-23   959  	if (strlen(linereq.consumer)) {
f3b3ae8752adc5 Kent Gibson 2020-06-23   960  		line->label = kstrdup(linereq.consumer, GFP_KERNEL);
f3b3ae8752adc5 Kent Gibson 2020-06-23   961  		if (!line->label) {
f3b3ae8752adc5 Kent Gibson 2020-06-23   962  			ret = -ENOMEM;
f3b3ae8752adc5 Kent Gibson 2020-06-23   963  			goto out_free_line;
f3b3ae8752adc5 Kent Gibson 2020-06-23   964  		}
f3b3ae8752adc5 Kent Gibson 2020-06-23   965  	}
f3b3ae8752adc5 Kent Gibson 2020-06-23   966  
f3b3ae8752adc5 Kent Gibson 2020-06-23   967  	mutex_init(&line->config_mutex);
f3b3ae8752adc5 Kent Gibson 2020-06-23   968  	init_waitqueue_head(&line->wait);
f3b3ae8752adc5 Kent Gibson 2020-06-23   969  	if (lc->edge_detection) {
f3b3ae8752adc5 Kent Gibson 2020-06-23   970  		size = linereq.event_buffer_size;
f3b3ae8752adc5 Kent Gibson 2020-06-23   971  
f3b3ae8752adc5 Kent Gibson 2020-06-23   972  		if (size > GPIOLINES_MAX*16)
f3b3ae8752adc5 Kent Gibson 2020-06-23   973  			size = GPIOLINES_MAX*16;
f3b3ae8752adc5 Kent Gibson 2020-06-23   974  		else if (size == 0)
f3b3ae8752adc5 Kent Gibson 2020-06-23   975  			size = linereq.num_lines*16;
f3b3ae8752adc5 Kent Gibson 2020-06-23   976  
f3b3ae8752adc5 Kent Gibson 2020-06-23   977  		ret = kfifo_alloc(&line->events, size, GFP_KERNEL);
f3b3ae8752adc5 Kent Gibson 2020-06-23   978  		if (ret)
f3b3ae8752adc5 Kent Gibson 2020-06-23   979  			goto out_free_line;
f3b3ae8752adc5 Kent Gibson 2020-06-23   980  
f3b3ae8752adc5 Kent Gibson 2020-06-23   981  		line->edge_detection = lc->edge_detection;
f3b3ae8752adc5 Kent Gibson 2020-06-23   982  	}
f3b3ae8752adc5 Kent Gibson 2020-06-23   983  
f3b3ae8752adc5 Kent Gibson 2020-06-23   984  	atomic_set(&line->seqno, 0);
f3b3ae8752adc5 Kent Gibson 2020-06-23   985  	line->num_descs = linereq.num_lines;
f3b3ae8752adc5 Kent Gibson 2020-06-23   986  	vals = (unsigned long *)lc->values.bitmap;
f3b3ae8752adc5 Kent Gibson 2020-06-23   987  
f3b3ae8752adc5 Kent Gibson 2020-06-23   988  	/* Request each GPIO */
f3b3ae8752adc5 Kent Gibson 2020-06-23   989  	for (i = 0; i < linereq.num_lines; i++) {
f3b3ae8752adc5 Kent Gibson 2020-06-23   990  		u32 offset = linereq.offsets[i];
f3b3ae8752adc5 Kent Gibson 2020-06-23   991  		struct gpio_desc *desc = gpiochip_get_desc(gdev->chip, offset);
f3b3ae8752adc5 Kent Gibson 2020-06-23   992  
f3b3ae8752adc5 Kent Gibson 2020-06-23   993  		if (IS_ERR(desc)) {
f3b3ae8752adc5 Kent Gibson 2020-06-23   994  			ret = PTR_ERR(desc);
f3b3ae8752adc5 Kent Gibson 2020-06-23   995  			goto out_free_line;
f3b3ae8752adc5 Kent Gibson 2020-06-23   996  		}
f3b3ae8752adc5 Kent Gibson 2020-06-23   997  
f3b3ae8752adc5 Kent Gibson 2020-06-23   998  		ret = gpiod_request(desc, line->label);
f3b3ae8752adc5 Kent Gibson 2020-06-23   999  		if (ret)
f3b3ae8752adc5 Kent Gibson 2020-06-23  1000  			goto out_free_line;
f3b3ae8752adc5 Kent Gibson 2020-06-23  1001  
f3b3ae8752adc5 Kent Gibson 2020-06-23  1002  		line->descs[i] = desc;
f3b3ae8752adc5 Kent Gibson 2020-06-23  1003  		gpioline_config_to_desc_flags(lc, &desc->flags);
f3b3ae8752adc5 Kent Gibson 2020-06-23  1004  
f3b3ae8752adc5 Kent Gibson 2020-06-23  1005  		ret = gpiod_set_transitory(desc, false);
f3b3ae8752adc5 Kent Gibson 2020-06-23  1006  		if (ret < 0)
f3b3ae8752adc5 Kent Gibson 2020-06-23  1007  			goto out_free_line;
f3b3ae8752adc5 Kent Gibson 2020-06-23  1008  
f3b3ae8752adc5 Kent Gibson 2020-06-23  1009  		/*
f3b3ae8752adc5 Kent Gibson 2020-06-23  1010  		 * Lines have to be requested explicitly for input
f3b3ae8752adc5 Kent Gibson 2020-06-23  1011  		 * or output, else the line will be treated "as is".
f3b3ae8752adc5 Kent Gibson 2020-06-23  1012  		 */
f3b3ae8752adc5 Kent Gibson 2020-06-23  1013  		if (lc->flags & GPIOLINE_FLAG_V2_DIRECTION) {
f3b3ae8752adc5 Kent Gibson 2020-06-23  1014  			if (lc->direction == GPIOLINE_DIRECTION_OUTPUT) {
f3b3ae8752adc5 Kent Gibson 2020-06-23  1015  				int val = test_bit(i, vals);
f3b3ae8752adc5 Kent Gibson 2020-06-23  1016  
f3b3ae8752adc5 Kent Gibson 2020-06-23  1017  				ret = gpiod_direction_output(desc, val);
f3b3ae8752adc5 Kent Gibson 2020-06-23  1018  				if (ret)
f3b3ae8752adc5 Kent Gibson 2020-06-23  1019  					goto out_free_line;
f3b3ae8752adc5 Kent Gibson 2020-06-23  1020  			} else {
f3b3ae8752adc5 Kent Gibson 2020-06-23  1021  				ret = gpiod_direction_input(desc);
f3b3ae8752adc5 Kent Gibson 2020-06-23  1022  				if (ret)
f3b3ae8752adc5 Kent Gibson 2020-06-23  1023  					goto out_free_line;
f3b3ae8752adc5 Kent Gibson 2020-06-23  1024  				ret = edge_detector_setup(&line->edets[i], lc);
f3b3ae8752adc5 Kent Gibson 2020-06-23  1025  				if (ret)
f3b3ae8752adc5 Kent Gibson 2020-06-23  1026  					goto out_free_line;
f3b3ae8752adc5 Kent Gibson 2020-06-23  1027  			}
f3b3ae8752adc5 Kent Gibson 2020-06-23  1028  		}
f3b3ae8752adc5 Kent Gibson 2020-06-23  1029  
f3b3ae8752adc5 Kent Gibson 2020-06-23  1030  		atomic_notifier_call_chain(&desc->gdev->notifier,
f3b3ae8752adc5 Kent Gibson 2020-06-23  1031  					   GPIOLINE_CHANGED_REQUESTED, desc);
f3b3ae8752adc5 Kent Gibson 2020-06-23  1032  
f3b3ae8752adc5 Kent Gibson 2020-06-23  1033  		dev_dbg(&gdev->dev, "registered chardev handle for line %d\n",
f3b3ae8752adc5 Kent Gibson 2020-06-23  1034  			offset);
f3b3ae8752adc5 Kent Gibson 2020-06-23  1035  	}
f3b3ae8752adc5 Kent Gibson 2020-06-23  1036  
f3b3ae8752adc5 Kent Gibson 2020-06-23  1037  	fd = get_unused_fd_flags(O_RDONLY | O_CLOEXEC);
f3b3ae8752adc5 Kent Gibson 2020-06-23  1038  	if (fd < 0) {
f3b3ae8752adc5 Kent Gibson 2020-06-23  1039  		ret = fd;
f3b3ae8752adc5 Kent Gibson 2020-06-23  1040  		goto out_free_line;
f3b3ae8752adc5 Kent Gibson 2020-06-23  1041  	}
f3b3ae8752adc5 Kent Gibson 2020-06-23  1042  
f3b3ae8752adc5 Kent Gibson 2020-06-23  1043  	file = anon_inode_getfile("gpio-line",
f3b3ae8752adc5 Kent Gibson 2020-06-23  1044  				  &line_fileops,
f3b3ae8752adc5 Kent Gibson 2020-06-23  1045  				  line,
f3b3ae8752adc5 Kent Gibson 2020-06-23  1046  				  O_RDONLY | O_CLOEXEC);
f3b3ae8752adc5 Kent Gibson 2020-06-23  1047  	if (IS_ERR(file)) {
f3b3ae8752adc5 Kent Gibson 2020-06-23  1048  		ret = PTR_ERR(file);
f3b3ae8752adc5 Kent Gibson 2020-06-23  1049  		goto out_put_unused_fd;
f3b3ae8752adc5 Kent Gibson 2020-06-23  1050  	}
f3b3ae8752adc5 Kent Gibson 2020-06-23  1051  
f3b3ae8752adc5 Kent Gibson 2020-06-23  1052  	linereq.fd = fd;
f3b3ae8752adc5 Kent Gibson 2020-06-23  1053  	if (copy_to_user(ip, &linereq, sizeof(linereq))) {
f3b3ae8752adc5 Kent Gibson 2020-06-23  1054  		/*
f3b3ae8752adc5 Kent Gibson 2020-06-23  1055  		 * fput() will trigger the release() callback, so do not go onto
f3b3ae8752adc5 Kent Gibson 2020-06-23  1056  		 * the regular error cleanup path here.
f3b3ae8752adc5 Kent Gibson 2020-06-23  1057  		 */
f3b3ae8752adc5 Kent Gibson 2020-06-23  1058  		fput(file);
f3b3ae8752adc5 Kent Gibson 2020-06-23  1059  		put_unused_fd(fd);
f3b3ae8752adc5 Kent Gibson 2020-06-23  1060  		return -EFAULT;
f3b3ae8752adc5 Kent Gibson 2020-06-23  1061  	}
f3b3ae8752adc5 Kent Gibson 2020-06-23  1062  
f3b3ae8752adc5 Kent Gibson 2020-06-23  1063  	fd_install(fd, file);
f3b3ae8752adc5 Kent Gibson 2020-06-23  1064  
f3b3ae8752adc5 Kent Gibson 2020-06-23  1065  	dev_dbg(&gdev->dev, "registered chardev handle for %d lines\n",
f3b3ae8752adc5 Kent Gibson 2020-06-23  1066  		line->num_descs);
f3b3ae8752adc5 Kent Gibson 2020-06-23  1067  
f3b3ae8752adc5 Kent Gibson 2020-06-23  1068  	return 0;
f3b3ae8752adc5 Kent Gibson 2020-06-23  1069  
f3b3ae8752adc5 Kent Gibson 2020-06-23  1070  out_put_unused_fd:
f3b3ae8752adc5 Kent Gibson 2020-06-23  1071  	put_unused_fd(fd);
f3b3ae8752adc5 Kent Gibson 2020-06-23  1072  out_free_line:
f3b3ae8752adc5 Kent Gibson 2020-06-23  1073  	line_free(line);
f3b3ae8752adc5 Kent Gibson 2020-06-23  1074  	return ret;
f3b3ae8752adc5 Kent Gibson 2020-06-23  1075  }

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 25304 bytes --]

WARNING: multiple messages have this Message-ID (diff)
From: Dan Carpenter <dan.carpenter@oracle.com>
To: kbuild@lists.01.org
Subject: Re: [PATCH 16/22] gpiolib: cdev: add V2 uAPI implementation to parity with V1
Date: Tue, 23 Jun 2020 20:44:38 +0300	[thread overview]
Message-ID: <20200623174438.GL4151@kadam> (raw)
In-Reply-To: <20200623040107.22270-17-warthog618@gmail.com>

[-- Attachment #1: Type: text/plain, Size: 15572 bytes --]

[ The copy_to_user() overflow code is weird.  Why do we need to do a
  atomic_read()?  That suggests that there is a potential time of check
  time of use bug where we do:

	if (atomic_read(&gcdev->watch_abi_version) == 2) // <<-- time of check
		event_size = sizeof(struct gpioline_info_changed_v2);

	...

	if (atomic_read(&gcdev->watch_abi_version) == 2) { // <<-- time of use
		copy_to_user(blah, blah, event_size);

  If the value for "gcdev->watch_abi_version" changes between the time
  of check and the time of use then it can read beyond the end of the
  buffer.

  -- dan ]

Hi Kent,

Thank you for the patch! Perhaps something to improve:

url:    https://github.com/0day-ci/linux/commits/Kent-Gibson/gpio-cdev-add-uAPI-V2/20200623-120634
base:   https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio.git for-next
config: openrisc-randconfig-m031-20200623 (attached as .config)
compiler: or1k-linux-gcc (GCC) 9.3.0

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>

smatch warnings:
drivers/gpio/gpiolib-cdev.c:891 line_free() error: dereferencing freed memory 'line'
drivers/gpio/gpiolib-cdev.c:949 line_create() warn: possible memory leak of 'line'
drivers/gpio/gpiolib-cdev.c:1860 lineinfo_watch_read() error: copy_to_user() '&event_v1' too small (104 vs 168)

# https://github.com/0day-ci/linux/commit/f3b3ae8752adc5ac33dcf83d49b0b02f2d7ef43b
git remote add linux-review https://github.com/0day-ci/linux
git remote update linux-review
git checkout f3b3ae8752adc5ac33dcf83d49b0b02f2d7ef43b
vim +/line +891 drivers/gpio/gpiolib-cdev.c

f3b3ae8752adc5 Kent Gibson 2020-06-23   877  static void line_free(struct line *line)
f3b3ae8752adc5 Kent Gibson 2020-06-23   878  {
f3b3ae8752adc5 Kent Gibson 2020-06-23   879  	int i;
f3b3ae8752adc5 Kent Gibson 2020-06-23   880  
f3b3ae8752adc5 Kent Gibson 2020-06-23   881  	for (i = 0; i < line->num_descs; i++) {
f3b3ae8752adc5 Kent Gibson 2020-06-23   882  		if (line->edets)
f3b3ae8752adc5 Kent Gibson 2020-06-23   883  			edge_detector_stop(&line->edets[i]);
f3b3ae8752adc5 Kent Gibson 2020-06-23   884  		if (line->descs[i])
f3b3ae8752adc5 Kent Gibson 2020-06-23   885  			gpiod_free(line->descs[i]);
f3b3ae8752adc5 Kent Gibson 2020-06-23   886  	}
f3b3ae8752adc5 Kent Gibson 2020-06-23   887  	kfifo_free(&line->events);
f3b3ae8752adc5 Kent Gibson 2020-06-23   888  	kfree(line->label);
f3b3ae8752adc5 Kent Gibson 2020-06-23   889  	kfree(line->edets);
f3b3ae8752adc5 Kent Gibson 2020-06-23   890  	kfree(line);
f3b3ae8752adc5 Kent Gibson 2020-06-23  @891  	put_device(&line->gdev->dev);
f3b3ae8752adc5 Kent Gibson 2020-06-23   892  }
f3b3ae8752adc5 Kent Gibson 2020-06-23   893  
f3b3ae8752adc5 Kent Gibson 2020-06-23   894  static int line_release(struct inode *inode, struct file *file)
f3b3ae8752adc5 Kent Gibson 2020-06-23   895  {
f3b3ae8752adc5 Kent Gibson 2020-06-23   896  	struct line *line = file->private_data;
f3b3ae8752adc5 Kent Gibson 2020-06-23   897  
f3b3ae8752adc5 Kent Gibson 2020-06-23   898  	line_free(line);
f3b3ae8752adc5 Kent Gibson 2020-06-23   899  	return 0;
f3b3ae8752adc5 Kent Gibson 2020-06-23   900  }
f3b3ae8752adc5 Kent Gibson 2020-06-23   901  
f3b3ae8752adc5 Kent Gibson 2020-06-23   902  static const struct file_operations line_fileops = {
f3b3ae8752adc5 Kent Gibson 2020-06-23   903  	.release = line_release,
f3b3ae8752adc5 Kent Gibson 2020-06-23   904  	.read = line_read,
f3b3ae8752adc5 Kent Gibson 2020-06-23   905  	.poll = line_poll,
f3b3ae8752adc5 Kent Gibson 2020-06-23   906  	.owner = THIS_MODULE,
f3b3ae8752adc5 Kent Gibson 2020-06-23   907  	.llseek = noop_llseek,
f3b3ae8752adc5 Kent Gibson 2020-06-23   908  	.unlocked_ioctl = line_ioctl,
f3b3ae8752adc5 Kent Gibson 2020-06-23   909  #ifdef CONFIG_COMPAT
f3b3ae8752adc5 Kent Gibson 2020-06-23   910  	.compat_ioctl = line_ioctl_compat,
f3b3ae8752adc5 Kent Gibson 2020-06-23   911  #endif
f3b3ae8752adc5 Kent Gibson 2020-06-23   912  };
f3b3ae8752adc5 Kent Gibson 2020-06-23   913  
f3b3ae8752adc5 Kent Gibson 2020-06-23   914  static int line_create(struct gpio_device *gdev, void __user *ip)
f3b3ae8752adc5 Kent Gibson 2020-06-23   915  {
f3b3ae8752adc5 Kent Gibson 2020-06-23   916  	struct gpioline_request linereq;
f3b3ae8752adc5 Kent Gibson 2020-06-23   917  	struct line *line;
f3b3ae8752adc5 Kent Gibson 2020-06-23   918  	struct file *file;
f3b3ae8752adc5 Kent Gibson 2020-06-23   919  	int fd, i, ret, size;
f3b3ae8752adc5 Kent Gibson 2020-06-23   920  	struct gpioline_config *lc;
f3b3ae8752adc5 Kent Gibson 2020-06-23   921  	unsigned long *vals;
f3b3ae8752adc5 Kent Gibson 2020-06-23   922  
f3b3ae8752adc5 Kent Gibson 2020-06-23   923  	if (copy_from_user(&linereq, ip, sizeof(linereq)))
f3b3ae8752adc5 Kent Gibson 2020-06-23   924  		return -EFAULT;
f3b3ae8752adc5 Kent Gibson 2020-06-23   925  	if ((linereq.num_lines == 0) || (linereq.num_lines > GPIOLINES_MAX))
f3b3ae8752adc5 Kent Gibson 2020-06-23   926  		return -EINVAL;
f3b3ae8752adc5 Kent Gibson 2020-06-23   927  
f3b3ae8752adc5 Kent Gibson 2020-06-23   928  	if (padding_not_zeroed(linereq.padding, GPIOLINE_REQUEST_PAD_SIZE))
f3b3ae8752adc5 Kent Gibson 2020-06-23   929  		return -EINVAL;
f3b3ae8752adc5 Kent Gibson 2020-06-23   930  
f3b3ae8752adc5 Kent Gibson 2020-06-23   931  	lc = &linereq.config;
f3b3ae8752adc5 Kent Gibson 2020-06-23   932  	ret = gpioline_config_validate(lc);
f3b3ae8752adc5 Kent Gibson 2020-06-23   933  	if (ret)
f3b3ae8752adc5 Kent Gibson 2020-06-23   934  		return ret;
f3b3ae8752adc5 Kent Gibson 2020-06-23   935  
f3b3ae8752adc5 Kent Gibson 2020-06-23   936  	/* event_buffer_size only valid with edge_detection */
f3b3ae8752adc5 Kent Gibson 2020-06-23   937  	if ((linereq.event_buffer_size) &&
f3b3ae8752adc5 Kent Gibson 2020-06-23   938  	    !(linereq.config.flags & GPIOLINE_FLAG_V2_EDGE_DETECTION))
f3b3ae8752adc5 Kent Gibson 2020-06-23   939  		return -EINVAL;
f3b3ae8752adc5 Kent Gibson 2020-06-23   940  
f3b3ae8752adc5 Kent Gibson 2020-06-23   941  	line = kzalloc(struct_size(line, descs, linereq.num_lines),
f3b3ae8752adc5 Kent Gibson 2020-06-23   942  		       GFP_KERNEL);
f3b3ae8752adc5 Kent Gibson 2020-06-23   943  	if (!line)
f3b3ae8752adc5 Kent Gibson 2020-06-23   944  		return -ENOMEM;
f3b3ae8752adc5 Kent Gibson 2020-06-23   945  
f3b3ae8752adc5 Kent Gibson 2020-06-23   946  	line->edets = kcalloc(linereq.num_lines, sizeof(*line->edets),
f3b3ae8752adc5 Kent Gibson 2020-06-23   947  			      GFP_KERNEL);
f3b3ae8752adc5 Kent Gibson 2020-06-23   948  	if (!line->edets)
f3b3ae8752adc5 Kent Gibson 2020-06-23  @949  		return -ENOMEM;
                                                        ^^^^^^^^^^^^^^^
kfree(line) before returning.

f3b3ae8752adc5 Kent Gibson 2020-06-23   950  
f3b3ae8752adc5 Kent Gibson 2020-06-23   951  	for (i = 0; i < linereq.num_lines; i++)
f3b3ae8752adc5 Kent Gibson 2020-06-23   952  		line->edets[i].line = line;
f3b3ae8752adc5 Kent Gibson 2020-06-23   953  
f3b3ae8752adc5 Kent Gibson 2020-06-23   954  	line->gdev = gdev;
f3b3ae8752adc5 Kent Gibson 2020-06-23   955  	get_device(&gdev->dev);
f3b3ae8752adc5 Kent Gibson 2020-06-23   956  
f3b3ae8752adc5 Kent Gibson 2020-06-23   957  	/* Make sure this is terminated */
f3b3ae8752adc5 Kent Gibson 2020-06-23   958  	linereq.consumer[sizeof(linereq.consumer)-1] = '\0';
f3b3ae8752adc5 Kent Gibson 2020-06-23   959  	if (strlen(linereq.consumer)) {
f3b3ae8752adc5 Kent Gibson 2020-06-23   960  		line->label = kstrdup(linereq.consumer, GFP_KERNEL);
f3b3ae8752adc5 Kent Gibson 2020-06-23   961  		if (!line->label) {
f3b3ae8752adc5 Kent Gibson 2020-06-23   962  			ret = -ENOMEM;
f3b3ae8752adc5 Kent Gibson 2020-06-23   963  			goto out_free_line;
f3b3ae8752adc5 Kent Gibson 2020-06-23   964  		}
f3b3ae8752adc5 Kent Gibson 2020-06-23   965  	}
f3b3ae8752adc5 Kent Gibson 2020-06-23   966  
f3b3ae8752adc5 Kent Gibson 2020-06-23   967  	mutex_init(&line->config_mutex);
f3b3ae8752adc5 Kent Gibson 2020-06-23   968  	init_waitqueue_head(&line->wait);
f3b3ae8752adc5 Kent Gibson 2020-06-23   969  	if (lc->edge_detection) {
f3b3ae8752adc5 Kent Gibson 2020-06-23   970  		size = linereq.event_buffer_size;
f3b3ae8752adc5 Kent Gibson 2020-06-23   971  
f3b3ae8752adc5 Kent Gibson 2020-06-23   972  		if (size > GPIOLINES_MAX*16)
f3b3ae8752adc5 Kent Gibson 2020-06-23   973  			size = GPIOLINES_MAX*16;
f3b3ae8752adc5 Kent Gibson 2020-06-23   974  		else if (size == 0)
f3b3ae8752adc5 Kent Gibson 2020-06-23   975  			size = linereq.num_lines*16;
f3b3ae8752adc5 Kent Gibson 2020-06-23   976  
f3b3ae8752adc5 Kent Gibson 2020-06-23   977  		ret = kfifo_alloc(&line->events, size, GFP_KERNEL);
f3b3ae8752adc5 Kent Gibson 2020-06-23   978  		if (ret)
f3b3ae8752adc5 Kent Gibson 2020-06-23   979  			goto out_free_line;
f3b3ae8752adc5 Kent Gibson 2020-06-23   980  
f3b3ae8752adc5 Kent Gibson 2020-06-23   981  		line->edge_detection = lc->edge_detection;
f3b3ae8752adc5 Kent Gibson 2020-06-23   982  	}
f3b3ae8752adc5 Kent Gibson 2020-06-23   983  
f3b3ae8752adc5 Kent Gibson 2020-06-23   984  	atomic_set(&line->seqno, 0);
f3b3ae8752adc5 Kent Gibson 2020-06-23   985  	line->num_descs = linereq.num_lines;
f3b3ae8752adc5 Kent Gibson 2020-06-23   986  	vals = (unsigned long *)lc->values.bitmap;
f3b3ae8752adc5 Kent Gibson 2020-06-23   987  
f3b3ae8752adc5 Kent Gibson 2020-06-23   988  	/* Request each GPIO */
f3b3ae8752adc5 Kent Gibson 2020-06-23   989  	for (i = 0; i < linereq.num_lines; i++) {
f3b3ae8752adc5 Kent Gibson 2020-06-23   990  		u32 offset = linereq.offsets[i];
f3b3ae8752adc5 Kent Gibson 2020-06-23   991  		struct gpio_desc *desc = gpiochip_get_desc(gdev->chip, offset);
f3b3ae8752adc5 Kent Gibson 2020-06-23   992  
f3b3ae8752adc5 Kent Gibson 2020-06-23   993  		if (IS_ERR(desc)) {
f3b3ae8752adc5 Kent Gibson 2020-06-23   994  			ret = PTR_ERR(desc);
f3b3ae8752adc5 Kent Gibson 2020-06-23   995  			goto out_free_line;
f3b3ae8752adc5 Kent Gibson 2020-06-23   996  		}
f3b3ae8752adc5 Kent Gibson 2020-06-23   997  
f3b3ae8752adc5 Kent Gibson 2020-06-23   998  		ret = gpiod_request(desc, line->label);
f3b3ae8752adc5 Kent Gibson 2020-06-23   999  		if (ret)
f3b3ae8752adc5 Kent Gibson 2020-06-23  1000  			goto out_free_line;
f3b3ae8752adc5 Kent Gibson 2020-06-23  1001  
f3b3ae8752adc5 Kent Gibson 2020-06-23  1002  		line->descs[i] = desc;
f3b3ae8752adc5 Kent Gibson 2020-06-23  1003  		gpioline_config_to_desc_flags(lc, &desc->flags);
f3b3ae8752adc5 Kent Gibson 2020-06-23  1004  
f3b3ae8752adc5 Kent Gibson 2020-06-23  1005  		ret = gpiod_set_transitory(desc, false);
f3b3ae8752adc5 Kent Gibson 2020-06-23  1006  		if (ret < 0)
f3b3ae8752adc5 Kent Gibson 2020-06-23  1007  			goto out_free_line;
f3b3ae8752adc5 Kent Gibson 2020-06-23  1008  
f3b3ae8752adc5 Kent Gibson 2020-06-23  1009  		/*
f3b3ae8752adc5 Kent Gibson 2020-06-23  1010  		 * Lines have to be requested explicitly for input
f3b3ae8752adc5 Kent Gibson 2020-06-23  1011  		 * or output, else the line will be treated "as is".
f3b3ae8752adc5 Kent Gibson 2020-06-23  1012  		 */
f3b3ae8752adc5 Kent Gibson 2020-06-23  1013  		if (lc->flags & GPIOLINE_FLAG_V2_DIRECTION) {
f3b3ae8752adc5 Kent Gibson 2020-06-23  1014  			if (lc->direction == GPIOLINE_DIRECTION_OUTPUT) {
f3b3ae8752adc5 Kent Gibson 2020-06-23  1015  				int val = test_bit(i, vals);
f3b3ae8752adc5 Kent Gibson 2020-06-23  1016  
f3b3ae8752adc5 Kent Gibson 2020-06-23  1017  				ret = gpiod_direction_output(desc, val);
f3b3ae8752adc5 Kent Gibson 2020-06-23  1018  				if (ret)
f3b3ae8752adc5 Kent Gibson 2020-06-23  1019  					goto out_free_line;
f3b3ae8752adc5 Kent Gibson 2020-06-23  1020  			} else {
f3b3ae8752adc5 Kent Gibson 2020-06-23  1021  				ret = gpiod_direction_input(desc);
f3b3ae8752adc5 Kent Gibson 2020-06-23  1022  				if (ret)
f3b3ae8752adc5 Kent Gibson 2020-06-23  1023  					goto out_free_line;
f3b3ae8752adc5 Kent Gibson 2020-06-23  1024  				ret = edge_detector_setup(&line->edets[i], lc);
f3b3ae8752adc5 Kent Gibson 2020-06-23  1025  				if (ret)
f3b3ae8752adc5 Kent Gibson 2020-06-23  1026  					goto out_free_line;
f3b3ae8752adc5 Kent Gibson 2020-06-23  1027  			}
f3b3ae8752adc5 Kent Gibson 2020-06-23  1028  		}
f3b3ae8752adc5 Kent Gibson 2020-06-23  1029  
f3b3ae8752adc5 Kent Gibson 2020-06-23  1030  		atomic_notifier_call_chain(&desc->gdev->notifier,
f3b3ae8752adc5 Kent Gibson 2020-06-23  1031  					   GPIOLINE_CHANGED_REQUESTED, desc);
f3b3ae8752adc5 Kent Gibson 2020-06-23  1032  
f3b3ae8752adc5 Kent Gibson 2020-06-23  1033  		dev_dbg(&gdev->dev, "registered chardev handle for line %d\n",
f3b3ae8752adc5 Kent Gibson 2020-06-23  1034  			offset);
f3b3ae8752adc5 Kent Gibson 2020-06-23  1035  	}
f3b3ae8752adc5 Kent Gibson 2020-06-23  1036  
f3b3ae8752adc5 Kent Gibson 2020-06-23  1037  	fd = get_unused_fd_flags(O_RDONLY | O_CLOEXEC);
f3b3ae8752adc5 Kent Gibson 2020-06-23  1038  	if (fd < 0) {
f3b3ae8752adc5 Kent Gibson 2020-06-23  1039  		ret = fd;
f3b3ae8752adc5 Kent Gibson 2020-06-23  1040  		goto out_free_line;
f3b3ae8752adc5 Kent Gibson 2020-06-23  1041  	}
f3b3ae8752adc5 Kent Gibson 2020-06-23  1042  
f3b3ae8752adc5 Kent Gibson 2020-06-23  1043  	file = anon_inode_getfile("gpio-line",
f3b3ae8752adc5 Kent Gibson 2020-06-23  1044  				  &line_fileops,
f3b3ae8752adc5 Kent Gibson 2020-06-23  1045  				  line,
f3b3ae8752adc5 Kent Gibson 2020-06-23  1046  				  O_RDONLY | O_CLOEXEC);
f3b3ae8752adc5 Kent Gibson 2020-06-23  1047  	if (IS_ERR(file)) {
f3b3ae8752adc5 Kent Gibson 2020-06-23  1048  		ret = PTR_ERR(file);
f3b3ae8752adc5 Kent Gibson 2020-06-23  1049  		goto out_put_unused_fd;
f3b3ae8752adc5 Kent Gibson 2020-06-23  1050  	}
f3b3ae8752adc5 Kent Gibson 2020-06-23  1051  
f3b3ae8752adc5 Kent Gibson 2020-06-23  1052  	linereq.fd = fd;
f3b3ae8752adc5 Kent Gibson 2020-06-23  1053  	if (copy_to_user(ip, &linereq, sizeof(linereq))) {
f3b3ae8752adc5 Kent Gibson 2020-06-23  1054  		/*
f3b3ae8752adc5 Kent Gibson 2020-06-23  1055  		 * fput() will trigger the release() callback, so do not go onto
f3b3ae8752adc5 Kent Gibson 2020-06-23  1056  		 * the regular error cleanup path here.
f3b3ae8752adc5 Kent Gibson 2020-06-23  1057  		 */
f3b3ae8752adc5 Kent Gibson 2020-06-23  1058  		fput(file);
f3b3ae8752adc5 Kent Gibson 2020-06-23  1059  		put_unused_fd(fd);
f3b3ae8752adc5 Kent Gibson 2020-06-23  1060  		return -EFAULT;
f3b3ae8752adc5 Kent Gibson 2020-06-23  1061  	}
f3b3ae8752adc5 Kent Gibson 2020-06-23  1062  
f3b3ae8752adc5 Kent Gibson 2020-06-23  1063  	fd_install(fd, file);
f3b3ae8752adc5 Kent Gibson 2020-06-23  1064  
f3b3ae8752adc5 Kent Gibson 2020-06-23  1065  	dev_dbg(&gdev->dev, "registered chardev handle for %d lines\n",
f3b3ae8752adc5 Kent Gibson 2020-06-23  1066  		line->num_descs);
f3b3ae8752adc5 Kent Gibson 2020-06-23  1067  
f3b3ae8752adc5 Kent Gibson 2020-06-23  1068  	return 0;
f3b3ae8752adc5 Kent Gibson 2020-06-23  1069  
f3b3ae8752adc5 Kent Gibson 2020-06-23  1070  out_put_unused_fd:
f3b3ae8752adc5 Kent Gibson 2020-06-23  1071  	put_unused_fd(fd);
f3b3ae8752adc5 Kent Gibson 2020-06-23  1072  out_free_line:
f3b3ae8752adc5 Kent Gibson 2020-06-23  1073  	line_free(line);
f3b3ae8752adc5 Kent Gibson 2020-06-23  1074  	return ret;
f3b3ae8752adc5 Kent Gibson 2020-06-23  1075  }

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 25304 bytes --]

WARNING: multiple messages have this Message-ID (diff)
From: Dan Carpenter <dan.carpenter@oracle.com>
To: kbuild-all@lists.01.org
Subject: Re: [PATCH 16/22] gpiolib: cdev: add V2 uAPI implementation to parity with V1
Date: Tue, 23 Jun 2020 20:44:38 +0300	[thread overview]
Message-ID: <20200623174438.GL4151@kadam> (raw)
In-Reply-To: <20200623040107.22270-17-warthog618@gmail.com>

[-- Attachment #1: Type: text/plain, Size: 15572 bytes --]

[ The copy_to_user() overflow code is weird.  Why do we need to do a
  atomic_read()?  That suggests that there is a potential time of check
  time of use bug where we do:

	if (atomic_read(&gcdev->watch_abi_version) == 2) // <<-- time of check
		event_size = sizeof(struct gpioline_info_changed_v2);

	...

	if (atomic_read(&gcdev->watch_abi_version) == 2) { // <<-- time of use
		copy_to_user(blah, blah, event_size);

  If the value for "gcdev->watch_abi_version" changes between the time
  of check and the time of use then it can read beyond the end of the
  buffer.

  -- dan ]

Hi Kent,

Thank you for the patch! Perhaps something to improve:

url:    https://github.com/0day-ci/linux/commits/Kent-Gibson/gpio-cdev-add-uAPI-V2/20200623-120634
base:   https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio.git for-next
config: openrisc-randconfig-m031-20200623 (attached as .config)
compiler: or1k-linux-gcc (GCC) 9.3.0

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>

smatch warnings:
drivers/gpio/gpiolib-cdev.c:891 line_free() error: dereferencing freed memory 'line'
drivers/gpio/gpiolib-cdev.c:949 line_create() warn: possible memory leak of 'line'
drivers/gpio/gpiolib-cdev.c:1860 lineinfo_watch_read() error: copy_to_user() '&event_v1' too small (104 vs 168)

# https://github.com/0day-ci/linux/commit/f3b3ae8752adc5ac33dcf83d49b0b02f2d7ef43b
git remote add linux-review https://github.com/0day-ci/linux
git remote update linux-review
git checkout f3b3ae8752adc5ac33dcf83d49b0b02f2d7ef43b
vim +/line +891 drivers/gpio/gpiolib-cdev.c

f3b3ae8752adc5 Kent Gibson 2020-06-23   877  static void line_free(struct line *line)
f3b3ae8752adc5 Kent Gibson 2020-06-23   878  {
f3b3ae8752adc5 Kent Gibson 2020-06-23   879  	int i;
f3b3ae8752adc5 Kent Gibson 2020-06-23   880  
f3b3ae8752adc5 Kent Gibson 2020-06-23   881  	for (i = 0; i < line->num_descs; i++) {
f3b3ae8752adc5 Kent Gibson 2020-06-23   882  		if (line->edets)
f3b3ae8752adc5 Kent Gibson 2020-06-23   883  			edge_detector_stop(&line->edets[i]);
f3b3ae8752adc5 Kent Gibson 2020-06-23   884  		if (line->descs[i])
f3b3ae8752adc5 Kent Gibson 2020-06-23   885  			gpiod_free(line->descs[i]);
f3b3ae8752adc5 Kent Gibson 2020-06-23   886  	}
f3b3ae8752adc5 Kent Gibson 2020-06-23   887  	kfifo_free(&line->events);
f3b3ae8752adc5 Kent Gibson 2020-06-23   888  	kfree(line->label);
f3b3ae8752adc5 Kent Gibson 2020-06-23   889  	kfree(line->edets);
f3b3ae8752adc5 Kent Gibson 2020-06-23   890  	kfree(line);
f3b3ae8752adc5 Kent Gibson 2020-06-23  @891  	put_device(&line->gdev->dev);
f3b3ae8752adc5 Kent Gibson 2020-06-23   892  }
f3b3ae8752adc5 Kent Gibson 2020-06-23   893  
f3b3ae8752adc5 Kent Gibson 2020-06-23   894  static int line_release(struct inode *inode, struct file *file)
f3b3ae8752adc5 Kent Gibson 2020-06-23   895  {
f3b3ae8752adc5 Kent Gibson 2020-06-23   896  	struct line *line = file->private_data;
f3b3ae8752adc5 Kent Gibson 2020-06-23   897  
f3b3ae8752adc5 Kent Gibson 2020-06-23   898  	line_free(line);
f3b3ae8752adc5 Kent Gibson 2020-06-23   899  	return 0;
f3b3ae8752adc5 Kent Gibson 2020-06-23   900  }
f3b3ae8752adc5 Kent Gibson 2020-06-23   901  
f3b3ae8752adc5 Kent Gibson 2020-06-23   902  static const struct file_operations line_fileops = {
f3b3ae8752adc5 Kent Gibson 2020-06-23   903  	.release = line_release,
f3b3ae8752adc5 Kent Gibson 2020-06-23   904  	.read = line_read,
f3b3ae8752adc5 Kent Gibson 2020-06-23   905  	.poll = line_poll,
f3b3ae8752adc5 Kent Gibson 2020-06-23   906  	.owner = THIS_MODULE,
f3b3ae8752adc5 Kent Gibson 2020-06-23   907  	.llseek = noop_llseek,
f3b3ae8752adc5 Kent Gibson 2020-06-23   908  	.unlocked_ioctl = line_ioctl,
f3b3ae8752adc5 Kent Gibson 2020-06-23   909  #ifdef CONFIG_COMPAT
f3b3ae8752adc5 Kent Gibson 2020-06-23   910  	.compat_ioctl = line_ioctl_compat,
f3b3ae8752adc5 Kent Gibson 2020-06-23   911  #endif
f3b3ae8752adc5 Kent Gibson 2020-06-23   912  };
f3b3ae8752adc5 Kent Gibson 2020-06-23   913  
f3b3ae8752adc5 Kent Gibson 2020-06-23   914  static int line_create(struct gpio_device *gdev, void __user *ip)
f3b3ae8752adc5 Kent Gibson 2020-06-23   915  {
f3b3ae8752adc5 Kent Gibson 2020-06-23   916  	struct gpioline_request linereq;
f3b3ae8752adc5 Kent Gibson 2020-06-23   917  	struct line *line;
f3b3ae8752adc5 Kent Gibson 2020-06-23   918  	struct file *file;
f3b3ae8752adc5 Kent Gibson 2020-06-23   919  	int fd, i, ret, size;
f3b3ae8752adc5 Kent Gibson 2020-06-23   920  	struct gpioline_config *lc;
f3b3ae8752adc5 Kent Gibson 2020-06-23   921  	unsigned long *vals;
f3b3ae8752adc5 Kent Gibson 2020-06-23   922  
f3b3ae8752adc5 Kent Gibson 2020-06-23   923  	if (copy_from_user(&linereq, ip, sizeof(linereq)))
f3b3ae8752adc5 Kent Gibson 2020-06-23   924  		return -EFAULT;
f3b3ae8752adc5 Kent Gibson 2020-06-23   925  	if ((linereq.num_lines == 0) || (linereq.num_lines > GPIOLINES_MAX))
f3b3ae8752adc5 Kent Gibson 2020-06-23   926  		return -EINVAL;
f3b3ae8752adc5 Kent Gibson 2020-06-23   927  
f3b3ae8752adc5 Kent Gibson 2020-06-23   928  	if (padding_not_zeroed(linereq.padding, GPIOLINE_REQUEST_PAD_SIZE))
f3b3ae8752adc5 Kent Gibson 2020-06-23   929  		return -EINVAL;
f3b3ae8752adc5 Kent Gibson 2020-06-23   930  
f3b3ae8752adc5 Kent Gibson 2020-06-23   931  	lc = &linereq.config;
f3b3ae8752adc5 Kent Gibson 2020-06-23   932  	ret = gpioline_config_validate(lc);
f3b3ae8752adc5 Kent Gibson 2020-06-23   933  	if (ret)
f3b3ae8752adc5 Kent Gibson 2020-06-23   934  		return ret;
f3b3ae8752adc5 Kent Gibson 2020-06-23   935  
f3b3ae8752adc5 Kent Gibson 2020-06-23   936  	/* event_buffer_size only valid with edge_detection */
f3b3ae8752adc5 Kent Gibson 2020-06-23   937  	if ((linereq.event_buffer_size) &&
f3b3ae8752adc5 Kent Gibson 2020-06-23   938  	    !(linereq.config.flags & GPIOLINE_FLAG_V2_EDGE_DETECTION))
f3b3ae8752adc5 Kent Gibson 2020-06-23   939  		return -EINVAL;
f3b3ae8752adc5 Kent Gibson 2020-06-23   940  
f3b3ae8752adc5 Kent Gibson 2020-06-23   941  	line = kzalloc(struct_size(line, descs, linereq.num_lines),
f3b3ae8752adc5 Kent Gibson 2020-06-23   942  		       GFP_KERNEL);
f3b3ae8752adc5 Kent Gibson 2020-06-23   943  	if (!line)
f3b3ae8752adc5 Kent Gibson 2020-06-23   944  		return -ENOMEM;
f3b3ae8752adc5 Kent Gibson 2020-06-23   945  
f3b3ae8752adc5 Kent Gibson 2020-06-23   946  	line->edets = kcalloc(linereq.num_lines, sizeof(*line->edets),
f3b3ae8752adc5 Kent Gibson 2020-06-23   947  			      GFP_KERNEL);
f3b3ae8752adc5 Kent Gibson 2020-06-23   948  	if (!line->edets)
f3b3ae8752adc5 Kent Gibson 2020-06-23  @949  		return -ENOMEM;
                                                        ^^^^^^^^^^^^^^^
kfree(line) before returning.

f3b3ae8752adc5 Kent Gibson 2020-06-23   950  
f3b3ae8752adc5 Kent Gibson 2020-06-23   951  	for (i = 0; i < linereq.num_lines; i++)
f3b3ae8752adc5 Kent Gibson 2020-06-23   952  		line->edets[i].line = line;
f3b3ae8752adc5 Kent Gibson 2020-06-23   953  
f3b3ae8752adc5 Kent Gibson 2020-06-23   954  	line->gdev = gdev;
f3b3ae8752adc5 Kent Gibson 2020-06-23   955  	get_device(&gdev->dev);
f3b3ae8752adc5 Kent Gibson 2020-06-23   956  
f3b3ae8752adc5 Kent Gibson 2020-06-23   957  	/* Make sure this is terminated */
f3b3ae8752adc5 Kent Gibson 2020-06-23   958  	linereq.consumer[sizeof(linereq.consumer)-1] = '\0';
f3b3ae8752adc5 Kent Gibson 2020-06-23   959  	if (strlen(linereq.consumer)) {
f3b3ae8752adc5 Kent Gibson 2020-06-23   960  		line->label = kstrdup(linereq.consumer, GFP_KERNEL);
f3b3ae8752adc5 Kent Gibson 2020-06-23   961  		if (!line->label) {
f3b3ae8752adc5 Kent Gibson 2020-06-23   962  			ret = -ENOMEM;
f3b3ae8752adc5 Kent Gibson 2020-06-23   963  			goto out_free_line;
f3b3ae8752adc5 Kent Gibson 2020-06-23   964  		}
f3b3ae8752adc5 Kent Gibson 2020-06-23   965  	}
f3b3ae8752adc5 Kent Gibson 2020-06-23   966  
f3b3ae8752adc5 Kent Gibson 2020-06-23   967  	mutex_init(&line->config_mutex);
f3b3ae8752adc5 Kent Gibson 2020-06-23   968  	init_waitqueue_head(&line->wait);
f3b3ae8752adc5 Kent Gibson 2020-06-23   969  	if (lc->edge_detection) {
f3b3ae8752adc5 Kent Gibson 2020-06-23   970  		size = linereq.event_buffer_size;
f3b3ae8752adc5 Kent Gibson 2020-06-23   971  
f3b3ae8752adc5 Kent Gibson 2020-06-23   972  		if (size > GPIOLINES_MAX*16)
f3b3ae8752adc5 Kent Gibson 2020-06-23   973  			size = GPIOLINES_MAX*16;
f3b3ae8752adc5 Kent Gibson 2020-06-23   974  		else if (size == 0)
f3b3ae8752adc5 Kent Gibson 2020-06-23   975  			size = linereq.num_lines*16;
f3b3ae8752adc5 Kent Gibson 2020-06-23   976  
f3b3ae8752adc5 Kent Gibson 2020-06-23   977  		ret = kfifo_alloc(&line->events, size, GFP_KERNEL);
f3b3ae8752adc5 Kent Gibson 2020-06-23   978  		if (ret)
f3b3ae8752adc5 Kent Gibson 2020-06-23   979  			goto out_free_line;
f3b3ae8752adc5 Kent Gibson 2020-06-23   980  
f3b3ae8752adc5 Kent Gibson 2020-06-23   981  		line->edge_detection = lc->edge_detection;
f3b3ae8752adc5 Kent Gibson 2020-06-23   982  	}
f3b3ae8752adc5 Kent Gibson 2020-06-23   983  
f3b3ae8752adc5 Kent Gibson 2020-06-23   984  	atomic_set(&line->seqno, 0);
f3b3ae8752adc5 Kent Gibson 2020-06-23   985  	line->num_descs = linereq.num_lines;
f3b3ae8752adc5 Kent Gibson 2020-06-23   986  	vals = (unsigned long *)lc->values.bitmap;
f3b3ae8752adc5 Kent Gibson 2020-06-23   987  
f3b3ae8752adc5 Kent Gibson 2020-06-23   988  	/* Request each GPIO */
f3b3ae8752adc5 Kent Gibson 2020-06-23   989  	for (i = 0; i < linereq.num_lines; i++) {
f3b3ae8752adc5 Kent Gibson 2020-06-23   990  		u32 offset = linereq.offsets[i];
f3b3ae8752adc5 Kent Gibson 2020-06-23   991  		struct gpio_desc *desc = gpiochip_get_desc(gdev->chip, offset);
f3b3ae8752adc5 Kent Gibson 2020-06-23   992  
f3b3ae8752adc5 Kent Gibson 2020-06-23   993  		if (IS_ERR(desc)) {
f3b3ae8752adc5 Kent Gibson 2020-06-23   994  			ret = PTR_ERR(desc);
f3b3ae8752adc5 Kent Gibson 2020-06-23   995  			goto out_free_line;
f3b3ae8752adc5 Kent Gibson 2020-06-23   996  		}
f3b3ae8752adc5 Kent Gibson 2020-06-23   997  
f3b3ae8752adc5 Kent Gibson 2020-06-23   998  		ret = gpiod_request(desc, line->label);
f3b3ae8752adc5 Kent Gibson 2020-06-23   999  		if (ret)
f3b3ae8752adc5 Kent Gibson 2020-06-23  1000  			goto out_free_line;
f3b3ae8752adc5 Kent Gibson 2020-06-23  1001  
f3b3ae8752adc5 Kent Gibson 2020-06-23  1002  		line->descs[i] = desc;
f3b3ae8752adc5 Kent Gibson 2020-06-23  1003  		gpioline_config_to_desc_flags(lc, &desc->flags);
f3b3ae8752adc5 Kent Gibson 2020-06-23  1004  
f3b3ae8752adc5 Kent Gibson 2020-06-23  1005  		ret = gpiod_set_transitory(desc, false);
f3b3ae8752adc5 Kent Gibson 2020-06-23  1006  		if (ret < 0)
f3b3ae8752adc5 Kent Gibson 2020-06-23  1007  			goto out_free_line;
f3b3ae8752adc5 Kent Gibson 2020-06-23  1008  
f3b3ae8752adc5 Kent Gibson 2020-06-23  1009  		/*
f3b3ae8752adc5 Kent Gibson 2020-06-23  1010  		 * Lines have to be requested explicitly for input
f3b3ae8752adc5 Kent Gibson 2020-06-23  1011  		 * or output, else the line will be treated "as is".
f3b3ae8752adc5 Kent Gibson 2020-06-23  1012  		 */
f3b3ae8752adc5 Kent Gibson 2020-06-23  1013  		if (lc->flags & GPIOLINE_FLAG_V2_DIRECTION) {
f3b3ae8752adc5 Kent Gibson 2020-06-23  1014  			if (lc->direction == GPIOLINE_DIRECTION_OUTPUT) {
f3b3ae8752adc5 Kent Gibson 2020-06-23  1015  				int val = test_bit(i, vals);
f3b3ae8752adc5 Kent Gibson 2020-06-23  1016  
f3b3ae8752adc5 Kent Gibson 2020-06-23  1017  				ret = gpiod_direction_output(desc, val);
f3b3ae8752adc5 Kent Gibson 2020-06-23  1018  				if (ret)
f3b3ae8752adc5 Kent Gibson 2020-06-23  1019  					goto out_free_line;
f3b3ae8752adc5 Kent Gibson 2020-06-23  1020  			} else {
f3b3ae8752adc5 Kent Gibson 2020-06-23  1021  				ret = gpiod_direction_input(desc);
f3b3ae8752adc5 Kent Gibson 2020-06-23  1022  				if (ret)
f3b3ae8752adc5 Kent Gibson 2020-06-23  1023  					goto out_free_line;
f3b3ae8752adc5 Kent Gibson 2020-06-23  1024  				ret = edge_detector_setup(&line->edets[i], lc);
f3b3ae8752adc5 Kent Gibson 2020-06-23  1025  				if (ret)
f3b3ae8752adc5 Kent Gibson 2020-06-23  1026  					goto out_free_line;
f3b3ae8752adc5 Kent Gibson 2020-06-23  1027  			}
f3b3ae8752adc5 Kent Gibson 2020-06-23  1028  		}
f3b3ae8752adc5 Kent Gibson 2020-06-23  1029  
f3b3ae8752adc5 Kent Gibson 2020-06-23  1030  		atomic_notifier_call_chain(&desc->gdev->notifier,
f3b3ae8752adc5 Kent Gibson 2020-06-23  1031  					   GPIOLINE_CHANGED_REQUESTED, desc);
f3b3ae8752adc5 Kent Gibson 2020-06-23  1032  
f3b3ae8752adc5 Kent Gibson 2020-06-23  1033  		dev_dbg(&gdev->dev, "registered chardev handle for line %d\n",
f3b3ae8752adc5 Kent Gibson 2020-06-23  1034  			offset);
f3b3ae8752adc5 Kent Gibson 2020-06-23  1035  	}
f3b3ae8752adc5 Kent Gibson 2020-06-23  1036  
f3b3ae8752adc5 Kent Gibson 2020-06-23  1037  	fd = get_unused_fd_flags(O_RDONLY | O_CLOEXEC);
f3b3ae8752adc5 Kent Gibson 2020-06-23  1038  	if (fd < 0) {
f3b3ae8752adc5 Kent Gibson 2020-06-23  1039  		ret = fd;
f3b3ae8752adc5 Kent Gibson 2020-06-23  1040  		goto out_free_line;
f3b3ae8752adc5 Kent Gibson 2020-06-23  1041  	}
f3b3ae8752adc5 Kent Gibson 2020-06-23  1042  
f3b3ae8752adc5 Kent Gibson 2020-06-23  1043  	file = anon_inode_getfile("gpio-line",
f3b3ae8752adc5 Kent Gibson 2020-06-23  1044  				  &line_fileops,
f3b3ae8752adc5 Kent Gibson 2020-06-23  1045  				  line,
f3b3ae8752adc5 Kent Gibson 2020-06-23  1046  				  O_RDONLY | O_CLOEXEC);
f3b3ae8752adc5 Kent Gibson 2020-06-23  1047  	if (IS_ERR(file)) {
f3b3ae8752adc5 Kent Gibson 2020-06-23  1048  		ret = PTR_ERR(file);
f3b3ae8752adc5 Kent Gibson 2020-06-23  1049  		goto out_put_unused_fd;
f3b3ae8752adc5 Kent Gibson 2020-06-23  1050  	}
f3b3ae8752adc5 Kent Gibson 2020-06-23  1051  
f3b3ae8752adc5 Kent Gibson 2020-06-23  1052  	linereq.fd = fd;
f3b3ae8752adc5 Kent Gibson 2020-06-23  1053  	if (copy_to_user(ip, &linereq, sizeof(linereq))) {
f3b3ae8752adc5 Kent Gibson 2020-06-23  1054  		/*
f3b3ae8752adc5 Kent Gibson 2020-06-23  1055  		 * fput() will trigger the release() callback, so do not go onto
f3b3ae8752adc5 Kent Gibson 2020-06-23  1056  		 * the regular error cleanup path here.
f3b3ae8752adc5 Kent Gibson 2020-06-23  1057  		 */
f3b3ae8752adc5 Kent Gibson 2020-06-23  1058  		fput(file);
f3b3ae8752adc5 Kent Gibson 2020-06-23  1059  		put_unused_fd(fd);
f3b3ae8752adc5 Kent Gibson 2020-06-23  1060  		return -EFAULT;
f3b3ae8752adc5 Kent Gibson 2020-06-23  1061  	}
f3b3ae8752adc5 Kent Gibson 2020-06-23  1062  
f3b3ae8752adc5 Kent Gibson 2020-06-23  1063  	fd_install(fd, file);
f3b3ae8752adc5 Kent Gibson 2020-06-23  1064  
f3b3ae8752adc5 Kent Gibson 2020-06-23  1065  	dev_dbg(&gdev->dev, "registered chardev handle for %d lines\n",
f3b3ae8752adc5 Kent Gibson 2020-06-23  1066  		line->num_descs);
f3b3ae8752adc5 Kent Gibson 2020-06-23  1067  
f3b3ae8752adc5 Kent Gibson 2020-06-23  1068  	return 0;
f3b3ae8752adc5 Kent Gibson 2020-06-23  1069  
f3b3ae8752adc5 Kent Gibson 2020-06-23  1070  out_put_unused_fd:
f3b3ae8752adc5 Kent Gibson 2020-06-23  1071  	put_unused_fd(fd);
f3b3ae8752adc5 Kent Gibson 2020-06-23  1072  out_free_line:
f3b3ae8752adc5 Kent Gibson 2020-06-23  1073  	line_free(line);
f3b3ae8752adc5 Kent Gibson 2020-06-23  1074  	return ret;
f3b3ae8752adc5 Kent Gibson 2020-06-23  1075  }

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 25304 bytes --]

  reply	other threads:[~2020-06-23 17:45 UTC|newest]

Thread overview: 65+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-06-23  4:00 [PATCH 00/22] gpio: cdev: add uAPI V2 Kent Gibson
2020-06-23  4:00 ` [PATCH 01/22] gpiolib: move gpiolib-sysfs function declarations into their own header Kent Gibson
2020-06-24 13:34   ` Bartosz Golaszewski
2020-06-24 13:38     ` Kent Gibson
2020-06-23  4:00 ` [PATCH 02/22] gpiolib: cdev: sort includes Kent Gibson
2020-06-24 13:34   ` Bartosz Golaszewski
2020-06-23  4:00 ` [PATCH 03/22] gpiolib: cdev: minor indentation fixes Kent Gibson
2020-06-24 13:35   ` Bartosz Golaszewski
2020-06-23  4:00 ` [PATCH 04/22] gpiolib: cdev: refactor gpiohandle_flags_to_desc_flags Kent Gibson
2020-06-24 13:51   ` Bartosz Golaszewski
2020-06-23  4:00 ` [PATCH 05/22] gpiolib: cdev: rename 'filep' and 'filp' to 'file' to be consistent with other use Kent Gibson
2020-06-24 13:52   ` Bartosz Golaszewski
2020-06-23  4:00 ` [PATCH 06/22] gpiolib: cdev: rename numdescs to num_descs Kent Gibson
2020-06-24 13:53   ` Bartosz Golaszewski
2020-06-23  4:00 ` [PATCH 07/22] gpiolib: cdev: remove pointless decrement of i Kent Gibson
2020-06-24 13:53   ` Bartosz Golaszewski
2020-06-23  4:00 ` [PATCH 08/22] gpiolib: cdev: complete the irq/thread timestamp handshake Kent Gibson
2020-06-24 14:00   ` Bartosz Golaszewski
2020-06-24 14:08     ` Kent Gibson
2020-06-25  9:44       ` Bartosz Golaszewski
2020-06-25 10:01         ` Kent Gibson
2020-06-30  9:08           ` Bartosz Golaszewski
2020-06-23  4:00 ` [PATCH 09/22] gpiolib: cdev: rename priv to gcdev Kent Gibson
2020-06-24 14:04   ` Bartosz Golaszewski
2020-06-24 14:19     ` Kent Gibson
2020-06-24 14:20       ` Bartosz Golaszewski
2020-06-24 23:16         ` Kent Gibson
2020-06-25 10:26           ` Bartosz Golaszewski
2020-06-23  4:00 ` [PATCH 10/22] gpiolib: cdev: fix minor race in GET_LINEINFO_WATCH Kent Gibson
2020-06-24 14:05   ` Bartosz Golaszewski
2020-06-24 14:46   ` Andy Shevchenko
2020-06-24 15:57     ` Kent Gibson
2020-06-24 22:58       ` Kent Gibson
2020-06-25  8:44         ` Andy Shevchenko
2020-06-25  9:13           ` Kent Gibson
2020-06-25  9:23             ` Andy Shevchenko
2020-06-25  9:36               ` Kent Gibson
2020-06-23  4:00 ` [PATCH 11/22] gpiolib: cdev: remove recalculation of offset Kent Gibson
2020-06-30  8:56   ` Bartosz Golaszewski
2020-06-23  4:00 ` [PATCH 12/22] gpio: uapi: define GPIO_MAX_NAME_SIZE for array sizes Kent Gibson
2020-06-24 14:13   ` Bartosz Golaszewski
2020-06-23  4:00 ` [PATCH 13/22] gpio: uapi: define uAPI V2 Kent Gibson
2020-06-24 14:33   ` Andy Shevchenko
2020-06-24 15:40     ` Kent Gibson
2020-06-26 14:02       ` Kent Gibson
2020-06-24 14:36   ` Bartosz Golaszewski
2020-06-24 23:58     ` Kent Gibson
2020-06-23  4:00 ` [PATCH 14/22] gpiolib: make cdev a build option Kent Gibson
2020-06-29 14:25   ` Bartosz Golaszewski
2020-06-23  4:01 ` [PATCH 15/22] gpiolib: add build option for CDEV V1 ABI Kent Gibson
2020-06-29 14:26   ` Bartosz Golaszewski
2020-06-23  4:01 ` [PATCH 16/22] gpiolib: cdev: add V2 uAPI implementation to parity with V1 Kent Gibson
2020-06-23 17:44   ` Dan Carpenter [this message]
2020-06-23 17:44     ` Dan Carpenter
2020-06-23 17:44     ` Dan Carpenter
2020-06-23 23:23     ` Kent Gibson
2020-06-23  4:01 ` [PATCH 17/22] gpiolib: cdev: report edge detection in lineinfo Kent Gibson
2020-06-23  4:01 ` [PATCH 18/22] gpiolib: cdev: support setting debounce Kent Gibson
2020-06-23  4:01 ` [PATCH 19/22] gpio: uapi: document uAPI V1 as deprecated Kent Gibson
2020-06-23  4:01 ` [PATCH 20/22] tools: gpio: switch tools to V2 uAPI Kent Gibson
2020-06-23  4:01 ` [PATCH 21/22] tools: gpio: add debounce support to gpio-event-mon Kent Gibson
2020-06-23  4:01 ` [PATCH 22/22] tools: gpio: support monitoring multiple lines Kent Gibson
2020-06-30 10:43   ` Bartosz Golaszewski
  -- strict thread matches above, loose matches on Subject: below --
2020-06-23  7:26 [PATCH 16/22] gpiolib: cdev: add V2 uAPI implementation to parity with V1 kernel test robot
2020-06-23 16:56 kernel test robot

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200623174438.GL4151@kadam \
    --to=dan.carpenter@oracle.com \
    --cc=bgolaszewski@baylibre.com \
    --cc=kbuild-all@lists.01.org \
    --cc=kbuild@lists.01.org \
    --cc=linus.walleij@linaro.org \
    --cc=linux-gpio@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=lkp@intel.com \
    --cc=warthog618@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.