diff options
author | Philipp Rudo <prudo@linux.vnet.ibm.com> | 2018-04-13 18:36:21 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-04-13 20:10:28 -0400 |
commit | 961d921a1b967f76e13f9e11f2b0c2bcb5741f10 (patch) | |
tree | 4934f6507ab82fa24bed42bd7ae71640bd5aeb3f | |
parent | 65c225d3280542f3ea145e052215ce0538f6bb69 (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.c | 38 |
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 | ||
965 | static 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 | */ | ||
972 | static 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, | |||
1013 | void *kexec_purgatory_get_symbol_addr(struct kimage *image, const char *name) | 1020 | void *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) | |||
1036 | int kexec_purgatory_get_set_symbol(struct kimage *image, const char *name, | 1043 | int 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); |