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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
diff -urN 2.4.11pre3/fs/binfmt_elf.c elf/fs/binfmt_elf.c
--- 2.4.11pre3/fs/binfmt_elf.c Thu Oct 4 10:06:57 2001
+++ elf/fs/binfmt_elf.c Thu Oct 4 18:23:34 2001
@@ -78,13 +78,13 @@
#define BAD_ADDR(x) ((unsigned long)(x) > TASK_SIZE)
-static void set_brk(unsigned long start, unsigned long end)
+static unsigned long set_brk(unsigned long start, unsigned long end)
{
start = ELF_PAGEALIGN(start);
end = ELF_PAGEALIGN(end);
if (end <= start)
- return;
- do_brk(start, end - start);
+ return 0;
+ return do_brk(start, end - start);
}
@@ -300,6 +300,7 @@
elf_type |= MAP_FIXED;
map_addr = elf_map(interpreter, load_addr + vaddr, eppnt, elf_prot, elf_type);
+ error = map_addr;
if (BAD_ADDR(map_addr))
goto out_close;
@@ -338,8 +339,11 @@
elf_bss = ELF_PAGESTART(elf_bss + ELF_MIN_ALIGN - 1); /* What we have mapped so far */
/* Map the last of the bss segment */
- if (last_bss > elf_bss)
- do_brk(elf_bss, last_bss - elf_bss);
+ if (last_bss > elf_bss) {
+ error = do_brk(elf_bss, last_bss - elf_bss);
+ if (BAD_ADDR(error))
+ goto out_close;
+ }
*interp_load_addr = load_addr;
error = ((unsigned long) interp_elf_ex->e_entry) + load_addr;
@@ -626,7 +630,11 @@
/* There was a PT_LOAD segment with p_memsz > p_filesz
before this one. Map anonymous pages, if needed,
and clear the area. */
- set_brk (elf_bss + load_bias, elf_brk + load_bias);
+ error = set_brk (elf_bss + load_bias, elf_brk + load_bias);
+ /* here retval is zero */
+ if (BAD_ADDR(error))
+ goto out_free_dentry;
+
nbyte = ELF_PAGEOFFSET(elf_bss);
if (nbyte) {
nbyte = ELF_MIN_ALIGN - nbyte;
@@ -653,8 +661,9 @@
}
error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, elf_prot, elf_flags);
+ /* here retval is zero */
if (BAD_ADDR(error))
- continue;
+ goto out_free_dentry;
if (!load_addr_set) {
load_addr_set = 1;
@@ -703,11 +712,10 @@
fput(interpreter);
kfree(elf_interpreter);
+ /* here retval is zero */
if (BAD_ADDR(elf_entry)) {
- printk(KERN_ERR "Unable to load interpreter\n");
- kfree(elf_phdata);
- send_sig(SIGSEGV, current, 0);
- return 0;
+ printk(KERN_WARNING "Unable to load interpreter\n");
+ goto out_free_ph;
}
}
@@ -741,7 +749,10 @@
/* Calling set_brk effectively mmaps the pages that we need
* for the bss and break sections
*/
- set_brk(elf_bss, elf_brk);
+ error = set_brk(elf_bss, elf_brk);
+ /* here retval is zero */
+ if (BAD_ADDR(error))
+ goto out;
padzero(elf_bss);
@@ -781,14 +792,15 @@
start_thread(regs, elf_entry, bprm->p);
if (current->ptrace & PT_PTRACED)
send_sig(SIGTRAP, current, 0);
- retval = 0;
+ /* here retval is zero */
out:
return retval;
/* error cleanup */
out_free_dentry:
allow_write_access(interpreter);
- fput(interpreter);
+ if (interpreter)
+ fput(interpreter);
out_free_interp:
if (elf_interpreter)
kfree(elf_interpreter);
@@ -866,8 +878,11 @@
len = ELF_PAGESTART(elf_phdata->p_filesz + elf_phdata->p_vaddr + ELF_MIN_ALIGN - 1);
bss = elf_phdata->p_memsz + elf_phdata->p_vaddr;
- if (bss > len)
- do_brk(len, bss - len);
+ if (bss > len) {
+ error = do_brk(len, bss - len);
+ if (BAD_ADDR(error))
+ goto out_free_ph;
+ }
error = 0;
out_free_ph:
|