> > #include <linux/ethtool.h> > > +#include <linux/sfp.h> > > +#include <linux/firmware.h> > > alphabetical order, please Ok. > > > +static int > > +module_flash_fw_schedule(struct net_device *dev, > > + struct ethtool_module_fw_flash_params *params, > > + struct netlink_ext_ack *extack) > > +{ > > + const struct ethtool_ops *ops = dev->ethtool_ops; > > + struct ethtool_module_fw_flash *module_fw; > > + int err; > > + > > + if (!ops->set_module_eeprom_by_page || > > + !ops->get_module_eeprom_by_page) { > > + NL_SET_ERR_MSG(extack, > > + "Flashing module firmware is not supported by > this device"); > > + return -EOPNOTSUPP; > > + } > > + > > + if (dev->module_fw_flash_in_progress) { > > + NL_SET_ERR_MSG(extack, "Module firmware flashing already > in progress"); > > + return -EBUSY; > > + } > > + > > + module_fw = kzalloc(sizeof(*module_fw), GFP_KERNEL); > > + if (!module_fw) > > + return -ENOMEM; > > + > > + module_fw->params = *params; > > + err = request_firmware(&module_fw->fw, module_fw- > >params.file_name, > > request_firmware_direct() ? I think udev timeout is 30 sec and we're holding > rtnl_lock.. I don't remember why we didn't use that in devlink Ok will change. > > > + &dev->dev); > > + if (err) { > > + NL_SET_ERR_MSG(extack, > > + "Failed to request module firmware image"); > > + goto err_request_firmware; > > + } > > + > > + err = module_flash_fw_work_init(module_fw, dev, extack); > > + if (err < 0) { > > + NL_SET_ERR_MSG(extack, > > + "Flashing module firmware is not supported by > this device"); > > + goto err_work_init; > > + } > > + > > + dev->module_fw_flash_in_progress = true; > > What does this protect us from? Currently, it protects us from flashing an in-progress-flashing-module. > > > +static int module_flash_fw(struct net_device *dev, struct nlattr **tb, > > + struct netlink_ext_ack *extack) { > > + struct ethtool_module_fw_flash_params params = {}; > > + struct nlattr *attr; > > + > > + if (!tb[ETHTOOL_A_MODULE_FW_FLASH_FILE_NAME]) { > > + NL_SET_ERR_MSG_ATTR(extack, > > GENL_REQ_ATTR_CHECK, and you can check it in the caller, before taking > rtnl_lock. > OK, np. The idea was to have module_flash_fw() that checks the attrs and extract them into params and ethnl_act_module_fw_flash() should be free from those checks. But if so, maybe this separation is redundant and should combine the two? > > + > tb[ETHTOOL_A_MODULE_FW_FLASH_FILE_NAME], > > + "File name attribute is missing"); > > + return -EINVAL; > > + } > > + > > + params.file_name = > > + nla_data(tb[ETHTOOL_A_MODULE_FW_FLASH_FILE_NAME]); > > Hm. I think you copy the param struct by value to the work container. > nla_data() is in the skb which is going to get freed after _ACT returns. > So if anyone tries to access the name from the work it's going to UAF? The file_name parameter is not really needed inside the work. Once we called request_firmware_direct(), we have all that we need in module_fw->fw. Do we still need to avoid that situation? If so, can you please suggest how? > > > + > > + attr = tb[ETHTOOL_A_MODULE_FW_FLASH_PASSWORD]; > > + if (attr) { > > + params.password = cpu_to_be32(nla_get_u32(attr)); > > + params.password_valid = true; > > + } > > + > > + return module_flash_fw_schedule(dev, ¶ms, extack); } >