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