Example #1
0
/* These are the functions used to load ELF style executables and shared
 * libraries.  There is no binary dependent code anywhere else.
 */
static int load_irix_binary(struct linux_binprm * bprm, struct pt_regs * regs)
{
	struct elfhdr elf_ex, interp_elf_ex;
	struct file *interpreter;
	struct elf_phdr *elf_phdata, *elf_ihdr, *elf_ephdr;
	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 retval, has_interp, has_ephdr, size, i;
	char *elf_interpreter;
	mm_segment_t old_fs;

	load_addr = 0;
	has_interp = has_ephdr = 0;
	elf_ihdr = elf_ephdr = NULL;
	elf_ex = *((struct elfhdr *) bprm->buf);
	retval = -ENOEXEC;

	if (verify_binary(&elf_ex, bprm))
		goto out;

	/*
	 * Telling -o32 static binaries from Linux and Irix apart from each
	 * other is difficult. There are 2 differences to be noted for static
	 * binaries from the 2 operating systems:
	 *
	 *    1) Irix binaries have their .text section before their .init
	 *       section. Linux binaries are just the opposite.
	 *
	 *    2) Irix binaries usually have <= 12 sections and Linux
	 *       binaries have > 20.
	 *
	 * We will use Method #2 since Method #1 would require us to read in
	 * the section headers which is way too much overhead. This appears
	 * to work for everything we have ran into so far. If anyone has a
	 * better method to tell the binaries apart, I'm listening.
	 */
	if (elf_ex.e_shnum > 20)
		goto out;

	print_elfhdr(&elf_ex);

	/* Now read in all of the header information */
	size = elf_ex.e_phentsize * elf_ex.e_phnum;
	if (size > 65536)
		goto out;
	elf_phdata = kmalloc(size, GFP_KERNEL);
	if (elf_phdata == NULL) {
		retval = -ENOMEM;
		goto out;
	}

	retval = kernel_read(bprm->file, elf_ex.e_phoff, (char *)elf_phdata, size);
	if (retval < 0)
		goto out_free_ph;

	dump_phdrs(elf_phdata, elf_ex.e_phnum);

	/* Set some things for later. */
	for (i = 0; i < elf_ex.e_phnum; i++) {
		switch (elf_phdata[i].p_type) {
		case PT_INTERP:
			has_interp = 1;
			elf_ihdr = &elf_phdata[i];
			break;
		case PT_PHDR:
			has_ephdr = 1;
			elf_ephdr = &elf_phdata[i];
			break;
		};
	}

	pr_debug("\n");

	elf_bss = 0;
	elf_brk = 0;

	elf_stack = 0xffffffff;
	elf_interpreter = NULL;
	start_code = 0xffffffff;
	end_code = 0;
	end_data = 0;

	/*
	 * If we get a return value, we change the value to be ENOEXEC
	 * so that we can exit gracefully and the main binary format
	 * search loop in 'fs/exec.c' will move onto the next handler
	 * which should be the normal ELF binary handler.
	 */
	retval = look_for_irix_interpreter(&elf_interpreter, &interpreter,
					   &interp_elf_ex, elf_phdata, bprm,
					   elf_ex.e_phnum);
	if (retval) {
		retval = -ENOEXEC;
		goto out_free_file;
	}

	if (elf_interpreter) {
		retval = verify_irix_interpreter(&interp_elf_ex);
		if (retval)
			goto out_free_interp;
	}

	/* OK, we are done with that, now set up the arg stuff,
	 * and then start this sucker up.
	 */
	retval = -E2BIG;
	if (!bprm->sh_bang && !bprm->p)
		goto out_free_interp;

	/* Flush all traces of the currently running executable */
	retval = flush_old_exec(bprm);
	if (retval)
		goto out_free_dentry;

	/* OK, This is the point of no return */
	current->mm->end_data = 0;
	current->mm->end_code = 0;
	current->mm->mmap = NULL;
	current->flags &= ~PF_FORKNOEXEC;
	elf_entry = (unsigned int) elf_ex.e_entry;

	/* Do this so that we can load the interpreter, if need be.  We will
	 * change some of these later.
	 */
	setup_arg_pages(bprm, STACK_TOP, EXSTACK_DEFAULT);
	current->mm->start_stack = bprm->p;

	/* At this point, we assume that the image should be loaded at
	 * fixed address, not at a variable address.
	 */
	old_fs = get_fs();
	set_fs(get_ds());

	map_executable(bprm->file, elf_phdata, elf_ex.e_phnum, &elf_stack,
	               &load_addr, &start_code, &elf_bss, &end_code,
	               &end_data, &elf_brk);

	if (elf_interpreter) {
		retval = map_interpreter(elf_phdata, &interp_elf_ex,
					 interpreter, &interp_load_addr,
					 elf_ex.e_phnum, old_fs, &elf_entry);
		kfree(elf_interpreter);
		if (retval) {
			set_fs(old_fs);
			printk("Unable to load IRIX ELF interpreter\n");
			send_sig(SIGSEGV, current, 0);
			retval = 0;
			goto out_free_file;
		}
	}

	set_fs(old_fs);

	kfree(elf_phdata);
	set_personality(PER_IRIX32);
	set_binfmt(&irix_format);
	compute_creds(bprm);
	current->flags &= ~PF_FORKNOEXEC;
	bprm->p = (unsigned long)
	  create_irix_tables((char *)bprm->p, bprm->argc, bprm->envc,
			(elf_interpreter ? &elf_ex : NULL),
			load_addr, interp_load_addr, regs, elf_ephdr);
	current->mm->start_brk = current->mm->brk = elf_brk;
	current->mm->end_code = end_code;
	current->mm->start_code = start_code;
	current->mm->end_data = end_data;
	current->mm->start_stack = bprm->p;

	/* Calling set_brk effectively mmaps the pages that we need for the
	 * bss and break sections.
	 */
	set_brk(elf_bss, elf_brk);

	/*
	 * IRIX maps a page at 0x200000 which holds some system
	 * information.  Programs depend on this.
	 */
	irix_map_prda_page();

	padzero(elf_bss);

	pr_debug("(start_brk) %lx\n" , (long) current->mm->start_brk);
	pr_debug("(end_code) %lx\n" , (long) current->mm->end_code);
	pr_debug("(start_code) %lx\n" , (long) current->mm->start_code);
	pr_debug("(end_data) %lx\n" , (long) current->mm->end_data);
	pr_debug("(start_stack) %lx\n" , (long) current->mm->start_stack);
	pr_debug("(brk) %lx\n" , (long) current->mm->brk);

#if 0 /* XXX No f*****g way dude... */
	/* Why this, you ask???  Well SVr4 maps page 0 as read-only,
	 * and some applications "depend" upon this behavior.
	 * Since we do not have the power to recompile these, we
	 * emulate the SVr4 behavior.  Sigh.
	 */
	down_write(&current->mm->mmap_sem);
	(void) do_mmap(NULL, 0, 4096, PROT_READ | PROT_EXEC,
		       MAP_FIXED | MAP_PRIVATE, 0);
	up_write(&current->mm->mmap_sem);
#endif

	start_thread(regs, elf_entry, bprm->p);
	if (current->ptrace & PT_PTRACED)
		send_sig(SIGTRAP, current, 0);
	return 0;
out:
	return retval;

out_free_dentry:
	allow_write_access(interpreter);
	fput(interpreter);
out_free_interp:
	kfree(elf_interpreter);
out_free_file:
out_free_ph:
	kfree(elf_phdata);
	goto out;
}
/* These are the functions used to load ELF style executables and shared
 * libraries.  There is no binary dependent code anywhere else.
 */
