Commit ebf275b8 authored by Bjorn Helgaas's avatar Bjorn Helgaas

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
...@@ -1947,11 +1947,9 @@ static ssize_t epf_ntb_##_name##_store(struct config_item *item, \ ...@@ -1947,11 +1947,9 @@ static ssize_t epf_ntb_##_name##_store(struct config_item *item, \
struct config_group *group = to_config_group(item); \ struct config_group *group = to_config_group(item); \
struct epf_ntb *ntb = to_epf_ntb(group); \ struct epf_ntb *ntb = to_epf_ntb(group); \
u32 val; \ u32 val; \
int ret; \
\ \
ret = kstrtou32(page, 0, &val); \ if (kstrtou32(page, 0, &val) < 0) \
if (ret) \ return -EINVAL; \
return ret; \
\ \
ntb->_name = val; \ ntb->_name = val; \
\ \
...@@ -1980,11 +1978,9 @@ static ssize_t epf_ntb_##_name##_store(struct config_item *item, \ ...@@ -1980,11 +1978,9 @@ static ssize_t epf_ntb_##_name##_store(struct config_item *item, \
struct device *dev = &ntb->epf->dev; \ struct device *dev = &ntb->epf->dev; \
int win_no; \ int win_no; \
u64 val; \ u64 val; \
int ret; \
\ \
ret = kstrtou64(page, 0, &val); \ if (kstrtou64(page, 0, &val) < 0) \
if (ret) \ return -EINVAL; \
return ret; \
\ \
if (sscanf(#_name, "mw%d", &win_no) != 1) \ if (sscanf(#_name, "mw%d", &win_no) != 1) \
return -EINVAL; \ return -EINVAL; \
...@@ -2005,11 +2001,9 @@ static ssize_t epf_ntb_num_mws_store(struct config_item *item, ...@@ -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 config_group *group = to_config_group(item);
struct epf_ntb *ntb = to_epf_ntb(group); struct epf_ntb *ntb = to_epf_ntb(group);
u32 val; u32 val;
int ret;
ret = kstrtou32(page, 0, &val); if (kstrtou32(page, 0, &val) < 0)
if (ret) return -EINVAL;
return ret;
if (val > MAX_MW) if (val > MAX_MW)
return -EINVAL; return -EINVAL;
......
...@@ -175,9 +175,8 @@ static ssize_t pci_epc_start_store(struct config_item *item, const char *page, ...@@ -175,9 +175,8 @@ static ssize_t pci_epc_start_store(struct config_item *item, const char *page,
epc = epc_group->epc; epc = epc_group->epc;
ret = kstrtobool(page, &start); if (kstrtobool(page, &start) < 0)
if (ret) return -EINVAL;
return ret;
if (!start) { if (!start) {
pci_epc_stop(epc); pci_epc_stop(epc);
...@@ -329,13 +328,11 @@ static ssize_t pci_epf_##_name##_store(struct config_item *item, \ ...@@ -329,13 +328,11 @@ static ssize_t pci_epf_##_name##_store(struct config_item *item, \
const char *page, size_t len) \ const char *page, size_t len) \
{ \ { \
u32 val; \ u32 val; \
int ret; \
struct pci_epf *epf = to_pci_epf_group(item)->epf; \ struct pci_epf *epf = to_pci_epf_group(item)->epf; \
if (WARN_ON_ONCE(!epf->header)) \ if (WARN_ON_ONCE(!epf->header)) \
return -EINVAL; \ return -EINVAL; \
ret = kstrtou32(page, 0, &val); \ if (kstrtou32(page, 0, &val) < 0) \
if (ret) \ return -EINVAL; \
return ret; \
epf->header->_name = val; \ epf->header->_name = val; \
return len; \ return len; \
} }
...@@ -345,13 +342,11 @@ static ssize_t pci_epf_##_name##_store(struct config_item *item, \ ...@@ -345,13 +342,11 @@ static ssize_t pci_epf_##_name##_store(struct config_item *item, \
const char *page, size_t len) \ const char *page, size_t len) \
{ \ { \
u16 val; \ u16 val; \
int ret; \
struct pci_epf *epf = to_pci_epf_group(item)->epf; \ struct pci_epf *epf = to_pci_epf_group(item)->epf; \
if (WARN_ON_ONCE(!epf->header)) \ if (WARN_ON_ONCE(!epf->header)) \
return -EINVAL; \ return -EINVAL; \
ret = kstrtou16(page, 0, &val); \ if (kstrtou16(page, 0, &val) < 0) \
if (ret) \ return -EINVAL; \
return ret; \
epf->header->_name = val; \ epf->header->_name = val; \
return len; \ return len; \
} }
...@@ -361,13 +356,11 @@ static ssize_t pci_epf_##_name##_store(struct config_item *item, \ ...@@ -361,13 +356,11 @@ static ssize_t pci_epf_##_name##_store(struct config_item *item, \
const char *page, size_t len) \ const char *page, size_t len) \
{ \ { \
u8 val; \ u8 val; \
int ret; \
struct pci_epf *epf = to_pci_epf_group(item)->epf; \ struct pci_epf *epf = to_pci_epf_group(item)->epf; \
if (WARN_ON_ONCE(!epf->header)) \ if (WARN_ON_ONCE(!epf->header)) \
return -EINVAL; \ return -EINVAL; \
ret = kstrtou8(page, 0, &val); \ if (kstrtou8(page, 0, &val) < 0) \
if (ret) \ return -EINVAL; \
return ret; \
epf->header->_name = val; \ epf->header->_name = val; \
return len; \ return len; \
} }
...@@ -376,11 +369,9 @@ static ssize_t pci_epf_msi_interrupts_store(struct config_item *item, ...@@ -376,11 +369,9 @@ static ssize_t pci_epf_msi_interrupts_store(struct config_item *item,
const char *page, size_t len) const char *page, size_t len)
{ {
u8 val; u8 val;
int ret;
ret = kstrtou8(page, 0, &val); if (kstrtou8(page, 0, &val) < 0)
if (ret) return -EINVAL;
return ret;
to_pci_epf_group(item)->epf->msi_interrupts = val; 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, ...@@ -398,11 +389,9 @@ static ssize_t pci_epf_msix_interrupts_store(struct config_item *item,
const char *page, size_t len) const char *page, size_t len)
{ {
u16 val; u16 val;
int ret;
ret = kstrtou16(page, 0, &val); if (kstrtou16(page, 0, &val) < 0)
if (ret) return -EINVAL;
return ret;
to_pci_epf_group(item)->epf->msix_interrupts = val; to_pci_epf_group(item)->epf->msix_interrupts = val;
......
...@@ -186,11 +186,10 @@ static ssize_t sriov_vf_msix_count_store(struct device *dev, ...@@ -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 *vf_dev = to_pci_dev(dev);
struct pci_dev *pdev = pci_physfn(vf_dev); struct pci_dev *pdev = pci_physfn(vf_dev);
struct pci_driver *pdrv; struct pci_driver *pdrv;
int val, ret; int val, ret = 0;
ret = kstrtoint(buf, 0, &val); if (kstrtoint(buf, 0, &val) < 0)
if (ret) return -EINVAL;
return ret;
if (val < 0) if (val < 0)
return -EINVAL; return -EINVAL;
...@@ -381,12 +380,11 @@ static ssize_t sriov_numvfs_store(struct device *dev, ...@@ -381,12 +380,11 @@ static ssize_t sriov_numvfs_store(struct device *dev,
{ {
struct pci_dev *pdev = to_pci_dev(dev); struct pci_dev *pdev = to_pci_dev(dev);
struct pci_driver *pdrv; struct pci_driver *pdrv;
int ret; int ret = 0;
u16 num_vfs; u16 num_vfs;
ret = kstrtou16(buf, 0, &num_vfs); if (kstrtou16(buf, 0, &num_vfs) < 0)
if (ret < 0) return -EINVAL;
return ret;
if (num_vfs > pci_sriov_get_totalvfs(pdev)) if (num_vfs > pci_sriov_get_totalvfs(pdev))
return -ERANGE; return -ERANGE;
......
...@@ -943,7 +943,7 @@ EXPORT_SYMBOL_GPL(pci_p2pdma_unmap_sg_attrs); ...@@ -943,7 +943,7 @@ EXPORT_SYMBOL_GPL(pci_p2pdma_unmap_sg_attrs);
* *
* Parses an attribute value to decide whether to enable p2pdma. * Parses an attribute value to decide whether to enable p2pdma.
* The value can select a PCI device (using its full BDF device * 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 * value disables p2pdma, a true value expects the caller
* to automatically find a compatible device and specifying a PCI device * to automatically find a compatible device and specifying a PCI device
* expects the caller to use the specific provider. * 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, ...@@ -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])) { } else if ((page[0] == '0' || page[0] == '1') && !iscntrl(page[1])) {
/* /*
* If the user enters a PCI device that doesn't exist * 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. * 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. * 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; return 0;
} }
......
...@@ -295,15 +295,15 @@ static ssize_t enable_store(struct device *dev, struct device_attribute *attr, ...@@ -295,15 +295,15 @@ static ssize_t enable_store(struct device *dev, struct device_attribute *attr,
{ {
struct pci_dev *pdev = to_pci_dev(dev); struct pci_dev *pdev = to_pci_dev(dev);
unsigned long val; unsigned long val;
ssize_t result = kstrtoul(buf, 0, &val); ssize_t result = 0;
if (result < 0)
return result;
/* this can crash the machine when done on the "wrong" device */ /* this can crash the machine when done on the "wrong" device */
if (!capable(CAP_SYS_ADMIN)) if (!capable(CAP_SYS_ADMIN))
return -EPERM; return -EPERM;
if (kstrtoul(buf, 0, &val) < 0)
return -EINVAL;
device_lock(dev); device_lock(dev);
if (dev->driver) if (dev->driver)
result = -EBUSY; result = -EBUSY;
...@@ -334,14 +334,13 @@ static ssize_t numa_node_store(struct device *dev, ...@@ -334,14 +334,13 @@ static ssize_t numa_node_store(struct device *dev,
size_t count) size_t count)
{ {
struct pci_dev *pdev = to_pci_dev(dev); struct pci_dev *pdev = to_pci_dev(dev);
int node, ret; int node;
if (!capable(CAP_SYS_ADMIN)) if (!capable(CAP_SYS_ADMIN))
return -EPERM; return -EPERM;
ret = kstrtoint(buf, 0, &node); if (kstrtoint(buf, 0, &node) < 0)
if (ret) return -EINVAL;
return ret;
if ((node < 0 && node != NUMA_NO_NODE) || node >= MAX_NUMNODES) if ((node < 0 && node != NUMA_NO_NODE) || node >= MAX_NUMNODES)
return -EINVAL; return -EINVAL;
...@@ -400,12 +399,12 @@ static ssize_t msi_bus_store(struct device *dev, struct device_attribute *attr, ...@@ -400,12 +399,12 @@ static ssize_t msi_bus_store(struct device *dev, struct device_attribute *attr,
struct pci_bus *subordinate = pdev->subordinate; struct pci_bus *subordinate = pdev->subordinate;
unsigned long val; unsigned long val;
if (kstrtoul(buf, 0, &val) < 0)
return -EINVAL;
if (!capable(CAP_SYS_ADMIN)) if (!capable(CAP_SYS_ADMIN))
return -EPERM; return -EPERM;
if (kstrtoul(buf, 0, &val) < 0)
return -EINVAL;
/* /*
* "no_msi" and "bus_flags" only affect what happens when a driver * "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 * 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, ...@@ -1361,10 +1360,10 @@ static ssize_t reset_store(struct device *dev, struct device_attribute *attr,
{ {
struct pci_dev *pdev = to_pci_dev(dev); struct pci_dev *pdev = to_pci_dev(dev);
unsigned long val; unsigned long val;
ssize_t result = kstrtoul(buf, 0, &val); ssize_t result;
if (result < 0) if (kstrtoul(buf, 0, &val) < 0)
return result; return -EINVAL;
if (val != 1) if (val != 1)
return -EINVAL; return -EINVAL;
......
...@@ -1219,7 +1219,7 @@ static ssize_t aspm_attr_store_common(struct device *dev, ...@@ -1219,7 +1219,7 @@ static ssize_t aspm_attr_store_common(struct device *dev,
struct pcie_link_state *link = pcie_aspm_get_link(pdev); struct pcie_link_state *link = pcie_aspm_get_link(pdev);
bool state_enable; bool state_enable;
if (strtobool(buf, &state_enable) < 0) if (kstrtobool(buf, &state_enable) < 0)
return -EINVAL; return -EINVAL;
down_read(&pci_bus_sem); down_read(&pci_bus_sem);
...@@ -1276,7 +1276,7 @@ static ssize_t clkpm_store(struct device *dev, ...@@ -1276,7 +1276,7 @@ static ssize_t clkpm_store(struct device *dev,
struct pcie_link_state *link = pcie_aspm_get_link(pdev); struct pcie_link_state *link = pcie_aspm_get_link(pdev);
bool state_enable; bool state_enable;
if (strtobool(buf, &state_enable) < 0) if (kstrtobool(buf, &state_enable) < 0)
return -EINVAL; return -EINVAL;
down_read(&pci_bus_sem); down_read(&pci_bus_sem);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment