Skip to content

Commit

Permalink
kernel/kexec_file.c: search symbols in read-only kexec_purgatory
Browse files Browse the repository at this point in the history
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/[email protected]
Signed-off-by: Philipp Rudo <[email protected]>
Acked-by: Dave Young <[email protected]>
Cc: AKASHI Takahiro <[email protected]>
Cc: Eric Biederman <[email protected]>
Cc: Heiko Carstens <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Martin Schwidefsky <[email protected]>
Cc: Michael Ellerman <[email protected]>
Cc: Thiago Jung Bauermann <[email protected]>
Cc: Vivek Goyal <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
Philipp Rudo authored and torvalds committed Apr 14, 2018
1 parent 65c225d commit 961d921
Showing 1 changed file with 22 additions and 16 deletions.
38 changes: 22 additions & 16 deletions kernel/kexec_file.c
Original file line number Diff line number Diff line change
Expand Up @@ -962,20 +962,27 @@ int kexec_load_purgatory(struct kimage *image, unsigned long min,
return ret;
}

static Elf_Sym *kexec_purgatory_find_symbol(struct purgatory_info *pi,
const char *name)
/*
* kexec_purgatory_find_symbol - find a symbol in the purgatory
* @pi: Purgatory to search in.
* @name: Name of the symbol.
*
* Return: pointer to symbol in read-only symtab on success, NULL on error.
*/
static const Elf_Sym *kexec_purgatory_find_symbol(struct purgatory_info *pi,
const char *name)
{
const Elf_Shdr *sechdrs;
const Elf_Ehdr *ehdr;
Elf_Sym *syms;
Elf_Shdr *sechdrs;
int i, k;
const Elf_Sym *syms;
const char *strtab;
int i, k;

if (!pi->sechdrs || !pi->ehdr)
if (!pi->ehdr)
return NULL;

sechdrs = pi->sechdrs;
ehdr = pi->ehdr;
sechdrs = (void *)ehdr + ehdr->e_shoff;

for (i = 0; i < ehdr->e_shnum; i++) {
if (sechdrs[i].sh_type != SHT_SYMTAB)
Expand All @@ -984,8 +991,8 @@ static Elf_Sym *kexec_purgatory_find_symbol(struct purgatory_info *pi,
if (sechdrs[i].sh_link >= ehdr->e_shnum)
/* Invalid strtab section number */
continue;
strtab = (char *)sechdrs[sechdrs[i].sh_link].sh_offset;
syms = (Elf_Sym *)sechdrs[i].sh_offset;
strtab = (void *)ehdr + sechdrs[sechdrs[i].sh_link].sh_offset;
syms = (void *)ehdr + sechdrs[i].sh_offset;

/* Go through symbols for a match */
for (k = 0; k < sechdrs[i].sh_size/sizeof(Elf_Sym); k++) {
Expand Down Expand Up @@ -1013,7 +1020,7 @@ static Elf_Sym *kexec_purgatory_find_symbol(struct purgatory_info *pi,
void *kexec_purgatory_get_symbol_addr(struct kimage *image, const char *name)
{
struct purgatory_info *pi = &image->purgatory_info;
Elf_Sym *sym;
const Elf_Sym *sym;
Elf_Shdr *sechdr;

sym = kexec_purgatory_find_symbol(pi, name);
Expand All @@ -1036,9 +1043,9 @@ void *kexec_purgatory_get_symbol_addr(struct kimage *image, const char *name)
int kexec_purgatory_get_set_symbol(struct kimage *image, const char *name,
void *buf, unsigned int size, bool get_value)
{
Elf_Sym *sym;
Elf_Shdr *sechdrs;
struct purgatory_info *pi = &image->purgatory_info;
const Elf_Sym *sym;
Elf_Shdr *sec;
char *sym_buf;

sym = kexec_purgatory_find_symbol(pi, name);
Expand All @@ -1051,16 +1058,15 @@ int kexec_purgatory_get_set_symbol(struct kimage *image, const char *name,
return -EINVAL;
}

sechdrs = pi->sechdrs;
sec = pi->sechdrs + sym->st_shndx;

if (sechdrs[sym->st_shndx].sh_type == SHT_NOBITS) {
if (sec->sh_type == SHT_NOBITS) {
pr_err("symbol %s is in a bss section. Cannot %s\n", name,
get_value ? "get" : "set");
return -EINVAL;
}

sym_buf = (unsigned char *)sechdrs[sym->st_shndx].sh_offset +
sym->st_value;
sym_buf = (char *)sec->sh_offset + sym->st_value;

if (get_value)
memcpy((void *)buf, sym_buf, size);
Expand Down

0 comments on commit 961d921

Please sign in to comment.