diff --git a/libexec/rtld-elf/map_object.c b/libexec/rtld-elf/map_object.c index 8f579d660e9d..adc032b095b6 100644 --- a/libexec/rtld-elf/map_object.c +++ b/libexec/rtld-elf/map_object.c @@ -550,12 +550,8 @@ obj_free(Obj_Entry *obj) free(obj->path); #ifdef __CHERI_PURE_CAPABILITY__ #ifdef CHERI_LIB_C18N - if (obj->comparts) { - for (unsigned long i = 0; i < obj->ncomparts; i++) { - free(obj->comparts[i].compart_name); - } + if (obj->comparts) free(obj->comparts); - } #endif if (obj->pcc_caps) free(obj->pcc_caps); diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c index 692041b0ef9d..5f4df1bb1191 100644 --- a/libexec/rtld-elf/rtld.c +++ b/libexec/rtld-elf/rtld.c @@ -6324,6 +6324,7 @@ c18n_setup_compartments(Obj_Entry *obj, const char *name, int flags) { Compart_Entry *compart; const Elf_Phdr *ph; + char *compart_name; size_t len; assert(obj->default_compart_id == 0); @@ -6354,11 +6355,12 @@ c18n_setup_compartments(Obj_Entry *obj, const char *name, int flags) compart->end = compart->start + ph->p_memsz; len = strlen(name) + 1 + strlen(compart->name) + 1; - compart->compart_name = malloc(len); - rtld_snprintf(compart->compart_name, len, "%s:%s", - name, compart->name); + compart_name = malloc(len); + rtld_snprintf(compart_name, len, "%s:%s", name, + compart->name); compart->compart_id = - compart_id_allocate(compart->compart_name, flags); + compart_id_allocate(compart_name, flags); + free(compart_name); compart++; break; } diff --git a/libexec/rtld-elf/rtld.h b/libexec/rtld-elf/rtld.h index 051c3de45904..631bdba887bf 100644 --- a/libexec/rtld-elf/rtld.h +++ b/libexec/rtld-elf/rtld.h @@ -205,7 +205,6 @@ typedef struct Struct_Compart_Entry { const char *name; Elf_Addr start; Elf_Addr end; - char *compart_name; uint16_t compart_id; } Compart_Entry; #endif diff --git a/libexec/rtld-elf/rtld_c18n.c b/libexec/rtld-elf/rtld_c18n.c index 41884deb0a3b..ae3bdcb96bde 100644 --- a/libexec/rtld-elf/rtld_c18n.c +++ b/libexec/rtld-elf/rtld_c18n.c @@ -190,6 +190,15 @@ c18n_free(void *buf) INC_NUM_BYTES(-old); } +static char * +c18n_strdup(const char *s) +{ + char *buf = strdup(s); + + INC_NUM_BYTES(cheri_getlen(buf)); + return (buf); +} + /* * Policies */ @@ -320,10 +329,13 @@ add_comparts_data(const char *name) { compart_id_t i; struct compart *com; + char *c_name; rtld_require(comparts.size <= COMPART_ID_MAX, "c18n: Compartment ID overflow for %s", name); + c_name = c18n_strdup(name); + if (comparts.size == comparts.capacity) expand_comparts_data(comparts.capacity * 2); @@ -335,10 +347,10 @@ add_comparts_data(const char *name) com = &comparts.data[i]; *com = (struct compart) { .info = (struct rtld_c18n_compart) { - .rcc_name = name, + .rcc_name = c_name, .rcc_id = i }, - .name = name + .name = c_name }; c18n_info->comparts_size = r_debug.r_comparts_size = comparts.size; @@ -485,7 +497,7 @@ parse_policy(const char *pol, size_t size) if (eat(&cur, "compartment ")) { if (eat_token(&cur, '\n', buf, sizeof(buf))) - com = add_comparts_data(strdup(buf)); + com = add_comparts_data(buf); else policy_error(&cur);