aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/binfmt_flat.c31
1 files changed, 24 insertions, 7 deletions
diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c
index ae8595d49856..7b0265d7f3a8 100644
--- a/fs/binfmt_flat.c
+++ b/fs/binfmt_flat.c
@@ -419,7 +419,7 @@ static int load_flat_file(struct linux_binprm * bprm,
419 unsigned long textpos = 0, datapos = 0, result; 419 unsigned long textpos = 0, datapos = 0, result;
420 unsigned long realdatastart = 0; 420 unsigned long realdatastart = 0;
421 unsigned long text_len, data_len, bss_len, stack_len, flags; 421 unsigned long text_len, data_len, bss_len, stack_len, flags;
422 unsigned long memp = 0; /* for finding the brk area */ 422 unsigned long len, reallen, memp = 0;
423 unsigned long extra, rlim; 423 unsigned long extra, rlim;
424 unsigned long *reloc = 0, *rp; 424 unsigned long *reloc = 0, *rp;
425 struct inode *inode; 425 struct inode *inode;
@@ -540,10 +540,18 @@ static int load_flat_file(struct linux_binprm * bprm,
540 goto err; 540 goto err;
541 } 541 }
542 542
543 len = data_len + extra + MAX_SHARED_LIBS * sizeof(unsigned long);
543 down_write(&current->mm->mmap_sem); 544 down_write(&current->mm->mmap_sem);
544 realdatastart = do_mmap(0, 0, data_len + extra + 545 realdatastart = do_mmap(0, 0, len,
545 MAX_SHARED_LIBS * sizeof(unsigned long), 546 PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, 0);
546 PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, 0); 547 /* Remap to use all availabe slack region space */
548 if (realdatastart && (realdatastart < (unsigned long)-4096)) {
549 reallen = ksize(realdatastart);
550 if (reallen > len) {
551 realdatastart = do_mremap(realdatastart, len,
552 reallen, MREMAP_FIXED, realdatastart);
553 }
554 }
547 up_write(&current->mm->mmap_sem); 555 up_write(&current->mm->mmap_sem);
548 556
549 if (realdatastart == 0 || realdatastart >= (unsigned long)-4096) { 557 if (realdatastart == 0 || realdatastart >= (unsigned long)-4096) {
@@ -584,11 +592,20 @@ static int load_flat_file(struct linux_binprm * bprm,
584 592
585 } else { 593 } else {
586 594
595 len = text_len + data_len + extra + MAX_SHARED_LIBS * sizeof(unsigned long);
587 down_write(&current->mm->mmap_sem); 596 down_write(&current->mm->mmap_sem);
588 textpos = do_mmap(0, 0, text_len + data_len + extra + 597 textpos = do_mmap(0, 0, len,
589 MAX_SHARED_LIBS * sizeof(unsigned long), 598 PROT_READ | PROT_EXEC | PROT_WRITE, MAP_PRIVATE, 0);
590 PROT_READ | PROT_EXEC | PROT_WRITE, MAP_PRIVATE, 0); 599 /* Remap to use all availabe slack region space */
600 if (textpos && (textpos < (unsigned long) -4096)) {
601 reallen = ksize(textpos);
602 if (reallen > len) {
603 textpos = do_mremap(textpos, len, reallen,
604 MREMAP_FIXED, textpos);
605 }
606 }
591 up_write(&current->mm->mmap_sem); 607 up_write(&current->mm->mmap_sem);
608
592 if (!textpos || textpos >= (unsigned long) -4096) { 609 if (!textpos || textpos >= (unsigned long) -4096) {
593 if (!textpos) 610 if (!textpos)
594 textpos = (unsigned long) -ENOMEM; 611 textpos = (unsigned long) -ENOMEM;