diff options
Diffstat (limited to 'fs/exec.c')
| -rw-r--r-- | fs/exec.c | 42 | 
1 files changed, 22 insertions, 20 deletions
diff --git a/fs/exec.c b/fs/exec.c index 8875dd10ae7a..977319fd77f3 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -106,6 +106,7 @@ static inline void put_binfmt(struct linux_binfmt * fmt)   */  SYSCALL_DEFINE1(uselib, const char __user *, library)  { +	struct linux_binfmt *fmt;  	struct file *file;  	struct filename *tmp = getname(library);  	int error = PTR_ERR(tmp); @@ -136,24 +137,21 @@ SYSCALL_DEFINE1(uselib, const char __user *, library)  	fsnotify_open(file);  	error = -ENOEXEC; -	if(file->f_op) { -		struct linux_binfmt * fmt; -		read_lock(&binfmt_lock); -		list_for_each_entry(fmt, &formats, lh) { -			if (!fmt->load_shlib) -				continue; -			if (!try_module_get(fmt->module)) -				continue; -			read_unlock(&binfmt_lock); -			error = fmt->load_shlib(file); -			read_lock(&binfmt_lock); -			put_binfmt(fmt); -			if (error != -ENOEXEC) -				break; -		} +	read_lock(&binfmt_lock); +	list_for_each_entry(fmt, &formats, lh) { +		if (!fmt->load_shlib) +			continue; +		if (!try_module_get(fmt->module)) +			continue;  		read_unlock(&binfmt_lock); +		error = fmt->load_shlib(file); +		read_lock(&binfmt_lock); +		put_binfmt(fmt); +		if (error != -ENOEXEC) +			break;  	} +	read_unlock(&binfmt_lock);  exit:  	fput(file);  out: @@ -1277,13 +1275,10 @@ static int check_unsafe_exec(struct linux_binprm *bprm)   */  int prepare_binprm(struct linux_binprm *bprm)  { -	umode_t mode; -	struct inode * inode = file_inode(bprm->file); +	struct inode *inode = file_inode(bprm->file); +	umode_t mode = inode->i_mode;  	int retval; -	mode = inode->i_mode; -	if (bprm->file->f_op == NULL) -		return -EACCES;  	/* clear any previous set[ug]id data from a previous binary */  	bprm->cred->euid = current_euid(); @@ -1547,6 +1542,7 @@ static int do_execve_common(const char *filename,  	current->fs->in_exec = 0;  	current->in_execve = 0;  	acct_update_integrals(current); +	task_numa_free(current);  	free_bprm(bprm);  	if (displaced)  		put_files_struct(displaced); @@ -1668,6 +1664,12 @@ int __get_dumpable(unsigned long mm_flags)  	return (ret > SUID_DUMP_USER) ? SUID_DUMP_ROOT : ret;  } +/* + * This returns the actual value of the suid_dumpable flag. For things + * that are using this for checking for privilege transitions, it must + * test against SUID_DUMP_USER rather than treating it as a boolean + * value. + */  int get_dumpable(struct mm_struct *mm)  {  	return __get_dumpable(mm->flags);  |