Example #1
0
//--------------------------------------------------------------------------
int get_aout_file_format_index(linput_t *li)
{
  exec ex;
  register int i = 0;
  if(qlread(li, &ex, sizeof(ex)) != sizeof(ex)) return false;

  if(N_BADMAG(ex)) {
    ex.a_info = swap32(ex.a_info);
    switch(N_MACHTYPE(ex)) {
      case M_386_NETBSD:
      case M_68K_NETBSD:
      case M_68K4K_NETBSD:
      case M_532_NETBSD:
      case M_SPARC_NETBSD:
      case M_PMAX_NETBSD:
      case M_VAX_NETBSD:
      case M_ALPHA_NETBSD:
      case M_ARM6_NETBSD:
        break;

      default:
        return false;
    }
  }

  switch(N_MAGIC(ex)) {
    case NMAGIC:
      ++i;
    case CMAGIC:
      ++i;
    case ZMAGIC:
      ++i;
    case OMAGIC:
      ++i;
    case QMAGIC:
//      msg("text=%d data=%d symsize=%d txtoff=%d sum=%d\n", ex.a_text, ex.a_data,
//                N_SYMSIZE(ex), N_TXTOFF(ex), ex.a_text + ex.a_data + N_SYMSIZE(ex) + N_TXTOFF(ex));
      if ( qlsize(li) >= ex.a_text + ex.a_data + N_SYMSIZE(ex) + N_TXTOFF(ex) )
        break;
      if ( N_MAGIC(ex) == ZMAGIC
        && qlsize(li) >= ex.a_text + ex.a_data + N_SYMSIZE(ex) )
      {
        i = 5; // OpenBSD demand-paged
        break;
      }
    default:
      return false;
  }

  return i+1;
}
Example #2
0
static inline int
do_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);

#if defined (__i386__) || defined (CONFIG_ARM)
	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
#if defined(CONFIG_ARM)
	if (N_MACHTYPE(ex) != M_ARM) {
		printk(KERN_NOTICE "Binary != ARM.  Please recompile 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;

	if (flush_old_exec(bprm))
		return -ENOMEM;

	/* OK, This is the point of no return */

	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;
 	current->flags &= ~PF_FORKNOEXEC;
	if (N_MAGIC(ex) == OMAGIC) {
#if defined(__alpha__) || defined(CONFIG_ARM)
#ifndef CONFIG_ARM
		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);
#else
		do_mmap(NULL, N_TXTADDR(ex),
			ex.a_text+ex.a_data,
			PROT_READ|PROT_WRITE|PROT_EXEC,
			MAP_FIXED|MAP_PRIVATE, 0);
#endif
		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) {
			send_sig(SIGKILL, current, 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);

	p = setup_arg_pages(p, bprm);
	
	p = (unsigned long) create_aout_tables((char *)p, bprm);
	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);
#ifndef CONFIG_ARM
	return 0;
#else
	return regs->ARM_r0;
#endif
}