diff options
Diffstat (limited to 'drivers/iio/industrialio-buffer.c')
| -rw-r--r-- | drivers/iio/industrialio-buffer.c | 34 | 
1 files changed, 19 insertions, 15 deletions
diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c index e180728914c0..208b5193c621 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -1569,9 +1569,17 @@ static long iio_device_buffer_getfd(struct iio_dev *indio_dev, unsigned long arg  	}  	if (copy_to_user(ival, &fd, sizeof(fd))) { -		put_unused_fd(fd); -		ret = -EFAULT; -		goto error_free_ib; +		/* +		 * "Leak" the fd, as there's not much we can do about this +		 * anyway. 'fd' might have been closed already, as +		 * anon_inode_getfd() called fd_install() on it, which made +		 * it reachable by userland. +		 * +		 * Instead of allowing a malicious user to play tricks with +		 * us, rely on the process exit path to do any necessary +		 * cleanup, as in releasing the file, if still needed. +		 */ +		return -EFAULT;  	}  	return 0; @@ -1727,8 +1735,7 @@ int iio_buffers_alloc_sysfs_and_mask(struct iio_dev *indio_dev)  	struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev);  	const struct iio_chan_spec *channels;  	struct iio_buffer *buffer; -	int unwind_idx; -	int ret, i; +	int ret, i, idx;  	size_t sz;  	channels = indio_dev->channels; @@ -1743,15 +1750,12 @@ int iio_buffers_alloc_sysfs_and_mask(struct iio_dev *indio_dev)  	if (!iio_dev_opaque->attached_buffers_cnt)  		return 0; -	for (i = 0; i < iio_dev_opaque->attached_buffers_cnt; i++) { -		buffer = iio_dev_opaque->attached_buffers[i]; -		ret = __iio_buffer_alloc_sysfs_and_mask(buffer, indio_dev, i); -		if (ret) { -			unwind_idx = i - 1; +	for (idx = 0; idx < iio_dev_opaque->attached_buffers_cnt; idx++) { +		buffer = iio_dev_opaque->attached_buffers[idx]; +		ret = __iio_buffer_alloc_sysfs_and_mask(buffer, indio_dev, idx); +		if (ret)  			goto error_unwind_sysfs_and_mask; -		}  	} -	unwind_idx = iio_dev_opaque->attached_buffers_cnt - 1;  	sz = sizeof(*(iio_dev_opaque->buffer_ioctl_handler));  	iio_dev_opaque->buffer_ioctl_handler = kzalloc(sz, GFP_KERNEL); @@ -1767,9 +1771,9 @@ int iio_buffers_alloc_sysfs_and_mask(struct iio_dev *indio_dev)  	return 0;  error_unwind_sysfs_and_mask: -	for (; unwind_idx >= 0; unwind_idx--) { -		buffer = iio_dev_opaque->attached_buffers[unwind_idx]; -		__iio_buffer_free_sysfs_and_mask(buffer, indio_dev, unwind_idx); +	while (idx--) { +		buffer = iio_dev_opaque->attached_buffers[idx]; +		__iio_buffer_free_sysfs_and_mask(buffer, indio_dev, idx);  	}  	return ret;  }  |