struct elfhdr interp_elf_ex;
struct exec interp_ex;
char passed_fileno[6];
+ struct files_struct *files;
/* Get the exec-header */
elf_ex = *((struct elfhdr *) bprm->buf);
if (retval < 0)
goto out_free_ph;
+ files = current->files; /* Refcounted so ok */
+ if(unshare_files() < 0)
+ goto out_free_ph;
+ if (files == current->files) {
+ put_files_struct(files);
+ files = NULL;
+ }
+
+ /* exec will make our files private anyway, but for the a.out
+ loader stuff we need to do it earlier */
+
retval = get_unused_fd();
if (retval < 0)
- goto out_free_ph;
+ goto out_free_fh;
get_file(bprm->file);
fd_install(elf_exec_fileno = retval, bprm->file);
if (retval)
goto out_free_dentry;
+ /* Discard our unneeded old files struct */
+ if (files) {
+ put_files_struct(files);
+ files = NULL;
+ }
+
/* OK, This is the point of no return */
current->mm->start_data = 0;
current->mm->end_data = 0;
elf_entry = load_elf_interp(&interp_elf_ex,
interpreter,
&interp_load_addr);
-
- allow_write_access(interpreter);
- fput(interpreter);
- kfree(elf_interpreter);
-
if (BAD_ADDR(elf_entry)) {
printk(KERN_ERR "Unable to load interpreter\n");
- kfree(elf_phdata);
send_sig(SIGSEGV, current, 0);
retval = -ENOEXEC; /* Nobody gets to see this, but.. */
- goto out;
+ goto out_free_dentry;
}
reloc_func_desc = interp_load_addr;
+
+ allow_write_access(interpreter);
+ fput(interpreter);
+ kfree(elf_interpreter);
} else {
elf_entry = elf_ex.e_entry;
}
kfree(elf_interpreter);
out_free_file:
sys_close(elf_exec_fileno);
+out_free_fh:
+ if (files) {
+ put_files_struct(current->files);
+ current->files = files;
+ }
out_free_ph:
kfree(elf_phdata);
goto out;
{
char * name;
int i, ch, retval;
+ struct files_struct *files;
/*
* Make sure we have a private signal table and that
if (retval)
goto out;
+ /*
+ * Make sure we have private file handles. Ask the
+ * fork helper to do the work for us and the exit
+ * helper to do the cleanup of the old one.
+ */
+ files = current->files; /* refcounted so safe to hold */
+ retval = unshare_files();
+ if (retval)
+ goto out;
/*
* Release all of the old mmap stuff
*/
retval = exec_mmap(bprm->mm);
if (retval)
- goto out;
+ goto mmap_failed;
bprm->mm = NULL; /* We're using it now */
/* This is the point of no return */
+ put_files_struct(files);
current->sas_ss_sp = current->sas_ss_size = 0;
return 0;
+mmap_failed:
+ put_files_struct(current->files);
+ current->files = files;
out:
return retval;
}