diff --git a/sys/kern/link_elf_obj.c b/sys/kern/link_elf_obj.c --- a/sys/kern/link_elf_obj.c +++ b/sys/kern/link_elf_obj.c @@ -938,14 +938,16 @@ } static Elf_Addr -findbase(elf_file_t ef, int sec) +findbase(elf_file_t ef, int sec, Elf_Size *secsize) { int i; Elf_Addr base = 0; + *secsize = 0; for (i = 0; i < ef->nprogtab; i++) { if (sec == ef->progtab[i].sec) { base = (Elf_Addr)ef->progtab[i].addr; + *secsize = ef->progtab[i].size; break; } } @@ -957,6 +959,7 @@ { elf_file_t ef = lf->priv; const Elf_Rel *rellim; + Elf_Size secsize; const Elf_Rel *rel; const Elf_Rela *relalim; const Elf_Rela *rela; @@ -972,13 +975,15 @@ if (rel == NULL) panic("lost a reltab!"); rellim = rel + ef->reltab[i].nrel; - base = findbase(ef, ef->reltab[i].sec); + base = findbase(ef, ef->reltab[i].sec, &secsize); if (base == 0) panic("lost base for reltab"); for ( ; rel < rellim; rel++) { symidx = ELF_R_SYM(rel->r_info); if (symidx >= ef->ddbsymcnt) continue; + if (rel->r_offset >= secsize) + continue; sym = ef->ddbsymtab + symidx; /* Local relocs are already done */ if (ELF_ST_BIND(sym->st_info) == STB_LOCAL) @@ -999,13 +1004,15 @@ if (rela == NULL) panic("lost a relatab!"); relalim = rela + ef->relatab[i].nrela; - base = findbase(ef, ef->relatab[i].sec); + base = findbase(ef, ef->relatab[i].sec, &secsize); if (base == 0) panic("lost base for relatab"); for ( ; rela < relalim; rela++) { symidx = ELF_R_SYM(rela->r_info); if (symidx >= ef->ddbsymcnt) continue; + if (rela->r_offset >= secsize) + continue; sym = ef->ddbsymtab + symidx; /* Local relocs are already done */ if (ELF_ST_BIND(sym->st_info) == STB_LOCAL) @@ -1231,6 +1238,7 @@ Elf_Addr base; int i; Elf_Size symidx; + Elf_Size secsize; link_elf_obj_fix_link_set(ef); @@ -1240,13 +1248,15 @@ if (rel == NULL) panic("lost a reltab!"); rellim = rel + ef->reltab[i].nrel; - base = findbase(ef, ef->reltab[i].sec); + base = findbase(ef, ef->reltab[i].sec, &secsize); if (base == 0) panic("lost base for reltab"); for ( ; rel < rellim; rel++) { symidx = ELF_R_SYM(rel->r_info); if (symidx >= ef->ddbsymcnt) continue; + if (rel->r_offset >= secsize) + continue; sym = ef->ddbsymtab + symidx; /* Only do local relocs */ if (ELF_ST_BIND(sym->st_info) != STB_LOCAL) @@ -1262,13 +1272,15 @@ if (rela == NULL) panic("lost a relatab!"); relalim = rela + ef->relatab[i].nrela; - base = findbase(ef, ef->relatab[i].sec); + base = findbase(ef, ef->relatab[i].sec, &secsize); if (base == 0) panic("lost base for relatab"); for ( ; rela < relalim; rela++) { symidx = ELF_R_SYM(rela->r_info); if (symidx >= ef->ddbsymcnt) continue; + if (rela->r_offset >= secsize) + continue; sym = ef->ddbsymtab + symidx; /* Only do local relocs */ if (ELF_ST_BIND(sym->st_info) != STB_LOCAL)