diff options
Diffstat (limited to 'security')
-rw-r--r-- | security/selinux/hooks.c | 73 |
1 files changed, 21 insertions, 52 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 6c77f63c7591..651d8456611a 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,58 +2127,23 @@ 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 | int fd; | ||
2130 | |||
2131 | j++; | ||
2132 | i = j * BITS_PER_LONG; | ||
2133 | fdt = files_fdtable(files); | ||
2134 | if (i >= fdt->max_fds) | ||
2135 | break; | ||
2136 | set = fdt->open_fds[j]; | ||
2137 | if (!set) | ||
2138 | continue; | ||
2139 | spin_unlock(&files->file_lock); | ||
2140 | for ( ; set ; i++, set >>= 1) { | ||
2141 | if (set & 1) { | ||
2142 | file = fget(i); | ||
2143 | if (!file) | ||
2144 | continue; | ||
2145 | if (file_has_perm(cred, | ||
2146 | file, | ||
2147 | file_to_av(file))) { | ||
2148 | sys_close(i); | ||
2149 | fd = get_unused_fd(); | ||
2150 | if (fd != i) { | ||
2151 | if (fd >= 0) | ||
2152 | put_unused_fd(fd); | ||
2153 | fput(file); | ||
2154 | continue; | ||
2155 | } | ||
2156 | if (devnull) { | ||
2157 | get_file(devnull); | ||
2158 | } else { | ||
2159 | devnull = dentry_open( | ||
2160 | &selinux_null, | ||
2161 | O_RDWR, cred); | ||
2162 | if (IS_ERR(devnull)) { | ||
2163 | devnull = NULL; | ||
2164 | put_unused_fd(fd); | ||
2165 | fput(file); | ||
2166 | continue; | ||
2167 | } | ||
2168 | } | ||
2169 | fd_install(fd, devnull); | ||
2170 | } | ||
2171 | fput(file); | ||
2172 | } | ||
2173 | } | ||
2174 | spin_lock(&files->file_lock); | ||
2175 | 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 | replace_fd(n - 1, get_file(devnull), 0); | ||
2139 | } while ((n = iterate_fd(files, n, match_file, cred)) != 0); | ||
2140 | fput(devnull); | ||
2141 | } else { | ||
2142 | /* just close all the matching ones */ | ||
2143 | do { | ||
2144 | replace_fd(n - 1, NULL, 0); | ||
2145 | } while ((n = iterate_fd(files, n, match_file, cred)) != 0); | ||
2176 | } | 2146 | } |
2177 | spin_unlock(&files->file_lock); | ||
2178 | } | 2147 | } |
2179 | 2148 | ||
2180 | /* | 2149 | /* |