[PATCH 05/17] kexec_file: Use read-only sections in arch_kexec_apply_relocations*

2018-02-12 Thread Philipp Rudo
When the relocations are applied to the purgatory only the section the
relocations are applied to is writable. The other sections, i.e. the symtab
and .rel/.rela, are in read-only kexec_purgatory. Highlight this by marking
the corresponding variables as 'const'.

While at it also change the signatures of arch_kexec_apply_relocations* to
take section pointers instead of just the index of the relocation section.
This removes the second lookup and sanity check of the sections in arch
code.

Signed-off-by: Philipp Rudo 
---
 arch/x86/kernel/machine_kexec_64.c | 56 -
 include/linux/kexec.h  | 12 +---
 kernel/kexec_file.c| 63 +-
 3 files changed, 70 insertions(+), 61 deletions(-)

diff --git a/arch/x86/kernel/machine_kexec_64.c 
b/arch/x86/kernel/machine_kexec_64.c
index 1f790cf9d38f..6be04e4d4a7e 100644
--- a/arch/x86/kernel/machine_kexec_64.c
+++ b/arch/x86/kernel/machine_kexec_64.c
@@ -422,52 +422,36 @@ int arch_kexec_kernel_verify_sig(struct kimage *image, 
void *kernel,
 /*
  * Apply purgatory relocations.
  *
- * ehdr: Pointer to elf headers
- * sechdrs: Pointer to section headers.
- * relsec: section index of SHT_RELA section.
+ * @pi:Purgatory to be relocated.
+ * @section:   Section relocations applying to.
+ * @relsec:Section containing RELAs.
+ * @symtabsec: Corresponding symtab.
  *
  * TODO: Some of the code belongs to generic code. Move that in kexec.c.
  */
-int arch_kexec_apply_relocations_add(const Elf64_Ehdr *ehdr,
-Elf64_Shdr *sechdrs, unsigned int relsec)
+int arch_kexec_apply_relocations_add(struct purgatory_info *pi,
+Elf_Shdr *section, const Elf_Shdr *relsec,
+const Elf_Shdr *symtabsec)
 {
unsigned int i;
Elf64_Rela *rel;
Elf64_Sym *sym;
void *location;
-   Elf64_Shdr *section, *symtabsec;
unsigned long address, sec_base, value;
const char *strtab, *name, *shstrtab;
+   const Elf_Shdr *sechdrs;
 
-   /*
-* ->sh_offset has been modified to keep the pointer to section
-* contents in memory
-*/
-   rel = (void *)sechdrs[relsec].sh_offset;
-
-   /* Section to which relocations apply */
-   section = &sechdrs[sechdrs[relsec].sh_info];
-
-   pr_debug("Applying relocate section %u to %u\n", relsec,
-sechdrs[relsec].sh_info);
-
-   /* Associated symbol table */
-   symtabsec = &sechdrs[sechdrs[relsec].sh_link];
-
-   /* String table */
-   if (symtabsec->sh_link >= ehdr->e_shnum) {
-   /* Invalid strtab section number */
-   pr_err("Invalid string table section index %d\n",
-  symtabsec->sh_link);
-   return -ENOEXEC;
-   }
+   /* String & section header string table */
+   sechdrs = (void *)pi->ehdr + pi->ehdr->e_shoff;
+   strtab = (char *)pi->ehdr + sechdrs[symtabsec->sh_link].sh_offset;
+   shstrtab = (char *)pi->ehdr + sechdrs[pi->ehdr->e_shstrndx].sh_offset;
 
-   strtab = (char *)sechdrs[symtabsec->sh_link].sh_offset;
+   rel = (void *)pi->ehdr + relsec->sh_offset;
 
-   /* section header string table */
-   shstrtab = (char *)sechdrs[ehdr->e_shstrndx].sh_offset;
+   pr_debug("Applying relocate section %s to %u\n",
+shstrtab + relsec->sh_name, relsec->sh_info);
 
-   for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
+   for (i = 0; i < relsec->sh_size / sizeof(*rel); i++) {
 
/*
 * rel[i].r_offset contains byte offset from beginning
@@ -490,8 +474,8 @@ int arch_kexec_apply_relocations_add(const Elf64_Ehdr *ehdr,
 * to apply. ELF64_R_SYM() and ELF64_R_TYPE() macros get
 * these respectively.
 */
-   sym = (Elf64_Sym *)symtabsec->sh_offset +
-   ELF64_R_SYM(rel[i].r_info);
+   sym = (void *)pi->ehdr + symtabsec->sh_offset;
+   sym += ELF64_R_SYM(rel[i].r_info);
 
if (sym->st_name)
name = strtab + sym->st_name;
@@ -514,12 +498,12 @@ int arch_kexec_apply_relocations_add(const Elf64_Ehdr 
*ehdr,
 
if (sym->st_shndx == SHN_ABS)
sec_base = 0;
-   else if (sym->st_shndx >= ehdr->e_shnum) {
+   else if (sym->st_shndx >= pi->ehdr->e_shnum) {
pr_err("Invalid section %d for symbol %s\n",
   sym->st_shndx, name);
return -ENOEXEC;
} else
-   sec_base = sechdrs[sym->st_shndx].sh_addr;
+   sec_base = pi->sechdrs[sym->st_shndx].sh_addr;
 
value = sym->st_value;
value += sec_base;
diff --git a/include/linux/kexec.h b/inc

[PATCH 05/17] kexec_file: Use read-only sections in arch_kexec_apply_relocations*

2018-02-02 Thread Philipp Rudo
When the relocations are applied to the purgatory only the section the
relocations are applied to is writable. The other sections, i.e. the symtab
and .rel/.rela, are in read-only kexec_purgatory. Highlight this by marking
the corresponding variables as 'const'.

While at it also change the signatures of arch_kexec_apply_relocations* to
take section pointers instead of just the index of the relocation section.
This removes the second lookup and sanity check of the sections in arch
code.

Signed-off-by: Philipp Rudo 
---
 arch/x86/kernel/machine_kexec_64.c | 56 -
 include/linux/kexec.h  | 12 +---
 kernel/kexec_file.c| 63 +-
 3 files changed, 70 insertions(+), 61 deletions(-)

diff --git a/arch/x86/kernel/machine_kexec_64.c 
b/arch/x86/kernel/machine_kexec_64.c
index 1f790cf9d38f..6be04e4d4a7e 100644
--- a/arch/x86/kernel/machine_kexec_64.c
+++ b/arch/x86/kernel/machine_kexec_64.c
@@ -422,52 +422,36 @@ int arch_kexec_kernel_verify_sig(struct kimage *image, 
void *kernel,
 /*
  * Apply purgatory relocations.
  *
- * ehdr: Pointer to elf headers
- * sechdrs: Pointer to section headers.
- * relsec: section index of SHT_RELA section.
+ * @pi:Purgatory to be relocated.
+ * @section:   Section relocations applying to.
+ * @relsec:Section containing RELAs.
+ * @symtabsec: Corresponding symtab.
  *
  * TODO: Some of the code belongs to generic code. Move that in kexec.c.
  */
-int arch_kexec_apply_relocations_add(const Elf64_Ehdr *ehdr,
-Elf64_Shdr *sechdrs, unsigned int relsec)
+int arch_kexec_apply_relocations_add(struct purgatory_info *pi,
+Elf_Shdr *section, const Elf_Shdr *relsec,
+const Elf_Shdr *symtabsec)
 {
unsigned int i;
Elf64_Rela *rel;
Elf64_Sym *sym;
void *location;
-   Elf64_Shdr *section, *symtabsec;
unsigned long address, sec_base, value;
const char *strtab, *name, *shstrtab;
+   const Elf_Shdr *sechdrs;
 
-   /*
-* ->sh_offset has been modified to keep the pointer to section
-* contents in memory
-*/
-   rel = (void *)sechdrs[relsec].sh_offset;
-
-   /* Section to which relocations apply */
-   section = &sechdrs[sechdrs[relsec].sh_info];
-
-   pr_debug("Applying relocate section %u to %u\n", relsec,
-sechdrs[relsec].sh_info);
-
-   /* Associated symbol table */
-   symtabsec = &sechdrs[sechdrs[relsec].sh_link];
-
-   /* String table */
-   if (symtabsec->sh_link >= ehdr->e_shnum) {
-   /* Invalid strtab section number */
-   pr_err("Invalid string table section index %d\n",
-  symtabsec->sh_link);
-   return -ENOEXEC;
-   }
+   /* String & section header string table */
+   sechdrs = (void *)pi->ehdr + pi->ehdr->e_shoff;
+   strtab = (char *)pi->ehdr + sechdrs[symtabsec->sh_link].sh_offset;
+   shstrtab = (char *)pi->ehdr + sechdrs[pi->ehdr->e_shstrndx].sh_offset;
 
-   strtab = (char *)sechdrs[symtabsec->sh_link].sh_offset;
+   rel = (void *)pi->ehdr + relsec->sh_offset;
 
-   /* section header string table */
-   shstrtab = (char *)sechdrs[ehdr->e_shstrndx].sh_offset;
+   pr_debug("Applying relocate section %s to %u\n",
+shstrtab + relsec->sh_name, relsec->sh_info);
 
-   for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
+   for (i = 0; i < relsec->sh_size / sizeof(*rel); i++) {
 
/*
 * rel[i].r_offset contains byte offset from beginning
@@ -490,8 +474,8 @@ int arch_kexec_apply_relocations_add(const Elf64_Ehdr *ehdr,
 * to apply. ELF64_R_SYM() and ELF64_R_TYPE() macros get
 * these respectively.
 */
-   sym = (Elf64_Sym *)symtabsec->sh_offset +
-   ELF64_R_SYM(rel[i].r_info);
+   sym = (void *)pi->ehdr + symtabsec->sh_offset;
+   sym += ELF64_R_SYM(rel[i].r_info);
 
if (sym->st_name)
name = strtab + sym->st_name;
@@ -514,12 +498,12 @@ int arch_kexec_apply_relocations_add(const Elf64_Ehdr 
*ehdr,
 
if (sym->st_shndx == SHN_ABS)
sec_base = 0;
-   else if (sym->st_shndx >= ehdr->e_shnum) {
+   else if (sym->st_shndx >= pi->ehdr->e_shnum) {
pr_err("Invalid section %d for symbol %s\n",
   sym->st_shndx, name);
return -ENOEXEC;
} else
-   sec_base = sechdrs[sym->st_shndx].sh_addr;
+   sec_base = pi->sechdrs[sym->st_shndx].sh_addr;
 
value = sym->st_value;
value += sec_base;
diff --git a/include/linux/kexec.h b/inc