7
7
* Author(s): Philipp Rudo <[email protected] >
8
8
*/
9
9
10
+ #define pr_fmt (fmt ) "kexec: " fmt
11
+
10
12
#include <linux/elf.h>
11
13
#include <linux/errno.h>
12
14
#include <linux/kexec.h>
@@ -290,9 +292,16 @@ int arch_kexec_apply_relocations_add(struct purgatory_info *pi,
290
292
const Elf_Shdr * relsec ,
291
293
const Elf_Shdr * symtab )
292
294
{
295
+ const char * strtab , * name , * shstrtab ;
296
+ const Elf_Shdr * sechdrs ;
293
297
Elf_Rela * relas ;
294
298
int i , r_type ;
295
299
300
+ /* String & section header string table */
301
+ sechdrs = (void * )pi -> ehdr + pi -> ehdr -> e_shoff ;
302
+ strtab = (char * )pi -> ehdr + sechdrs [symtab -> sh_link ].sh_offset ;
303
+ shstrtab = (char * )pi -> ehdr + sechdrs [pi -> ehdr -> e_shstrndx ].sh_offset ;
304
+
296
305
relas = (void * )pi -> ehdr + relsec -> sh_offset ;
297
306
298
307
for (i = 0 ; i < relsec -> sh_size / sizeof (* relas ); i ++ ) {
@@ -304,15 +313,27 @@ int arch_kexec_apply_relocations_add(struct purgatory_info *pi,
304
313
sym = (void * )pi -> ehdr + symtab -> sh_offset ;
305
314
sym += ELF64_R_SYM (relas [i ].r_info );
306
315
307
- if (sym -> st_shndx == SHN_UNDEF )
316
+ if (sym -> st_name )
317
+ name = strtab + sym -> st_name ;
318
+ else
319
+ name = shstrtab + sechdrs [sym -> st_shndx ].sh_name ;
320
+
321
+ if (sym -> st_shndx == SHN_UNDEF ) {
322
+ pr_err ("Undefined symbol: %s\n" , name );
308
323
return - ENOEXEC ;
324
+ }
309
325
310
- if (sym -> st_shndx == SHN_COMMON )
326
+ if (sym -> st_shndx == SHN_COMMON ) {
327
+ pr_err ("symbol '%s' in common section\n" , name );
311
328
return - ENOEXEC ;
329
+ }
312
330
313
331
if (sym -> st_shndx >= pi -> ehdr -> e_shnum &&
314
- sym -> st_shndx != SHN_ABS )
332
+ sym -> st_shndx != SHN_ABS ) {
333
+ pr_err ("Invalid section %d for symbol %s\n" ,
334
+ sym -> st_shndx , name );
315
335
return - ENOEXEC ;
336
+ }
316
337
317
338
loc = pi -> purgatory_buf ;
318
339
loc += section -> sh_offset ;
0 commit comments