diff options
Diffstat (limited to 'fs/binfmt_aout.c')
-rw-r--r-- | fs/binfmt_aout.c | 68 |
1 files changed, 29 insertions, 39 deletions
diff --git a/fs/binfmt_aout.c b/fs/binfmt_aout.c index b639dcf7c778..f96eff04e11a 100644 --- a/fs/binfmt_aout.c +++ b/fs/binfmt_aout.c | |||
@@ -20,10 +20,11 @@ | |||
20 | #include <linux/fcntl.h> | 20 | #include <linux/fcntl.h> |
21 | #include <linux/ptrace.h> | 21 | #include <linux/ptrace.h> |
22 | #include <linux/user.h> | 22 | #include <linux/user.h> |
23 | #include <linux/slab.h> | ||
24 | #include <linux/binfmts.h> | 23 | #include <linux/binfmts.h> |
25 | #include <linux/personality.h> | 24 | #include <linux/personality.h> |
26 | #include <linux/init.h> | 25 | #include <linux/init.h> |
26 | #include <linux/coredump.h> | ||
27 | #include <linux/slab.h> | ||
27 | 28 | ||
28 | #include <asm/system.h> | 29 | #include <asm/system.h> |
29 | #include <asm/uaccess.h> | 30 | #include <asm/uaccess.h> |
@@ -32,7 +33,7 @@ | |||
32 | 33 | ||
33 | static int load_aout_binary(struct linux_binprm *, struct pt_regs * regs); | 34 | static int load_aout_binary(struct linux_binprm *, struct pt_regs * regs); |
34 | static int load_aout_library(struct file*); | 35 | static int load_aout_library(struct file*); |
35 | static int aout_core_dump(long signr, struct pt_regs *regs, struct file *file, unsigned long limit); | 36 | static int aout_core_dump(struct coredump_params *cprm); |
36 | 37 | ||
37 | static struct linux_binfmt aout_format = { | 38 | static struct linux_binfmt aout_format = { |
38 | .module = THIS_MODULE, | 39 | .module = THIS_MODULE, |
@@ -60,26 +61,6 @@ static int set_brk(unsigned long start, unsigned long end) | |||
60 | } | 61 | } |
61 | 62 | ||
62 | /* | 63 | /* |
63 | * These are the only things you should do on a core-file: use only these | ||
64 | * macros to write out all the necessary info. | ||
65 | */ | ||
66 | |||
67 | static int dump_write(struct file *file, const void *addr, int nr) | ||
68 | { | ||
69 | return file->f_op->write(file, addr, nr, &file->f_pos) == nr; | ||
70 | } | ||
71 | |||
72 | #define DUMP_WRITE(addr, nr) \ | ||
73 | if (!dump_write(file, (void *)(addr), (nr))) \ | ||
74 | goto end_coredump; | ||
75 | |||
76 | #define DUMP_SEEK(offset) \ | ||
77 | if (file->f_op->llseek) { \ | ||
78 | if (file->f_op->llseek(file,(offset),0) != (offset)) \ | ||
79 | goto end_coredump; \ | ||
80 | } else file->f_pos = (offset) | ||
81 | |||
82 | /* | ||
83 | * Routine writes a core dump image in the current directory. | 64 | * Routine writes a core dump image in the current directory. |
84 | * Currently only a stub-function. | 65 | * Currently only a stub-function. |
85 | * | 66 | * |
@@ -89,18 +70,21 @@ if (file->f_op->llseek) { \ | |||
89 | * dumping of the process results in another error.. | 70 | * dumping of the process results in another error.. |
90 | */ | 71 | */ |
91 | 72 | ||
92 | static int aout_core_dump(long signr, struct pt_regs *regs, struct file *file, unsigned long limit) | 73 | static int aout_core_dump(struct coredump_params *cprm) |
93 | { | 74 | { |
75 | struct file *file = cprm->file; | ||
94 | mm_segment_t fs; | 76 | mm_segment_t fs; |
95 | int has_dumped = 0; | 77 | int has_dumped = 0; |
96 | unsigned long dump_start, dump_size; | 78 | void __user *dump_start; |
79 | int dump_size; | ||
97 | struct user dump; | 80 | struct user dump; |
98 | #ifdef __alpha__ | 81 | #ifdef __alpha__ |
99 | # define START_DATA(u) (u.start_data) | 82 | # define START_DATA(u) ((void __user *)u.start_data) |
100 | #else | 83 | #else |
101 | # define START_DATA(u) ((u.u_tsize << PAGE_SHIFT) + u.start_code) | 84 | # define START_DATA(u) ((void __user *)((u.u_tsize << PAGE_SHIFT) + \ |
85 | u.start_code)) | ||
102 | #endif | 86 | #endif |
103 | # define START_STACK(u) (u.start_stack) | 87 | # define START_STACK(u) ((void __user *)u.start_stack) |
104 | 88 | ||
105 | fs = get_fs(); | 89 | fs = get_fs(); |
106 | set_fs(KERNEL_DS); | 90 | set_fs(KERNEL_DS); |
@@ -108,47 +92,52 @@ static int aout_core_dump(long signr, struct pt_regs *regs, struct file *file, u | |||
108 | current->flags |= PF_DUMPCORE; | 92 | current->flags |= PF_DUMPCORE; |
109 | strncpy(dump.u_comm, current->comm, sizeof(dump.u_comm)); | 93 | strncpy(dump.u_comm, current->comm, sizeof(dump.u_comm)); |
110 | dump.u_ar0 = offsetof(struct user, regs); | 94 | dump.u_ar0 = offsetof(struct user, regs); |
111 | dump.signal = signr; | 95 | dump.signal = cprm->signr; |
112 | aout_dump_thread(regs, &dump); | 96 | aout_dump_thread(cprm->regs, &dump); |
113 | 97 | ||
114 | /* If the size of the dump file exceeds the rlimit, then see what would happen | 98 | /* If the size of the dump file exceeds the rlimit, then see what would happen |
115 | if we wrote the stack, but not the data area. */ | 99 | if we wrote the stack, but not the data area. */ |
116 | if ((dump.u_dsize + dump.u_ssize+1) * PAGE_SIZE > limit) | 100 | if ((dump.u_dsize + dump.u_ssize+1) * PAGE_SIZE > cprm->limit) |
117 | dump.u_dsize = 0; | 101 | dump.u_dsize = 0; |
118 | 102 | ||
119 | /* Make sure we have enough room to write the stack and data areas. */ | 103 | /* Make sure we have enough room to write the stack and data areas. */ |
120 | if ((dump.u_ssize + 1) * PAGE_SIZE > limit) | 104 | if ((dump.u_ssize + 1) * PAGE_SIZE > cprm->limit) |
121 | dump.u_ssize = 0; | 105 | dump.u_ssize = 0; |
122 | 106 | ||
123 | /* make sure we actually have a data and stack area to dump */ | 107 | /* make sure we actually have a data and stack area to dump */ |
124 | set_fs(USER_DS); | 108 | set_fs(USER_DS); |
125 | if (!access_ok(VERIFY_READ, (void __user *)START_DATA(dump), dump.u_dsize << PAGE_SHIFT)) | 109 | if (!access_ok(VERIFY_READ, START_DATA(dump), dump.u_dsize << PAGE_SHIFT)) |
126 | dump.u_dsize = 0; | 110 | dump.u_dsize = 0; |
127 | if (!access_ok(VERIFY_READ, (void __user *)START_STACK(dump), dump.u_ssize << PAGE_SHIFT)) | 111 | if (!access_ok(VERIFY_READ, START_STACK(dump), dump.u_ssize << PAGE_SHIFT)) |
128 | dump.u_ssize = 0; | 112 | dump.u_ssize = 0; |
129 | 113 | ||
130 | set_fs(KERNEL_DS); | 114 | set_fs(KERNEL_DS); |
131 | /* struct user */ | 115 | /* struct user */ |
132 | DUMP_WRITE(&dump,sizeof(dump)); | 116 | if (!dump_write(file, &dump, sizeof(dump))) |
117 | goto end_coredump; | ||
133 | /* Now dump all of the user data. Include malloced stuff as well */ | 118 | /* Now dump all of the user data. Include malloced stuff as well */ |
134 | DUMP_SEEK(PAGE_SIZE); | 119 | if (!dump_seek(cprm->file, PAGE_SIZE - sizeof(dump))) |
120 | goto end_coredump; | ||
135 | /* now we start writing out the user space info */ | 121 | /* now we start writing out the user space info */ |
136 | set_fs(USER_DS); | 122 | set_fs(USER_DS); |
137 | /* Dump the data area */ | 123 | /* Dump the data area */ |
138 | if (dump.u_dsize != 0) { | 124 | if (dump.u_dsize != 0) { |
139 | dump_start = START_DATA(dump); | 125 | dump_start = START_DATA(dump); |
140 | dump_size = dump.u_dsize << PAGE_SHIFT; | 126 | dump_size = dump.u_dsize << PAGE_SHIFT; |
141 | DUMP_WRITE(dump_start,dump_size); | 127 | if (!dump_write(file, dump_start, dump_size)) |
128 | goto end_coredump; | ||
142 | } | 129 | } |
143 | /* Now prepare to dump the stack area */ | 130 | /* Now prepare to dump the stack area */ |
144 | if (dump.u_ssize != 0) { | 131 | if (dump.u_ssize != 0) { |
145 | dump_start = START_STACK(dump); | 132 | dump_start = START_STACK(dump); |
146 | dump_size = dump.u_ssize << PAGE_SHIFT; | 133 | dump_size = dump.u_ssize << PAGE_SHIFT; |
147 | DUMP_WRITE(dump_start,dump_size); | 134 | if (!dump_write(file, dump_start, dump_size)) |
135 | goto end_coredump; | ||
148 | } | 136 | } |
149 | /* Finally dump the task struct. Not be used by gdb, but could be useful */ | 137 | /* Finally dump the task struct. Not be used by gdb, but could be useful */ |
150 | set_fs(KERNEL_DS); | 138 | set_fs(KERNEL_DS); |
151 | DUMP_WRITE(current,sizeof(*current)); | 139 | if (!dump_write(file, current, sizeof(*current))) |
140 | goto end_coredump; | ||
152 | end_coredump: | 141 | end_coredump: |
153 | set_fs(fs); | 142 | set_fs(fs); |
154 | return has_dumped; | 143 | return has_dumped; |
@@ -246,7 +235,7 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs) | |||
246 | * size limits imposed on them by creating programs with large | 235 | * size limits imposed on them by creating programs with large |
247 | * arrays in the data or bss. | 236 | * arrays in the data or bss. |
248 | */ | 237 | */ |
249 | rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur; | 238 | rlim = rlimit(RLIMIT_DATA); |
250 | if (rlim >= RLIM_INFINITY) | 239 | if (rlim >= RLIM_INFINITY) |
251 | rlim = ~0; | 240 | rlim = ~0; |
252 | if (ex.a_data + ex.a_bss > rlim) | 241 | if (ex.a_data + ex.a_bss > rlim) |
@@ -263,6 +252,7 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs) | |||
263 | #else | 252 | #else |
264 | set_personality(PER_LINUX); | 253 | set_personality(PER_LINUX); |
265 | #endif | 254 | #endif |
255 | setup_new_exec(bprm); | ||
266 | 256 | ||
267 | current->mm->end_code = ex.a_text + | 257 | current->mm->end_code = ex.a_text + |
268 | (current->mm->start_code = N_TXTADDR(ex)); | 258 | (current->mm->start_code = N_TXTADDR(ex)); |