diff options
| -rw-r--r-- | fs/binfmt_flat.c | 31 |
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(¤t->mm->mmap_sem); | 544 | down_write(¤t->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(¤t->mm->mmap_sem); | 555 | up_write(¤t->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(¤t->mm->mmap_sem); | 596 | down_write(¤t->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(¤t->mm->mmap_sem); | 607 | up_write(¤t->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; |
