diff options
author | Jan Matyas <matyas@codasip.com> | 2021-04-23 10:47:17 +0200 |
---|---|---|
committer | Antonio Borneo <borneo.antonio@gmail.com> | 2021-06-13 19:58:28 +0100 |
commit | 64c2e03b23d9cadc1b919d38e902a079d015ddc6 (patch) | |
tree | 789350b475b723de7ff22c52cc1b1fefa2f96c2a /src/flash/nor/cfi.c | |
parent | f2958fc04bd879393fa743860478834e234f05d0 (diff) | |
download | riscv-openocd-64c2e03b23d9cadc1b919d38e902a079d015ddc6.zip riscv-openocd-64c2e03b23d9cadc1b919d38e902a079d015ddc6.tar.gz riscv-openocd-64c2e03b23d9cadc1b919d38e902a079d015ddc6.tar.bz2 |
flash/nor: improved API of flash_driver.info & fixed buffer overruns
1) The API of "info" callback in "struct flash_driver" has been
improved. Fixed buffers for strings
2) Removed the calls to snprintf() from the flash_driver.info
implementations. Many of them were used in an unsafe manner
(buffer overruns were possible).
Change-Id: I42ab8a8018d01f9af43c5ba49f650c3cb5d31dcb
Signed-off-by: Jan Matyas <matyas@codasip.com>
Reviewed-on: http://openocd.zylin.com/6182
Tested-by: jenkins
Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com>
Reviewed-by: Tomas Vanek <vanekt@fbl.cz>
Diffstat (limited to 'src/flash/nor/cfi.c')
-rw-r--r-- | src/flash/nor/cfi.c | 89 |
1 files changed, 25 insertions, 64 deletions
diff --git a/src/flash/nor/cfi.c b/src/flash/nor/cfi.c index c9eb38b..6663169 100644 --- a/src/flash/nor/cfi.c +++ b/src/flash/nor/cfi.c @@ -728,79 +728,57 @@ static int cfi_read_0002_pri_ext(struct flash_bank *bank) return cfi_read_spansion_pri_ext(bank); } -static int cfi_spansion_info(struct flash_bank *bank, char *buf, int buf_size) +static int cfi_spansion_info(struct flash_bank *bank, struct command_invocation *cmd) { - int printed; struct cfi_flash_bank *cfi_info = bank->driver_priv; struct cfi_spansion_pri_ext *pri_ext = cfi_info->pri_ext; - printed = snprintf(buf, buf_size, "\nSpansion primary algorithm extend information:\n"); - buf += printed; - buf_size -= printed; + command_print_sameline(cmd, "\nSpansion primary algorithm extend information:\n"); - printed = snprintf(buf, buf_size, "pri: '%c%c%c', version: %c.%c\n", pri_ext->pri[0], - pri_ext->pri[1], pri_ext->pri[2], + command_print_sameline(cmd, "pri: '%c%c%c', version: %c.%c\n", + pri_ext->pri[0], pri_ext->pri[1], pri_ext->pri[2], pri_ext->major_version, pri_ext->minor_version); - buf += printed; - buf_size -= printed; - printed = snprintf(buf, buf_size, "Silicon Rev.: 0x%x, Address Sensitive unlock: 0x%x\n", + command_print_sameline(cmd, "Silicon Rev.: 0x%x, Address Sensitive unlock: 0x%x\n", (pri_ext->SiliconRevision) >> 2, (pri_ext->SiliconRevision) & 0x03); - buf += printed; - buf_size -= printed; - printed = snprintf(buf, buf_size, "Erase Suspend: 0x%x, Sector Protect: 0x%x\n", + command_print_sameline(cmd, "Erase Suspend: 0x%x, Sector Protect: 0x%x\n", pri_ext->EraseSuspend, pri_ext->BlkProt); - buf += printed; - buf_size -= printed; - snprintf(buf, buf_size, "VppMin: %u.%x, VppMax: %u.%x\n", + command_print_sameline(cmd, "VppMin: %u.%x, VppMax: %u.%x\n", (pri_ext->VppMin & 0xf0) >> 4, pri_ext->VppMin & 0x0f, (pri_ext->VppMax & 0xf0) >> 4, pri_ext->VppMax & 0x0f); return ERROR_OK; } -static int cfi_intel_info(struct flash_bank *bank, char *buf, int buf_size) +static int cfi_intel_info(struct flash_bank *bank, struct command_invocation *cmd) { - int printed; struct cfi_flash_bank *cfi_info = bank->driver_priv; struct cfi_intel_pri_ext *pri_ext = cfi_info->pri_ext; - printed = snprintf(buf, buf_size, "\nintel primary algorithm extend information:\n"); - buf += printed; - buf_size -= printed; + command_print_sameline(cmd, "\nintel primary algorithm extend information:\n"); - printed = snprintf(buf, - buf_size, - "pri: '%c%c%c', version: %c.%c\n", + command_print_sameline(cmd, "pri: '%c%c%c', version: %c.%c\n", pri_ext->pri[0], pri_ext->pri[1], pri_ext->pri[2], pri_ext->major_version, pri_ext->minor_version); - buf += printed; - buf_size -= printed; - printed = snprintf(buf, - buf_size, - "feature_support: 0x%" PRIx32 ", " + command_print_sameline(cmd, "feature_support: 0x%" PRIx32 ", " "suspend_cmd_support: 0x%x, blk_status_reg_mask: 0x%x\n", pri_ext->feature_support, pri_ext->suspend_cmd_support, pri_ext->blk_status_reg_mask); - buf += printed; - buf_size -= printed; - printed = snprintf(buf, buf_size, "Vcc opt: %x.%x, Vpp opt: %u.%x\n", + command_print_sameline(cmd, "Vcc opt: %x.%x, Vpp opt: %u.%x\n", (pri_ext->vcc_optimal & 0xf0) >> 4, pri_ext->vcc_optimal & 0x0f, (pri_ext->vpp_optimal & 0xf0) >> 4, pri_ext->vpp_optimal & 0x0f); - buf += printed; - buf_size -= printed; - snprintf(buf, buf_size, "protection_fields: %i, prot_reg_addr: 0x%x, " + command_print_sameline(cmd, "protection_fields: %i, prot_reg_addr: 0x%x, " "factory pre-programmed: %i, user programmable: %i\n", pri_ext->num_protection_fields, pri_ext->prot_reg_addr, 1 << pri_ext->fact_prot_reg_size, 1 << pri_ext->user_prot_reg_size); @@ -2992,45 +2970,36 @@ int cfi_protect_check(struct flash_bank *bank) return ERROR_OK; } -int cfi_get_info(struct flash_bank *bank, char *buf, int buf_size) +int cfi_get_info(struct flash_bank *bank, struct command_invocation *cmd) { - int printed; struct cfi_flash_bank *cfi_info = bank->driver_priv; if (cfi_info->qry[0] == 0xff) { - snprintf(buf, buf_size, "\ncfi flash bank not probed yet\n"); + command_print_sameline(cmd, "\ncfi flash bank not probed yet\n"); return ERROR_OK; } if (!cfi_info->not_cfi) - printed = snprintf(buf, buf_size, "\nCFI flash: "); + command_print_sameline(cmd, "\nCFI flash: "); else - printed = snprintf(buf, buf_size, "\nnon-CFI flash: "); - buf += printed; - buf_size -= printed; + command_print_sameline(cmd, "\nnon-CFI flash: "); - printed = snprintf(buf, buf_size, "mfr: 0x%4.4x, id:0x%4.4x\n\n", + command_print_sameline(cmd, "mfr: 0x%4.4x, id:0x%4.4x\n", cfi_info->manufacturer, cfi_info->device_id); - buf += printed; - buf_size -= printed; - printed = snprintf(buf, buf_size, "qry: '%c%c%c', pri_id: 0x%4.4x, pri_addr: " + command_print_sameline(cmd, "qry: '%c%c%c', pri_id: 0x%4.4x, pri_addr: " "0x%4.4x, alt_id: 0x%4.4x, alt_addr: 0x%4.4x\n", cfi_info->qry[0], cfi_info->qry[1], cfi_info->qry[2], cfi_info->pri_id, cfi_info->pri_addr, cfi_info->alt_id, cfi_info->alt_addr); - buf += printed; - buf_size -= printed; - printed = snprintf(buf, buf_size, "Vcc min: %x.%x, Vcc max: %x.%x, " + command_print_sameline(cmd, "Vcc min: %x.%x, Vcc max: %x.%x, " "Vpp min: %u.%x, Vpp max: %u.%x\n", (cfi_info->vcc_min & 0xf0) >> 4, cfi_info->vcc_min & 0x0f, (cfi_info->vcc_max & 0xf0) >> 4, cfi_info->vcc_max & 0x0f, (cfi_info->vpp_min & 0xf0) >> 4, cfi_info->vpp_min & 0x0f, (cfi_info->vpp_max & 0xf0) >> 4, cfi_info->vpp_max & 0x0f); - buf += printed; - buf_size -= printed; - printed = snprintf(buf, buf_size, "typ. word write timeout: %u us, " + command_print_sameline(cmd, "typ. word write timeout: %u us, " "typ. buf write timeout: %u us, " "typ. block erase timeout: %u ms, " "typ. chip erase timeout: %u ms\n", @@ -3038,12 +3007,8 @@ int cfi_get_info(struct flash_bank *bank, char *buf, int buf_size) 1 << cfi_info->buf_write_timeout_typ, 1 << cfi_info->block_erase_timeout_typ, 1 << cfi_info->chip_erase_timeout_typ); - buf += printed; - buf_size -= printed; - printed = snprintf(buf, - buf_size, - "max. word write timeout: %u us, " + command_print_sameline(cmd, "max. word write timeout: %u us, " "max. buf write timeout: %u us, max. " "block erase timeout: %u ms, max. chip erase timeout: %u ms\n", (1 << @@ -3056,24 +3021,20 @@ int cfi_get_info(struct flash_bank *bank, char *buf, int buf_size) (1 << cfi_info->chip_erase_timeout_max) * (1 << cfi_info->chip_erase_timeout_typ)); - buf += printed; - buf_size -= printed; - printed = snprintf(buf, buf_size, "size: 0x%" PRIx32 ", interface desc: %i, " + command_print_sameline(cmd, "size: 0x%" PRIx32 ", interface desc: %i, " "max buffer write size: 0x%x\n", cfi_info->dev_size, cfi_info->interface_desc, 1 << cfi_info->max_buf_write_size); - buf += printed; - buf_size -= printed; switch (cfi_info->pri_id) { case 1: case 3: - cfi_intel_info(bank, buf, buf_size); + cfi_intel_info(bank, cmd); break; case 2: - cfi_spansion_info(bank, buf, buf_size); + cfi_spansion_info(bank, cmd); break; default: LOG_ERROR("cfi primary command set %i unsupported", cfi_info->pri_id); |