diff options
Diffstat (limited to 'fs/compat.c')
| -rw-r--r-- | fs/compat.c | 235 | 
1 files changed, 0 insertions, 235 deletions
diff --git a/fs/compat.c b/fs/compat.c index 72fe6cda910..0ea00832de2 100644 --- a/fs/compat.c +++ b/fs/compat.c @@ -1306,241 +1306,6 @@ compat_sys_openat(unsigned int dfd, const char __user *filename, int flags, int  	return do_sys_open(dfd, filename, flags, mode);  } -/* - * compat_count() counts the number of arguments/envelopes. It is basically - * a copy of count() from fs/exec.c, except that it works with 32 bit argv - * and envp pointers. - */ -static int compat_count(compat_uptr_t __user *argv, int max) -{ -	int i = 0; - -	if (argv != NULL) { -		for (;;) { -			compat_uptr_t p; - -			if (get_user(p, argv)) -				return -EFAULT; -			if (!p) -				break; -			argv++; -			if (i++ >= max) -				return -E2BIG; - -			if (fatal_signal_pending(current)) -				return -ERESTARTNOHAND; -			cond_resched(); -		} -	} -	return i; -} - -/* - * compat_copy_strings() is basically a copy of copy_strings() from fs/exec.c - * except that it works with 32 bit argv and envp pointers. - */ -static int compat_copy_strings(int argc, compat_uptr_t __user *argv, -				struct linux_binprm *bprm) -{ -	struct page *kmapped_page = NULL; -	char *kaddr = NULL; -	unsigned long kpos = 0; -	int ret; - -	while (argc-- > 0) { -		compat_uptr_t str; -		int len; -		unsigned long pos; - -		if (get_user(str, argv+argc) || -		    !(len = strnlen_user(compat_ptr(str), MAX_ARG_STRLEN))) { -			ret = -EFAULT; -			goto out; -		} - -		if (len > MAX_ARG_STRLEN) { -			ret = -E2BIG; -			goto out; -		} - -		/* We're going to work our way backwords. */ -		pos = bprm->p; -		str += len; -		bprm->p -= len; - -		while (len > 0) { -			int offset, bytes_to_copy; - -			if (fatal_signal_pending(current)) { -				ret = -ERESTARTNOHAND; -				goto out; -			} -			cond_resched(); - -			offset = pos % PAGE_SIZE; -			if (offset == 0) -				offset = PAGE_SIZE; - -			bytes_to_copy = offset; -			if (bytes_to_copy > len) -				bytes_to_copy = len; - -			offset -= bytes_to_copy; -			pos -= bytes_to_copy; -			str -= bytes_to_copy; -			len -= bytes_to_copy; - -			if (!kmapped_page || kpos != (pos & PAGE_MASK)) { -				struct page *page; - -				page = get_arg_page(bprm, pos, 1); -				if (!page) { -					ret = -E2BIG; -					goto out; -				} - -				if (kmapped_page) { -					flush_kernel_dcache_page(kmapped_page); -					kunmap(kmapped_page); -					put_page(kmapped_page); -				} -				kmapped_page = page; -				kaddr = kmap(kmapped_page); -				kpos = pos & PAGE_MASK; -				flush_cache_page(bprm->vma, kpos, -						 page_to_pfn(kmapped_page)); -			} -			if (copy_from_user(kaddr+offset, compat_ptr(str), -						bytes_to_copy)) { -				ret = -EFAULT; -				goto out; -			} -		} -	} -	ret = 0; -out: -	if (kmapped_page) { -		flush_kernel_dcache_page(kmapped_page); -		kunmap(kmapped_page); -		put_page(kmapped_page); -	} -	return ret; -} - -/* - * compat_do_execve() is mostly a copy of do_execve(), with the exception - * that it processes 32 bit argv and envp pointers. - */ -int compat_do_execve(char * filename, -	compat_uptr_t __user *argv, -	compat_uptr_t __user *envp, -	struct pt_regs * regs) -{ -	struct linux_binprm *bprm; -	struct file *file; -	struct files_struct *displaced; -	bool clear_in_exec; -	int retval; - -	retval = unshare_files(&displaced); -	if (retval) -		goto out_ret; - -	retval = -ENOMEM; -	bprm = kzalloc(sizeof(*bprm), GFP_KERNEL); -	if (!bprm) -		goto out_files; - -	retval = prepare_bprm_creds(bprm); -	if (retval) -		goto out_free; - -	retval = check_unsafe_exec(bprm); -	if (retval < 0) -		goto out_free; -	clear_in_exec = retval; -	current->in_execve = 1; - -	file = open_exec(filename); -	retval = PTR_ERR(file); -	if (IS_ERR(file)) -		goto out_unmark; - -	sched_exec(); - -	bprm->file = file; -	bprm->filename = filename; -	bprm->interp = filename; - -	retval = bprm_mm_init(bprm); -	if (retval) -		goto out_file; - -	bprm->argc = compat_count(argv, MAX_ARG_STRINGS); -	if ((retval = bprm->argc) < 0) -		goto out; - -	bprm->envc = compat_count(envp, MAX_ARG_STRINGS); -	if ((retval = bprm->envc) < 0) -		goto out; - -	retval = prepare_binprm(bprm); -	if (retval < 0) -		goto out; - -	retval = copy_strings_kernel(1, &bprm->filename, bprm); -	if (retval < 0) -		goto out; - -	bprm->exec = bprm->p; -	retval = compat_copy_strings(bprm->envc, envp, bprm); -	if (retval < 0) -		goto out; - -	retval = compat_copy_strings(bprm->argc, argv, bprm); -	if (retval < 0) -		goto out; - -	retval = search_binary_handler(bprm, regs); -	if (retval < 0) -		goto out; - -	/* execve succeeded */ -	current->fs->in_exec = 0; -	current->in_execve = 0; -	acct_update_integrals(current); -	free_bprm(bprm); -	if (displaced) -		put_files_struct(displaced); -	return retval; - -out: -	if (bprm->mm) { -		acct_arg_size(bprm, 0); -		mmput(bprm->mm); -	} - -out_file: -	if (bprm->file) { -		allow_write_access(bprm->file); -		fput(bprm->file); -	} - -out_unmark: -	if (clear_in_exec) -		current->fs->in_exec = 0; -	current->in_execve = 0; - -out_free: -	free_bprm(bprm); - -out_files: -	if (displaced) -		reset_files_struct(displaced); -out_ret: -	return retval; -} -  #define __COMPAT_NFDBITS       (8 * sizeof(compat_ulong_t))  static int poll_select_copy_remaining(struct timespec *end_time, void __user *p,  |