static int load_irix_binary(struct linux_binprm * bprm, struct pt_regs * regs)
{
	struct elfhdr elf_ex, interp_elf_ex;
	struct file *interpreter;
	struct elf_phdr *elf_phdata, *elf_ihdr, *elf_ephdr;
	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 retval, has_interp, has_ephdr, size, i;
	char *elf_interpreter;
	mm_segment_t old_fs;

	load_addr = 0;
	has_interp = has_ephdr = 0;
	elf_ihdr = elf_ephdr = 0;
	elf_ex = *((struct elfhdr *) bprm->buf);
	retval = -ENOEXEC;

	if (verify_binary(&elf_ex, bprm))
		goto out;

#ifdef DEBUG_ELF
	print_elfhdr(&elf_ex);
#endif

	/* Now read in all of the header information */
	size = elf_ex.e_phentsize * elf_ex.e_phnum;
	if (size > 65536)
		goto out;
	elf_phdata = (struct elf_phdr *) kmalloc(size, GFP_KERNEL);
	if (elf_phdata == NULL) {
		retval = -ENOMEM;
		goto out;
	}

	retval = kernel_read(bprm->file, elf_ex.e_phoff, (char *)elf_phdata, size);
	if (retval < 0)
		goto out_free_ph;

#ifdef DEBUG_ELF
	dump_phdrs(elf_phdata, elf_ex.e_phnum);
#endif

	/* Set some things for later. */
	for(i = 0; i < elf_ex.e_phnum; i++) {
		switch(elf_phdata[i].p_type) {
		case PT_INTERP:
			has_interp = 1;
			elf_ihdr = &elf_phdata[i];
			break;
		case PT_PHDR:
			has_ephdr = 1;
			elf_ephdr = &elf_phdata[i];
			break;
		};
	}
#ifdef DEBUG_ELF
	printk("\n");
#endif

	elf_bss = 0;
	elf_brk = 0;

	elf_stack = 0xffffffff;
	elf_interpreter = NULL;
	start_code = 0xffffffff;
	end_code = 0;
	end_data = 0;

	retval = look_for_irix_interpreter(&elf_interpreter,
	                                   &interpreter,
					   &interp_elf_ex, elf_phdata, bprm,
					   elf_ex.e_phnum);
	if (retval)
		goto out_free_file;

	if (elf_interpreter) {
		retval = verify_irix_interpreter(&interp_elf_ex);
		if(retval)
			goto out_free_interp;
	}

	/* OK, we are done with that, now set up the arg stuff,
	 * and then start this sucker up.
	 */
	retval = -E2BIG;
	if (!bprm->sh_bang && !bprm->p)
		goto out_free_interp;

	/* Flush all traces of the currently running executable */
	retval = flush_old_exec(bprm);
	if (retval)
		goto out_free_dentry;

	/* OK, This is the point of no return */
	current->mm->end_data = 0;
	current->mm->end_code = 0;
	current->mm->mmap = NULL;
	current->flags &= ~PF_FORKNOEXEC;
	elf_entry = (unsigned int) elf_ex.e_entry;

	/* Do this so that we can load the interpreter, if need be.  We will
	 * change some of these later.
	 */
	current->mm->rss = 0;
	setup_arg_pages(bprm);
	current->mm->start_stack = bprm->p;

	/* At this point, we assume that the image should be loaded at
	 * fixed address, not at a variable address.
	 */
	old_fs = get_fs();
	set_fs(get_ds());

	map_executable(bprm->file, elf_phdata, elf_ex.e_phnum, &elf_stack,
	               &load_addr, &start_code, &elf_bss, &end_code,
	               &end_data, &elf_brk);

	if(elf_interpreter) {
		retval = map_interpreter(elf_phdata, &interp_elf_ex,
					 interpreter, &interp_load_addr,
					 elf_ex.e_phnum, old_fs, &elf_entry);
		kfree(elf_interpreter);
		if(retval) {
			set_fs(old_fs);
			printk("Unable to load IRIX ELF interpreter\n");
			send_sig(SIGSEGV, current, 0);
			retval = 0;
			goto out_free_file;
		}
	}

	set_fs(old_fs);

	kfree(elf_phdata);
	set_personality(PER_IRIX32);
	set_binfmt(&irix_format);
	compute_creds(bprm);
	current->flags &= ~PF_FORKNOEXEC;
	bprm->p = (unsigned long)
	  create_irix_tables((char *)bprm->p, bprm->argc, bprm->envc,
			(elf_interpreter ? &elf_ex : NULL),
			load_addr, interp_load_addr, regs, elf_ephdr);
	current->mm->start_brk = current->mm->brk = elf_brk;
	current->mm->end_code = end_code;
	current->mm->start_code = start_code;
	current->mm->end_data = end_data;
	current->mm->start_stack = bprm->p;

	/* Calling set_brk effectively mmaps the pages that we need for the
	 * bss and break sections.
	 */
	set_brk(elf_bss, elf_brk);

	/*
	 * IRIX maps a page at 0x200000 which holds some system
	 * information.  Programs depend on this.
	 */
	irix_map_prda_page ();

	padzero(elf_bss);

#ifdef DEBUG_ELF
	printk("(start_brk) %lx\n" , (long) current->mm->start_brk);
	printk("(end_code) %lx\n" , (long) current->mm->end_code);
	printk("(start_code) %lx\n" , (long) current->mm->start_code);
	printk("(end_data) %lx\n" , (long) current->mm->end_data);
	printk("(start_stack) %lx\n" , (long) current->mm->start_stack);
	printk("(brk) %lx\n" , (long) current->mm->brk);
#endif

#if 0 /* XXX No f*****g way dude... */
	/* Why this, you ask???  Well SVr4 maps page 0 as read-only,
	 * and some applications "depend" upon this behavior.
	 * Since we do not have the power to recompile these, we
	 * emulate the SVr4 behavior.  Sigh.
	 */
	down_write(&current->mm->mmap_sem);
	(void) do_mmap(NULL, 0, 4096, PROT_READ | PROT_EXEC,
		       MAP_FIXED | MAP_PRIVATE, 0);
	up_write(&current->mm->mmap_sem);
#endif

	start_thread(regs, elf_entry, bprm->p);
	if (current->ptrace & PT_PTRACED)
		send_sig(SIGTRAP, current, 0);
	return 0;
out:
	return retval;

out_free_dentry:
	allow_write_access(interpreter);
	fput(interpreter);
out_free_interp:
	if (elf_interpreter)
		kfree(elf_interpreter);
out_free_file:
out_free_ph:
	kfree (elf_phdata);
	goto out;
}