提交 0f3e442a 编写于 作者: D David Howells

FLAT: Don't attempt to expand the userspace stack to fill the space allocated

Stop the FLAT binfmt from attempting to expand the userspace stack and brk
segments to fill the space actually allocated for it.  The space allocated may
be rounded up by mmap(), and may be wasted.

However, finding out how much space we actually obtained uses the contentious
kobjsize() function which we'd like to get rid of as it doesn't necessarily
work for all slab allocators.
Signed-off-by: NDavid Howells <dhowells@redhat.com>
Tested-by: NMike Frysinger <vapier.adi@gmail.com>
Acked-by: NPaul Mundt <lethal@linux-sh.org>
上级 f4bbf510
...@@ -417,8 +417,8 @@ static int load_flat_file(struct linux_binprm * bprm, ...@@ -417,8 +417,8 @@ static int load_flat_file(struct linux_binprm * bprm,
unsigned long textpos = 0, datapos = 0, result; unsigned long textpos = 0, datapos = 0, result;
unsigned long realdatastart = 0; unsigned long realdatastart = 0;
unsigned long text_len, data_len, bss_len, stack_len, flags; unsigned long text_len, data_len, bss_len, stack_len, flags;
unsigned long len, reallen, memp = 0; unsigned long len, memp = 0;
unsigned long extra, rlim; unsigned long memp_size, extra, rlim;
unsigned long *reloc = 0, *rp; unsigned long *reloc = 0, *rp;
struct inode *inode; struct inode *inode;
int i, rev, relocs = 0; int i, rev, relocs = 0;
...@@ -543,17 +543,10 @@ static int load_flat_file(struct linux_binprm * bprm, ...@@ -543,17 +543,10 @@ static int load_flat_file(struct linux_binprm * bprm,
} }
len = data_len + extra + MAX_SHARED_LIBS * sizeof(unsigned long); len = data_len + extra + MAX_SHARED_LIBS * sizeof(unsigned long);
len = PAGE_ALIGN(len);
down_write(&current->mm->mmap_sem); down_write(&current->mm->mmap_sem);
realdatastart = do_mmap(0, 0, len, realdatastart = do_mmap(0, 0, len,
PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, 0); PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, 0);
/* Remap to use all availabe slack region space */
if (realdatastart && (realdatastart < (unsigned long)-4096)) {
reallen = kobjsize((void *)realdatastart);
if (reallen > len) {
realdatastart = do_mremap(realdatastart, len,
reallen, MREMAP_FIXED, realdatastart);
}
}
up_write(&current->mm->mmap_sem); up_write(&current->mm->mmap_sem);
if (realdatastart == 0 || realdatastart >= (unsigned long)-4096) { if (realdatastart == 0 || realdatastart >= (unsigned long)-4096) {
...@@ -591,21 +584,14 @@ static int load_flat_file(struct linux_binprm * bprm, ...@@ -591,21 +584,14 @@ static int load_flat_file(struct linux_binprm * bprm,
reloc = (unsigned long *) (datapos+(ntohl(hdr->reloc_start)-text_len)); reloc = (unsigned long *) (datapos+(ntohl(hdr->reloc_start)-text_len));
memp = realdatastart; memp = realdatastart;
memp_size = len;
} else { } else {
len = text_len + data_len + extra + MAX_SHARED_LIBS * sizeof(unsigned long); len = text_len + data_len + extra + MAX_SHARED_LIBS * sizeof(unsigned long);
len = PAGE_ALIGN(len);
down_write(&current->mm->mmap_sem); down_write(&current->mm->mmap_sem);
textpos = do_mmap(0, 0, len, textpos = do_mmap(0, 0, len,
PROT_READ | PROT_EXEC | PROT_WRITE, MAP_PRIVATE, 0); PROT_READ | PROT_EXEC | PROT_WRITE, MAP_PRIVATE, 0);
/* Remap to use all availabe slack region space */
if (textpos && (textpos < (unsigned long) -4096)) {
reallen = kobjsize((void *)textpos);
if (reallen > len) {
textpos = do_mremap(textpos, len, reallen,
MREMAP_FIXED, textpos);
}
}
up_write(&current->mm->mmap_sem); up_write(&current->mm->mmap_sem);
if (!textpos || textpos >= (unsigned long) -4096) { if (!textpos || textpos >= (unsigned long) -4096) {
...@@ -622,7 +608,7 @@ static int load_flat_file(struct linux_binprm * bprm, ...@@ -622,7 +608,7 @@ static int load_flat_file(struct linux_binprm * bprm,
reloc = (unsigned long *) (textpos + ntohl(hdr->reloc_start) + reloc = (unsigned long *) (textpos + ntohl(hdr->reloc_start) +
MAX_SHARED_LIBS * sizeof(unsigned long)); MAX_SHARED_LIBS * sizeof(unsigned long));
memp = textpos; memp = textpos;
memp_size = len;
#ifdef CONFIG_BINFMT_ZFLAT #ifdef CONFIG_BINFMT_ZFLAT
/* /*
* load it all in and treat it like a RAM load from now on * 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,10 +666,12 @@ static int load_flat_file(struct linux_binprm * bprm,
* set up the brk stuff, uses any slack left in data/bss/stack * set up the brk stuff, uses any slack left in data/bss/stack
* allocation. We put the brk after the bss (between the bss * allocation. We put the brk after the bss (between the bss
* and stack) like other platforms. * and stack) like other platforms.
* Userspace code relies on the stack pointer starting out at
* an address right at the end of a page.
*/ */
current->mm->start_brk = datapos + data_len + bss_len; current->mm->start_brk = datapos + data_len + bss_len;
current->mm->brk = (current->mm->start_brk + 3) & ~3; current->mm->brk = (current->mm->start_brk + 3) & ~3;
current->mm->context.end_brk = memp + kobjsize((void *) memp) - stack_len; current->mm->context.end_brk = memp + memp_size - stack_len;
} }
if (flags & FLAT_FLAG_KTRACE) if (flags & FLAT_FLAG_KTRACE)
...@@ -790,8 +778,8 @@ static int load_flat_file(struct linux_binprm * bprm, ...@@ -790,8 +778,8 @@ static int load_flat_file(struct linux_binprm * bprm,
/* zero the BSS, BRK and stack areas */ /* zero the BSS, BRK and stack areas */
memset((void*)(datapos + data_len), 0, bss_len + memset((void*)(datapos + data_len), 0, bss_len +
(memp + kobjsize((void *) memp) - stack_len - /* end brk */ (memp + memp_size - stack_len - /* end brk */
libinfo->lib_list[id].start_brk) + /* start brk */ libinfo->lib_list[id].start_brk) + /* start brk */
stack_len); stack_len);
return 0; return 0;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册