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

+25 -31
+25 -31
tools/objtool/elf.c
··· 508 508 list_add_tail(&reloc->list, &sec->reloc->reloc_list); 509 509 elf_hash_add(reloc, &reloc->hash, reloc_hash(reloc)); 510 510 511 + sec->reloc->sh.sh_size += sec->reloc->sh.sh_entsize; 511 512 sec->reloc->changed = true; 512 513 513 514 return 0; ··· 978 977 } 979 978 } 980 979 981 - static int elf_rebuild_rel_reloc_section(struct section *sec, int nr) 980 + static int elf_rebuild_rel_reloc_section(struct section *sec) 982 981 { 983 982 struct reloc *reloc; 984 - int idx = 0, size; 983 + int idx = 0; 985 984 void *buf; 986 985 987 986 /* Allocate a buffer for relocations */ 988 - size = nr * sizeof(GElf_Rel); 989 - buf = malloc(size); 987 + buf = malloc(sec->sh.sh_size); 990 988 if (!buf) { 991 989 perror("malloc"); 992 990 return -1; 993 991 } 994 992 995 993 sec->data->d_buf = buf; 996 - sec->data->d_size = size; 994 + sec->data->d_size = sec->sh.sh_size; 997 995 sec->data->d_type = ELF_T_REL; 998 - 999 - sec->sh.sh_size = size; 1000 996 1001 997 idx = 0; 1002 998 list_for_each_entry(reloc, &sec->reloc_list, list) { 1003 999 reloc->rel.r_offset = reloc->offset; 1004 1000 reloc->rel.r_info = GELF_R_INFO(reloc->sym->idx, reloc->type); 1005 - gelf_update_rel(sec->data, idx, &reloc->rel); 1001 + if (!gelf_update_rel(sec->data, idx, &reloc->rel)) { 1002 + WARN_ELF("gelf_update_rel"); 1003 + return -1; 1004 + } 1006 1005 idx++; 1007 1006 } 1008 1007 1009 1008 return 0; 1010 1009 } 1011 1010 1012 - static int elf_rebuild_rela_reloc_section(struct section *sec, int nr) 1011 + static int elf_rebuild_rela_reloc_section(struct section *sec) 1013 1012 { 1014 1013 struct reloc *reloc; 1015 - int idx = 0, size; 1014 + int idx = 0; 1016 1015 void *buf; 1017 1016 1018 1017 /* Allocate a buffer for relocations with addends */ 1019 - size = nr * sizeof(GElf_Rela); 1020 - buf = malloc(size); 1018 + buf = malloc(sec->sh.sh_size); 1021 1019 if (!buf) { 1022 1020 perror("malloc"); 1023 1021 return -1; 1024 1022 } 1025 1023 1026 1024 sec->data->d_buf = buf; 1027 - sec->data->d_size = size; 1025 + sec->data->d_size = sec->sh.sh_size; 1028 1026 sec->data->d_type = ELF_T_RELA; 1029 - 1030 - sec->sh.sh_size = size; 1031 1027 1032 1028 idx = 0; 1033 1029 list_for_each_entry(reloc, &sec->reloc_list, list) { 1034 1030 reloc->rela.r_offset = reloc->offset; 1035 1031 reloc->rela.r_addend = reloc->addend; 1036 1032 reloc->rela.r_info = GELF_R_INFO(reloc->sym->idx, reloc->type); 1037 - gelf_update_rela(sec->data, idx, &reloc->rela); 1033 + if (!gelf_update_rela(sec->data, idx, &reloc->rela)) { 1034 + WARN_ELF("gelf_update_rela"); 1035 + return -1; 1036 + } 1038 1037 idx++; 1039 1038 } 1040 1039 ··· 1043 1042 1044 1043 static int elf_rebuild_reloc_section(struct elf *elf, struct section *sec) 1045 1044 { 1046 - struct reloc *reloc; 1047 - int nr; 1048 - 1049 - nr = 0; 1050 - list_for_each_entry(reloc, &sec->reloc_list, list) 1051 - nr++; 1052 - 1053 1045 switch (sec->sh.sh_type) { 1054 - case SHT_REL: return elf_rebuild_rel_reloc_section(sec, nr); 1055 - case SHT_RELA: return elf_rebuild_rela_reloc_section(sec, nr); 1046 + case SHT_REL: return elf_rebuild_rel_reloc_section(sec); 1047 + case SHT_RELA: return elf_rebuild_rela_reloc_section(sec); 1056 1048 default: return -1; 1057 1049 } 1058 1050 } ··· 1105 1111 /* Update changed relocation sections and section headers: */ 1106 1112 list_for_each_entry(sec, &elf->sections, list) { 1107 1113 if (sec->changed) { 1108 - if (sec->base && 1109 - elf_rebuild_reloc_section(elf, sec)) { 1110 - WARN("elf_rebuild_reloc_section"); 1111 - return -1; 1112 - } 1113 - 1114 1114 s = elf_getscn(elf->elf, sec->idx); 1115 1115 if (!s) { 1116 1116 WARN_ELF("elf_getscn"); ··· 1112 1124 } 1113 1125 if (!gelf_update_shdr(s, &sec->sh)) { 1114 1126 WARN_ELF("gelf_update_shdr"); 1127 + return -1; 1128 + } 1129 + 1130 + if (sec->base && 1131 + elf_rebuild_reloc_section(elf, sec)) { 1132 + WARN("elf_rebuild_reloc_section"); 1115 1133 return -1; 1116 1134 } 1117 1135