From 600bc9f0294f07a5572511c98041710d80d95769 Mon Sep 17 00:00:00 2001 From: Richard Meadows <962920+richardeoin@users.noreply.github.com> Date: Tue, 21 May 2019 19:39:37 +0100 Subject: [PATCH] Generate DEBUG warnings and return if `malloc`/`calloc` fail. This is will make debugging earier if this does happen, rather than dereferencing the null pointer (or passing it to memcpy, or worse). blackmagic PR #475 --- src/target/adiv5.c | 5 +++++ src/target/adiv5_jtagdp.c | 5 ++++- src/target/adiv5_swdp.c | 5 ++++- src/target/cortexa.c | 9 +++++++++ src/target/cortexm.c | 10 +++++++++- src/target/efm32.c | 5 +++++ src/target/kinetis.c | 13 ++++++++++++- src/target/lmi.c | 5 +++++ src/target/lpc_common.c | 9 ++++++++- src/target/msp432.c | 10 ++++++++-- src/target/nrf51.c | 9 +++++++++ src/target/nxpke04.c | 5 +++++ src/target/sam3x.c | 18 ++++++++++++++++-- src/target/sam4l.c | 5 +++++ src/target/samd.c | 5 +++++ src/target/stm32f1.c | 5 +++++ src/target/stm32f4.c | 8 +++++++- src/target/stm32h7.c | 9 ++++++++- src/target/stm32l0.c | 10 ++++++++++ src/target/stm32l4.c | 9 ++++++++- src/target/target.c | 33 +++++++++++++++++++++++++++++---- 21 files changed, 176 insertions(+), 16 deletions(-) diff --git a/src/target/adiv5.c b/src/target/adiv5.c index e5850c0..3379164 100644 --- a/src/target/adiv5.c +++ b/src/target/adiv5.c @@ -397,6 +397,11 @@ ADIv5_AP_t *adiv5_new_ap(ADIv5_DP_t *dp, uint8_t apsel) /* It's valid to so create a heap copy */ ap = malloc(sizeof(*ap)); + if (!ap) { /* malloc failed: heap exhaustion */ + DEBUG("malloc: failed in %s\n", __func__); + return NULL; + } + memcpy(ap, &tmpap, sizeof(*ap)); adiv5_dp_ref(dp); diff --git a/src/target/adiv5_jtagdp.c b/src/target/adiv5_jtagdp.c index c8b5847..e8d5879 100644 --- a/src/target/adiv5_jtagdp.c +++ b/src/target/adiv5_jtagdp.c @@ -49,6 +49,10 @@ static void adiv5_jtagdp_abort(ADIv5_DP_t *dp, uint32_t abort); void adiv5_jtag_dp_handler(jtag_dev_t *dev) { ADIv5_DP_t *dp = (void*)calloc(1, sizeof(*dp)); + if (!dp) { /* calloc failed: heap exhaustion */ + DEBUG("calloc: failed in %s\n", __func__); + return; + } dp->dev = dev; dp->idcode = dev->idcode; @@ -109,4 +113,3 @@ static void adiv5_jtagdp_abort(ADIv5_DP_t *dp, uint32_t abort) jtag_dev_write_ir(dp->dev, IR_ABORT); jtag_dev_shift_dr(dp->dev, NULL, (const uint8_t*)&request, 35); } - diff --git a/src/target/adiv5_swdp.c b/src/target/adiv5_swdp.c index 3cb8368..6ac1d7b 100644 --- a/src/target/adiv5_swdp.c +++ b/src/target/adiv5_swdp.c @@ -48,6 +48,10 @@ int adiv5_swdp_scan(void) target_list_free(); ADIv5_DP_t *dp = (void*)calloc(1, sizeof(*dp)); + if (!dp) { /* calloc failed: heap exhaustion */ + DEBUG("calloc: failed in %s\n", __func__); + return -1; + } if (swdptap_init()) return -1; @@ -179,4 +183,3 @@ static void adiv5_swdp_abort(ADIv5_DP_t *dp, uint32_t abort) { adiv5_dp_write(dp, ADIV5_DP_ABORT, abort); } - diff --git a/src/target/cortexa.c b/src/target/cortexa.c index e562673..2e7e723 100644 --- a/src/target/cortexa.c +++ b/src/target/cortexa.c @@ -323,8 +323,17 @@ bool cortexa_probe(ADIv5_AP_t *apb, uint32_t debug_base) target *t; t = target_new(); + if (!t) { + return false; + } + adiv5_ap_ref(apb); struct cortexa_priv *priv = calloc(1, sizeof(*priv)); + if (!priv) { /* calloc failed: heap exhaustion */ + DEBUG("calloc: failed in %s\n", __func__); + return false; + } + t->priv = priv; t->priv_free = free; priv->apb = apb; diff --git a/src/target/cortexm.c b/src/target/cortexm.c index 233eb17..b72ca7e 100644 --- a/src/target/cortexm.c +++ b/src/target/cortexm.c @@ -264,8 +264,17 @@ bool cortexm_probe(ADIv5_AP_t *ap, bool forced) target *t; t = target_new(); + if (!t) { + return false; + } + adiv5_ap_ref(ap); struct cortexm_priv *priv = calloc(1, sizeof(*priv)); + if (!priv) { /* calloc failed: heap exhaustion */ + DEBUG("calloc: failed in %s\n", __func__); + return false; + } + t->priv = priv; t->priv_free = cortexm_priv_free; priv->ap = ap; @@ -1035,4 +1044,3 @@ static int cortexm_hostio_request(target *t) return t->tc->interrupted; } - diff --git a/src/target/efm32.c b/src/target/efm32.c index 5a1ed09..fff186b 100644 --- a/src/target/efm32.c +++ b/src/target/efm32.c @@ -518,6 +518,11 @@ static void efm32_add_flash(target *t, target_addr addr, size_t length, size_t page_size) { struct target_flash *f = calloc(1, sizeof(*f)); + if (!f) { /* calloc failed: heap exhaustion */ + DEBUG("calloc: failed in %s\n", __func__); + return; + } + f->start = addr; f->length = length; f->blocksize = page_size; diff --git a/src/target/kinetis.c b/src/target/kinetis.c index 331e38f..b7ec7e4 100644 --- a/src/target/kinetis.c +++ b/src/target/kinetis.c @@ -105,7 +105,14 @@ static void kl_gen_add_flash(target *t, uint32_t addr, size_t length, size_t erasesize, size_t write_len) { struct kinetis_flash *kf = calloc(1, sizeof(*kf)); - struct target_flash *f = &kf->f; + struct target_flash *f; + + if (!kf) { /* calloc failed: heap exhaustion */ + DEBUG("calloc: failed in %s\n", __func__); + return; + } + + f = &kf->f; f->start = addr; f->length = length; f->blocksize = erasesize; @@ -367,6 +374,10 @@ void kinetis_mdm_probe(ADIv5_AP_t *ap) } target *t = target_new(); + if (!t) { + return; + } + adiv5_ap_ref(ap); t->priv = ap; t->priv_free = (void*)adiv5_ap_unref; diff --git a/src/target/lmi.c b/src/target/lmi.c index e0ecd68..97c39eb 100644 --- a/src/target/lmi.c +++ b/src/target/lmi.c @@ -60,6 +60,11 @@ static const uint16_t lmi_flash_write_stub[] = { static void lmi_add_flash(target *t, size_t length) { struct target_flash *f = calloc(1, sizeof(*f)); + if (!f) { /* calloc failed: heap exhaustion */ + DEBUG("calloc: failed in %s\n", __func__); + return; + } + f->start = 0; f->length = length; f->blocksize = 0x400; diff --git a/src/target/lpc_common.c b/src/target/lpc_common.c index bdae7e1..fa486ef 100644 --- a/src/target/lpc_common.c +++ b/src/target/lpc_common.c @@ -36,7 +36,14 @@ struct flash_param { struct lpc_flash *lpc_add_flash(target *t, target_addr addr, size_t length) { struct lpc_flash *lf = calloc(1, sizeof(*lf)); - struct target_flash *f = &lf->f; + struct target_flash *f; + + if (!lf) { /* calloc failed: heap exhaustion */ + DEBUG("calloc: failed in %s\n", __func__); + return NULL; + } + + f = &lf->f; f->start = addr; f->length = length; f->erase = lpc_flash_erase; diff --git a/src/target/msp432.c b/src/target/msp432.c index 4a9e7ec..96acfed 100644 --- a/src/target/msp432.c +++ b/src/target/msp432.c @@ -148,7 +148,13 @@ const struct command_s msp432_cmd_list[] = { static void msp432_add_flash(target *t, uint32_t addr, size_t length, target_addr prot_reg) { struct msp432_flash *mf = calloc(1, sizeof(*mf)); - struct target_flash *f = &mf->f; + struct target_flash *f; + if (!mf) { /* calloc failed: heap exhaustion */ + DEBUG("calloc: failed in %s\n", __func__); + return; + } + + f = &mf->f; f->start = addr; f->length = length; f->blocksize = SECTOR_SIZE; @@ -183,7 +189,7 @@ bool msp432_probe(target *t) /* If we got till this point, we are most probably looking at a real TLV */ /* Device Information structure. Now check for the correct device */ - switch (target_mem_read32(t, DEVID_ADDR)) { + switch (target_mem_read32(t, DEVID_ADDR)) { case DEVID_MSP432P401RIPZ: case DEVID_MSP432P401RIZXH: case DEVID_MSP432P401RIRGC: diff --git a/src/target/nrf51.c b/src/target/nrf51.c index ad1b554..48885bc 100644 --- a/src/target/nrf51.c +++ b/src/target/nrf51.c @@ -98,6 +98,11 @@ static void nrf51_add_flash(target *t, uint32_t addr, size_t length, size_t erasesize) { struct target_flash *f = calloc(1, sizeof(*f)); + if (!f) { /* calloc failed: heap exhaustion */ + DEBUG("calloc: failed in %s\n", __func__); + return; + } + f->start = addr; f->length = length; f->blocksize = erasesize; @@ -370,6 +375,10 @@ void nrf51_mdm_probe(ADIv5_AP_t *ap) } target *t = target_new(); + if (!t) { + return; + } + adiv5_ap_ref(ap); t->priv = ap; t->priv_free = (void*)adiv5_ap_unref; diff --git a/src/target/nxpke04.c b/src/target/nxpke04.c index 92b7079..01d154b 100644 --- a/src/target/nxpke04.c +++ b/src/target/nxpke04.c @@ -238,6 +238,11 @@ bool ke04_probe(target *t) /* Add flash, all KE04 have same write and erase size */ struct target_flash *f = calloc(1, sizeof(*f)); + if (!f) { /* calloc failed: heap exhaustion */ + DEBUG("calloc: failed in %s\n", __func__); + return false; + } + f->start = FLASH_BASE_ADDR; f->length = flashsize; f->blocksize = KE04_SECTOR_SIZE; diff --git a/src/target/sam3x.c b/src/target/sam3x.c index 48403d6..b7e5ea0 100644 --- a/src/target/sam3x.c +++ b/src/target/sam3x.c @@ -126,7 +126,14 @@ static void sam3_add_flash(target *t, uint32_t eefc_base, uint32_t addr, size_t length) { struct sam_flash *sf = calloc(1, sizeof(*sf)); - struct target_flash *f = &sf->f; + struct target_flash *f; + + if (!sf) { /* calloc failed: heap exhaustion */ + DEBUG("calloc: failed in %s\n", __func__); + return; + } + + f = &sf->f; f->start = addr; f->length = length; f->blocksize = SAM3_PAGE_SIZE; @@ -142,7 +149,14 @@ static void sam4_add_flash(target *t, uint32_t eefc_base, uint32_t addr, size_t length) { struct sam_flash *sf = calloc(1, sizeof(*sf)); - struct target_flash *f = &sf->f; + struct target_flash *f; + + if (!sf) { /* calloc failed: heap exhaustion */ + DEBUG("calloc: failed in %s\n", __func__); + return; + } + + f = &sf->f; f->start = addr; f->length = length; f->blocksize = SAM4_PAGE_SIZE * 8; diff --git a/src/target/sam4l.c b/src/target/sam4l.c index 1db37ba..8471764 100644 --- a/src/target/sam4l.c +++ b/src/target/sam4l.c @@ -169,6 +169,11 @@ static const size_t __nvp_size[16] = { static void sam4l_add_flash(target *t, uint32_t addr, size_t length) { struct target_flash *f = calloc(1, sizeof(struct target_flash)); + if (!f) { /* calloc failed: heap exhaustion */ + DEBUG("calloc: failed in %s\n", __func__); + return; + } + f->start = addr; f->length = length; f->blocksize = SAM4L_PAGE_SIZE; diff --git a/src/target/samd.c b/src/target/samd.c index e489d7e..588ca83 100644 --- a/src/target/samd.c +++ b/src/target/samd.c @@ -350,6 +350,11 @@ struct samd_descr samd_parse_device_id(uint32_t did) static void samd_add_flash(target *t, uint32_t addr, size_t length) { struct target_flash *f = calloc(1, sizeof(*f)); + if (!f) { /* calloc failed: heap exhaustion */ + DEBUG("calloc: failed in %s\n", __func__); + return; + } + f->start = addr; f->length = length; f->blocksize = SAMD_ROW_SIZE; diff --git a/src/target/stm32f1.c b/src/target/stm32f1.c index 1c7f4ff..0719dd0 100644 --- a/src/target/stm32f1.c +++ b/src/target/stm32f1.c @@ -98,6 +98,11 @@ static void stm32f1_add_flash(target *t, uint32_t addr, size_t length, size_t erasesize) { struct target_flash *f = calloc(1, sizeof(*f)); + if (!f) { /* calloc failed: heap exhaustion */ + DEBUG("calloc: failed in %s\n", __func__); + return; + } + f->start = addr; f->length = length; f->blocksize = erasesize; diff --git a/src/target/stm32f4.c b/src/target/stm32f4.c index 5a90990..338cb10 100644 --- a/src/target/stm32f4.c +++ b/src/target/stm32f4.c @@ -136,7 +136,13 @@ static void stm32f4_add_flash(target *t, { if (length == 0) return; struct stm32f4_flash *sf = calloc(1, sizeof(*sf)); - struct target_flash *f = &sf->f; + struct target_flash *f; + if (!sf) { /* calloc failed: heap exhaustion */ + DEBUG("calloc: failed in %s\n", __func__); + return; + } + + f = &sf->f; f->start = addr; f->length = length; f->blocksize = blocksize; diff --git a/src/target/stm32h7.c b/src/target/stm32h7.c index 01a8e6b..15d9614 100644 --- a/src/target/stm32h7.c +++ b/src/target/stm32h7.c @@ -162,7 +162,14 @@ static void stm32h7_add_flash(target *t, uint32_t addr, size_t length, size_t blocksize) { struct stm32h7_flash *sf = calloc(1, sizeof(*sf)); - struct target_flash *f = &sf->f; + struct target_flash *f; + + if (!sf) { /* calloc failed: heap exhaustion */ + DEBUG("calloc: failed in %s\n", __func__); + return; + } + + f = &sf->f; f->start = addr; f->length = length; f->blocksize = blocksize; diff --git a/src/target/stm32l0.c b/src/target/stm32l0.c index 14e42d6..388becf 100644 --- a/src/target/stm32l0.c +++ b/src/target/stm32l0.c @@ -233,6 +233,11 @@ static void stm32l_add_flash(target *t, uint32_t addr, size_t length, size_t erasesize) { struct target_flash *f = calloc(1, sizeof(*f)); + if (!f) { /* calloc failed: heap exhaustion */ + DEBUG("calloc: failed in %s\n", __func__); + return; + } + f->start = addr; f->length = length; f->blocksize = erasesize; @@ -245,6 +250,11 @@ static void stm32l_add_flash(target *t, static void stm32l_add_eeprom(target *t, uint32_t addr, size_t length) { struct target_flash *f = calloc(1, sizeof(*f)); + if (!f) { /* calloc failed: heap exhaustion */ + DEBUG("calloc: failed in %s\n", __func__); + return; + } + f->start = addr; f->length = length; f->blocksize = 4; diff --git a/src/target/stm32l4.c b/src/target/stm32l4.c index f4dc11c..99d6b6c 100644 --- a/src/target/stm32l4.c +++ b/src/target/stm32l4.c @@ -239,7 +239,14 @@ static void stm32l4_add_flash(target *t, uint32_t bank1_start) { struct stm32l4_flash *sf = calloc(1, sizeof(*sf)); - struct target_flash *f = &sf->f; + struct target_flash *f; + + if (!sf) { /* calloc failed: heap exhaustion */ + DEBUG("calloc: failed in %s\n", __func__); + return; + } + + f = &sf->f; f->start = addr; f->length = length; f->blocksize = blocksize; diff --git a/src/target/target.c b/src/target/target.c index 559792c..092673c 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -33,6 +33,11 @@ static int target_flash_done_buffered(struct target_flash *f); target *target_new(void) { target *t = (void*)calloc(1, sizeof(*t)); + if (!t) { /* calloc failed: heap exhaustion */ + DEBUG("calloc: failed in %s\n", __func__); + return NULL; + } + if (target_list) { target *c = target_list; while (c->next) @@ -98,12 +103,17 @@ void target_list_free(void) void target_add_commands(target *t, const struct command_s *cmds, const char *name) { - struct target_command_s *tc; + struct target_command_s *tc = malloc(sizeof(*tc)); + if (!tc) { /* malloc failed: heap exhaustion */ + DEBUG("malloc: failed in %s\n", __func__); + return; + } + if (t->commands) { for (tc = t->commands; tc->next; tc = tc->next); - tc = tc->next = malloc(sizeof(*tc)); + tc->next = tc; } else { - t->commands = tc = malloc(sizeof(*tc)); + t->commands = tc; } tc->specific_name = name; tc->cmds = cmds; @@ -137,6 +147,11 @@ target *target_attach(target *t, struct target_controller *tc) void target_add_ram(target *t, target_addr start, uint32_t len) { struct target_ram *ram = malloc(sizeof(*ram)); + if (!ram) { /* malloc failed: heap exhaustion */ + DEBUG("malloc: failed in %s\n", __func__); + return; + } + ram->start = start; ram->length = len; ram->next = t->ram; @@ -250,6 +265,10 @@ int target_flash_write_buffered(struct target_flash *f, if (f->buf == NULL) { /* Allocate flash sector buffer */ f->buf = malloc(f->buf_size); + if (!f->buf) { /* malloc failed: heap exhaustion */ + DEBUG("malloc: failed in %s\n", __func__); + return 1; + } f->buf_addr = -1; } while (len) { @@ -345,9 +364,15 @@ int target_breakwatch_set(target *t, ret = t->breakwatch_set(t, &bw); if (ret == 0) { - /* Success, make a heap copy and add to list */ + /* Success, make a heap copy */ struct breakwatch *bwm = malloc(sizeof bw); + if (!bwm) { /* malloc failed: heap exhaustion */ + DEBUG("malloc: failed in %s\n", __func__); + return 1; + } memcpy(bwm, &bw, sizeof(bw)); + + /* Add to list */ bwm->next = t->bw_list; t->bw_list = bwm; }