45
45
46
46
static int load_elf_binary (struct linux_binprm * bprm , struct pt_regs * regs );
47
47
static int load_elf_library (struct file * );
48
- static unsigned long elf_map (struct file * , unsigned long , struct elf_phdr * , int , int );
48
+ static unsigned long elf_map (struct file * , unsigned long , struct elf_phdr * , int , int , unsigned long );
49
49
50
50
/*
51
51
* If we don't support core dumping, then supply a NULL so we
@@ -80,7 +80,7 @@ static struct linux_binfmt elf_format = {
80
80
.hasvdso = 1
81
81
};
82
82
83
- #define BAD_ADDR (x ) ((unsigned long)(x) >= TASK_SIZE )
83
+ #define BAD_ADDR (x ) IS_ERR_VALUE(x )
84
84
85
85
static int set_brk (unsigned long start , unsigned long end )
86
86
{
@@ -285,40 +285,78 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec,
285
285
#ifndef elf_map
286
286
287
287
static unsigned long elf_map (struct file * filep , unsigned long addr ,
288
- struct elf_phdr * eppnt , int prot , int type )
288
+ struct elf_phdr * eppnt , int prot , int type ,
289
+ unsigned long total_size )
289
290
{
290
291
unsigned long map_addr ;
291
- unsigned long pageoffset = ELF_PAGEOFFSET (eppnt -> p_vaddr );
292
+ unsigned long size = eppnt -> p_filesz + ELF_PAGEOFFSET (eppnt -> p_vaddr );
293
+ unsigned long off = eppnt -> p_offset - ELF_PAGEOFFSET (eppnt -> p_vaddr );
294
+ addr = ELF_PAGESTART (addr );
295
+ size = ELF_PAGEALIGN (size );
292
296
293
- down_write (& current -> mm -> mmap_sem );
294
297
/* mmap() will return -EINVAL if given a zero size, but a
295
298
* segment with zero filesize is perfectly valid */
296
- if (eppnt -> p_filesz + pageoffset )
297
- map_addr = do_mmap (filep , ELF_PAGESTART (addr ),
298
- eppnt -> p_filesz + pageoffset , prot , type ,
299
- eppnt -> p_offset - pageoffset );
300
- else
301
- map_addr = ELF_PAGESTART (addr );
299
+ if (!size )
300
+ return addr ;
301
+
302
+ down_write (& current -> mm -> mmap_sem );
303
+ /*
304
+ * total_size is the size of the ELF (interpreter) image.
305
+ * The _first_ mmap needs to know the full size, otherwise
306
+ * randomization might put this image into an overlapping
307
+ * position with the ELF binary image. (since size < total_size)
308
+ * So we first map the 'big' image - and unmap the remainder at
309
+ * the end. (which unmap is needed for ELF images with holes.)
310
+ */
311
+ if (total_size ) {
312
+ total_size = ELF_PAGEALIGN (total_size );
313
+ map_addr = do_mmap (filep , addr , total_size , prot , type , off );
314
+ if (!BAD_ADDR (map_addr ))
315
+ do_munmap (current -> mm , map_addr + size , total_size - size );
316
+ } else
317
+ map_addr = do_mmap (filep , addr , size , prot , type , off );
318
+
302
319
up_write (& current -> mm -> mmap_sem );
303
320
return (map_addr );
304
321
}
305
322
306
323
#endif /* !elf_map */
307
324
325
+ static unsigned long total_mapping_size (struct elf_phdr * cmds , int nr )
326
+ {
327
+ int i , first_idx = -1 , last_idx = -1 ;
328
+
329
+ for (i = 0 ; i < nr ; i ++ ) {
330
+ if (cmds [i ].p_type == PT_LOAD ) {
331
+ last_idx = i ;
332
+ if (first_idx == -1 )
333
+ first_idx = i ;
334
+ }
335
+ }
336
+ if (first_idx == -1 )
337
+ return 0 ;
338
+
339
+ return cmds [last_idx ].p_vaddr + cmds [last_idx ].p_memsz -
340
+ ELF_PAGESTART (cmds [first_idx ].p_vaddr );
341
+ }
342
+
343
+
308
344
/* This is much more generalized than the library routine read function,
309
345
so we keep this separate. Technically the library read function
310
346
is only provided so that we can read a.out libraries that have
311
347
an ELF header */
312
348
313
349
static unsigned long load_elf_interp (struct elfhdr * interp_elf_ex ,
314
- struct file * interpreter , unsigned long * interp_load_addr )
350
+ struct file * interpreter , unsigned long * interp_map_addr ,
351
+ unsigned long no_base )
315
352
{
316
353
struct elf_phdr * elf_phdata ;
317
354
struct elf_phdr * eppnt ;
318
355
unsigned long load_addr = 0 ;
319
356
int load_addr_set = 0 ;
320
357
unsigned long last_bss = 0 , elf_bss = 0 ;
321
358
unsigned long error = ~0UL ;
359
+ unsigned long total_size ;
322
360
int retval , i , size ;
323
361
324
362
/* First of all, some simple consistency checks */
@@ -357,6 +395,12 @@ static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex,
357
395
goto out_close ;
358
396
}
359
397
398
+ total_size = total_mapping_size (elf_phdata , interp_elf_ex -> e_phnum );
399
+ if (!total_size ) {
400
+ error = - EINVAL ;
401
+ goto out_close ;
402
+ }
403
+
360
404
eppnt = elf_phdata ;
361
405
for (i = 0 ; i < interp_elf_ex -> e_phnum ; i ++ , eppnt ++ ) {
362
406
if (eppnt -> p_type == PT_LOAD ) {
@@ -374,9 +418,14 @@ static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex,
374
418
vaddr = eppnt -> p_vaddr ;
375
419
if (interp_elf_ex -> e_type == ET_EXEC || load_addr_set )
376
420
elf_type |= MAP_FIXED ;
421
+ else if (no_base && interp_elf_ex -> e_type == ET_DYN )
422
+ load_addr = - vaddr ;
377
423
378
424
map_addr = elf_map (interpreter , load_addr + vaddr ,
379
- eppnt , elf_prot , elf_type );
425
+ eppnt , elf_prot , elf_type , total_size );
426
+ total_size = 0 ;
427
+ if (!* interp_map_addr )
428
+ * interp_map_addr = map_addr ;
380
429
error = map_addr ;
381
430
if (BAD_ADDR (map_addr ))
382
431
goto out_close ;
@@ -442,8 +491,7 @@ static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex,
442
491
goto out_close ;
443
492
}
444
493
445
- * interp_load_addr = load_addr ;
446
- error = ((unsigned long )interp_elf_ex -> e_entry ) + load_addr ;
494
+ error = load_addr ;
447
495
448
496
out_close :
449
497
kfree (elf_phdata );
@@ -540,7 +588,8 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
540
588
int elf_exec_fileno ;
541
589
int retval , i ;
542
590
unsigned int size ;
543
- unsigned long elf_entry , interp_load_addr = 0 ;
591
+ unsigned long elf_entry ;
592
+ unsigned long interp_load_addr = 0 ;
544
593
unsigned long start_code , end_code , start_data , end_data ;
545
594
unsigned long reloc_func_desc = 0 ;
546
595
char passed_fileno [6 ];
@@ -808,9 +857,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
808
857
current -> mm -> start_stack = bprm -> p ;
809
858
810
859
/* Now we do a little grungy work by mmaping the ELF image into
811
- the correct location in memory. At this point, we assume that
812
- the image should be loaded at fixed address, not at a variable
813
- address. */
860
+ the correct location in memory. */
814
861
for (i = 0 , elf_ppnt = elf_phdata ;
815
862
i < loc -> elf_ex .e_phnum ; i ++ , elf_ppnt ++ ) {
816
863
int elf_prot = 0 , elf_flags ;
@@ -864,11 +911,15 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
864
911
* default mmap base, as well as whatever program they
865
912
* might try to exec. This is because the brk will
866
913
* follow the loader, and is not movable. */
914
+ #ifdef CONFIG_X86
915
+ load_bias = 0 ;
916
+ #else
867
917
load_bias = ELF_PAGESTART (ELF_ET_DYN_BASE - vaddr );
918
+ #endif
868
919
}
869
920
870
921
error = elf_map (bprm -> file , load_bias + vaddr , elf_ppnt ,
871
- elf_prot , elf_flags );
922
+ elf_prot , elf_flags , 0 );
872
923
if (BAD_ADDR (error )) {
873
924
send_sig (SIGKILL , current , 0 );
874
925
retval = IS_ERR ((void * )error ) ?
@@ -944,13 +995,25 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
944
995
}
945
996
946
997
if (elf_interpreter ) {
947
- if (interpreter_type == INTERPRETER_AOUT )
998
+ if (interpreter_type == INTERPRETER_AOUT ) {
948
999
elf_entry = load_aout_interp (& loc -> interp_ex ,
949
1000
interpreter );
950
- else
1001
+ } else {
1002
+ unsigned long interp_map_addr ; /* unused */
1003
+
951
1004
elf_entry = load_elf_interp (& loc -> interp_elf_ex ,
952
1005
interpreter ,
953
- & interp_load_addr );
1006
+ & interp_map_addr ,
1007
+ load_bias );
1008
+ if (!BAD_ADDR (elf_entry )) {
1009
+ /*
1010
+ * load_elf_interp() returns relocation
1011
+ * adjustment
1012
+ */
1013
+ interp_load_addr = elf_entry ;
1014
+ elf_entry += loc -> interp_elf_ex .e_entry ;
1015
+ }
1016
+ }
954
1017
if (BAD_ADDR (elf_entry )) {
955
1018
force_sig (SIGSEGV , current );
956
1019
retval = IS_ERR ((void * )elf_entry ) ?
0 commit comments