diff options
Diffstat (limited to 'fs/exec.c')
| -rw-r--r-- | fs/exec.c | 39 | 
1 files changed, 30 insertions, 9 deletions
diff --git a/fs/exec.c b/fs/exec.c index 183059c427b9..2d4e0075bd24 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -1706,14 +1706,13 @@ static int exec_binprm(struct linux_binprm *bprm)  /*   * sys_execve() executes a new program.   */ -static int do_execveat_common(int fd, struct filename *filename, -			      struct user_arg_ptr argv, -			      struct user_arg_ptr envp, -			      int flags) +static int __do_execve_file(int fd, struct filename *filename, +			    struct user_arg_ptr argv, +			    struct user_arg_ptr envp, +			    int flags, struct file *file)  {  	char *pathbuf = NULL;  	struct linux_binprm *bprm; -	struct file *file;  	struct files_struct *displaced;  	int retval; @@ -1752,7 +1751,8 @@ static int do_execveat_common(int fd, struct filename *filename,  	check_unsafe_exec(bprm);  	current->in_execve = 1; -	file = do_open_execat(fd, filename, flags); +	if (!file) +		file = do_open_execat(fd, filename, flags);  	retval = PTR_ERR(file);  	if (IS_ERR(file))  		goto out_unmark; @@ -1760,7 +1760,9 @@ static int do_execveat_common(int fd, struct filename *filename,  	sched_exec();  	bprm->file = file; -	if (fd == AT_FDCWD || filename->name[0] == '/') { +	if (!filename) { +		bprm->filename = "none"; +	} else if (fd == AT_FDCWD || filename->name[0] == '/') {  		bprm->filename = filename->name;  	} else {  		if (filename->name[0] == '\0') @@ -1822,11 +1824,13 @@ static int do_execveat_common(int fd, struct filename *filename,  	current->fs->in_exec = 0;  	current->in_execve = 0;  	membarrier_execve(current); +	rseq_execve(current);  	acct_update_integrals(current);  	task_numa_free(current);  	free_bprm(bprm);  	kfree(pathbuf); -	putname(filename); +	if (filename) +		putname(filename);  	if (displaced)  		put_files_struct(displaced);  	return retval; @@ -1849,10 +1853,27 @@ out_files:  	if (displaced)  		reset_files_struct(displaced);  out_ret: -	putname(filename); +	if (filename) +		putname(filename);  	return retval;  } +static int do_execveat_common(int fd, struct filename *filename, +			      struct user_arg_ptr argv, +			      struct user_arg_ptr envp, +			      int flags) +{ +	return __do_execve_file(fd, filename, argv, envp, flags, NULL); +} + +int do_execve_file(struct file *file, void *__argv, void *__envp) +{ +	struct user_arg_ptr argv = { .ptr.native = __argv }; +	struct user_arg_ptr envp = { .ptr.native = __envp }; + +	return __do_execve_file(AT_FDCWD, NULL, argv, envp, 0, file); +} +  int do_execve(struct filename *filename,  	const char __user *const __user *__argv,  	const char __user *const __user *__envp)  |