Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F147359460
D18817.id52761.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
2 KB
Referenced Files
None
Subscribers
None
D18817.id52761.diff
View Options
Index: sys/dev/ixl/ixl_pf_main.c
===================================================================
--- sys/dev/ixl/ixl_pf_main.c
+++ sys/dev/ixl/ixl_pf_main.c
@@ -3663,23 +3663,34 @@
struct i40e_nvm_access *nvma;
device_t dev = pf->dev;
enum i40e_status_code status = 0;
- int perrno;
+ size_t nvma_size, ifd_len, exp_len;
+ int err, perrno;
DEBUGFUNC("ixl_handle_nvmupd_cmd");
/* Sanity checks */
- if (ifd->ifd_len < sizeof(struct i40e_nvm_access) ||
+ nvma_size = sizeof(struct i40e_nvm_access);
+ ifd_len = ifd->ifd_len;
+
+ if (ifd_len < nvma_size ||
ifd->ifd_data == NULL) {
device_printf(dev, "%s: incorrect ifdrv length or data pointer\n",
__func__);
device_printf(dev, "%s: ifdrv length: %zu, sizeof(struct i40e_nvm_access): %zu\n",
- __func__, ifd->ifd_len, sizeof(struct i40e_nvm_access));
+ __func__, ifd_len, nvma_size);
device_printf(dev, "%s: data pointer: %p\n", __func__,
ifd->ifd_data);
return (EINVAL);
}
- nvma = (struct i40e_nvm_access *)ifd->ifd_data;
+ nvma = malloc(ifd_len, M_DEVBUF, M_WAITOK);
+ err = copyin(ifd->ifd_data, nvma, ifd_len);
+ if (err) {
+ device_printf(dev, "%s: Cannot get request from user space\n",
+ __func__);
+ free(nvma, M_DEVBUF);
+ return (err);
+ }
if (pf->dbg_mask & IXL_DBG_NVMUPD)
ixl_print_nvm_cmd(dev, nvma);
@@ -3693,13 +3704,49 @@
}
}
- if (!(pf->state & IXL_PF_STATE_ADAPTER_RESETTING)) {
- // TODO: Might need a different lock here
- // IXL_PF_LOCK(pf);
- status = i40e_nvmupd_command(hw, nvma, nvma->data, &perrno);
- // IXL_PF_UNLOCK(pf);
- } else {
- perrno = -EBUSY;
+ if (pf->state & IXL_PF_STATE_ADAPTER_RESETTING) {
+ free(nvma, M_DEVBUF);
+ return (-EBUSY);
+ }
+
+ if (nvma->data_size < 1 || nvma->data_size > 4096) {
+ device_printf(dev, "%s: invalid request, data size not in supported range\n",
+ __func__);
+ free(nvma, M_DEVBUF);
+ return (EINVAL);
+ }
+
+ /*
+ * Older versions of the NVM update tool don't set ifd_len to the size
+ * of the entire buffer passed to the ioctl. Check the data_size field
+ * in the contained i40e_nvm_access struct and ensure everything is
+ * copied in from userspace.
+ */
+ exp_len = nvma_size + nvma->data_size - 1; /* One byte is kept in struct */
+
+ if (ifd_len < exp_len) {
+ ifd_len = exp_len;
+ nvma = realloc(nvma, ifd_len, M_DEVBUF, M_WAITOK);
+ err = copyin(ifd->ifd_data, nvma, ifd_len);
+ if (err) {
+ device_printf(dev, "%s: Cannot get request from user space\n",
+ __func__);
+ free(nvma, M_DEVBUF);
+ return (err);
+ }
+ }
+
+ // TODO: Might need a different lock here
+ // IXL_PF_LOCK(pf);
+ status = i40e_nvmupd_command(hw, nvma, nvma->data, &perrno);
+ // IXL_PF_UNLOCK(pf);
+
+ err = copyout(nvma, ifd->ifd_data, ifd_len);
+ free(nvma, M_DEVBUF);
+ if (err) {
+ device_printf(dev, "%s: Cannot return data to user space\n",
+ __func__);
+ return (err);
}
/* Let the nvmupdate report errors, show them only when debug is enabled */
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Mar 11, 7:44 AM (8 h, 31 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29532287
Default Alt Text
D18817.id52761.diff (2 KB)
Attached To
Mode
D18817: ixl(4): Fix handling data passed with ioctl from NVM update tool
Attached
Detach File
Event Timeline
Log In to Comment