diff options
-rw-r--r-- | arch/alpha/kernel/osf_sys.c | 6 | ||||
-rw-r--r-- | arch/mips/kernel/kspd.c | 2 | ||||
-rw-r--r-- | fs/compat.c | 10 | ||||
-rw-r--r-- | fs/exec.c | 2 | ||||
-rw-r--r-- | fs/fcntl.c | 5 | ||||
-rw-r--r-- | fs/file.c | 56 | ||||
-rw-r--r-- | fs/open.c | 3 | ||||
-rw-r--r-- | fs/select.c | 10 | ||||
-rw-r--r-- | include/linux/file.h | 6 | ||||
-rw-r--r-- | include/linux/init_task.h | 1 | ||||
-rw-r--r-- | kernel/exit.c | 2 | ||||
-rw-r--r-- | kernel/fork.c | 24 | ||||
-rw-r--r-- | security/selinux/hooks.c | 2 |
13 files changed, 48 insertions, 81 deletions
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c index fb804043b320..be133f1f75a4 100644 --- a/arch/alpha/kernel/osf_sys.c +++ b/arch/alpha/kernel/osf_sys.c | |||
@@ -979,7 +979,7 @@ osf_select(int n, fd_set __user *inp, fd_set __user *outp, fd_set __user *exp, | |||
979 | long timeout; | 979 | long timeout; |
980 | int ret = -EINVAL; | 980 | int ret = -EINVAL; |
981 | struct fdtable *fdt; | 981 | struct fdtable *fdt; |
982 | int max_fdset; | 982 | int max_fds; |
983 | 983 | ||
984 | timeout = MAX_SCHEDULE_TIMEOUT; | 984 | timeout = MAX_SCHEDULE_TIMEOUT; |
985 | if (tvp) { | 985 | if (tvp) { |
@@ -1003,9 +1003,9 @@ osf_select(int n, fd_set __user *inp, fd_set __user *outp, fd_set __user *exp, | |||
1003 | 1003 | ||
1004 | rcu_read_lock(); | 1004 | rcu_read_lock(); |
1005 | fdt = files_fdtable(current->files); | 1005 | fdt = files_fdtable(current->files); |
1006 | max_fdset = fdt->max_fdset; | 1006 | max_fds = fdt->max_fds; |
1007 | rcu_read_unlock(); | 1007 | rcu_read_unlock(); |
1008 | if (n < 0 || n > max_fdset) | 1008 | if (n < 0 || n > max_fds) |
1009 | goto out_nofds; | 1009 | goto out_nofds; |
1010 | 1010 | ||
1011 | /* | 1011 | /* |
diff --git a/arch/mips/kernel/kspd.c b/arch/mips/kernel/kspd.c index 2c82412b9efe..5929f883e46b 100644 --- a/arch/mips/kernel/kspd.c +++ b/arch/mips/kernel/kspd.c | |||
@@ -301,7 +301,7 @@ static void sp_cleanup(void) | |||
301 | for (;;) { | 301 | for (;;) { |
302 | unsigned long set; | 302 | unsigned long set; |
303 | i = j * __NFDBITS; | 303 | i = j * __NFDBITS; |
304 | if (i >= fdt->max_fdset || i >= fdt->max_fds) | 304 | if (i >= fdt->max_fds) |
305 | break; | 305 | break; |
306 | set = fdt->open_fds->fds_bits[j++]; | 306 | set = fdt->open_fds->fds_bits[j++]; |
307 | while (set) { | 307 | while (set) { |
diff --git a/fs/compat.c b/fs/compat.c index b766964a625c..0ec70e3cee0a 100644 --- a/fs/compat.c +++ b/fs/compat.c | |||
@@ -1679,19 +1679,19 @@ int compat_core_sys_select(int n, compat_ulong_t __user *inp, | |||
1679 | { | 1679 | { |
1680 | fd_set_bits fds; | 1680 | fd_set_bits fds; |
1681 | char *bits; | 1681 | char *bits; |
1682 | int size, max_fdset, ret = -EINVAL; | 1682 | int size, max_fds, ret = -EINVAL; |
1683 | struct fdtable *fdt; | 1683 | struct fdtable *fdt; |
1684 | 1684 | ||
1685 | if (n < 0) | 1685 | if (n < 0) |
1686 | goto out_nofds; | 1686 | goto out_nofds; |
1687 | 1687 | ||
1688 | /* max_fdset can increase, so grab it once to avoid race */ | 1688 | /* max_fds can increase, so grab it once to avoid race */ |
1689 | rcu_read_lock(); | 1689 | rcu_read_lock(); |
1690 | fdt = files_fdtable(current->files); | 1690 | fdt = files_fdtable(current->files); |
1691 | max_fdset = fdt->max_fdset; | 1691 | max_fds = fdt->max_fds; |
1692 | rcu_read_unlock(); | 1692 | rcu_read_unlock(); |
1693 | if (n > max_fdset) | 1693 | if (n > max_fds) |
1694 | n = max_fdset; | 1694 | n = max_fds; |
1695 | 1695 | ||
1696 | /* | 1696 | /* |
1697 | * We need 6 bitmaps (in/out/ex for both incoming and outgoing), | 1697 | * We need 6 bitmaps (in/out/ex for both incoming and outgoing), |
@@ -783,7 +783,7 @@ static void flush_old_files(struct files_struct * files) | |||
783 | j++; | 783 | j++; |
784 | i = j * __NFDBITS; | 784 | i = j * __NFDBITS; |
785 | fdt = files_fdtable(files); | 785 | fdt = files_fdtable(files); |
786 | if (i >= fdt->max_fds || i >= fdt->max_fdset) | 786 | if (i >= fdt->max_fds) |
787 | break; | 787 | break; |
788 | set = fdt->close_on_exec->fds_bits[j]; | 788 | set = fdt->close_on_exec->fds_bits[j]; |
789 | if (!set) | 789 | if (!set) |
diff --git a/fs/fcntl.c b/fs/fcntl.c index 2bdaef35da54..8e382a5d51bd 100644 --- a/fs/fcntl.c +++ b/fs/fcntl.c | |||
@@ -77,10 +77,9 @@ repeat: | |||
77 | start = files->next_fd; | 77 | start = files->next_fd; |
78 | 78 | ||
79 | newfd = start; | 79 | newfd = start; |
80 | if (start < fdt->max_fdset) { | 80 | if (start < fdt->max_fds) |
81 | newfd = find_next_zero_bit(fdt->open_fds->fds_bits, | 81 | newfd = find_next_zero_bit(fdt->open_fds->fds_bits, |
82 | fdt->max_fdset, start); | 82 | fdt->max_fds, start); |
83 | } | ||
84 | 83 | ||
85 | error = -EMFILE; | 84 | error = -EMFILE; |
86 | if (newfd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur) | 85 | if (newfd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur) |
@@ -68,8 +68,8 @@ void free_fd_array(struct file **array, int num) | |||
68 | 68 | ||
69 | static void __free_fdtable(struct fdtable *fdt) | 69 | static void __free_fdtable(struct fdtable *fdt) |
70 | { | 70 | { |
71 | free_fdset(fdt->open_fds, fdt->max_fdset); | 71 | free_fdset(fdt->open_fds, fdt->max_fds); |
72 | free_fdset(fdt->close_on_exec, fdt->max_fdset); | 72 | free_fdset(fdt->close_on_exec, fdt->max_fds); |
73 | free_fd_array(fdt->fd, fdt->max_fds); | 73 | free_fd_array(fdt->fd, fdt->max_fds); |
74 | kfree(fdt); | 74 | kfree(fdt); |
75 | } | 75 | } |
@@ -98,7 +98,7 @@ static void free_fdtable_rcu(struct rcu_head *rcu) | |||
98 | struct fdtable_defer *fddef; | 98 | struct fdtable_defer *fddef; |
99 | 99 | ||
100 | BUG_ON(!fdt); | 100 | BUG_ON(!fdt); |
101 | fdset_size = fdt->max_fdset / 8; | 101 | fdset_size = fdt->max_fds / 8; |
102 | fdarray_size = fdt->max_fds * sizeof(struct file *); | 102 | fdarray_size = fdt->max_fds * sizeof(struct file *); |
103 | 103 | ||
104 | if (fdt->free_files) { | 104 | if (fdt->free_files) { |
@@ -110,13 +110,11 @@ static void free_fdtable_rcu(struct rcu_head *rcu) | |||
110 | kmem_cache_free(files_cachep, fdt->free_files); | 110 | kmem_cache_free(files_cachep, fdt->free_files); |
111 | return; | 111 | return; |
112 | } | 112 | } |
113 | if (fdt->max_fdset <= EMBEDDED_FD_SET_SIZE && | 113 | if (fdt->max_fds <= NR_OPEN_DEFAULT) |
114 | fdt->max_fds <= NR_OPEN_DEFAULT) { | ||
115 | /* | 114 | /* |
116 | * The fdtable was embedded | 115 | * The fdtable was embedded |
117 | */ | 116 | */ |
118 | return; | 117 | return; |
119 | } | ||
120 | if (fdset_size <= PAGE_SIZE && fdarray_size <= PAGE_SIZE) { | 118 | if (fdset_size <= PAGE_SIZE && fdarray_size <= PAGE_SIZE) { |
121 | kfree(fdt->open_fds); | 119 | kfree(fdt->open_fds); |
122 | kfree(fdt->close_on_exec); | 120 | kfree(fdt->close_on_exec); |
@@ -136,9 +134,7 @@ static void free_fdtable_rcu(struct rcu_head *rcu) | |||
136 | 134 | ||
137 | void free_fdtable(struct fdtable *fdt) | 135 | void free_fdtable(struct fdtable *fdt) |
138 | { | 136 | { |
139 | if (fdt->free_files || | 137 | if (fdt->free_files || fdt->max_fds > NR_OPEN_DEFAULT) |
140 | fdt->max_fdset > EMBEDDED_FD_SET_SIZE || | ||
141 | fdt->max_fds > NR_OPEN_DEFAULT) | ||
142 | call_rcu(&fdt->rcu, free_fdtable_rcu); | 138 | call_rcu(&fdt->rcu, free_fdtable_rcu); |
143 | } | 139 | } |
144 | 140 | ||
@@ -151,12 +147,11 @@ static void copy_fdtable(struct fdtable *nfdt, struct fdtable *fdt) | |||
151 | int i; | 147 | int i; |
152 | int count; | 148 | int count; |
153 | 149 | ||
154 | BUG_ON(nfdt->max_fdset < fdt->max_fdset); | ||
155 | BUG_ON(nfdt->max_fds < fdt->max_fds); | 150 | BUG_ON(nfdt->max_fds < fdt->max_fds); |
156 | /* Copy the existing tables and install the new pointers */ | 151 | /* Copy the existing tables and install the new pointers */ |
157 | 152 | ||
158 | i = fdt->max_fdset / (sizeof(unsigned long) * 8); | 153 | i = fdt->max_fds / (sizeof(unsigned long) * 8); |
159 | count = (nfdt->max_fdset - fdt->max_fdset) / 8; | 154 | count = (nfdt->max_fds - fdt->max_fds) / 8; |
160 | 155 | ||
161 | /* | 156 | /* |
162 | * Don't copy the entire array if the current fdset is | 157 | * Don't copy the entire array if the current fdset is |
@@ -164,9 +159,9 @@ static void copy_fdtable(struct fdtable *nfdt, struct fdtable *fdt) | |||
164 | */ | 159 | */ |
165 | if (i) { | 160 | if (i) { |
166 | memcpy (nfdt->open_fds, fdt->open_fds, | 161 | memcpy (nfdt->open_fds, fdt->open_fds, |
167 | fdt->max_fdset/8); | 162 | fdt->max_fds/8); |
168 | memcpy (nfdt->close_on_exec, fdt->close_on_exec, | 163 | memcpy (nfdt->close_on_exec, fdt->close_on_exec, |
169 | fdt->max_fdset/8); | 164 | fdt->max_fds/8); |
170 | memset (&nfdt->open_fds->fds_bits[i], 0, count); | 165 | memset (&nfdt->open_fds->fds_bits[i], 0, count); |
171 | memset (&nfdt->close_on_exec->fds_bits[i], 0, count); | 166 | memset (&nfdt->close_on_exec->fds_bits[i], 0, count); |
172 | } | 167 | } |
@@ -201,7 +196,7 @@ fd_set * alloc_fdset(int num) | |||
201 | 196 | ||
202 | void free_fdset(fd_set *array, int num) | 197 | void free_fdset(fd_set *array, int num) |
203 | { | 198 | { |
204 | if (num <= EMBEDDED_FD_SET_SIZE) /* Don't free an embedded fdset */ | 199 | if (num <= NR_OPEN_DEFAULT) /* Don't free an embedded fdset */ |
205 | return; | 200 | return; |
206 | else if (num <= 8 * PAGE_SIZE) | 201 | else if (num <= 8 * PAGE_SIZE) |
207 | kfree(array); | 202 | kfree(array); |
@@ -220,18 +215,6 @@ static struct fdtable *alloc_fdtable(int nr) | |||
220 | if (!fdt) | 215 | if (!fdt) |
221 | goto out; | 216 | goto out; |
222 | 217 | ||
223 | nfds = max_t(int, 8 * L1_CACHE_BYTES, roundup_pow_of_two(nr + 1)); | ||
224 | if (nfds > NR_OPEN) | ||
225 | nfds = NR_OPEN; | ||
226 | |||
227 | new_openset = alloc_fdset(nfds); | ||
228 | new_execset = alloc_fdset(nfds); | ||
229 | if (!new_openset || !new_execset) | ||
230 | goto out; | ||
231 | fdt->open_fds = new_openset; | ||
232 | fdt->close_on_exec = new_execset; | ||
233 | fdt->max_fdset = nfds; | ||
234 | |||
235 | nfds = NR_OPEN_DEFAULT; | 218 | nfds = NR_OPEN_DEFAULT; |
236 | /* | 219 | /* |
237 | * Expand to the max in easy steps, and keep expanding it until | 220 | * Expand to the max in easy steps, and keep expanding it until |
@@ -251,15 +234,21 @@ static struct fdtable *alloc_fdtable(int nr) | |||
251 | nfds = NR_OPEN; | 234 | nfds = NR_OPEN; |
252 | } | 235 | } |
253 | } while (nfds <= nr); | 236 | } while (nfds <= nr); |
237 | |||
238 | new_openset = alloc_fdset(nfds); | ||
239 | new_execset = alloc_fdset(nfds); | ||
240 | if (!new_openset || !new_execset) | ||
241 | goto out; | ||
242 | fdt->open_fds = new_openset; | ||
243 | fdt->close_on_exec = new_execset; | ||
244 | |||
254 | new_fds = alloc_fd_array(nfds); | 245 | new_fds = alloc_fd_array(nfds); |
255 | if (!new_fds) | 246 | if (!new_fds) |
256 | goto out2; | 247 | goto out; |
257 | fdt->fd = new_fds; | 248 | fdt->fd = new_fds; |
258 | fdt->max_fds = nfds; | 249 | fdt->max_fds = nfds; |
259 | fdt->free_files = NULL; | 250 | fdt->free_files = NULL; |
260 | return fdt; | 251 | return fdt; |
261 | out2: | ||
262 | nfds = fdt->max_fdset; | ||
263 | out: | 252 | out: |
264 | free_fdset(new_openset, nfds); | 253 | free_fdset(new_openset, nfds); |
265 | free_fdset(new_execset, nfds); | 254 | free_fdset(new_execset, nfds); |
@@ -290,7 +279,7 @@ static int expand_fdtable(struct files_struct *files, int nr) | |||
290 | * we dropped the lock | 279 | * we dropped the lock |
291 | */ | 280 | */ |
292 | cur_fdt = files_fdtable(files); | 281 | cur_fdt = files_fdtable(files); |
293 | if (nr >= cur_fdt->max_fds || nr >= cur_fdt->max_fdset) { | 282 | if (nr >= cur_fdt->max_fds) { |
294 | /* Continue as planned */ | 283 | /* Continue as planned */ |
295 | copy_fdtable(new_fdt, cur_fdt); | 284 | copy_fdtable(new_fdt, cur_fdt); |
296 | rcu_assign_pointer(files->fdt, new_fdt); | 285 | rcu_assign_pointer(files->fdt, new_fdt); |
@@ -316,11 +305,10 @@ int expand_files(struct files_struct *files, int nr) | |||
316 | 305 | ||
317 | fdt = files_fdtable(files); | 306 | fdt = files_fdtable(files); |
318 | /* Do we need to expand? */ | 307 | /* Do we need to expand? */ |
319 | if (nr < fdt->max_fdset && nr < fdt->max_fds) | 308 | if (nr < fdt->max_fds) |
320 | return 0; | 309 | return 0; |
321 | /* Can we expand? */ | 310 | /* Can we expand? */ |
322 | if (fdt->max_fdset >= NR_OPEN || fdt->max_fds >= NR_OPEN || | 311 | if (nr >= NR_OPEN) |
323 | nr >= NR_OPEN) | ||
324 | return -EMFILE; | 312 | return -EMFILE; |
325 | 313 | ||
326 | /* All good, so we try */ | 314 | /* All good, so we try */ |
@@ -864,8 +864,7 @@ int get_unused_fd(void) | |||
864 | 864 | ||
865 | repeat: | 865 | repeat: |
866 | fdt = files_fdtable(files); | 866 | fdt = files_fdtable(files); |
867 | fd = find_next_zero_bit(fdt->open_fds->fds_bits, | 867 | fd = find_next_zero_bit(fdt->open_fds->fds_bits, fdt->max_fds, |
868 | fdt->max_fdset, | ||
869 | files->next_fd); | 868 | files->next_fd); |
870 | 869 | ||
871 | /* | 870 | /* |
diff --git a/fs/select.c b/fs/select.c index dcbc1112b7ec..fe0893afd931 100644 --- a/fs/select.c +++ b/fs/select.c | |||
@@ -311,7 +311,7 @@ static int core_sys_select(int n, fd_set __user *inp, fd_set __user *outp, | |||
311 | { | 311 | { |
312 | fd_set_bits fds; | 312 | fd_set_bits fds; |
313 | void *bits; | 313 | void *bits; |
314 | int ret, max_fdset; | 314 | int ret, max_fds; |
315 | unsigned int size; | 315 | unsigned int size; |
316 | struct fdtable *fdt; | 316 | struct fdtable *fdt; |
317 | /* Allocate small arguments on the stack to save memory and be faster */ | 317 | /* Allocate small arguments on the stack to save memory and be faster */ |
@@ -321,13 +321,13 @@ static int core_sys_select(int n, fd_set __user *inp, fd_set __user *outp, | |||
321 | if (n < 0) | 321 | if (n < 0) |
322 | goto out_nofds; | 322 | goto out_nofds; |
323 | 323 | ||
324 | /* max_fdset can increase, so grab it once to avoid race */ | 324 | /* max_fds can increase, so grab it once to avoid race */ |
325 | rcu_read_lock(); | 325 | rcu_read_lock(); |
326 | fdt = files_fdtable(current->files); | 326 | fdt = files_fdtable(current->files); |
327 | max_fdset = fdt->max_fdset; | 327 | max_fds = fdt->max_fds; |
328 | rcu_read_unlock(); | 328 | rcu_read_unlock(); |
329 | if (n > max_fdset) | 329 | if (n > max_fds) |
330 | n = max_fdset; | 330 | n = max_fds; |
331 | 331 | ||
332 | /* | 332 | /* |
333 | * We need 6 bitmaps (in/out/ex for both incoming and outgoing), | 333 | * We need 6 bitmaps (in/out/ex for both incoming and outgoing), |
diff --git a/include/linux/file.h b/include/linux/file.h index 6e77b9177f9e..02be4012225b 100644 --- a/include/linux/file.h +++ b/include/linux/file.h | |||
@@ -26,14 +26,8 @@ struct embedded_fd_set { | |||
26 | unsigned long fds_bits[1]; | 26 | unsigned long fds_bits[1]; |
27 | }; | 27 | }; |
28 | 28 | ||
29 | /* | ||
30 | * More than this number of fds: we use a separately allocated fd_set | ||
31 | */ | ||
32 | #define EMBEDDED_FD_SET_SIZE (BITS_PER_BYTE * sizeof(struct embedded_fd_set)) | ||
33 | |||
34 | struct fdtable { | 29 | struct fdtable { |
35 | unsigned int max_fds; | 30 | unsigned int max_fds; |
36 | int max_fdset; | ||
37 | struct file ** fd; /* current fd array */ | 31 | struct file ** fd; /* current fd array */ |
38 | fd_set *close_on_exec; | 32 | fd_set *close_on_exec; |
39 | fd_set *open_fds; | 33 | fd_set *open_fds; |
diff --git a/include/linux/init_task.h b/include/linux/init_task.h index 7272ff9ee77c..58c18daab65d 100644 --- a/include/linux/init_task.h +++ b/include/linux/init_task.h | |||
@@ -12,7 +12,6 @@ | |||
12 | #define INIT_FDTABLE \ | 12 | #define INIT_FDTABLE \ |
13 | { \ | 13 | { \ |
14 | .max_fds = NR_OPEN_DEFAULT, \ | 14 | .max_fds = NR_OPEN_DEFAULT, \ |
15 | .max_fdset = EMBEDDED_FD_SET_SIZE, \ | ||
16 | .fd = &init_files.fd_array[0], \ | 15 | .fd = &init_files.fd_array[0], \ |
17 | .close_on_exec = (fd_set *)&init_files.close_on_exec_init, \ | 16 | .close_on_exec = (fd_set *)&init_files.close_on_exec_init, \ |
18 | .open_fds = (fd_set *)&init_files.open_fds_init, \ | 17 | .open_fds = (fd_set *)&init_files.open_fds_init, \ |
diff --git a/kernel/exit.c b/kernel/exit.c index 03e64fe4a14a..5f77e76b4f97 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
@@ -425,7 +425,7 @@ static void close_files(struct files_struct * files) | |||
425 | for (;;) { | 425 | for (;;) { |
426 | unsigned long set; | 426 | unsigned long set; |
427 | i = j * __NFDBITS; | 427 | i = j * __NFDBITS; |
428 | if (i >= fdt->max_fdset || i >= fdt->max_fds) | 428 | if (i >= fdt->max_fds) |
429 | break; | 429 | break; |
430 | set = fdt->open_fds->fds_bits[j++]; | 430 | set = fdt->open_fds->fds_bits[j++]; |
431 | while (set) { | 431 | while (set) { |
diff --git a/kernel/fork.c b/kernel/fork.c index 30eab4f063cd..aba595424f78 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -614,7 +614,7 @@ static inline int copy_fs(unsigned long clone_flags, struct task_struct * tsk) | |||
614 | 614 | ||
615 | static int count_open_files(struct fdtable *fdt) | 615 | static int count_open_files(struct fdtable *fdt) |
616 | { | 616 | { |
617 | int size = fdt->max_fdset; | 617 | int size = fdt->max_fds; |
618 | int i; | 618 | int i; |
619 | 619 | ||
620 | /* Find the last open fd */ | 620 | /* Find the last open fd */ |
@@ -641,7 +641,6 @@ static struct files_struct *alloc_files(void) | |||
641 | newf->next_fd = 0; | 641 | newf->next_fd = 0; |
642 | fdt = &newf->fdtab; | 642 | fdt = &newf->fdtab; |
643 | fdt->max_fds = NR_OPEN_DEFAULT; | 643 | fdt->max_fds = NR_OPEN_DEFAULT; |
644 | fdt->max_fdset = EMBEDDED_FD_SET_SIZE; | ||
645 | fdt->close_on_exec = (fd_set *)&newf->close_on_exec_init; | 644 | fdt->close_on_exec = (fd_set *)&newf->close_on_exec_init; |
646 | fdt->open_fds = (fd_set *)&newf->open_fds_init; | 645 | fdt->open_fds = (fd_set *)&newf->open_fds_init; |
647 | fdt->fd = &newf->fd_array[0]; | 646 | fdt->fd = &newf->fd_array[0]; |
@@ -662,7 +661,7 @@ static struct files_struct *dup_fd(struct files_struct *oldf, int *errorp) | |||
662 | { | 661 | { |
663 | struct files_struct *newf; | 662 | struct files_struct *newf; |
664 | struct file **old_fds, **new_fds; | 663 | struct file **old_fds, **new_fds; |
665 | int open_files, size, i, expand; | 664 | int open_files, size, i; |
666 | struct fdtable *old_fdt, *new_fdt; | 665 | struct fdtable *old_fdt, *new_fdt; |
667 | 666 | ||
668 | *errorp = -ENOMEM; | 667 | *errorp = -ENOMEM; |
@@ -673,25 +672,14 @@ static struct files_struct *dup_fd(struct files_struct *oldf, int *errorp) | |||
673 | spin_lock(&oldf->file_lock); | 672 | spin_lock(&oldf->file_lock); |
674 | old_fdt = files_fdtable(oldf); | 673 | old_fdt = files_fdtable(oldf); |
675 | new_fdt = files_fdtable(newf); | 674 | new_fdt = files_fdtable(newf); |
676 | size = old_fdt->max_fdset; | ||
677 | open_files = count_open_files(old_fdt); | 675 | open_files = count_open_files(old_fdt); |
678 | expand = 0; | ||
679 | 676 | ||
680 | /* | 677 | /* |
681 | * Check whether we need to allocate a larger fd array or fd set. | 678 | * Check whether we need to allocate a larger fd array and fd set. |
682 | * Note: we're not a clone task, so the open count won't change. | 679 | * Note: we're not a clone task, so the open count won't change. |
683 | */ | 680 | */ |
684 | if (open_files > new_fdt->max_fdset) { | ||
685 | new_fdt->max_fdset = 0; | ||
686 | expand = 1; | ||
687 | } | ||
688 | if (open_files > new_fdt->max_fds) { | 681 | if (open_files > new_fdt->max_fds) { |
689 | new_fdt->max_fds = 0; | 682 | new_fdt->max_fds = 0; |
690 | expand = 1; | ||
691 | } | ||
692 | |||
693 | /* if the old fdset gets grown now, we'll only copy up to "size" fds */ | ||
694 | if (expand) { | ||
695 | spin_unlock(&oldf->file_lock); | 683 | spin_unlock(&oldf->file_lock); |
696 | spin_lock(&newf->file_lock); | 684 | spin_lock(&newf->file_lock); |
697 | *errorp = expand_files(newf, open_files-1); | 685 | *errorp = expand_files(newf, open_files-1); |
@@ -739,8 +727,8 @@ static struct files_struct *dup_fd(struct files_struct *oldf, int *errorp) | |||
739 | /* This is long word aligned thus could use a optimized version */ | 727 | /* This is long word aligned thus could use a optimized version */ |
740 | memset(new_fds, 0, size); | 728 | memset(new_fds, 0, size); |
741 | 729 | ||
742 | if (new_fdt->max_fdset > open_files) { | 730 | if (new_fdt->max_fds > open_files) { |
743 | int left = (new_fdt->max_fdset-open_files)/8; | 731 | int left = (new_fdt->max_fds-open_files)/8; |
744 | int start = open_files / (8 * sizeof(unsigned long)); | 732 | int start = open_files / (8 * sizeof(unsigned long)); |
745 | 733 | ||
746 | memset(&new_fdt->open_fds->fds_bits[start], 0, left); | 734 | memset(&new_fdt->open_fds->fds_bits[start], 0, left); |
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 3753416eb9b9..65fb5e8ea941 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -1734,7 +1734,7 @@ static inline void flush_unauthorized_files(struct files_struct * files) | |||
1734 | j++; | 1734 | j++; |
1735 | i = j * __NFDBITS; | 1735 | i = j * __NFDBITS; |
1736 | fdt = files_fdtable(files); | 1736 | fdt = files_fdtable(files); |
1737 | if (i >= fdt->max_fds || i >= fdt->max_fdset) | 1737 | if (i >= fdt->max_fds) |
1738 | break; | 1738 | break; |
1739 | set = fdt->open_fds->fds_bits[j]; | 1739 | set = fdt->open_fds->fds_bits[j]; |
1740 | if (!set) | 1740 | if (!set) |