diff options
Diffstat (limited to 'security/selinux/hooks.c')
| -rw-r--r-- | security/selinux/hooks.c | 57 | 
1 files changed, 22 insertions, 35 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 00b50113642..4dfbcea10eb 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -2088,15 +2088,19 @@ static int selinux_bprm_secureexec(struct linux_binprm *bprm)  	return (atsecure || cap_bprm_secureexec(bprm));  } +static int match_file(const void *p, struct file *file, unsigned fd) +{ +	return file_has_perm(p, file, file_to_av(file)) ? fd + 1 : 0; +} +  /* Derived from fs/exec.c:flush_old_files. */  static inline void flush_unauthorized_files(const struct cred *cred,  					    struct files_struct *files)  {  	struct file *file, *devnull = NULL;  	struct tty_struct *tty; -	struct fdtable *fdt; -	long j = -1;  	int drop_tty = 0; +	unsigned n;  	tty = get_current_tty();  	if (tty) { @@ -2123,41 +2127,24 @@ static inline void flush_unauthorized_files(const struct cred *cred,  		no_tty();  	/* Revalidate access to inherited open files. */ -	spin_lock(&files->file_lock); -	for (;;) { -		unsigned long set, i; -		j++; -		i = j * BITS_PER_LONG; -		fdt = files_fdtable(files); -		if (i >= fdt->max_fds) -			break; -		set = fdt->open_fds[j]; -		if (!set) -			continue; -		spin_unlock(&files->file_lock); -		for ( ; set ; i++, set >>= 1) { -			if (!(set & 1)) -				continue; -			file = fget(i); -			if (!file) -				continue; -			if (file_has_perm(cred, file, file_to_av(file))) { -				if (devnull) { -					get_file(devnull); -				} else { -					devnull = dentry_open(&selinux_null, -								O_RDWR, cred); -					if (IS_ERR(devnull)) -						devnull = NULL; -				} -				replace_fd(i, devnull, 0); -			} -			fput(file); -		} -		spin_lock(&files->file_lock); +	n = iterate_fd(files, 0, match_file, cred); +	if (!n) /* none found? */ +		return; +	devnull = dentry_open(&selinux_null, O_RDWR, cred); +	if (!IS_ERR(devnull)) { +		/* replace all the matching ones with this */ +		do { +			get_file(devnull); +			replace_fd(n - 1, devnull, 0); +		} while ((n = iterate_fd(files, n, match_file, cred)) != 0); +		fput(devnull); +	} else { +		/* just close all the matching ones */ +		do { +			replace_fd(n - 1, NULL, 0); +		} while ((n = iterate_fd(files, n, match_file, cred)) != 0);  	} -	spin_unlock(&files->file_lock);  }  /*  |