aboutsummaryrefslogtreecommitdiffstats
path: root/fs/binfmt_elf.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2008-04-22 05:11:59 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2008-04-25 09:23:53 -0400
commitfd8328be874f4190a811c58cd4778ec2c74d2c05 (patch)
treeb44ae8e99ce96a1a4739b04d4d1a23c40ab8b163 /fs/binfmt_elf.c
parent6b335d9c80d7f3c2a3f6545f664ae9007a0f3821 (diff)
[PATCH] sanitize handling of shared descriptor tables in failing execve()
* unshare_files() can fail; doing it after irreversible actions is wrong and de_thread() is certainly irreversible. * since we do it unconditionally anyway, we might as well do it in do_execve() and save ourselves the PITA in binfmt handlers, etc. * while we are at it, binfmt_som actually leaked files_struct on failure. As a side benefit, unshare_files(), put_files_struct() and reset_files_struct() become unexported. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/binfmt_elf.c')
-rw-r--r--fs/binfmt_elf.c23
1 files changed, 1 insertions, 22 deletions
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 5e1a4fb5cacb..9924581df6f6 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -543,7 +543,6 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
543 unsigned long interp_load_addr = 0; 543 unsigned long interp_load_addr = 0;
544 unsigned long start_code, end_code, start_data, end_data; 544 unsigned long start_code, end_code, start_data, end_data;
545 unsigned long reloc_func_desc = 0; 545 unsigned long reloc_func_desc = 0;
546 struct files_struct *files;
547 int executable_stack = EXSTACK_DEFAULT; 546 int executable_stack = EXSTACK_DEFAULT;
548 unsigned long def_flags = 0; 547 unsigned long def_flags = 0;
549 struct { 548 struct {
@@ -593,20 +592,9 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
593 goto out_free_ph; 592 goto out_free_ph;
594 } 593 }
595 594
596 files = current->files; /* Refcounted so ok */
597 retval = unshare_files();
598 if (retval < 0)
599 goto out_free_ph;
600 if (files == current->files) {
601 put_files_struct(files);
602 files = NULL;
603 }
604
605 /* exec will make our files private anyway, but for the a.out
606 loader stuff we need to do it earlier */
607 retval = get_unused_fd(); 595 retval = get_unused_fd();
608 if (retval < 0) 596 if (retval < 0)
609 goto out_free_fh; 597 goto out_free_ph;
610 get_file(bprm->file); 598 get_file(bprm->file);
611 fd_install(elf_exec_fileno = retval, bprm->file); 599 fd_install(elf_exec_fileno = retval, bprm->file);
612 600
@@ -728,12 +716,6 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
728 if (retval) 716 if (retval)
729 goto out_free_dentry; 717 goto out_free_dentry;
730 718
731 /* Discard our unneeded old files struct */
732 if (files) {
733 put_files_struct(files);
734 files = NULL;
735 }
736
737 /* OK, This is the point of no return */ 719 /* OK, This is the point of no return */
738 current->flags &= ~PF_FORKNOEXEC; 720 current->flags &= ~PF_FORKNOEXEC;
739 current->mm->def_flags = def_flags; 721 current->mm->def_flags = def_flags;
@@ -1016,9 +998,6 @@ out_free_interp:
1016 kfree(elf_interpreter); 998 kfree(elf_interpreter);
1017out_free_file: 999out_free_file:
1018 sys_close(elf_exec_fileno); 1000 sys_close(elf_exec_fileno);
1019out_free_fh:
1020 if (files)
1021 reset_files_struct(current, files);
1022out_free_ph: 1001out_free_ph:
1023 kfree(elf_phdata); 1002 kfree(elf_phdata);
1024 goto out; 1003 goto out;