scsi: csiostor: Avoid content leaks and casts
When copying attributes, the len argument was padded out and the resulting memcpy() would copy beyond the end of the source buffer. Avoid this, and use size_t for val_len to avoid all the casts. Similarly, avoid source buffer casts and use void *. Additionally enforces val_len can be represented by u16 and that the DMA buffer was not overflowed. Fixes the size of mfa, which is not FC_FDMI_PORT_ATTR_MAXFRAMESIZE_LEN (but it will be padded up to 4). This was noticed by the future CONFIG_FORTIFY_SOURCE checks. Cc: Daniel Micay <danielmicay@gmail.com> Signed-off-by: Kees Cook <keescook@chromium.org> Acked-by: Varun Prakash <varun@chelsio.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
2371cd90ab
commit
42c335f7e6
|
@ -238,14 +238,23 @@ csio_osname(uint8_t *buf, size_t buf_len)
|
|||
}
|
||||
|
||||
static inline void
|
||||
csio_append_attrib(uint8_t **ptr, uint16_t type, uint8_t *val, uint16_t len)
|
||||
csio_append_attrib(uint8_t **ptr, uint16_t type, void *val, size_t val_len)
|
||||
{
|
||||
uint16_t len;
|
||||
struct fc_fdmi_attr_entry *ae = (struct fc_fdmi_attr_entry *)*ptr;
|
||||
|
||||
if (WARN_ON(val_len > U16_MAX))
|
||||
return;
|
||||
|
||||
len = val_len;
|
||||
|
||||
ae->type = htons(type);
|
||||
len += 4; /* includes attribute type and length */
|
||||
len = (len + 3) & ~3; /* should be multiple of 4 bytes */
|
||||
ae->len = htons(len);
|
||||
memcpy(ae->value, val, len);
|
||||
memcpy(ae->value, val, val_len);
|
||||
if (len > val_len)
|
||||
memset(ae->value + val_len, 0, len - val_len);
|
||||
*ptr += len;
|
||||
}
|
||||
|
||||
|
@ -335,7 +344,7 @@ csio_ln_fdmi_rhba_cbfn(struct csio_hw *hw, struct csio_ioreq *fdmi_req)
|
|||
numattrs++;
|
||||
val = htonl(FC_PORTSPEED_1GBIT | FC_PORTSPEED_10GBIT);
|
||||
csio_append_attrib(&pld, FC_FDMI_PORT_ATTR_SUPPORTEDSPEED,
|
||||
(uint8_t *)&val,
|
||||
&val,
|
||||
FC_FDMI_PORT_ATTR_SUPPORTEDSPEED_LEN);
|
||||
numattrs++;
|
||||
|
||||
|
@ -346,23 +355,22 @@ csio_ln_fdmi_rhba_cbfn(struct csio_hw *hw, struct csio_ioreq *fdmi_req)
|
|||
else
|
||||
val = htonl(CSIO_HBA_PORTSPEED_UNKNOWN);
|
||||
csio_append_attrib(&pld, FC_FDMI_PORT_ATTR_CURRENTPORTSPEED,
|
||||
(uint8_t *)&val,
|
||||
FC_FDMI_PORT_ATTR_CURRENTPORTSPEED_LEN);
|
||||
&val, FC_FDMI_PORT_ATTR_CURRENTPORTSPEED_LEN);
|
||||
numattrs++;
|
||||
|
||||
mfs = ln->ln_sparm.csp.sp_bb_data;
|
||||
csio_append_attrib(&pld, FC_FDMI_PORT_ATTR_MAXFRAMESIZE,
|
||||
(uint8_t *)&mfs, FC_FDMI_PORT_ATTR_MAXFRAMESIZE_LEN);
|
||||
&mfs, sizeof(mfs));
|
||||
numattrs++;
|
||||
|
||||
strcpy(buf, "csiostor");
|
||||
csio_append_attrib(&pld, FC_FDMI_PORT_ATTR_OSDEVICENAME, buf,
|
||||
(uint16_t)strlen(buf));
|
||||
strlen(buf));
|
||||
numattrs++;
|
||||
|
||||
if (!csio_hostname(buf, sizeof(buf))) {
|
||||
csio_append_attrib(&pld, FC_FDMI_PORT_ATTR_HOSTNAME,
|
||||
buf, (uint16_t)strlen(buf));
|
||||
buf, strlen(buf));
|
||||
numattrs++;
|
||||
}
|
||||
attrib_blk->numattrs = htonl(numattrs);
|
||||
|
@ -444,33 +452,32 @@ csio_ln_fdmi_dprt_cbfn(struct csio_hw *hw, struct csio_ioreq *fdmi_req)
|
|||
|
||||
strcpy(buf, "Chelsio Communications");
|
||||
csio_append_attrib(&pld, FC_FDMI_HBA_ATTR_MANUFACTURER, buf,
|
||||
(uint16_t)strlen(buf));
|
||||
strlen(buf));
|
||||
numattrs++;
|
||||
csio_append_attrib(&pld, FC_FDMI_HBA_ATTR_SERIALNUMBER,
|
||||
hw->vpd.sn, (uint16_t)sizeof(hw->vpd.sn));
|
||||
hw->vpd.sn, sizeof(hw->vpd.sn));
|
||||
numattrs++;
|
||||
csio_append_attrib(&pld, FC_FDMI_HBA_ATTR_MODEL, hw->vpd.id,
|
||||
(uint16_t)sizeof(hw->vpd.id));
|
||||
sizeof(hw->vpd.id));
|
||||
numattrs++;
|
||||
csio_append_attrib(&pld, FC_FDMI_HBA_ATTR_MODELDESCRIPTION,
|
||||
hw->model_desc, (uint16_t)strlen(hw->model_desc));
|
||||
hw->model_desc, strlen(hw->model_desc));
|
||||
numattrs++;
|
||||
csio_append_attrib(&pld, FC_FDMI_HBA_ATTR_HARDWAREVERSION,
|
||||
hw->hw_ver, (uint16_t)sizeof(hw->hw_ver));
|
||||
hw->hw_ver, sizeof(hw->hw_ver));
|
||||
numattrs++;
|
||||
csio_append_attrib(&pld, FC_FDMI_HBA_ATTR_FIRMWAREVERSION,
|
||||
hw->fwrev_str, (uint16_t)strlen(hw->fwrev_str));
|
||||
hw->fwrev_str, strlen(hw->fwrev_str));
|
||||
numattrs++;
|
||||
|
||||
if (!csio_osname(buf, sizeof(buf))) {
|
||||
csio_append_attrib(&pld, FC_FDMI_HBA_ATTR_OSNAMEVERSION,
|
||||
buf, (uint16_t)strlen(buf));
|
||||
buf, strlen(buf));
|
||||
numattrs++;
|
||||
}
|
||||
|
||||
csio_append_attrib(&pld, FC_FDMI_HBA_ATTR_MAXCTPAYLOAD,
|
||||
(uint8_t *)&maxpayload,
|
||||
FC_FDMI_HBA_ATTR_MAXCTPAYLOAD_LEN);
|
||||
&maxpayload, FC_FDMI_HBA_ATTR_MAXCTPAYLOAD_LEN);
|
||||
len = (uint32_t)(pld - (uint8_t *)cmd);
|
||||
numattrs++;
|
||||
attrib_blk->numattrs = htonl(numattrs);
|
||||
|
@ -1794,6 +1801,8 @@ csio_ln_mgmt_submit_req(struct csio_ioreq *io_req,
|
|||
struct csio_mgmtm *mgmtm = csio_hw_to_mgmtm(hw);
|
||||
int rv;
|
||||
|
||||
BUG_ON(pld_len > pld->len);
|
||||
|
||||
io_req->io_cbfn = io_cbfn; /* Upper layer callback handler */
|
||||
io_req->fw_handle = (uintptr_t) (io_req);
|
||||
io_req->eq_idx = mgmtm->eq_idx;
|
||||
|
|
Loading…
Reference in New Issue