diff options
Diffstat (limited to 'fs/binfmt_flat.c')
| -rw-r--r-- | fs/binfmt_flat.c | 34 |
1 files changed, 11 insertions, 23 deletions
diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c index 7bbd5c6b3725..5cebf0b37798 100644 --- a/fs/binfmt_flat.c +++ b/fs/binfmt_flat.c | |||
| @@ -417,8 +417,8 @@ static int load_flat_file(struct linux_binprm * bprm, | |||
| 417 | unsigned long textpos = 0, datapos = 0, result; | 417 | unsigned long textpos = 0, datapos = 0, result; |
| 418 | unsigned long realdatastart = 0; | 418 | unsigned long realdatastart = 0; |
| 419 | unsigned long text_len, data_len, bss_len, stack_len, flags; | 419 | unsigned long text_len, data_len, bss_len, stack_len, flags; |
| 420 | unsigned long len, reallen, memp = 0; | 420 | unsigned long len, memp = 0; |
| 421 | unsigned long extra, rlim; | 421 | unsigned long memp_size, extra, rlim; |
| 422 | unsigned long *reloc = 0, *rp; | 422 | unsigned long *reloc = 0, *rp; |
| 423 | struct inode *inode; | 423 | struct inode *inode; |
| 424 | int i, rev, relocs = 0; | 424 | int i, rev, relocs = 0; |
| @@ -543,17 +543,10 @@ static int load_flat_file(struct linux_binprm * bprm, | |||
| 543 | } | 543 | } |
| 544 | 544 | ||
| 545 | len = data_len + extra + MAX_SHARED_LIBS * sizeof(unsigned long); | 545 | len = data_len + extra + MAX_SHARED_LIBS * sizeof(unsigned long); |
| 546 | len = PAGE_ALIGN(len); | ||
| 546 | down_write(¤t->mm->mmap_sem); | 547 | down_write(¤t->mm->mmap_sem); |
| 547 | realdatastart = do_mmap(0, 0, len, | 548 | realdatastart = do_mmap(0, 0, len, |
| 548 | PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, 0); | 549 | PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, 0); |
| 549 | /* Remap to use all availabe slack region space */ | ||
| 550 | if (realdatastart && (realdatastart < (unsigned long)-4096)) { | ||
| 551 | reallen = kobjsize((void *)realdatastart); | ||
| 552 | if (reallen > len) { | ||
| 553 | realdatastart = do_mremap(realdatastart, len, | ||
| 554 | reallen, MREMAP_FIXED, realdatastart); | ||
| 555 | } | ||
| 556 | } | ||
| 557 | up_write(¤t->mm->mmap_sem); | 550 | up_write(¤t->mm->mmap_sem); |
| 558 | 551 | ||
| 559 | if (realdatastart == 0 || realdatastart >= (unsigned long)-4096) { | 552 | if (realdatastart == 0 || realdatastart >= (unsigned long)-4096) { |
| @@ -591,21 +584,14 @@ static int load_flat_file(struct linux_binprm * bprm, | |||
| 591 | 584 | ||
| 592 | reloc = (unsigned long *) (datapos+(ntohl(hdr->reloc_start)-text_len)); | 585 | reloc = (unsigned long *) (datapos+(ntohl(hdr->reloc_start)-text_len)); |
| 593 | memp = realdatastart; | 586 | memp = realdatastart; |
| 594 | 587 | memp_size = len; | |
| 595 | } else { | 588 | } else { |
| 596 | 589 | ||
| 597 | len = text_len + data_len + extra + MAX_SHARED_LIBS * sizeof(unsigned long); | 590 | len = text_len + data_len + extra + MAX_SHARED_LIBS * sizeof(unsigned long); |
| 591 | len = PAGE_ALIGN(len); | ||
| 598 | down_write(¤t->mm->mmap_sem); | 592 | down_write(¤t->mm->mmap_sem); |
| 599 | textpos = do_mmap(0, 0, len, | 593 | textpos = do_mmap(0, 0, len, |
| 600 | PROT_READ | PROT_EXEC | PROT_WRITE, MAP_PRIVATE, 0); | 594 | PROT_READ | PROT_EXEC | PROT_WRITE, MAP_PRIVATE, 0); |
| 601 | /* Remap to use all availabe slack region space */ | ||
| 602 | if (textpos && (textpos < (unsigned long) -4096)) { | ||
| 603 | reallen = kobjsize((void *)textpos); | ||
| 604 | if (reallen > len) { | ||
| 605 | textpos = do_mremap(textpos, len, reallen, | ||
| 606 | MREMAP_FIXED, textpos); | ||
| 607 | } | ||
| 608 | } | ||
| 609 | up_write(¤t->mm->mmap_sem); | 595 | up_write(¤t->mm->mmap_sem); |
| 610 | 596 | ||
| 611 | if (!textpos || textpos >= (unsigned long) -4096) { | 597 | if (!textpos || textpos >= (unsigned long) -4096) { |
| @@ -622,7 +608,7 @@ static int load_flat_file(struct linux_binprm * bprm, | |||
| 622 | reloc = (unsigned long *) (textpos + ntohl(hdr->reloc_start) + | 608 | reloc = (unsigned long *) (textpos + ntohl(hdr->reloc_start) + |
| 623 | MAX_SHARED_LIBS * sizeof(unsigned long)); | 609 | MAX_SHARED_LIBS * sizeof(unsigned long)); |
| 624 | memp = textpos; | 610 | memp = textpos; |
| 625 | 611 | memp_size = len; | |
| 626 | #ifdef CONFIG_BINFMT_ZFLAT | 612 | #ifdef CONFIG_BINFMT_ZFLAT |
| 627 | /* | 613 | /* |
| 628 | * load it all in and treat it like a RAM load from now on | 614 | * load it all in and treat it like a RAM load from now on |
| @@ -680,10 +666,12 @@ static int load_flat_file(struct linux_binprm * bprm, | |||
| 680 | * set up the brk stuff, uses any slack left in data/bss/stack | 666 | * set up the brk stuff, uses any slack left in data/bss/stack |
| 681 | * allocation. We put the brk after the bss (between the bss | 667 | * allocation. We put the brk after the bss (between the bss |
| 682 | * and stack) like other platforms. | 668 | * and stack) like other platforms. |
| 669 | * Userspace code relies on the stack pointer starting out at | ||
| 670 | * an address right at the end of a page. | ||
| 683 | */ | 671 | */ |
| 684 | current->mm->start_brk = datapos + data_len + bss_len; | 672 | current->mm->start_brk = datapos + data_len + bss_len; |
| 685 | current->mm->brk = (current->mm->start_brk + 3) & ~3; | 673 | current->mm->brk = (current->mm->start_brk + 3) & ~3; |
| 686 | current->mm->context.end_brk = memp + kobjsize((void *) memp) - stack_len; | 674 | current->mm->context.end_brk = memp + memp_size - stack_len; |
| 687 | } | 675 | } |
| 688 | 676 | ||
| 689 | if (flags & FLAT_FLAG_KTRACE) | 677 | if (flags & FLAT_FLAG_KTRACE) |
| @@ -790,8 +778,8 @@ static int load_flat_file(struct linux_binprm * bprm, | |||
| 790 | 778 | ||
| 791 | /* zero the BSS, BRK and stack areas */ | 779 | /* zero the BSS, BRK and stack areas */ |
| 792 | memset((void*)(datapos + data_len), 0, bss_len + | 780 | memset((void*)(datapos + data_len), 0, bss_len + |
| 793 | (memp + kobjsize((void *) memp) - stack_len - /* end brk */ | 781 | (memp + memp_size - stack_len - /* end brk */ |
| 794 | libinfo->lib_list[id].start_brk) + /* start brk */ | 782 | libinfo->lib_list[id].start_brk) + /* start brk */ |
| 795 | stack_len); | 783 | stack_len); |
| 796 | 784 | ||
| 797 | return 0; | 785 | return 0; |
