aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2012-08-21 22:32:06 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2012-09-26 21:09:59 -0400
commitc3c073f808b22dfae15ef8412b6f7b998644139a (patch)
tree3369bcbe414738d90e6ccfe257f6ce3e72f6a5ae /security
parentad47bd7252bf402fe7dba92f5240b5ed16832ae7 (diff)
new helper: iterate_fd()
iterates through the opened files in given descriptor table, calling a supplied function; we stop once non-zero is returned. Callback gets struct file *, descriptor number and const void * argument passed to iterator. It is called with files->file_lock held, so it is not allowed to block. tty_io, netprio_cgroup and selinux flush_unauthorized_files() converted to its use. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'security')
-rw-r--r--security/selinux/hooks.c57
1 files changed, 22 insertions, 35 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 00b50113642d..4dfbcea10eb7 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -2088,15 +2088,19 @@ static int selinux_bprm_secureexec(struct linux_binprm *bprm)
2088 return (atsecure || cap_bprm_secureexec(bprm)); 2088 return (atsecure || cap_bprm_secureexec(bprm));
2089} 2089}
2090 2090
2091static int match_file(const void *p, struct file *file, unsigned fd)
2092{
2093 return file_has_perm(p, file, file_to_av(file)) ? fd + 1 : 0;
2094}
2095
2091/* Derived from fs/exec.c:flush_old_files. */ 2096/* Derived from fs/exec.c:flush_old_files. */
2092static inline void flush_unauthorized_files(const struct cred *cred, 2097static inline void flush_unauthorized_files(const struct cred *cred,
2093 struct files_struct *files) 2098 struct files_struct *files)
2094{ 2099{
2095 struct file *file, *devnull = NULL; 2100 struct file *file, *devnull = NULL;
2096 struct tty_struct *tty; 2101 struct tty_struct *tty;
2097 struct fdtable *fdt;
2098 long j = -1;
2099 int drop_tty = 0; 2102 int drop_tty = 0;
2103 unsigned n;
2100 2104
2101 tty = get_current_tty(); 2105 tty = get_current_tty();
2102 if (tty) { 2106 if (tty) {
@@ -2123,41 +2127,24 @@ static inline void flush_unauthorized_files(const struct cred *cred,
2123 no_tty(); 2127 no_tty();
2124 2128
2125 /* Revalidate access to inherited open files. */ 2129 /* Revalidate access to inherited open files. */
2126 spin_lock(&files->file_lock); 2130 n = iterate_fd(files, 0, match_file, cred);
2127 for (;;) { 2131 if (!n) /* none found? */
2128 unsigned long set, i; 2132 return;
2129 j++;
2130 i = j * BITS_PER_LONG;
2131 fdt = files_fdtable(files);
2132 if (i >= fdt->max_fds)
2133 break;
2134 set = fdt->open_fds[j];
2135 if (!set)
2136 continue;
2137 spin_unlock(&files->file_lock);
2138 for ( ; set ; i++, set >>= 1) {
2139 if (!(set & 1))
2140 continue;
2141 file = fget(i);
2142 if (!file)
2143 continue;
2144 if (file_has_perm(cred, file, file_to_av(file))) {
2145 if (devnull) {
2146 get_file(devnull);
2147 } else {
2148 devnull = dentry_open(&selinux_null,
2149 O_RDWR, cred);
2150 if (IS_ERR(devnull))
2151 devnull = NULL;
2152 }
2153 replace_fd(i, devnull, 0);
2154 }
2155 fput(file);
2156 }
2157 spin_lock(&files->file_lock);
2158 2133
2134 devnull = dentry_open(&selinux_null, O_RDWR, cred);
2135 if (!IS_ERR(devnull)) {
2136 /* replace all the matching ones with this */
2137 do {
2138 get_file(devnull);
2139 replace_fd(n - 1, devnull, 0);
2140 } while ((n = iterate_fd(files, n, match_file, cred)) != 0);
2141 fput(devnull);
2142 } else {
2143 /* just close all the matching ones */
2144 do {
2145 replace_fd(n - 1, NULL, 0);
2146 } while ((n = iterate_fd(files, n, match_file, cred)) != 0);
2159 } 2147 }
2160 spin_unlock(&files->file_lock);
2161} 2148}
2162 2149
2163/* 2150/*