patch-1.3.61 linux/fs/exec.c

Next file: linux/fs/fat/buffer.c
Previous file: linux/fs/buffer.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v1.3.60/linux/fs/exec.c linux/fs/exec.c
@@ -51,28 +51,27 @@
 asmlinkage int sys_exit(int exit_code);
 asmlinkage int sys_brk(unsigned long);
 
-static int load_aout_binary(struct linux_binprm *, struct pt_regs * regs);
-static int load_aout_library(int fd);
-
-extern void dump_thread(struct pt_regs *, struct user *);
-
 /*
  * Here are the actual binaries that will be accepted:
  * add more with "register_binfmt()" if using modules...
+ *
+ * These are defined again for the 'real' modules if you are using a
+ * module definition for these routines.
  */
-extern struct linux_binfmt elf_format;
 
-static struct linux_binfmt aout_format = {
-#ifndef CONFIG_BINFMT_ELF
- 	NULL, NULL, load_aout_binary, load_aout_library, aout_core_dump
-#else
- 	&elf_format, NULL, load_aout_binary, load_aout_library, aout_core_dump
+static struct linux_binfmt *formats = (struct linux_binfmt *) NULL;
+
+void binfmt_setup(void)
+{
+#ifdef CONFIG_BINFMT_ELF
+	init_elf_binfmt();
 #endif
-};
 
-static struct linux_binfmt *formats = &aout_format;
+#ifdef CONFIG_BINFMT_AOUT
+	init_aout_binfmt();
+#endif
+}
 
-#ifdef CONFIG_MODULES
 int register_binfmt(struct linux_binfmt * fmt)
 {
 	struct linux_binfmt ** tmp = &formats;
@@ -91,6 +90,7 @@
 	return 0;	
 }
 
+#ifdef CONFIG_MODULES
 int unregister_binfmt(struct linux_binfmt * fmt)
 {
 	struct linux_binfmt ** tmp = &formats;
@@ -147,137 +147,6 @@
 }
 
 /*
- * These are the only things you should do on a core-file: use only these
- * macros to write out all the necessary info.
- */
-#define DUMP_WRITE(addr,nr) \
-while (file.f_op->write(inode,&file,(char *)(addr),(nr)) != (nr)) goto close_coredump
-
-#define DUMP_SEEK(offset) \
-if (file.f_op->lseek) { \
-	if (file.f_op->lseek(inode,&file,(offset),0) != (offset)) \
- 		goto close_coredump; \
-} else file.f_pos = (offset)		
-
-/*
- * Routine writes a core dump image in the current directory.
- * Currently only a stub-function.
- *
- * Note that setuid/setgid files won't make a core-dump if the uid/gid
- * changed due to the set[u|g]id. It's enforced by the "current->dumpable"
- * field, which also makes sure the core-dumps won't be recursive if the
- * dumping of the process results in another error..
- */
-int aout_core_dump(long signr, struct pt_regs * regs)
-{
-	struct inode * inode = NULL;
-	struct file file;
-	unsigned short fs;
-	int has_dumped = 0;
-	char corefile[6+sizeof(current->comm)];
-	unsigned long dump_start, dump_size;
-	struct user dump;
-#ifdef __alpha__
-#       define START_DATA(u)	(u.start_data)
-#else
-#       define START_DATA(u)	(u.u_tsize << PAGE_SHIFT)
-#endif
-
-	if (!current->dumpable)
-		return 0;
-	current->dumpable = 0;
-
-/* See if we have enough room to write the upage.  */
-	if (current->rlim[RLIMIT_CORE].rlim_cur < PAGE_SIZE)
-		return 0;
-	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
-	if (open_namei(corefile,O_CREAT | 2 | O_TRUNC,0600,&inode,NULL)) {
-		inode = NULL;
-		goto end_coredump;
-	}
-	if (!S_ISREG(inode->i_mode))
-		goto end_coredump;
-	if (!inode->i_op || !inode->i_op->default_file_ops)
-		goto end_coredump;
-	if (get_write_access(inode))
-		goto end_coredump;
-	file.f_mode = 3;
-	file.f_flags = 0;
-	file.f_count = 1;
-	file.f_inode = inode;
-	file.f_pos = 0;
-	file.f_reada = 0;
-	file.f_op = inode->i_op->default_file_ops;
-	if (file.f_op->open)
-		if (file.f_op->open(inode,&file))
-			goto done_coredump;
-	if (!file.f_op->write)
-		goto close_coredump;
-	has_dumped = 1;
-       	strncpy(dump.u_comm, current->comm, sizeof(current->comm));
-	dump.u_ar0 = (void *)(((unsigned long)(&dump.regs)) - ((unsigned long)(&dump)));
-	dump.signal = signr;
-	dump_thread(regs, &dump);
-
-/* If the size of the dump file exceeds the rlimit, then see what would happen
-   if we wrote the stack, but not the data area.  */
-	if ((dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE >
-	    current->rlim[RLIMIT_CORE].rlim_cur)
-		dump.u_dsize = 0;
-
-/* Make sure we have enough room to write the stack and data areas. */
-	if ((dump.u_ssize+1) * PAGE_SIZE >
-	    current->rlim[RLIMIT_CORE].rlim_cur)
-		dump.u_ssize = 0;
-
-/* make sure we actually have a data and stack area to dump */
-	set_fs(USER_DS);
-	if (verify_area(VERIFY_READ, (void *) START_DATA(dump), dump.u_dsize << PAGE_SHIFT))
-		dump.u_dsize = 0;
-	if (verify_area(VERIFY_READ, (void *) dump.start_stack, dump.u_ssize << PAGE_SHIFT))
-		dump.u_ssize = 0;
-
-	set_fs(KERNEL_DS);
-/* struct user */
-	DUMP_WRITE(&dump,sizeof(dump));
-/* Now dump all of the user data.  Include malloced stuff as well */
-	DUMP_SEEK(PAGE_SIZE);
-/* now we start writing out the user space info */
-	set_fs(USER_DS);
-/* Dump the data area */
-	if (dump.u_dsize != 0) {
-		dump_start = START_DATA(dump);
-		dump_size = dump.u_dsize << PAGE_SHIFT;
-		DUMP_WRITE(dump_start,dump_size);
-	}
-/* Now prepare to dump the stack area */
-	if (dump.u_ssize != 0) {
-		dump_start = dump.start_stack;
-		dump_size = dump.u_ssize << PAGE_SHIFT;
-		DUMP_WRITE(dump_start,dump_size);
-	}
-/* Finally dump the task struct.  Not be used by gdb, but could be useful */
-	set_fs(KERNEL_DS);
-	DUMP_WRITE(current,sizeof(*current));
-close_coredump:
-	if (file.f_op->release)
-		file.f_op->release(inode,&file);
-done_coredump:
-	put_write_access(inode);
-end_coredump:
-	set_fs(fs);
-	iput(inode);
-	return has_dumped;
-}
-
-/*
  * Note that a shared library must be both readable and executable due to
  * security reasons.
  *
@@ -821,229 +690,4 @@
 	for (i=0 ; i<MAX_ARG_PAGES ; i++)
 		free_page(bprm.page[i]);
 	return(retval);
-}
-
-static void set_brk(unsigned long start, unsigned long end)
-{
-	start = PAGE_ALIGN(start);
-	end = PAGE_ALIGN(end);
-	if (end <= start)
-		return;
-	do_mmap(NULL, start, end - start,
-		PROT_READ | PROT_WRITE | PROT_EXEC,
-		MAP_FIXED | MAP_PRIVATE, 0);
-}
-
-/*
- * These are the functions used to load a.out style executables and shared
- * libraries.  There is no binary dependent code anywhere else.
- */
-
-static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)
-{
-	struct exec ex;
-	struct file * file;
-	int fd;
-	unsigned long error;
-	unsigned long p = bprm->p;
-	unsigned long fd_offset;
-	unsigned long rlim;
-
-	ex = *((struct exec *) bprm->buf);		/* exec-header */
-	if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != OMAGIC && 
-	     N_MAGIC(ex) != QMAGIC) ||
-	    N_TRSIZE(ex) || N_DRSIZE(ex) ||
-	    bprm->inode->i_size < ex.a_text+ex.a_data+N_SYMSIZE(ex)+N_TXTOFF(ex)) {
-		return -ENOEXEC;
-	}
-
-	current->personality = PER_LINUX;
-	fd_offset = N_TXTOFF(ex);
-
-#ifdef __i386__
-	if (N_MAGIC(ex) == ZMAGIC && fd_offset != BLOCK_SIZE) {
-		printk(KERN_NOTICE "N_TXTOFF != BLOCK_SIZE. See a.out.h.\n");
-		return -ENOEXEC;
-	}
-
-	if (N_MAGIC(ex) == ZMAGIC && ex.a_text &&
-	    (fd_offset < bprm->inode->i_sb->s_blocksize)) {
-		printk(KERN_NOTICE "N_TXTOFF < BLOCK_SIZE. Please convert binary.\n");
-		return -ENOEXEC;
-	}
-#endif
-
-	/* Check initial limits. This avoids letting people circumvent
-	 * size limits imposed on them by creating programs with large
-	 * arrays in the data or bss.
-	 */
-	rlim = current->rlim[RLIMIT_DATA].rlim_cur;
-	if (rlim >= RLIM_INFINITY)
-		rlim = ~0;
-	if (ex.a_data + ex.a_bss > rlim)
-		return -ENOMEM;
-
-	/* OK, This is the point of no return */
-	flush_old_exec(bprm);
-
-	current->mm->end_code = ex.a_text +
-		(current->mm->start_code = N_TXTADDR(ex));
-	current->mm->end_data = ex.a_data +
-		(current->mm->start_data = N_DATADDR(ex));
-	current->mm->brk = ex.a_bss +
-		(current->mm->start_brk = N_BSSADDR(ex));
-
-	current->mm->rss = 0;
-	current->mm->mmap = NULL;
-	current->suid = current->euid = current->fsuid = bprm->e_uid;
-	current->sgid = current->egid = current->fsgid = bprm->e_gid;
-	if (N_MAGIC(ex) == OMAGIC) {
-#ifdef __alpha__
-		do_mmap(NULL, N_TXTADDR(ex) & PAGE_MASK,
-			ex.a_text+ex.a_data + PAGE_SIZE - 1,
-			PROT_READ|PROT_WRITE|PROT_EXEC,
-			MAP_FIXED|MAP_PRIVATE, 0);
-		read_exec(bprm->inode, fd_offset, (char *) N_TXTADDR(ex),
-			  ex.a_text+ex.a_data, 0);
-#else
-		do_mmap(NULL, 0, ex.a_text+ex.a_data,
-			PROT_READ|PROT_WRITE|PROT_EXEC,
-			MAP_FIXED|MAP_PRIVATE, 0);
-		read_exec(bprm->inode, 32, (char *) 0, ex.a_text+ex.a_data, 0);
-#endif
-	} else {
-		if (ex.a_text & 0xfff || ex.a_data & 0xfff)
-			printk(KERN_NOTICE "executable not page aligned\n");
-		
-		fd = open_inode(bprm->inode, O_RDONLY);
-		
-		if (fd < 0)
-			return fd;
-		file = current->files->fd[fd];
-		if (!file->f_op || !file->f_op->mmap) {
-			sys_close(fd);
-			do_mmap(NULL, 0, ex.a_text+ex.a_data,
-				PROT_READ|PROT_WRITE|PROT_EXEC,
-				MAP_FIXED|MAP_PRIVATE, 0);
-			read_exec(bprm->inode, fd_offset,
-				  (char *) N_TXTADDR(ex), ex.a_text+ex.a_data, 0);
-			goto beyond_if;
-		}
-
-		error = do_mmap(file, N_TXTADDR(ex), ex.a_text,
-			PROT_READ | PROT_EXEC,
-			MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
-			fd_offset);
-
-		if (error != N_TXTADDR(ex)) {
-			sys_close(fd);
-			send_sig(SIGKILL, current, 0);
-			return error;
-		}
-		
- 		error = do_mmap(file, N_DATADDR(ex), ex.a_data,
-				PROT_READ | PROT_WRITE | PROT_EXEC,
-				MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
-				fd_offset + ex.a_text);
-		sys_close(fd);
-		if (error != N_DATADDR(ex)) {
-			send_sig(SIGKILL, current, 0);
-			return error;
-		}
-	}
-beyond_if:
-	if (current->exec_domain && current->exec_domain->use_count)
-		(*current->exec_domain->use_count)--;
-	if (current->binfmt && current->binfmt->use_count)
-		(*current->binfmt->use_count)--;
-	current->exec_domain = lookup_exec_domain(current->personality);
-	current->binfmt = &aout_format;
-	if (current->exec_domain && current->exec_domain->use_count)
-		(*current->exec_domain->use_count)++;
-	if (current->binfmt && current->binfmt->use_count)
-		(*current->binfmt->use_count)++;
-
-	set_brk(current->mm->start_brk, current->mm->brk);
-
-	fd_offset = setup_arg_pages(ex.a_text,bprm->page) - MAX_ARG_PAGES*PAGE_SIZE;
-	p += fd_offset;
-	if (bprm->loader)
-		bprm->loader += fd_offset;
-	bprm->exec += fd_offset;
-	
-	p = (unsigned long)create_tables((char *)p, bprm,
-					current->personality != PER_LINUX);
-	current->mm->start_stack = p;
-#ifdef __alpha__
-	regs->gp = ex.a_gpvalue;
-#endif
-	start_thread(regs, ex.a_entry, p);
-	if (current->flags & PF_PTRACED)
-		send_sig(SIGTRAP, current, 0);
-	return 0;
-}
-
-
-static int load_aout_library(int fd)
-{
-        struct file * file;
-	struct exec ex;
-	struct  inode * inode;
-	unsigned int len;
-	unsigned int bss;
-	unsigned int start_addr;
-	unsigned long error;
-	
-	file = current->files->fd[fd];
-	inode = file->f_inode;
-	
-	if (!file || !file->f_op)
-		return -EACCES;
-
-	/* Seek into the file */
-	if (file->f_op->lseek) {
-		if ((error = file->f_op->lseek(inode, file, 0, 0)) != 0)
-			return -ENOEXEC;
-	} else
-		file->f_pos = 0;
-
-	set_fs(KERNEL_DS);
-	error = file->f_op->read(inode, file, (char *) &ex, sizeof(ex));
-	set_fs(USER_DS);
-	if (error != sizeof(ex))
-		return -ENOEXEC;
-
-	/* We come in here for the regular a.out style of shared libraries */
-	if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != QMAGIC) || N_TRSIZE(ex) ||
-	    N_DRSIZE(ex) || ((ex.a_entry & 0xfff) && N_MAGIC(ex) == ZMAGIC) ||
-	    inode->i_size < ex.a_text+ex.a_data+N_SYMSIZE(ex)+N_TXTOFF(ex)) {
-		return -ENOEXEC;
-	}
-	if (N_MAGIC(ex) == ZMAGIC && N_TXTOFF(ex) && 
-	    (N_TXTOFF(ex) < inode->i_sb->s_blocksize)) {
-		printk("N_TXTOFF < BLOCK_SIZE. Please convert library\n");
-		return -ENOEXEC;
-	}
-	
-	if (N_FLAGS(ex)) return -ENOEXEC;
-
-	/* For  QMAGIC, the starting address is 0x20 into the page.  We mask
-	   this off to get the starting address for the page */
-
-	start_addr =  ex.a_entry & 0xfffff000;
-
-	/* Now use mmap to map the library into memory. */
-	error = do_mmap(file, start_addr, ex.a_text + ex.a_data,
-			PROT_READ | PROT_WRITE | PROT_EXEC,
-			MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE,
-			N_TXTOFF(ex));
-	if (error != start_addr)
-		return error;
-	len = PAGE_ALIGN(ex.a_text + ex.a_data);
-	bss = ex.a_text + ex.a_data + ex.a_bss;
-	if (bss > len)
-		do_mmap(NULL, start_addr + len, bss-len,
-			PROT_READ|PROT_WRITE|PROT_EXEC,
-			MAP_PRIVATE|MAP_FIXED, 0);
-	return 0;
 }

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov with Sam's (original) version
of this