Commit ebf275b8 authored by Bjorn Helgaas's avatar Bjorn Helgaas
Browse files

Merge branch 'pci/sysfs'

- Check for CAP_SYS_ADMIN before validating sysfs user input, not after
  (Krzysztof Wilczyński)

- Always return -EINVAL from sysfs "store" functions for invalid user input
  instead of -EINVAL sometimes and -ERANGE others (Krzysztof Wilczyński)

- Use kstrtobool() directly instead of the strtobool() wrapper (Krzysztof
  Wilczyński)

* pci/sysfs:
  PCI: Use kstrtobool() directly, sans strtobool() wrapper
  PCI/sysfs: Return -EINVAL consistently from "store" functions
  PCI/sysfs: Check CAP_SYS_ADMIN before parsing user input

# Conflicts:
#	drivers/pci/iov.c
parents e34f4262 e0f7b192
Loading
Loading
Loading
Loading
+6 −12
Original line number Diff line number Diff line
@@ -1947,11 +1947,9 @@ static ssize_t epf_ntb_##_name##_store(struct config_item *item, \
	struct config_group *group = to_config_group(item);		\
	struct epf_ntb *ntb = to_epf_ntb(group);			\
	u32 val;							\
	int ret;							\
									\
	ret = kstrtou32(page, 0, &val);					\
	if (ret)							\
		return ret;						\
	if (kstrtou32(page, 0, &val) < 0)				\
		return -EINVAL;						\
									\
	ntb->_name = val;						\
									\
