Skip to content

Commit 6890aca

Browse files
committed
Merge tag 'objtool_urgent_for_v5.15_rc6' of git://git.kernel.org/pub/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
2 parents f644750 + 86e1e05 commit 6890aca

File tree

1 file changed

+25
-31
lines changed

1 file changed

+25
-31
lines changed

tools/objtool/elf.c

Lines changed: 25 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,7 @@ int elf_add_reloc(struct elf *elf, struct section *sec, unsigned long offset,
508508
list_add_tail(&reloc->list, &sec->reloc->reloc_list);
509509
elf_hash_add(reloc, &reloc->hash, reloc_hash(reloc));
510510

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

513514
return 0;
@@ -977,63 +978,63 @@ static struct section *elf_create_reloc_section(struct elf *elf,
977978
}
978979
}
979980

980-
static int elf_rebuild_rel_reloc_section(struct section *sec, int nr)
981+
static int elf_rebuild_rel_reloc_section(struct section *sec)
981982
{
982983
struct reloc *reloc;
983-
int idx = 0, size;
984+
int idx = 0;
984985
void *buf;
985986

986987
/* Allocate a buffer for relocations */
987-
size = nr * sizeof(GElf_Rel);
988-
buf = malloc(size);
988+
buf = malloc(sec->sh.sh_size);
989989
if (!buf) {
990990
perror("malloc");
991991
return -1;
992992
}
993993

994994
sec->data->d_buf = buf;
995-
sec->data->d_size = size;
995+
sec->data->d_size = sec->sh.sh_size;
996996
sec->data->d_type = ELF_T_REL;
997997

998-
sec->sh.sh_size = size;
999-
1000998
idx = 0;
1001999
list_for_each_entry(reloc, &sec->reloc_list, list) {
10021000
reloc->rel.r_offset = reloc->offset;
10031001
reloc->rel.r_info = GELF_R_INFO(reloc->sym->idx, reloc->type);
1004-
gelf_update_rel(sec->data, idx, &reloc->rel);
1002+
if (!gelf_update_rel(sec->data, idx, &reloc->rel)) {
1003+
WARN_ELF("gelf_update_rel");
1004+
return -1;
1005+
}
10051006
idx++;
10061007
}
10071008

10081009
return 0;
10091010
}
10101011

1011-
static int elf_rebuild_rela_reloc_section(struct section *sec, int nr)
1012+
static int elf_rebuild_rela_reloc_section(struct section *sec)
10121013
{
10131014
struct reloc *reloc;
1014-
int idx = 0, size;
1015+
int idx = 0;
10151016
void *buf;
10161017

10171018
/* Allocate a buffer for relocations with addends */
1018-
size = nr * sizeof(GElf_Rela);
1019-
buf = malloc(size);
1019+
buf = malloc(sec->sh.sh_size);
10201020
if (!buf) {
10211021
perror("malloc");
10221022
return -1;
10231023
}
10241024

10251025
sec->data->d_buf = buf;
1026-
sec->data->d_size = size;
1026+
sec->data->d_size = sec->sh.sh_size;
10271027
sec->data->d_type = ELF_T_RELA;
10281028

1029-
sec->sh.sh_size = size;
1030-
10311029
idx = 0;
10321030
list_for_each_entry(reloc, &sec->reloc_list, list) {
10331031
reloc->rela.r_offset = reloc->offset;
10341032
reloc->rela.r_addend = reloc->addend;
10351033
reloc->rela.r_info = GELF_R_INFO(reloc->sym->idx, reloc->type);
1036-
gelf_update_rela(sec->data, idx, &reloc->rela);
1034+
if (!gelf_update_rela(sec->data, idx, &reloc->rela)) {
1035+
WARN_ELF("gelf_update_rela");
1036+
return -1;
1037+
}
10371038
idx++;
10381039
}
10391040

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

10431044
static int elf_rebuild_reloc_section(struct elf *elf, struct section *sec)
10441045
{
1045-
struct reloc *reloc;
1046-
int nr;
1047-
1048-
nr = 0;
1049-
list_for_each_entry(reloc, &sec->reloc_list, list)
1050-
nr++;
1051-
10521046
switch (sec->sh.sh_type) {
1053-
case SHT_REL: return elf_rebuild_rel_reloc_section(sec, nr);
1054-
case SHT_RELA: return elf_rebuild_rela_reloc_section(sec, nr);
1047+
case SHT_REL: return elf_rebuild_rel_reloc_section(sec);
1048+
case SHT_RELA: return elf_rebuild_rela_reloc_section(sec);
10551049
default: return -1;
10561050
}
10571051
}
@@ -1111,12 +1105,6 @@ int elf_write(struct elf *elf)
11111105
/* Update changed relocation sections and section headers: */
11121106
list_for_each_entry(sec, &elf->sections, list) {
11131107
if (sec->changed) {
1114-
if (sec->base &&
1115-
elf_rebuild_reloc_section(elf, sec)) {
1116-
WARN("elf_rebuild_reloc_section");
1117-
return -1;
1118-
}
1119-
11201108
s = elf_getscn(elf->elf, sec->idx);
11211109
if (!s) {
11221110
WARN_ELF("elf_getscn");
@@ -1127,6 +1115,12 @@ int elf_write(struct elf *elf)
11271115
return -1;
11281116
}
11291117

1118+
if (sec->base &&
1119+
elf_rebuild_reloc_section(elf, sec)) {
1120+
WARN("elf_rebuild_reloc_section");
1121+
return -1;
1122+
}
1123+
11301124
sec->changed = false;
11311125
elf->changed = true;
11321126
}

0 commit comments

Comments
 (0)