summaryrefslogtreecommitdiff
blob: a37218b4ad2e27d81be11d5ce9df5c31b7b3e4bc (plain)
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: