patch-2.2.11 linux/arch/mips/kernel/irixelf.c
Next file: linux/arch/mips/kernel/irixinv.c
Previous file: linux/arch/mips/kernel/irix5sys.h
Back to the patch index
Back to the overall index
- Lines: 346
- Date:
Mon Aug 9 12:04:38 1999
- Orig file:
v2.2.10/linux/arch/mips/kernel/irixelf.c
- Orig date:
Wed Nov 11 11:49:59 1998
diff -u --recursive --new-file v2.2.10/linux/arch/mips/kernel/irixelf.c linux/arch/mips/kernel/irixelf.c
@@ -1,4 +1,5 @@
-/*
+/* $Id: irixelf.c,v 1.17.2.2 1999/06/22 20:53:26 ralf Exp $
+ *
* irixelf.c: Code to load IRIX ELF executables which conform to
* the MIPS ABI.
*
@@ -309,7 +310,7 @@
return 0xffffffff;
}
- file = current->files->fd[elf_exec_fileno];
+ file = fget(elf_exec_fileno);
eppnt = elf_phdata;
for(i=0; i<interp_elf_ex->e_phnum; i++, eppnt++) {
@@ -367,6 +368,7 @@
}
/* Now use mmap to map the library into memory. */
+ fput(file);
sys_close(elf_exec_fileno);
if(error < 0 && error > -1024) {
#ifdef DEBUG_ELF
@@ -617,8 +619,9 @@
unsigned int load_addr, elf_bss, elf_brk;
unsigned int elf_entry, interp_load_addr = 0;
unsigned int start_code, end_code, end_data, elf_stack;
- int elf_exec_fileno, retval, has_interp, has_ephdr, i;
+ int elf_exec_fileno, retval, has_interp, has_ephdr, size, i;
char *elf_interpreter;
+ struct file *file;
mm_segment_t old_fs;
load_addr = 0;
@@ -634,17 +637,15 @@
#endif
/* Now read in all of the header information */
- elf_phdata = (struct elf_phdr *) kmalloc(elf_ex.e_phentsize *
- elf_ex.e_phnum, GFP_KERNEL);
+ size = elf_ex.e_phentsize * elf_ex.e_phnum;
+ elf_phdata = (struct elf_phdr *) kmalloc(size, GFP_KERNEL);
if (elf_phdata == NULL)
return -ENOMEM;
- retval = read_exec(bprm->dentry, elf_ex.e_phoff, (char *) elf_phdata,
- elf_ex.e_phentsize * elf_ex.e_phnum, 1);
- if (retval < 0) {
- kfree (elf_phdata);
- return retval;
- }
+ retval = read_exec(bprm->dentry, elf_ex.e_phoff,
+ (char *) elf_phdata, size, 1);
+ if (retval < 0)
+ goto out_phdata;
#ifdef DEBUG_ELF
dump_phdrs(elf_phdata, elf_ex.e_phnum);
@@ -669,12 +670,10 @@
elf_bss = 0;
elf_brk = 0;
- elf_exec_fileno = open_dentry(bprm->dentry, O_RDONLY);
-
- if (elf_exec_fileno < 0) {
- kfree (elf_phdata);
- return elf_exec_fileno;
- }
+ retval = open_dentry(bprm->dentry, O_RDONLY);
+ if (retval < 0)
+ goto out_phdata;
+ file = fget(elf_exec_fileno = retval);
elf_stack = 0xffffffff;
elf_interpreter = NULL;
@@ -686,40 +685,26 @@
&interpreter_dentry,
&interp_elf_ex, elf_phdata, bprm,
elf_ex.e_phnum);
- if(retval) {
- kfree(elf_phdata);
- sys_close(elf_exec_fileno);
- return retval;
- }
+ if(retval)
+ goto out_file;
if(elf_interpreter) {
retval = verify_irix_interpreter(&interp_elf_ex);
- if(retval) {
- kfree(elf_interpreter);
- kfree(elf_phdata);
- sys_close(elf_exec_fileno);
- return retval;
- }
+ if(retval)
+ goto out_interp;
}
/* OK, we are done with that, now set up the arg stuff,
* and then start this sucker up.
*/
- if (!bprm->sh_bang) {
- if (!bprm->p) {
- if(elf_interpreter) {
- kfree(elf_interpreter);
- }
- kfree (elf_phdata);
- sys_close(elf_exec_fileno);
- return -E2BIG;
- }
- }
+ retval = -E2BIG;
+ if (!bprm->sh_bang && !bprm->p)
+ goto out_interp;
/* Flush all traces of the currently running executable */
retval = flush_old_exec(bprm);
if (retval)
- return retval;
+ goto out_interp;
/* OK, This is the point of no return */
current->mm->end_data = 0;
@@ -741,8 +726,7 @@
old_fs = get_fs();
set_fs(get_ds());
- map_executable(current->files->fd[elf_exec_fileno], elf_phdata,
- elf_ex.e_phnum, &elf_stack, &load_addr,
+ map_executable(file, elf_phdata, elf_ex.e_phnum, &elf_stack, &load_addr,
&start_code, &elf_bss, &end_code, &end_data, &elf_brk);
if(elf_interpreter) {
@@ -762,6 +746,7 @@
set_fs(old_fs);
kfree(elf_phdata);
+ fput(file);
sys_close(elf_exec_fileno);
current->personality = PER_IRIX32;
@@ -824,6 +809,17 @@
if (current->flags & PF_PTRACED)
send_sig(SIGTRAP, current, 0);
return 0;
+
+out_interp:
+ if(elf_interpreter) {
+ kfree(elf_interpreter);
+ }
+out_file:
+ fput(file);
+ sys_close(elf_exec_fileno);
+out_phdata:
+ kfree (elf_phdata);
+ return retval;
}
static int load_irix_binary(struct linux_binprm * bprm, struct pt_regs * regs)
@@ -839,9 +835,8 @@
/* This is really simpleminded and specialized - we are loading an
* a.out library that is given an ELF header.
*/
-static inline int do_load_irix_library(int fd)
+static inline int do_load_irix_library(struct file *file)
{
- struct file * file;
struct elfhdr elf_ex;
struct elf_phdr *elf_phdata = NULL;
struct dentry *dentry;
@@ -854,14 +849,12 @@
int i,j, k;
len = 0;
- file = current->files->fd[fd];
+ if (!file->f_op)
+ return -EACCES;
dentry = file->f_dentry;
inode = dentry->d_inode;
elf_bss = 0;
- if (!file || !file->f_op)
- return -EACCES;
-
/* Seek to the beginning of the file. */
if (file->f_op->llseek) {
if ((error = file->f_op->llseek(file, 0, 0)) != 0)
@@ -940,10 +933,15 @@
static int load_irix_library(int fd)
{
- int retval;
+ int retval = -EACCES;
+ struct file *file;
MOD_INC_USE_COUNT;
- retval = do_load_irix_library(fd);
+ file = fget(fd);
+ if (file) {
+ retval = do_load_irix_library(file);
+ fput(file);
+ }
MOD_DEC_USE_COUNT;
return retval;
}
@@ -984,9 +982,12 @@
return -ENOEXEC;
}
- filp = current->files->fd[fd];
- if(!filp || !filp->f_op) {
+ filp = fget(fd);
+ if (!filp)
+ return -EACCES;
+ if(!filp->f_op) {
printk("irix_mapelf: Bogon filp!\n");
+ fput(file);
return -EACCES;
}
@@ -1004,6 +1005,7 @@
if(retval != (hp->p_vaddr & 0xfffff000)) {
printk("irix_mapelf: do_mmap fails with %d!\n", retval);
+ fput(file);
return retval;
}
}
@@ -1011,6 +1013,7 @@
#ifdef DEBUG_ELF
printk("irix_mapelf: Success, returning %08lx\n", user_phdrp->p_vaddr);
#endif
+ fput(file);
return user_phdrp->p_vaddr;
}
@@ -1026,7 +1029,13 @@
*/
static int dump_write(struct file *file, const void *addr, int nr)
{
- return file->f_op->write(file, addr, nr, &file->f_pos) == nr;
+ int r;
+
+ down(&file->f_dentry->d_inode->i_sem);
+ r = file->f_op->write(file, addr, nr, &file->f_pos) == nr;
+ up(&file->f_dentry->d_inode->i_sem);
+
+ return r;
}
static int dump_seek(struct file *file, off_t off)
@@ -1108,10 +1117,10 @@
#undef DUMP_SEEK
#define DUMP_WRITE(addr, nr) \
- if (!dump_write(&file, (addr), (nr))) \
+ if (!dump_write(file, (addr), (nr))) \
goto close_coredump;
#define DUMP_SEEK(off) \
- if (!dump_seek(&file, (off))) \
+ if (!dump_seek(file, (off))) \
goto close_coredump;
/* Actual dumper.
*
@@ -1122,7 +1131,7 @@
static int irix_core_dump(long signr, struct pt_regs * regs)
{
int has_dumped = 0;
- struct file file;
+ struct file *file;
struct dentry *dentry;
struct inode *inode;
mm_segment_t fs;
@@ -1191,26 +1200,28 @@
fs = get_fs();
set_fs(KERNEL_DS);
+
memcpy(corefile,"core.", 5);
#if 0
memcpy(corefile+5,current->comm,sizeof(current->comm));
#else
corefile[4] = '\0';
#endif
- dentry = open_namei(corefile, O_CREAT | 2 | O_TRUNC | O_NOFOLLOW, 0600);
- if (IS_ERR(dentry)) {
- inode = NULL;
+ file = filp_open(corefile, O_CREAT | 2 | O_TRUNC | O_NOFOLLOW, 0600);
+ if (IS_ERR(file))
goto end_coredump;
- }
+ dentry = file->f_dentry;
inode = dentry->d_inode;
+ if (inode->i_nlink > 1)
+ goto close_coredump; /* multiple links - don't dump */
+
if (!S_ISREG(inode->i_mode))
- goto end_coredump;
+ goto close_coredump;
if (!inode->i_op || !inode->i_op->default_file_ops)
- goto end_coredump;
- if (init_private_file(&file, dentry, 3))
- goto end_coredump;
- if (!file.f_op->write)
goto close_coredump;
+ if (!file->f_op->write)
+ goto close_coredump;
+
has_dumped = 1;
current->flags |= PF_DUMPCORE;
@@ -1346,7 +1357,7 @@
}
for(i = 0; i < numnote; i++)
- if (!writenote(¬es[i], &file))
+ if (!writenote(¬es[i], file))
goto close_coredump;
set_fs(fs);
@@ -1368,19 +1379,17 @@
DUMP_WRITE((void *)addr, len);
}
- if ((off_t) file.f_pos != offset) {
+ if ((off_t) file->f_pos != offset) {
/* Sanity check. */
- printk("elf_core_dump: file.f_pos (%ld) != offset (%ld)\n",
- (off_t) file.f_pos, offset);
+ printk("elf_core_dump: file->f_pos (%ld) != offset (%ld)\n",
+ (off_t) file->f_pos, offset);
}
close_coredump:
- if (file.f_op->release)
- file.f_op->release(inode, &file);
+ filp_close(file, NULL);
end_coredump:
set_fs(fs);
- dput(dentry);
#ifndef CONFIG_BINFMT_ELF
MOD_DEC_USE_COUNT;
#endif
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)