aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhilipp Rudo <prudo@linux.vnet.ibm.com>2018-04-13 18:36:21 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-04-13 20:10:28 -0400
commit961d921a1b967f76e13f9e11f2b0c2bcb5741f10 (patch)
tree4934f6507ab82fa24bed42bd7ae71640bd5aeb3f
parent65c225d3280542f3ea145e052215ce0538f6bb69 (diff)
kernel/kexec_file.c: search symbols in read-only kexec_purgatory
The stripped purgatory does not contain a symtab. So when looking for symbols this is done in read-only kexec_purgatory. Highlight this by marking the corresponding variables as 'const'. Link: http://lkml.kernel.org/r/20180321112751.22196-5-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>
-rw-r--r--kernel/kexec_file.c38
1 files changed, 22 insertions, 16 deletions
diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
index 12cf9c9ff0bc..9bd1ec1dd875 100644
--- a/kernel/kexec_file.c
+++ b/kernel/kexec_file.c
@@ -962,20 +962,27 @@ out:
962 return ret; 962 return ret;
963} 963}
964 964
965static Elf_Sym *kexec_purgatory_find_symbol(struct purgatory_info *pi, 965/*
966 const char *name) 966 * kexec_purgatory_find_symbol - find a symbol in the purgatory
967 * @pi: Purgatory to search in.
968 * @name: Name of the symbol.
969 *
970 * Return: pointer to symbol in read-only symtab on success, NULL on error.
971 */
972static const Elf_Sym *kexec_purgatory_find_symbol(struct purgatory_info *pi,
973 const char *name)
967{ 974{
975 const Elf_Shdr *sechdrs;
968 const Elf_Ehdr *ehdr; 976 const Elf_Ehdr *ehdr;
969 Elf_Sym *syms; 977 const Elf_Sym *syms;
970 Elf_Shdr *sechdrs;
971 int i, k;
972 const char *strtab; 978 const char *strtab;
979 int i, k;
973 980
974 if (!pi->sechdrs || !pi->ehdr) 981 if (!pi->ehdr)
975 return NULL; 982 return NULL;
976 983
977 sechdrs = pi->sechdrs;
978 ehdr = pi->ehdr; 984 ehdr = pi->ehdr;
985 sechdrs = (void *)ehdr + ehdr->e_shoff;
979 986
980 for (i = 0; i < ehdr->e_shnum; i++) { 987 for (i = 0; i < ehdr->e_shnum; i++) {
981 if (sechdrs[i].sh_type != SHT_SYMTAB) 988 if (sechdrs[i].sh_type != SHT_SYMTAB)
@@ -984,8 +991,8 @@ static Elf_Sym *kexec_purgatory_find_symbol(struct purgatory_info *pi,
984 if (sechdrs[i].sh_link >= ehdr->e_shnum) 991 if (sechdrs[i].sh_link >= ehdr->e_shnum)
985 /* Invalid strtab section number */ 992 /* Invalid strtab section number */
986 continue; 993 continue;
987 strtab = (char *)sechdrs[sechdrs[i].sh_link].sh_offset; 994 strtab = (void *)ehdr + sechdrs[sechdrs[i].sh_link].sh_offset;
988 syms = (Elf_Sym *)sechdrs[i].sh_offset; 995 syms = (void *)ehdr + sechdrs[i].sh_offset;
989 996
990 /* Go through symbols for a match */ 997 /* Go through symbols for a match */
991 for (k = 0; k < sechdrs[i].sh_size/sizeof(Elf_Sym); k++) { 998 for (k = 0; k < sechdrs[i].sh_size/sizeof(Elf_Sym); k++) {
@@ -1013,7 +1020,7 @@ static Elf_Sym *kexec_purgatory_find_symbol(struct purgatory_info *pi,
1013void *kexec_purgatory_get_symbol_addr(struct kimage *image, const char *name) 1020void *kexec_purgatory_get_symbol_addr(struct kimage *image, const char *name)
1014{ 1021{
1015 struct purgatory_info *pi = &image->purgatory_info; 1022 struct purgatory_info *pi = &image->purgatory_info;
1016 Elf_Sym *sym; 1023 const Elf_Sym *sym;
1017 Elf_Shdr *sechdr; 1024 Elf_Shdr *sechdr;
1018 1025
1019 sym = kexec_purgatory_find_symbol(pi, name); 1026 sym = kexec_purgatory_find_symbol(pi, name);
@@ -1036,9 +1043,9 @@ void *kexec_purgatory_get_symbol_addr(struct kimage *image, const char *name)
1036int kexec_purgatory_get_set_symbol(struct kimage *image, const char *name, 1043int kexec_purgatory_get_set_symbol(struct kimage *image, const char *name,
1037 void *buf, unsigned int size, bool get_value) 1044 void *buf, unsigned int size, bool get_value)
1038{ 1045{
1039 Elf_Sym *sym;
1040 Elf_Shdr *sechdrs;
1041 struct purgatory_info *pi = &image->purgatory_info; 1046 struct purgatory_info *pi = &image->purgatory_info;
1047 const Elf_Sym *sym;
1048 Elf_Shdr *sec;
1042 char *sym_buf; 1049 char *sym_buf;
1043 1050
1044 sym = kexec_purgatory_find_symbol(pi, name); 1051 sym = kexec_purgatory_find_symbol(pi, name);
@@ -1051,16 +1058,15 @@ int kexec_purgatory_get_set_symbol(struct kimage *image, const char *name,
1051 return -EINVAL; 1058 return -EINVAL;
1052 } 1059 }
1053 1060
1054 sechdrs = pi->sechdrs; 1061 sec = pi->sechdrs + sym->st_shndx;
1055 1062
1056 if (sechdrs[sym->st_shndx].sh_type == SHT_NOBITS) { 1063 if (sec->sh_type == SHT_NOBITS) {
1057 pr_err("symbol %s is in a bss section. Cannot %s\n", name, 1064 pr_err("symbol %s is in a bss section. Cannot %s\n", name,
1058 get_value ? "get" : "set"); 1065 get_value ? "get" : "set");
1059 return -EINVAL; 1066 return -EINVAL;
1060 } 1067 }
1061 1068
1062 sym_buf = (unsigned char *)sechdrs[sym->st_shndx].sh_offset + 1069 sym_buf = (char *)sec->sh_offset + sym->st_value;
1063 sym->st_value;
1064 1070
1065 if (get_value) 1071 if (get_value)
1066 memcpy((void *)buf, sym_buf, size); 1072 memcpy((void *)buf, sym_buf, size);