Skip to content

Commit 7e87010

Browse files
Pull up following revision(s) (requested by tsutsui in ticket #34):
usr.bin/elf2ecoff/elf2ecoff.c: revision 1.37 usr.bin/elf2ecoff/elf2ecoff.c: revision 1.38 elf2ecoff: fix PR port-pmax/59234: "buffer overflow detected" problem. Explicitly calculate a size of the target ECOFF string table before copying symbol strings, as suggested by mlelstv@. Tested "build.sh -U -m pmax release" on ubuntu 24.04.2: --- % ./nbmips-elf2ecoff netboot.elf netboot combining PH 0 type 1 flags 0x7 with data, ndata = 73568, nbss =1392 skipping PH 1 type 0x70000000 flags 0x4 skipping PH 2 type 0x70000003 flags 0x4 wrote 20 byte file header. wrote 56 byte a.out header. wrote 240 bytes of section headers. wrote 4 byte pad. writing 73568 bytes... writing syms at offset 0x12100 2605 (0xa2d) bytes ELF string table 2705 (0xa91) bytes required for ECOFF string table 2705 (0xa91) bytes used for ECOFF string table writing symhdr for 258 entries at offset 0x120a0 ECOFF symhdr: symhdr 60, strsize a91, symsize 1020 --- s/estimate/compute/
1 parent 5a5a984 commit 7e87010

1 file changed

Lines changed: 58 additions & 18 deletions

File tree

usr.bin/elf2ecoff/elf2ecoff.c

Lines changed: 58 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $NetBSD: elf2ecoff.c,v 1.36 2025/03/30 14:13:59 tsutsui Exp $ */
1+
/* $NetBSD: elf2ecoff.c,v 1.36.2.1 2025/09/23 16:01:28 martin Exp $ */
22

33
/*
44
* Copyright (c) 1997 Jonathan Stone
@@ -83,6 +83,8 @@ static char *saveRead(int, off_t, off_t, const char *);
8383
static void safewrite(int, const void *, off_t, const char *);
8484
static void copy(int, int, off_t, off_t);
8585
static void combine(struct sect *, struct sect *, int);
86+
static size_t compute_stringsize(const Elf32_Sym *elf_syms, int nsymbols,
87+
const char *elf_stringbase);
8688
static void translate_syms(struct elf_syms *, struct ecoff_syms *);
8789
static void elf_symbol_table_to_ecoff(int, int, struct ecoff32_exechdr *,
8890
off_t, off_t, off_t, off_t);
@@ -715,7 +717,32 @@ elf_symbol_table_to_ecoff(int out, int in, struct ecoff32_exechdr *ep,
715717
pad16(out, padding, "symbols: padding");
716718
}
717719

720+
/*
721+
* Compute the total ECOFF string table size.
722+
* ELF .strtab can share or overlap substrings,
723+
* but ECOFF table needs to have duplicated names.
724+
*/
725+
static size_t
726+
compute_stringsize(const Elf32_Sym *elf_syms, int nsyms,
727+
const char *stringbase)
728+
{
729+
size_t stringsize = 0;
730+
int i;
731+
732+
for (i = 0; i < nsyms; i++) {
733+
const Elf32_Sym *esym = &elf_syms[i];
734+
const char *name;
718735

736+
if (ELF32_ST_BIND(esym->st_info) == STB_LOCAL)
737+
continue;
738+
name = stringbase + esym->st_name;
739+
stringsize += strlen(name) + 1;
740+
}
741+
if (stringsize == 0)
742+
stringsize = 1; /* for NUL */
743+
744+
return stringsize;
745+
}
719746

720747
/*
721748
* In-memory translation of ELF symbols to ECOFF.
@@ -727,7 +754,7 @@ translate_syms(struct elf_syms *elfp, struct ecoff_syms *ecoffp)
727754
int i;
728755
char *oldstringbase;
729756
char *newstrings, *nsp;
730-
757+
size_t stringsize;
731758
int nsyms, idx;
732759

733760
nsyms = elfp->nsymbols;
@@ -739,43 +766,56 @@ translate_syms(struct elf_syms *elfp, struct ecoff_syms *ecoffp)
739766
ecoffp->nsymbols = 0;
740767
ecoffp->ecoff_syms = malloc(sizeof(struct ecoff_extsym) * nsyms);
741768

742-
/* we are going to be no bigger than the ELF symbol table. */
743-
ecoffp->stringsize = elfp->stringsize;
744-
ecoffp->stringtab = malloc(elfp->stringsize);
745-
746-
newstrings = (char *) ecoffp->stringtab;
747-
nsp = (char *) ecoffp->stringtab;
769+
/* ECOFF string table could be bigger than the ELF one. */
770+
stringsize = compute_stringsize(elfp->elf_syms, nsyms, oldstringbase);
771+
if (debug) {
772+
fprintf(stderr,
773+
"%zu (0x%zx) bytes ELF string table\n",
774+
(size_t)elfp->stringsize, (size_t)elfp->stringsize);
775+
fprintf(stderr,
776+
"%zu (0x%zx) bytes required for ECOFF string table\n",
777+
stringsize, stringsize);
778+
}
779+
newstrings = malloc(stringsize);
748780
if (newstrings == NULL)
749781
errx(1, "No memory for new string table");
750-
/* Copy and translate symbols... */
782+
/* Copy and translate symbols... */
783+
nsp = newstrings;
751784
idx = 0;
752785
for (i = 0; i < nsyms; i++) {
753-
int binding;
786+
const Elf32_Sym *esym = &elfp->elf_syms[i];
787+
const char *name;
788+
size_t namelen;
754789

755-
binding = ELF32_ST_BIND((elfp->elf_syms[i].st_info));
756-
757-
/* skip strange symbols */
758-
if (binding == 0) {
790+
if (ELF32_ST_BIND(esym->st_info) == STB_LOCAL)
759791
continue;
760-
}
792+
name = oldstringbase + esym->st_name;
793+
namelen = strlen(name) + 1;
794+
if (nsp + namelen > newstrings + stringsize)
795+
errx(1, "ECOFF string table overflow");
761796
/* Copy the symbol into the new table */
762-
strcpy(nsp, oldstringbase + elfp->elf_syms[i].st_name);
797+
strcpy(nsp, name);
763798
ecoffp->ecoff_syms[idx].es_strindex = nsp - newstrings;
764-
nsp += strlen(nsp) + 1;
799+
nsp += namelen;
765800

766801
/* translate symbol types to ECOFF XXX */
767802
ecoffp->ecoff_syms[idx].es_type = 1;
768803
ecoffp->ecoff_syms[idx].es_class = 5;
769804

770805
/* Symbol values in executables should be compatible. */
771-
ecoffp->ecoff_syms[idx].es_value = elfp->elf_syms[i].st_value;
806+
ecoffp->ecoff_syms[idx].es_value = esym->st_value;
772807
ecoffp->ecoff_syms[idx].es_symauxindex = 0xfffff;
773808

774809
idx++;
775810
}
776811

777812
ecoffp->nsymbols = idx;
813+
ecoffp->stringtab = newstrings;
778814
ecoffp->stringsize = nsp - newstrings;
815+
if (debug)
816+
fprintf(stderr,
817+
"%zu (0x%zx) bytes used for ECOFF string table\n",
818+
(size_t)ecoffp->stringsize, (size_t)ecoffp->stringsize);
779819
}
780820
/*
781821
* pad to a 16-byte boundary

0 commit comments

Comments
 (0)