@@ -1980,11 +1978,9 @@ static ssize_t epf_ntb_##_name##_store(struct config_item *item, \
	struct device *dev = &ntb->epf->dev;				\
	int win_no;							\
	u64 val;							\
	int ret;							\
									\
	ret = kstrtou64(page, 0, &val);					\
	if (ret)							\
		return ret;						\
	if (kstrtou64(page, 0, &val) < 0)				\
		return -EINVAL;						\
									\
	if (sscanf(#_name, "mw%d", &win_no) != 1)			\
		return -EINVAL;						\
@@ -2005,11 +2001,9 @@ static ssize_t epf_ntb_num_mws_store(struct config_item *item,
	struct config_group *group = to_config_group(item);
	struct epf_ntb *ntb = to_epf_ntb(group);
	u32 val;
	int ret;

	ret = kstrtou32(page, 0, &val);
	if (ret)
		return ret;
	if (kstrtou32(page, 0, &val) < 0)
		return -EINVAL;

	if (val > MAX_MW)
		return -EINVAL;
+12 −23
Original line number Diff line number Diff line
@@ -175,9 +175,8 @@ static ssize_t pci_epc_start_store(struct config_item *item, const char *page,

	epc = epc_group->epc;

	ret = kstrtobool(page, &start);
	if (ret)
		return ret;
	if (kstrtobool(page, &start) < 0)
		return -EINVAL;

	if (!start) {
		pci_epc_stop(epc);
@@ -329,13 +328,11 @@ static ssize_t pci_epf_##_name##_store(struct config_item *item, \
				       const char *page, size_t len)	       \
{									       \
	u32 val;							       \
	int ret;							       \
	struct pci_epf *epf = to_pci_epf_group(item)->epf;		       \
	if (WARN_ON_ONCE(!epf->header))					       \
		return -EINVAL;						       \
	ret = kstrtou32(page, 0, &val);					       \
	if (ret)							       \
		return ret;						       \
	if (kstrtou32(page, 0, &val) < 0)				       \
		return -EINVAL;						       \
	epf->header->_name = val;					       \
	return len;							       \
}
@@ -345,13 +342,11 @@ static ssize_t pci_epf_##_name##_store(struct config_item *item, \
				       const char *page, size_t len)	       \
{									       \
	u16 val;							       \
	int ret;							       \
	struct pci_epf *epf = to_pci_epf_group(item)->epf;		       \
	if (WARN_ON_ONCE(!epf->header))					       \
		return -EINVAL;						       \
	ret = kstrtou16(page, 0, &val);					       \
	if (ret)							       \
		return ret;						       \
	if (kstrtou16(page, 0, &val) < 0)				       \
		return -EINVAL;						       \
	epf->header->_name = val;					       \
	return len;							       \
}
@@ -361,13 +356,11 @@ static ssize_t pci_epf_##_name##_store(struct config_item *item, \
				       const char *page, size_t len)	       \
{									       \
	u8 val;								       \
	int ret;							       \
	struct pci_epf *epf = to_pci_epf_group(item)->epf;		       \
	if (WARN_ON_ONCE(!epf->header))					       \
		return -EINVAL;						       \
	ret = kstrtou8(page, 0, &val);					       \
	if (ret)							       \
		return ret;						       \
	if (kstrtou8(page, 0, &val) < 0)				       \
		return -EINVAL;						       \
	epf->header->_name = val;					       \
	return len;							       \
}
@@ -376,11 +369,9 @@ static ssize_t pci_epf_msi_interrupts_store(struct config_item *item,
					    const char *page, size_t len)
{
	u8 val;
	int ret;

	ret = kstrtou8(page, 0, &val);
	if (ret)
		return ret;
	if (kstrtou8(page, 0, &val) < 0)
		return -EINVAL;

	to_pci_epf_group(item)->epf->msi_interrupts = val;

@@ -398,11 +389,9 @@ static ssize_t pci_epf_msix_interrupts_store(struct config_item *item,
					     const char *page, size_t len)
{
	u16 val;
	int ret;

	ret = kstrtou16(page, 0, &val);
	if (ret)
		return ret;
	if (kstrtou16(page, 0, &val) < 0)
		return -EINVAL;

	to_pci_epf_group(item)->epf->msix_interrupts = val;

+6 −8
Original line number Diff line number Diff line
@@ -186,11 +186,10 @@ static ssize_t sriov_vf_msix_count_store(struct device *dev,
	struct pci_dev *vf_dev = to_pci_dev(dev);
	struct pci_dev *pdev = pci_physfn(vf_dev);
	struct pci_driver *pdrv;
	int val, ret;
	int val, ret = 0;

	ret = kstrtoint(buf, 0, &val);
	if (ret)
		return ret;
	if (kstrtoint(buf, 0, &val) < 0)
		return -EINVAL;

	if (val < 0)
		return -EINVAL;
@@ -381,12 +380,11 @@ static ssize_t sriov_numvfs_store(struct device *dev,
{
	struct pci_dev *pdev = to_pci_dev(dev);
	struct pci_driver *pdrv;
	int ret;
	int ret = 0;
	u16 num_vfs;

	ret = kstrtou16(buf, 0, &num_vfs);
	if (ret < 0)
		return ret;
	if (kstrtou16(buf, 0, &num_vfs) < 0)
		return -EINVAL;

	if (num_vfs > pci_sriov_get_totalvfs(pdev))
		return -ERANGE;
+3 −3
Original line number Diff line number Diff line
@@ -943,7 +943,7 @@ EXPORT_SYMBOL_GPL(pci_p2pdma_unmap_sg_attrs);
 *
 * Parses an attribute value to decide whether to enable p2pdma.
 * The value can select a PCI device (using its full BDF device
 * name) or a boolean (in any format strtobool() accepts). A false
 * name) or a boolean (in any format kstrtobool() accepts). A false
 * value disables p2pdma, a true value expects the caller
 * to automatically find a compatible device and specifying a PCI device
 * expects the caller to use the specific provider.
@@ -975,11 +975,11 @@ int pci_p2pdma_enable_store(const char *page, struct pci_dev **p2p_dev,
	} else if ((page[0] == '0' || page[0] == '1') && !iscntrl(page[1])) {
		/*
		 * If the user enters a PCI device that  doesn't exist
		 * like "0000:01:00.1", we don't want strtobool to think
		 * like "0000:01:00.1", we don't want kstrtobool to think
		 * it's a '0' when it's clearly not what the user wanted.
		 * So we require 0's and 1's to be exactly one character.
		 */
	} else if (!strtobool(page, use_p2pdma)) {
	} else if (!kstrtobool(page, use_p2pdma)) {
		return 0;
	}

+13 −14
Original line number Diff line number Diff line
@@ -295,15 +295,15 @@ static ssize_t enable_store(struct device *dev, struct device_attribute *attr,
{
	struct pci_dev *pdev = to_pci_dev(dev);
	unsigned long val;
	ssize_t result = kstrtoul(buf, 0, &val);

	if (result < 0)
		return result;
	ssize_t result = 0;

	/* this can crash the machine when done on the "wrong" device */
	if (!capable(CAP_SYS_ADMIN))
		return -EPERM;

	if (kstrtoul(buf, 0, &val) < 0)
		return -EINVAL;

	device_lock(dev);
	if (dev->driver)
		result = -EBUSY;
@@ -334,14 +334,13 @@ static ssize_t numa_node_store(struct device *dev,
			       size_t count)
{
	struct pci_dev *pdev = to_pci_dev(dev);
	int node, ret;
	int node;

	if (!capable(CAP_SYS_ADMIN))
		return -EPERM;

	ret = kstrtoint(buf, 0, &node);
	if (ret)
		return ret;
	if (kstrtoint(buf, 0, &node) < 0)
		return -EINVAL;

	if ((node < 0 && node != NUMA_NO_NODE) || node >= MAX_NUMNODES)
		return -EINVAL;
@@ -400,12 +399,12 @@ static ssize_t msi_bus_store(struct device *dev, struct device_attribute *attr,
	struct pci_bus *subordinate = pdev->subordinate;
	unsigned long val;

	if (kstrtoul(buf, 0, &val) < 0)
		return -EINVAL;

	if (!capable(CAP_SYS_ADMIN))
		return -EPERM;

	if (kstrtoul(buf, 0, &val) < 0)
		return -EINVAL;

	/*
	 * "no_msi" and "bus_flags" only affect what happens when a driver
	 * requests MSI or MSI-X.  They don't affect any drivers that have
@@ -1361,10 +1360,10 @@ static ssize_t reset_store(struct device *dev, struct device_attribute *attr,
{
	struct pci_dev *pdev = to_pci_dev(dev);
	unsigned long val;
	ssize_t result = kstrtoul(buf, 0, &val);
	ssize_t result;

	if (result < 0)
		return result;
	if (kstrtoul(buf, 0, &val) < 0)
		return -EINVAL;

	if (val != 1)
		return -EINVAL;
Loading