aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Ungerer <gerg@snapgear.com>2007-02-06 21:03:08 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-02-09 13:45:33 -0500
commit72613e5f44adf2fe2684a5f1c1b62c2ee9984f40 (patch)
tree14cb1a018093cd1b5a0924850d36106cc0cd40d9
parentc051b01129560ea02ea2cebdf00db0721cc9a618 (diff)
[PATCH] uclinux: correctly remap bin_fmtflat exe allocated mem regions
remap() the region we get from mmap() to mark the fact that we are using all of the available slack space. Any slack space is used to form a simple brk region, and potentially more stack space than requested at load time. Any searches of the vma chain may well fail looking for stack (and especially arg) addresses if the remaping is not done. The simplest example is /proc/<pid>/cmdline, since the args are pretty much always at the top of the data/bss/stack region. Signed-off-by: Greg Ungerer <gerg@uclinux.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-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;