Commit 42c335f7 authored by Kees Cook's avatar Kees Cook Committed by Martin K. Petersen

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: default avatarKees Cook <keescook@chromium.org>
Acked-by: default avatarVarun Prakash <varun@chelsio.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 2371cd90
...@@ -238,14 +238,23 @@ csio_osname(uint8_t *buf, size_t buf_len) ...@@ -238,14 +238,23 @@ csio_osname(uint8_t *buf, size_t buf_len)
} }
static inline void 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; 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); ae->type = htons(type);
len += 4; /* includes attribute type and length */ len += 4; /* includes attribute type and length */
len = (len + 3) & ~3; /* should be multiple of 4 bytes */ len = (len + 3) & ~3; /* should be multiple of 4 bytes */
ae->len = htons(len); 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; *ptr += len;
} }
...@@ -335,7 +344,7 @@ csio_ln_fdmi_rhba_cbfn(struct csio_hw *hw, struct csio_ioreq *fdmi_req) ...@@ -335,7 +344,7 @@ csio_ln_fdmi_rhba_cbfn(struct csio_hw *hw, struct csio_ioreq *fdmi_req)
numattrs++; numattrs++;
val = htonl(FC_PORTSPEED_1GBIT | FC_PORTSPEED_10GBIT); val = htonl(FC_PORTSPEED_1GBIT | FC_PORTSPEED_10GBIT);
csio_append_attrib(&pld, FC_FDMI_PORT_ATTR_SUPPORTEDSPEED, csio_append_attrib(&pld, FC_FDMI_PORT_ATTR_SUPPORTEDSPEED,
(uint8_t *)&val, &val,
FC_FDMI_PORT_ATTR_SUPPORTEDSPEED_LEN); FC_FDMI_PORT_ATTR_SUPPORTEDSPEED_LEN);
numattrs++; numattrs++;
...@@ -346,23 +355,22 @@ csio_ln_fdmi_rhba_cbfn(struct csio_hw *hw, struct csio_ioreq *fdmi_req) ...@@ -346,23 +355,22 @@ csio_ln_fdmi_rhba_cbfn(struct csio_hw *hw, struct csio_ioreq *fdmi_req)
else else
val = htonl(CSIO_HBA_PORTSPEED_UNKNOWN); val = htonl(CSIO_HBA_PORTSPEED_UNKNOWN);
csio_append_attrib(&pld, FC_FDMI_PORT_ATTR_CURRENTPORTSPEED, csio_append_attrib(&pld, FC_FDMI_PORT_ATTR_CURRENTPORTSPEED,
(uint8_t *)&val, &val, FC_FDMI_PORT_ATTR_CURRENTPORTSPEED_LEN);
FC_FDMI_PORT_ATTR_CURRENTPORTSPEED_LEN);
numattrs++; numattrs++;
mfs = ln->ln_sparm.csp.sp_bb_data; mfs = ln->ln_sparm.csp.sp_bb_data;
csio_append_attrib(&pld, FC_FDMI_PORT_ATTR_MAXFRAMESIZE, csio_append_attrib(&pld, FC_FDMI_PORT_ATTR_MAXFRAMESIZE,
(uint8_t *)&mfs, FC_FDMI_PORT_ATTR_MAXFRAMESIZE_LEN); &mfs, sizeof(mfs));
numattrs++; numattrs++;
strcpy(buf, "csiostor"); strcpy(buf, "csiostor");
csio_append_attrib(&pld, FC_FDMI_PORT_ATTR_OSDEVICENAME, buf, csio_append_attrib(&pld, FC_FDMI_PORT_ATTR_OSDEVICENAME, buf,
(uint16_t)strlen(buf)); strlen(buf));
numattrs++; numattrs++;
if (!csio_hostname(buf, sizeof(buf))) { if (!csio_hostname(buf, sizeof(buf))) {
csio_append_attrib(&pld, FC_FDMI_PORT_ATTR_HOSTNAME, csio_append_attrib(&pld, FC_FDMI_PORT_ATTR_HOSTNAME,
buf, (uint16_t)strlen(buf)); buf, strlen(buf));
numattrs++; numattrs++;
} }
attrib_blk->numattrs = htonl(numattrs); attrib_blk->numattrs = htonl(numattrs);
...@@ -444,33 +452,32 @@ csio_ln_fdmi_dprt_cbfn(struct csio_hw *hw, struct csio_ioreq *fdmi_req) ...@@ -444,33 +452,32 @@ csio_ln_fdmi_dprt_cbfn(struct csio_hw *hw, struct csio_ioreq *fdmi_req)
strcpy(buf, "Chelsio Communications"); strcpy(buf, "Chelsio Communications");
csio_append_attrib(&pld, FC_FDMI_HBA_ATTR_MANUFACTURER, buf, csio_append_attrib(&pld, FC_FDMI_HBA_ATTR_MANUFACTURER, buf,
(uint16_t)strlen(buf)); strlen(buf));
numattrs++; numattrs++;
csio_append_attrib(&pld, FC_FDMI_HBA_ATTR_SERIALNUMBER, 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++; numattrs++;
csio_append_attrib(&pld, FC_FDMI_HBA_ATTR_MODEL, hw->vpd.id, csio_append_attrib(&pld, FC_FDMI_HBA_ATTR_MODEL, hw->vpd.id,
(uint16_t)sizeof(hw->vpd.id)); sizeof(hw->vpd.id));
numattrs++; numattrs++;
csio_append_attrib(&pld, FC_FDMI_HBA_ATTR_MODELDESCRIPTION, 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++; numattrs++;
csio_append_attrib(&pld, FC_FDMI_HBA_ATTR_HARDWAREVERSION, 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++; numattrs++;
csio_append_attrib(&pld, FC_FDMI_HBA_ATTR_FIRMWAREVERSION, 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++; numattrs++;
if (!csio_osname(buf, sizeof(buf))) { if (!csio_osname(buf, sizeof(buf))) {
csio_append_attrib(&pld, FC_FDMI_HBA_ATTR_OSNAMEVERSION, csio_append_attrib(&pld, FC_FDMI_HBA_ATTR_OSNAMEVERSION,
buf, (uint16_t)strlen(buf)); buf, strlen(buf));
numattrs++; numattrs++;
} }
csio_append_attrib(&pld, FC_FDMI_HBA_ATTR_MAXCTPAYLOAD, csio_append_attrib(&pld, FC_FDMI_HBA_ATTR_MAXCTPAYLOAD,
(uint8_t *)&maxpayload, &maxpayload, FC_FDMI_HBA_ATTR_MAXCTPAYLOAD_LEN);
FC_FDMI_HBA_ATTR_MAXCTPAYLOAD_LEN);
len = (uint32_t)(pld - (uint8_t *)cmd); len = (uint32_t)(pld - (uint8_t *)cmd);
numattrs++; numattrs++;
attrib_blk->numattrs = htonl(numattrs); attrib_blk->numattrs = htonl(numattrs);
...@@ -1794,6 +1801,8 @@ csio_ln_mgmt_submit_req(struct csio_ioreq *io_req, ...@@ -1794,6 +1801,8 @@ csio_ln_mgmt_submit_req(struct csio_ioreq *io_req,
struct csio_mgmtm *mgmtm = csio_hw_to_mgmtm(hw); struct csio_mgmtm *mgmtm = csio_hw_to_mgmtm(hw);
int rv; int rv;
BUG_ON(pld_len > pld->len);
io_req->io_cbfn = io_cbfn; /* Upper layer callback handler */ io_req->io_cbfn = io_cbfn; /* Upper layer callback handler */
io_req->fw_handle = (uintptr_t) (io_req); io_req->fw_handle = (uintptr_t) (io_req);
io_req->eq_idx = mgmtm->eq_idx; io_req->eq_idx = mgmtm->eq_idx;
......
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