diff options
Diffstat (limited to 'drivers/net/sfc/base/siena_vpd.c')
-rw-r--r-- | drivers/net/sfc/base/siena_vpd.c | 25 |
1 files changed, 16 insertions, 9 deletions
diff --git a/drivers/net/sfc/base/siena_vpd.c b/drivers/net/sfc/base/siena_vpd.c index f188eb58..ebb12abf 100644 --- a/drivers/net/sfc/base/siena_vpd.c +++ b/drivers/net/sfc/base/siena_vpd.c @@ -36,21 +36,26 @@ siena_vpd_get_static( if ((rc = siena_nvram_partn_size(enp, partn, &size)) != 0) goto fail1; + if (size < SIENA_NVRAM_CHUNK) { + rc = EINVAL; + goto fail2; + } + EFSYS_KMEM_ALLOC(enp->en_esip, size, scfg); if (scfg == NULL) { rc = ENOMEM; - goto fail2; + goto fail3; } if ((rc = siena_nvram_partn_read(enp, partn, 0, (caddr_t)scfg, SIENA_NVRAM_CHUNK)) != 0) - goto fail3; + goto fail4; /* Verify the magic number */ if (EFX_DWORD_FIELD(scfg->magic, EFX_DWORD_0) != SIENA_MC_STATIC_CONFIG_MAGIC) { rc = EINVAL; - goto fail4; + goto fail5; } /* All future versions of the structure must be backwards compatible */ @@ -64,7 +69,7 @@ siena_vpd_get_static( if (hdr_length > size || vpd_offset > size || vpd_length > size || vpd_length + vpd_offset > size) { rc = EINVAL; - goto fail5; + goto fail6; } /* Read the remainder of scfg + static vpd */ @@ -73,7 +78,7 @@ siena_vpd_get_static( if ((rc = siena_nvram_partn_read(enp, partn, SIENA_NVRAM_CHUNK, (caddr_t)scfg + SIENA_NVRAM_CHUNK, region - SIENA_NVRAM_CHUNK)) != 0) - goto fail6; + goto fail7; } /* Verify checksum */ @@ -82,7 +87,7 @@ siena_vpd_get_static( cksum += ((uint8_t *)scfg)[pos]; if (cksum != 0) { rc = EINVAL; - goto fail7; + goto fail8; } if (vpd_length == 0) @@ -92,7 +97,7 @@ siena_vpd_get_static( EFSYS_KMEM_ALLOC(enp->en_esip, vpd_length, svpd); if (svpd == NULL) { rc = ENOMEM; - goto fail8; + goto fail9; } memcpy(svpd, (caddr_t)scfg + vpd_offset, vpd_length); } @@ -104,6 +109,8 @@ siena_vpd_get_static( return (0); +fail9: + EFSYS_PROBE(fail9); fail8: EFSYS_PROBE(fail8); fail7: @@ -114,11 +121,11 @@ fail5: EFSYS_PROBE(fail5); fail4: EFSYS_PROBE(fail4); -fail3: - EFSYS_PROBE(fail3); EFSYS_KMEM_FREE(enp->en_esip, size, scfg); +fail3: + EFSYS_PROBE(fail3); fail2: EFSYS_PROBE(fail2); fail1: |