diff options
author | Michal Hocko <mhocko@suse.com> | 2016-05-23 19:25:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-05-23 20:04:14 -0400 |
commit | 864778b154233d3a673c520aa9606777589ecee7 (patch) | |
tree | 422b045224098ec95b23b1da8a441e25ee52288e /fs/binfmt_aout.c | |
parent | ae7987835643e470cb220e6685bd36d92179ef9c (diff) |
mm, aout: handle vm_brk failures
vm_brk is allowed to fail but load_aout_binary simply ignores the error
and happily continues. I haven't noticed any problem from that in real
life but later patches will make the failure more likely because vm_brk
will become killable (resp. mmap_sem for write waiting will become
killable) so we should be more careful now.
The error handling should be quite straightforward because there are
calls to vm_mmap which check the error properly already. The only
notable exception is set_brk which is called after beyond_if label. But
nothing indicates that we cannot move it above set_binfmt as the two do
not depend on each other and fail before we do set_binfmt and alter
reference counting.
Signed-off-by: Michal Hocko <mhocko@suse.com>
Acked-by: Vlastimil Babka <vbabka@suse.cz>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/binfmt_aout.c')
-rw-r--r-- | fs/binfmt_aout.c | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/fs/binfmt_aout.c b/fs/binfmt_aout.c index 4c556680fa74..2fab9f130e51 100644 --- a/fs/binfmt_aout.c +++ b/fs/binfmt_aout.c | |||
@@ -297,7 +297,10 @@ static int load_aout_binary(struct linux_binprm * bprm) | |||
297 | } | 297 | } |
298 | 298 | ||
299 | if (!bprm->file->f_op->mmap||((fd_offset & ~PAGE_MASK) != 0)) { | 299 | if (!bprm->file->f_op->mmap||((fd_offset & ~PAGE_MASK) != 0)) { |
300 | vm_brk(N_TXTADDR(ex), ex.a_text+ex.a_data); | 300 | error = vm_brk(N_TXTADDR(ex), ex.a_text+ex.a_data); |
301 | if (IS_ERR_VALUE(error)) | ||
302 | return error; | ||
303 | |||
301 | read_code(bprm->file, N_TXTADDR(ex), fd_offset, | 304 | read_code(bprm->file, N_TXTADDR(ex), fd_offset, |
302 | ex.a_text + ex.a_data); | 305 | ex.a_text + ex.a_data); |
303 | goto beyond_if; | 306 | goto beyond_if; |
@@ -378,8 +381,10 @@ static int load_aout_library(struct file *file) | |||
378 | "N_TXTOFF is not page aligned. Please convert library: %pD\n", | 381 | "N_TXTOFF is not page aligned. Please convert library: %pD\n", |
379 | file); | 382 | file); |
380 | } | 383 | } |
381 | vm_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss); | 384 | retval = vm_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss); |
382 | 385 | if (IS_ERR_VALUE(retval)) | |
386 | goto out; | ||
387 | |||
383 | read_code(file, start_addr, N_TXTOFF(ex), | 388 | read_code(file, start_addr, N_TXTOFF(ex), |
384 | ex.a_text + ex.a_data); | 389 | ex.a_text + ex.a_data); |
385 | retval = 0; | 390 | retval = 0; |