mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-18 08:35:08 +08:00
- 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 -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEzv7L6UO9uDPlPSfHEsHwGGHeVUoFAmFr+qQACgkQEsHwGGHe VUqYCxAAqkHYOu4ok1t0ZUePJSDNFXbMNEq8gfb9gY4zQfsk80eE40EUeZhaqyvq a4JHKJSMus+towDB+Zpy1s3ZEfT8V2leZCjMsIS4yIy/dLHPC3TCL4kS1CVlpw0U funRhy4FkeiY2Un7ghvhvqSM9l9Dnw3TqxhGUZ0LcdlUaPIKIwzFhHvEVmZsXRFM cccz5F/r0yeg7r4TbGtTAmxpKSIsx4BaFqf/LICaLrWGo3pDVGlhn9sPflzv1vue rlR4Lb1NKKCaQTefFmLdEpV7FCiJ0QXeoZNGCJlk9NHZyGoNSRfkVSZRDGt/fb5A aKfaDvrimgALDB4naWSEplC3slVp9Z2+TpS2zHyqDchGnHIAyx9E6MSOt9F0fs// DSv83K2j18rRvmnOPsZoy2pySqtMULohIPECPHOtdZ1y+PwhD/FpSNtO51t/hig5 2cPq8DnVycJiXM7VQpTcNXv+M2tZ2IZ/E3g8SHJCNSlGZ73YmZdiO2ZTmXGRPnmx Xq8gFl/nomMFQSdv6H+nlSy0EA5C3dWqa3pwtKBNrZ8mGAsrEZ2Ptl1TSKfjs28x tI7KTeZouxA2NlggBllgOFzm5HSSq+4S6l/gWjuR0yu7j2Kpha+UZUaXZHKHt+OU iFZ6BlITsFEE+cd2Nns2rTJjsjN08j/AfNJOGcjtiFVUjHeCc24= =tiWi -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
6890acacde
@ -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);
|
list_add_tail(&reloc->list, &sec->reloc->reloc_list);
|
||||||
elf_hash_add(reloc, &reloc->hash, reloc_hash(reloc));
|
elf_hash_add(reloc, &reloc->hash, reloc_hash(reloc));
|
||||||
|
|
||||||
|
sec->reloc->sh.sh_size += sec->reloc->sh.sh_entsize;
|
||||||
sec->reloc->changed = true;
|
sec->reloc->changed = true;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -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;
|
struct reloc *reloc;
|
||||||
int idx = 0, size;
|
int idx = 0;
|
||||||
void *buf;
|
void *buf;
|
||||||
|
|
||||||
/* Allocate a buffer for relocations */
|
/* Allocate a buffer for relocations */
|
||||||
size = nr * sizeof(GElf_Rel);
|
buf = malloc(sec->sh.sh_size);
|
||||||
buf = malloc(size);
|
|
||||||
if (!buf) {
|
if (!buf) {
|
||||||
perror("malloc");
|
perror("malloc");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
sec->data->d_buf = buf;
|
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->data->d_type = ELF_T_REL;
|
||||||
|
|
||||||
sec->sh.sh_size = size;
|
|
||||||
|
|
||||||
idx = 0;
|
idx = 0;
|
||||||
list_for_each_entry(reloc, &sec->reloc_list, list) {
|
list_for_each_entry(reloc, &sec->reloc_list, list) {
|
||||||
reloc->rel.r_offset = reloc->offset;
|
reloc->rel.r_offset = reloc->offset;
|
||||||
reloc->rel.r_info = GELF_R_INFO(reloc->sym->idx, reloc->type);
|
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++;
|
idx++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
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;
|
struct reloc *reloc;
|
||||||
int idx = 0, size;
|
int idx = 0;
|
||||||
void *buf;
|
void *buf;
|
||||||
|
|
||||||
/* Allocate a buffer for relocations with addends */
|
/* Allocate a buffer for relocations with addends */
|
||||||
size = nr * sizeof(GElf_Rela);
|
buf = malloc(sec->sh.sh_size);
|
||||||
buf = malloc(size);
|
|
||||||
if (!buf) {
|
if (!buf) {
|
||||||
perror("malloc");
|
perror("malloc");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
sec->data->d_buf = buf;
|
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->data->d_type = ELF_T_RELA;
|
||||||
|
|
||||||
sec->sh.sh_size = size;
|
|
||||||
|
|
||||||
idx = 0;
|
idx = 0;
|
||||||
list_for_each_entry(reloc, &sec->reloc_list, list) {
|
list_for_each_entry(reloc, &sec->reloc_list, list) {
|
||||||
reloc->rela.r_offset = reloc->offset;
|
reloc->rela.r_offset = reloc->offset;
|
||||||
reloc->rela.r_addend = reloc->addend;
|
reloc->rela.r_addend = reloc->addend;
|
||||||
reloc->rela.r_info = GELF_R_INFO(reloc->sym->idx, reloc->type);
|
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++;
|
idx++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -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)
|
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) {
|
switch (sec->sh.sh_type) {
|
||||||
case SHT_REL: return elf_rebuild_rel_reloc_section(sec, nr);
|
case SHT_REL: return elf_rebuild_rel_reloc_section(sec);
|
||||||
case SHT_RELA: return elf_rebuild_rela_reloc_section(sec, nr);
|
case SHT_RELA: return elf_rebuild_rela_reloc_section(sec);
|
||||||
default: return -1;
|
default: return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1111,12 +1105,6 @@ int elf_write(struct elf *elf)
|
|||||||
/* Update changed relocation sections and section headers: */
|
/* Update changed relocation sections and section headers: */
|
||||||
list_for_each_entry(sec, &elf->sections, list) {
|
list_for_each_entry(sec, &elf->sections, list) {
|
||||||
if (sec->changed) {
|
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);
|
s = elf_getscn(elf->elf, sec->idx);
|
||||||
if (!s) {
|
if (!s) {
|
||||||
WARN_ELF("elf_getscn");
|
WARN_ELF("elf_getscn");
|
||||||
@ -1127,6 +1115,12 @@ int elf_write(struct elf *elf)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sec->base &&
|
||||||
|
elf_rebuild_reloc_section(elf, sec)) {
|
||||||
|
WARN("elf_rebuild_reloc_section");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
sec->changed = false;
|
sec->changed = false;
|
||||||
elf->changed = true;
|
elf->changed = true;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user