Skip to content

Commit

Permalink
Merge tag 'objtool_urgent_for_v5.15_rc6' of git://git.kernel.org/pub/…
Browse files Browse the repository at this point in the history
…scm/linux/kernel/git/tip/tip

Pull objtool fixes from Borislav Petkov:

 - Update section headers before the respective relocations to not
   trigger a safety check in elftoolchain's implementation of libelf

 - Do not add garbage data to the .rela.orc_unwind_ip section

* tag 'objtool_urgent_for_v5.15_rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  objtool: Update section header before relocations
  objtool: Check for gelf_update_rel[a] failures
  • Loading branch information
Linus Torvalds committed Oct 18, 2021
2 parents f644750 + 86e1e05 commit 6890aca
Showing 1 changed file with 25 additions and 31 deletions.
56 changes: 25 additions & 31 deletions tools/objtool/elf.c
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,7 @@ int elf_add_reloc(struct elf *elf, struct section *sec, unsigned long offset,
list_add_tail(&reloc->list, &sec->reloc->reloc_list);
elf_hash_add(reloc, &reloc->hash, reloc_hash(reloc));

sec->reloc->sh.sh_size += sec->reloc->sh.sh_entsize;
sec->reloc->changed = true;

return 0;
Expand Down Expand Up @@ -977,63 +978,63 @@ static struct section *elf_create_reloc_section(struct elf *elf,
}
}

static int elf_rebuild_rel_reloc_section(struct section *sec, int nr)
static int elf_rebuild_rel_reloc_section(struct section *sec)
{
struct reloc *reloc;
int idx = 0, size;
int idx = 0;
void *buf;

/* Allocate a buffer for relocations */
size = nr * sizeof(GElf_Rel);
buf = malloc(size);
buf = malloc(sec->sh.sh_size);
if (!buf) {
perror("malloc");
return -1;
}

sec->data->d_buf = buf;
sec->data->d_size = size;
sec->data->d_size = sec->sh.sh_size;
sec->data->d_type = ELF_T_REL;

sec->sh.sh_size = size;

idx = 0;
list_for_each_entry(reloc, &sec->reloc_list, list) {
reloc->rel.r_offset = reloc->offset;
reloc->rel.r_info = GELF_R_INFO(reloc->sym->idx, reloc->type);
gelf_update_rel(sec->data, idx, &reloc->rel);
if (!gelf_update_rel(sec->data, idx, &reloc->rel)) {
WARN_ELF("gelf_update_rel");
return -1;
}
idx++;
}

return 0;
}

static int elf_rebuild_rela_reloc_section(struct section *sec, int nr)
static int elf_rebuild_rela_reloc_section(struct section *sec)
{
struct reloc *reloc;
int idx = 0, size;
int idx = 0;
void *buf;

/* Allocate a buffer for relocations with addends */
size = nr * sizeof(GElf_Rela);
buf = malloc(size);
buf = malloc(sec->sh.sh_size);
if (!buf) {
perror("malloc");
return -1;
}

sec->data->d_buf = buf;
sec->data->d_size = size;
sec->data->d_size = sec->sh.sh_size;
sec->data->d_type = ELF_T_RELA;

sec->sh.sh_size = size;

idx = 0;
list_for_each_entry(reloc, &sec->reloc_list, list) {
reloc->rela.r_offset = reloc->offset;
reloc->rela.r_addend = reloc->addend;
reloc->rela.r_info = GELF_R_INFO(reloc->sym->idx, reloc->type);
gelf_update_rela(sec->data, idx, &reloc->rela);
if (!gelf_update_rela(sec->data, idx, &reloc->rela)) {
WARN_ELF("gelf_update_rela");
return -1;
}
idx++;
}

Expand All @@ -1042,16 +1043,9 @@ static int elf_rebuild_rela_reloc_section(struct section *sec, int nr)

static int elf_rebuild_reloc_section(struct elf *elf, struct section *sec)
{
struct reloc *reloc;
int nr;

nr = 0;
list_for_each_entry(reloc, &sec->reloc_list, list)
nr++;

switch (sec->sh.sh_type) {
case SHT_REL: return elf_rebuild_rel_reloc_section(sec, nr);
case SHT_RELA: return elf_rebuild_rela_reloc_section(sec, nr);
case SHT_REL: return elf_rebuild_rel_reloc_section(sec);
case SHT_RELA: return elf_rebuild_rela_reloc_section(sec);
default: return -1;
}
}
Expand Down Expand Up @@ -1111,12 +1105,6 @@ int elf_write(struct elf *elf)
/* Update changed relocation sections and section headers: */
list_for_each_entry(sec, &elf->sections, list) {
if (sec->changed) {
if (sec->base &&
elf_rebuild_reloc_section(elf, sec)) {
WARN("elf_rebuild_reloc_section");
return -1;
}

s = elf_getscn(elf->elf, sec->idx);
if (!s) {
WARN_ELF("elf_getscn");
Expand All @@ -1127,6 +1115,12 @@ int elf_write(struct elf *elf)
return -1;
}

if (sec->base &&
elf_rebuild_reloc_section(elf, sec)) {
WARN("elf_rebuild_reloc_section");
return -1;
}

sec->changed = false;
elf->changed = true;
}
Expand Down

0 comments on commit 6890aca

Please sign in to comment.