Ejemplo n.º 1
0
/**
 * Copy a NULL-terminated array of strings from user memory.
 *
 * Copies a NULL-terminated array of strings from user memory. The array
 * itself and each array entry must be freed with kfree() once no longer
 * needed.
 *
 * @param src		Array to copy.
 * @param arrayp	Pointer to location in which to store address of
 *			allocated array.
 *
 * @return		Status code describing result of the operation.
 */
status_t arrcpy_from_user(const char *const src[], char ***arrayp) {
	char **array = NULL, **narr;
	status_t ret;
	int i;

	/* Copy the arrays across. */
	for(i = 0; ; i++) {
		narr = krealloc(array, sizeof(char *) * (i + 1), MM_USER);
		if(!narr) {
			ret = STATUS_NO_MEMORY;
			goto fail;
		}

		array = narr;
		array[i] = NULL;

		ret = memcpy_from_user(&array[i], &src[i], sizeof(char *));
		if(ret != STATUS_SUCCESS) {
			array[i] = NULL;
			goto fail;
		} else if(array[i] == NULL) {
			break;
		}

		ret = strdup_from_user(array[i], &array[i]);
		if(ret != STATUS_SUCCESS) {
			array[i] = NULL;
			goto fail;
		}
	}

	*arrayp = array;
	return STATUS_SUCCESS;
fail:
	if(array) {
		for(i = 0; array[i] != NULL; i++)
			kfree(array[i]);

		kfree(array);
	}

	return ret;
}
Ejemplo n.º 2
0
int _sys_write(unsigned int handle, const char *buf, size_t count)
{
	struct file *fd;
	struct task *me;
	char *kbuf;

	if ( handle == 1 ) {
		return _sys_write_stdout(handle, (void *)buf, count);
	}

	kbuf = strdup_from_user(buf, UACCESS_KERNEL_OK);
	if ( NULL == kbuf )
		return -1; /* EFAULT or ENOMEM */

	me = __this_task;
	fd = fdt_entry_retr(me->fd_table, handle);
	if ( NULL == fd )
		return -1; /* EMAXFILE */
	return kernel_write(fd, kbuf, count);
}
Ejemplo n.º 3
0
int _sys_exec(const char *path)
{
	struct mem_ctx *ctx;
	struct inode *inode;
	uint8_t *phbuf, *ph;
	struct task *tsk;
	unsigned int i;
	Elf32_Ehdr hdr;
	size_t phbufsz;
	char *kpath;
	ssize_t ret;

	kpath = strdup_from_user(path, UACCESS_KERNEL_OK);
	if ( NULL == kpath )
		return -1; /* EFAULT or ENOMEM */

	inode = namei(kpath);
	if ( NULL == inode ) {
		printk("exec: %s: ENOENT or ENOTDIR\n", kpath);
		kfree(kpath);
		return -1;
	}

	printk("exec: %s: mode 0%lo, %lu bytes in %lu blocks\n",
		kpath, inode->i_mode, inode->i_size, inode->i_blocks);

	kfree(kpath);

	ret = inode->i_iop->pread(inode, &hdr, sizeof(hdr), 0);
	if ( ret <= 0 || (size_t)ret != sizeof(hdr) ) {
		printk("exec: unable to read ELF header\n");
		return -1;
	}

	if ( !memcmp(hdr.e_ident, ELFMAG, sizeof(hdr.e_ident)) ) {
		printk("exec: bad ELF magic\n");
		return -1; /* ENOEXEC */
	}

	if ( hdr.e_type != ET_EXEC ) {
		printk("exec: not an ELF executable\n");
		return -1; /* ENOEXEC */
	}

	if ( hdr.e_machine != EM_386 ) {
		printk("exec: not an IA-32 executable\n");
		return -1; /* ENOEXEC */
	}

	if ( hdr.e_phentsize < sizeof(Elf32_Phdr) ) {
		printk("exec: Unexpectedly short program header entry size\n");
		return -1; /* ENOEXEC */
	}

	dprintk("exec: Program header contains %u entries\n", hdr.e_phnum);

	phbufsz = hdr.e_phentsize * hdr.e_phnum;
	phbuf = kmalloc(phbufsz);
	if ( NULL == phbuf )
		return -1; /* ENOMEM */

	ret = inode->i_iop->pread(inode, phbuf, phbufsz, hdr.e_phoff);
	if ( ret <= 0 || (size_t)ret != phbufsz ) {
		printk("exec: unable to read program header\n");
		goto err_free; /* ENOEXEC */
	}

	tsk = __this_task;

	ctx = mem_ctx_new();
	if ( NULL == ctx )
		goto err_free;

	for(ph = phbuf, i = 0; i < hdr.e_phnum; i++, ph += hdr.e_phentsize) {
		Elf32_Phdr *phdr = (Elf32_Phdr *)ph;
		if ( phdr->p_type != PT_LOAD )
			continue;
		if ( setup_vma(ctx, phdr->p_vaddr, phdr->p_memsz,
				PROT_READ|PROT_EXEC, inode, phdr->p_offset) )
			goto err_free_ctx;
		printk("elf: PT_LOAD: va=0x%.8lx %lu bytes from offset %lu\n",
			phdr->p_vaddr, phdr->p_filesz, phdr->p_offset);
	}

	/* setup usermode stack */
	if ( setup_vma(ctx, 0x80000000 - PAGE_SIZE, PAGE_SIZE,
			PROT_READ|PROT_WRITE, NULL, 0) )
		goto err_free_ctx;

	kfree(phbuf);

	/* commit to the exec, all the way now */
	cli();
	mem_use_ctx(ctx);
	mem_ctx_put(tsk->ctx);
	tsk->ctx = ctx;
	task_init_exec(tsk, hdr.e_entry, 0x80000000);
	return 0;

err_free_ctx:
	mem_ctx_put(ctx);
err_free:
	kfree(phbuf);
	return -1;
}
Ejemplo n.º 4
0
Archivo: rstr.c Proyecto: IRATI/stack
string_t * string_from_user(const char __user * src)
{ return strdup_from_user(src); }