diff options
author | Philipp Rudo <prudo@linux.vnet.ibm.com> | 2018-04-13 18:36:24 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-04-13 20:10:28 -0400 |
commit | 8aec395b8478310521031157ef5d44ef19c2c581 (patch) | |
tree | c48f8773b3c734ab3f8ebf0e51e262959948f1b9 /kernel/kexec_file.c | |
parent | 961d921a1b967f76e13f9e11f2b0c2bcb5741f10 (diff) |
kernel/kexec_file.c: use read-only sections in arch_kexec_apply_relocations*
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.
Link: http://lkml.kernel.org/r/20180321112751.22196-6-prudo@linux.vnet.ibm.com
Signed-off-by: Philipp Rudo <prudo@linux.vnet.ibm.com>
Acked-by: Dave Young <dyoung@redhat.com>
Cc: AKASHI Takahiro <takahiro.akashi@linaro.org>
Cc: Eric Biederman <ebiederm@xmission.com>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Thiago Jung Bauermann <bauerman@linux.vnet.ibm.com>
Cc: Vivek Goyal <vgoyal@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel/kexec_file.c')
-rw-r--r-- | kernel/kexec_file.c | 63 |
1 files changed, 42 insertions, 21 deletions
diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c index 9bd1ec1dd875..5c70f7f2bae3 100644 --- a/kernel/kexec_file.c +++ b/kernel/kexec_file.c | |||
@@ -110,19 +110,35 @@ int __weak arch_kexec_kernel_verify_sig(struct kimage *image, void *buf, | |||
110 | } | 110 | } |
111 | #endif | 111 | #endif |
112 | 112 | ||
113 | /* Apply relocations of type RELA */ | 113 | /* |
114 | * arch_kexec_apply_relocations_add - apply relocations of type RELA | ||
115 | * @pi: Purgatory to be relocated. | ||
116 | * @section: Section relocations applying to. | ||
117 | * @relsec: Section containing RELAs. | ||
118 | * @symtab: Corresponding symtab. | ||
119 | * | ||
120 | * Return: 0 on success, negative errno on error. | ||
121 | */ | ||
114 | int __weak | 122 | int __weak |
115 | arch_kexec_apply_relocations_add(const Elf_Ehdr *ehdr, Elf_Shdr *sechdrs, | 123 | arch_kexec_apply_relocations_add(struct purgatory_info *pi, Elf_Shdr *section, |
116 | unsigned int relsec) | 124 | const Elf_Shdr *relsec, const Elf_Shdr *symtab) |
117 | { | 125 | { |
118 | pr_err("RELA relocation unsupported.\n"); | 126 | pr_err("RELA relocation unsupported.\n"); |
119 | return -ENOEXEC; | 127 | return -ENOEXEC; |
120 | } | 128 | } |
121 | 129 | ||
122 | /* Apply relocations of type REL */ | 130 | /* |
131 | * arch_kexec_apply_relocations - apply relocations of type REL | ||
132 | * @pi: Purgatory to be relocated. | ||
133 | * @section: Section relocations applying to. | ||
134 | * @relsec: Section containing RELs. | ||
135 | * @symtab: Corresponding symtab. | ||
136 | * | ||
137 | * Return: 0 on success, negative errno on error. | ||
138 | */ | ||
123 | int __weak | 139 | int __weak |
124 | arch_kexec_apply_relocations(const Elf_Ehdr *ehdr, Elf_Shdr *sechdrs, | 140 | arch_kexec_apply_relocations(struct purgatory_info *pi, Elf_Shdr *section, |
125 | unsigned int relsec) | 141 | const Elf_Shdr *relsec, const Elf_Shdr *symtab) |
126 | { | 142 | { |
127 | pr_err("REL relocation unsupported.\n"); | 143 | pr_err("REL relocation unsupported.\n"); |
128 | return -ENOEXEC; | 144 | return -ENOEXEC; |
@@ -879,14 +895,19 @@ static int kexec_apply_relocations(struct kimage *image) | |||
879 | { | 895 | { |
880 | int i, ret; | 896 | int i, ret; |
881 | struct purgatory_info *pi = &image->purgatory_info; | 897 | struct purgatory_info *pi = &image->purgatory_info; |
882 | Elf_Shdr *sechdrs = pi->sechdrs; | 898 | const Elf_Shdr *sechdrs; |
899 | |||
900 | sechdrs = (void *)pi->ehdr + pi->ehdr->e_shoff; | ||
883 | 901 | ||
884 | /* Apply relocations */ | ||
885 | for (i = 0; i < pi->ehdr->e_shnum; i++) { | 902 | for (i = 0; i < pi->ehdr->e_shnum; i++) { |
886 | Elf_Shdr *section, *symtab; | 903 | const Elf_Shdr *relsec; |
904 | const Elf_Shdr *symtab; | ||
905 | Elf_Shdr *section; | ||
906 | |||
907 | relsec = sechdrs + i; | ||
887 | 908 | ||
888 | if (sechdrs[i].sh_type != SHT_RELA && | 909 | if (relsec->sh_type != SHT_RELA && |
889 | sechdrs[i].sh_type != SHT_REL) | 910 | relsec->sh_type != SHT_REL) |
890 | continue; | 911 | continue; |
891 | 912 | ||
892 | /* | 913 | /* |
@@ -895,12 +916,12 @@ static int kexec_apply_relocations(struct kimage *image) | |||
895 | * symbol table. And ->sh_info contains section header | 916 | * symbol table. And ->sh_info contains section header |
896 | * index of section to which relocations apply. | 917 | * index of section to which relocations apply. |
897 | */ | 918 | */ |
898 | if (sechdrs[i].sh_info >= pi->ehdr->e_shnum || | 919 | if (relsec->sh_info >= pi->ehdr->e_shnum || |
899 | sechdrs[i].sh_link >= pi->ehdr->e_shnum) | 920 | relsec->sh_link >= pi->ehdr->e_shnum) |
900 | return -ENOEXEC; | 921 | return -ENOEXEC; |
901 | 922 | ||
902 | section = &sechdrs[sechdrs[i].sh_info]; | 923 | section = pi->sechdrs + relsec->sh_info; |
903 | symtab = &sechdrs[sechdrs[i].sh_link]; | 924 | symtab = sechdrs + relsec->sh_link; |
904 | 925 | ||
905 | if (!(section->sh_flags & SHF_ALLOC)) | 926 | if (!(section->sh_flags & SHF_ALLOC)) |
906 | continue; | 927 | continue; |
@@ -917,12 +938,12 @@ static int kexec_apply_relocations(struct kimage *image) | |||
917 | * Respective architecture needs to provide support for applying | 938 | * Respective architecture needs to provide support for applying |
918 | * relocations of type SHT_RELA/SHT_REL. | 939 | * relocations of type SHT_RELA/SHT_REL. |
919 | */ | 940 | */ |
920 | if (sechdrs[i].sh_type == SHT_RELA) | 941 | if (relsec->sh_type == SHT_RELA) |
921 | ret = arch_kexec_apply_relocations_add(pi->ehdr, | 942 | ret = arch_kexec_apply_relocations_add(pi, section, |
922 | sechdrs, i); | 943 | relsec, symtab); |
923 | else if (sechdrs[i].sh_type == SHT_REL) | 944 | else if (relsec->sh_type == SHT_REL) |
924 | ret = arch_kexec_apply_relocations(pi->ehdr, | 945 | ret = arch_kexec_apply_relocations(pi, section, |
925 | sechdrs, i); | 946 | relsec, symtab); |
926 | if (ret) | 947 | if (ret) |
927 | return ret; | 948 | return ret; |
928 | } | 949 | } |