[PATCHv3] bfa: avoid buffer overrun for 12-byte model name

From: Jim Meyering
Date: Sun Apr 29 2012 - 04:41:05 EST


we use strncpy to copy a model name of length up to 15 (16, if you count
the NUL), into a buffer of size 12 (BFA_FCS_PORT_SYMBNAME_MODEL_SZ).
However, strncpy does not always NUL-terminate, so whenever the original
model string has strlen >= 12, the following strncat reads beyond end
of the ->sym_name buffer as it attempts to find end of string.
Also, factor out the 12 uses of (char *)&port_cfg->sym_name.

bfa_fcs_fabric_psymb_init(struct bfa_fcs_fabric_s *fabric)
{
bfa_ioc_get_adapter_model(&fabric->fcs->bfa->ioc, model);
...
strncpy((char *)&port_cfg->sym_name, model,
BFA_FCS_PORT_SYMBNAME_MODEL_SZ);
strncat((char *)&port_cfg->sym_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR,
sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
...

bfa_ioc_get_adapter_model(struct bfa_ioc_s *ioc, char *model)
{
struct bfi_ioc_attr_s *ioc_attr;

WARN_ON(!model);
memset((void *)model, 0, BFA_ADAPTER_MODEL_NAME_LEN);

BFA_ADAPTER_MODEL_NAME_LEN = 16

Signed-off-by: Jim Meyering <meyering@xxxxxxxxxx>
---
drivers/scsi/bfa/bfa_fcs.c | 31 +++++++++++++------------------
1 file changed, 13 insertions(+), 18 deletions(-)

diff --git a/drivers/scsi/bfa/bfa_fcs.c b/drivers/scsi/bfa/bfa_fcs.c
index eaac57e..77d08f9 100644
--- a/drivers/scsi/bfa/bfa_fcs.c
+++ b/drivers/scsi/bfa/bfa_fcs.c
@@ -707,26 +707,26 @@ bfa_fcs_fabric_psymb_init(struct bfa_fcs_fabric_s *fabric)
struct bfa_lport_cfg_s *port_cfg = &fabric->bport.port_cfg;
char model[BFA_ADAPTER_MODEL_NAME_LEN] = {0};
struct bfa_fcs_driver_info_s *driver_info = &fabric->fcs->driver_info;
+ char *s_name = (char *)&port_cfg->sym_name;

bfa_ioc_get_adapter_model(&fabric->fcs->bfa->ioc, model);

/* Model name/number */
- strncpy((char *)&port_cfg->sym_name, model,
- BFA_FCS_PORT_SYMBNAME_MODEL_SZ);
- strncat((char *)&port_cfg->sym_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR,
+ strncpy(s_name, model, BFA_FCS_PORT_SYMBNAME_MODEL_SZ);
+ s_name[BFA_FCS_PORT_SYMBNAME_MODEL_SZ - 1] = 0;
+ strncat(s_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR,
sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));

/* Driver Version */
- strncat((char *)&port_cfg->sym_name, (char *)driver_info->version,
+ strncat(s_name, (char *)driver_info->version,
BFA_FCS_PORT_SYMBNAME_VERSION_SZ);
- strncat((char *)&port_cfg->sym_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR,
+ strncat(s_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR,
sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));

/* Host machine name */
- strncat((char *)&port_cfg->sym_name,
- (char *)driver_info->host_machine_name,
+ strncat(s_name, (char *)driver_info->host_machine_name,
BFA_FCS_PORT_SYMBNAME_MACHINENAME_SZ);
- strncat((char *)&port_cfg->sym_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR,
+ strncat(s_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR,
sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));

/*
@@ -735,23 +735,18 @@ bfa_fcs_fabric_psymb_init(struct bfa_fcs_fabric_s *fabric)
* OS name string and instead copy the entire OS info string (64 bytes).
*/
if (driver_info->host_os_patch[0] == '\0') {
- strncat((char *)&port_cfg->sym_name,
- (char *)driver_info->host_os_name,
+ strncat(s_name, (char *)driver_info->host_os_name,
BFA_FCS_OS_STR_LEN);
- strncat((char *)&port_cfg->sym_name,
- BFA_FCS_PORT_SYMBNAME_SEPARATOR,
+ strncat(s_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR,
sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
} else {
- strncat((char *)&port_cfg->sym_name,
- (char *)driver_info->host_os_name,
+ strncat(s_name, (char *)driver_info->host_os_name,
BFA_FCS_PORT_SYMBNAME_OSINFO_SZ);
- strncat((char *)&port_cfg->sym_name,
- BFA_FCS_PORT_SYMBNAME_SEPARATOR,
+ strncat(s_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR,
sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));

/* Append host OS Patch Info */
- strncat((char *)&port_cfg->sym_name,
- (char *)driver_info->host_os_patch,
+ strncat(s_name, (char *)driver_info->host_os_patch,
BFA_FCS_PORT_SYMBNAME_OSPATCH_SZ);
}

--
1.7.12
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/