diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2012-08-21 22:32:06 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2012-09-26 21:09:59 -0400 |
commit | c3c073f808b22dfae15ef8412b6f7b998644139a (patch) | |
tree | 3369bcbe414738d90e6ccfe257f6ce3e72f6a5ae /security | |
parent | ad47bd7252bf402fe7dba92f5240b5ed16832ae7 (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.c | 57 |
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 | ||
2091 | static 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. */ |
2092 | static inline void flush_unauthorized_files(const struct cred *cred, | 2097 | static 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 | /* |