diff --git a/components/espcoredump/src/core_dump_elf.c b/components/espcoredump/src/core_dump_elf.c index 1909ad593c..667940a32b 100644 --- a/components/espcoredump/src/core_dump_elf.c +++ b/components/espcoredump/src/core_dump_elf.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -200,15 +200,28 @@ static int elf_add_segment(core_dump_elf_t *self, return data_len; } -static int elf_write_note_header(core_dump_elf_t *self, - const char* name, uint32_t name_len, uint32_t data_sz, uint32_t type) +/* + * Example Note Segment + * +================================================================+ + * | Offset | +0 | +1 | +2 | +3 | Description | + * +----------------------------------------------------------------+ + * | 0 | 0x05 | 0x00 | 0x00 | 0x00 | namesz = 5 | + * | 4 | 0x06 | 0x00 | 0x00 | 0x00 | descsz = 6 | + * | 8 | 0x01 | 0x00 | 0x00 | 0x00 | type = 1 | + * | 12 | 'C' | 'O' | 'R' | 'E' | name ("CORE") | + * | 16 | 0x00 | pad | pad | pad | NULL + padding | + * | 20 | 0x1 | 0x2 | 0x3 | 0x4 | desc (6 bytes) | + * | 24 | 0x5 | 0x6 | pad | pad | desc + padding | + * +================================================================+ +*/ +static int elf_write_note_header(core_dump_elf_t *self, const char* name, uint32_t data_sz, uint32_t type) { // temporary aligned buffer for note name static char name_buffer[ELF_NOTE_NAME_MAX_SIZE] = { 0 }; elf_note note_hdr = { 0 }; - memcpy(name_buffer, name, name_len); - note_hdr.n_namesz = ALIGN_UP(name_len + 1, 4); + size_t name_len = strlcpy(name_buffer, name, sizeof(name_buffer)); + note_hdr.n_namesz = name_len + 1; /* name_buffer must be null terminated */ note_hdr.n_descsz = data_sz; note_hdr.n_type = type; // write note header @@ -216,7 +229,7 @@ static int elf_write_note_header(core_dump_elf_t *self, ELF_CHECK_ERR((err == ESP_OK), ELF_PROC_ERR_WRITE_FAIL, "Write ELF note header failure (%d)", err); // write note name - err = esp_core_dump_write_data(&self->write_data, name_buffer, note_hdr.n_namesz); + err = esp_core_dump_write_data(&self->write_data, name_buffer, ALIGN_UP(note_hdr.n_namesz, 4)); ELF_CHECK_ERR((err == ESP_OK), ELF_PROC_ERR_WRITE_FAIL, "Write ELF note name failure (%d)", err); @@ -230,18 +243,17 @@ static int elf_write_note(core_dump_elf_t *self, uint32_t data_sz) { esp_err_t err = ESP_FAIL; - uint32_t name_len = ALIGN_UP(strlen(name) + 1, 4); // get name length including terminator - uint32_t data_len = ALIGN_UP(data_sz, 4); + uint32_t name_len = strlen(name) + 1; // get name length including terminator ELF_CHECK_ERR((name_len <= ELF_NOTE_NAME_MAX_SIZE), 0, "Segment note name is too long %d.", name_len); - uint32_t note_size = ALIGN_UP(name_len + data_len + sizeof(elf_note), 4); + uint32_t note_size = ALIGN_UP(name_len, 4) + ALIGN_UP(data_sz, 4) + sizeof(elf_note); // write segment data during second pass if (self->elf_stage == ELF_STAGE_PLACE_DATA) { ELF_CHECK_ERR(data, ELF_PROC_ERR_OTHER, "Invalid data pointer %x.", (uint32_t)data); - err = elf_write_note_header(self, name, strlen(name), data_sz, type); + err = elf_write_note_header(self, name, data_sz, type); if (err != ESP_OK) { return err; } @@ -250,8 +262,8 @@ static int elf_write_note(core_dump_elf_t *self, // which might not be aligned by default. Therefore, we need to verify alignment and add padding if necessary. err = esp_core_dump_write_data(&self->write_data, data, data_sz); if (err == ESP_OK) { - int pad_size = data_len - data_sz; - if (pad_size != 0) { + const int pad_size = ALIGN_UP(data_sz, 4) - data_sz; + if (pad_size > 0) { uint8_t pad_bytes[3] = {0}; ESP_COREDUMP_LOG_PROCESS("Core dump note data needs %d bytes padding", pad_size); err = esp_core_dump_write_data(&self->write_data, pad_bytes, pad_size); @@ -543,7 +555,7 @@ static void elf_write_core_dump_note_cb(void *opaque, const char *data) static int elf_add_wdt_panic_details(core_dump_elf_t *self) { - uint32_t name_len = sizeof(ELF_ESP_CORE_DUMP_PANIC_DETAILS_NOTE_NAME) - 1; + uint32_t name_len = sizeof(ELF_ESP_CORE_DUMP_PANIC_DETAILS_NOTE_NAME); /* len includes the null terminator */ core_dump_elf_opaque_t param = { .self = self, .total_size = 0, @@ -557,27 +569,25 @@ static int elf_add_wdt_panic_details(core_dump_elf_t *self) self->note_data_size = param.total_size; } else if (self->elf_stage == ELF_STAGE_PLACE_DATA) { esp_err_t err = elf_write_note_header(self, - ELF_ESP_CORE_DUMP_PANIC_DETAILS_NOTE_NAME, - name_len, - self->note_data_size, - ELF_ESP_CORE_DUMP_PANIC_DETAILS_TYPE); + ELF_ESP_CORE_DUMP_PANIC_DETAILS_NOTE_NAME, + self->note_data_size, + ELF_ESP_CORE_DUMP_PANIC_DETAILS_TYPE); if (err != ESP_OK) { return err; } esp_task_wdt_print_triggered_tasks(elf_write_core_dump_note_cb, ¶m, NULL); ELF_CHECK_ERR((param.total_size > 0), ELF_PROC_ERR_WRITE_FAIL, "Write ELF note data failure (%d)", err); - const uint32_t mod = self->note_data_size & 3; - if (mod != 0) { + const int pad_size = ALIGN_UP(self->note_data_size, 4) - self->note_data_size; + if (pad_size > 0) { uint8_t pad_bytes[3] = {0}; - uint32_t pad_size = 4 - mod; ESP_COREDUMP_LOG_PROCESS("Core dump note needs %d bytes padding", pad_size); err = esp_core_dump_write_data(&self->write_data, pad_bytes, pad_size); ELF_CHECK_ERR((err == ESP_OK), ELF_PROC_ERR_WRITE_FAIL, "Write ELF note padding failure (%d)", err); } } - return ALIGN_UP(ALIGN_UP(name_len, 4) + ALIGN_UP(self->note_data_size, 4) + sizeof(elf_note), 4); + return ALIGN_UP(name_len, 4) + ALIGN_UP(self->note_data_size, 4) + sizeof(elf_note); } #endif //CONFIG_ESP_TASK_WDT_EN @@ -839,17 +849,17 @@ static void esp_core_dump_parse_note_section(uint8_t *coredump_data, elf_note_co size_t consumed_note_sz = 0; while (consumed_note_sz < ph->p_memsz) { const elf_note *note = (const elf_note *)(coredump_data + ph->p_offset + consumed_note_sz); - for (size_t idx = 0; idx < size; ++idx) { - if (target_notes[idx].n_type == note->n_type) { - char *nm = (char *)¬e[1]; - target_notes[idx].n_ptr = nm + note->n_namesz; + for (size_t idx = 0; idx < size; ++idx) { + if (target_notes[idx].n_type == note->n_type) { + char *nm = (char *)¬e[1]; + target_notes[idx].n_ptr = nm + ALIGN_UP(note->n_namesz, 4); target_notes[idx].n_descsz = note->n_descsz; ESP_COREDUMP_LOGD("%d bytes target note (%X) found in the note section", - note->n_descsz, note->n_type); - break; - } - } - consumed_note_sz += ALIGN_UP(note->n_namesz + note->n_descsz + sizeof(elf_note), 4); + note->n_descsz, note->n_type); + break; + } + } + consumed_note_sz += ALIGN_UP(note->n_namesz, 4) + ALIGN_UP(note->n_descsz, 4) + sizeof(elf_note); } } }