1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
diff -uNr linux-2.6.8.1-pa11-r2.orig/fs/binfmt_aout.c linux-2.6.8.1-pa11-r2/fs/binfmt_aout.c
--- linux-2.6.8.1-pa11-r2.orig/fs/binfmt_aout.c 2004-12-09 14:43:33.191733360 +0100
+++ linux-2.6.8.1-pa11-r2/fs/binfmt_aout.c 2004-12-09 14:48:40.065081520 +0100
@@ -43,13 +43,18 @@
.min_coredump = PAGE_SIZE
};
-static void set_brk(unsigned long start, unsigned long end)
+#define BAD_ADDR(x) ((unsigned long)(x) >= TASK_SIZE)
+
+static int set_brk(unsigned long start, unsigned long end)
{
start = PAGE_ALIGN(start);
end = PAGE_ALIGN(end);
- if (end <= start)
- return;
- do_brk(start, end - start);
+ if (end > start) {
+ unsigned long addr = do_brk(start, end - start);
+ if (BAD_ADDR(addr))
+ return addr;
+ }
+ return 0;
}
/*
@@ -413,7 +418,12 @@
beyond_if:
set_binfmt(&aout_format);
- set_brk(current->mm->start_brk, current->mm->brk);
+
+ retval = set_brk(current->mm->start_brk, current->mm->brk);
+ if (retval < 0) {
+ send_sig(SIGKILL, current, 0);
+ return retval;
+ }
retval = setup_arg_pages(bprm, EXSTACK_DEFAULT);
if (retval < 0) {
diff -uNr linux-2.6.8.1-pa11-r2.orig/fs/exec.c linux-2.6.8.1-pa11-r2/fs/exec.c
--- linux-2.6.8.1-pa11-r2.orig/fs/exec.c 2004-12-09 14:43:33.247724848 +0100
+++ linux-2.6.8.1-pa11-r2/fs/exec.c 2004-12-09 14:46:24.696660648 +0100
@@ -412,6 +412,7 @@
down_write(&mm->mmap_sem);
{
+ struct vm_area_struct *vma;
mpnt->vm_mm = mm;
#ifdef CONFIG_STACK_GROWSUP
mpnt->vm_start = stack_base;
@@ -432,6 +433,12 @@
mpnt->vm_flags = VM_STACK_FLAGS;
mpnt->vm_flags |= mm->def_flags;
mpnt->vm_page_prot = protection_map[mpnt->vm_flags & 0x7];
+ vma = find_vma(mm, mpnt->vm_start);
+ if (vma) {
+ up_write(&mm->mmap_sem);
+ kmem_cache_free(vm_area_cachep, mpnt);
+ return -ENOMEM;
+ }
insert_vm_struct(mm, mpnt);
mm->total_vm = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT;
}
|