summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2008-05-10 10:08:32 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2008-05-16 17:22:52 -0400
commiteceea0b3df05ed262ae32e0c6340cc7a3626632d (patch)
tree73e5e33acace9187d5729a9a8c8ff53c3d720d52
parentadbecb128cd2cc5d14b0ebef6d020ced0efd0ec6 (diff)
[PATCH] avoid multiplication overflows and signedness issues for max_fds
Limit sysctl_nr_open - we don't want ->max_fds to exceed MAX_INT and we don't want size calculation for ->fd[] to overflow. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--fs/file.c4
-rw-r--r--kernel/sysctl.c5
2 files changed, 8 insertions, 1 deletions
diff --git a/fs/file.c b/fs/file.c
index 0f705c7cfefe..7b3887e054d0 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -26,6 +26,8 @@ struct fdtable_defer {
};
int sysctl_nr_open __read_mostly = 1024*1024;
+int sysctl_nr_open_min = BITS_PER_LONG;
+int sysctl_nr_open_max = 1024 * 1024; /* raised later */
/*
* We use this list to defer free fdtables that have vmalloced
@@ -405,6 +407,8 @@ void __init files_defer_init(void)
int i;
for_each_possible_cpu(i)
fdtable_defer_list_init(i);
+ sysctl_nr_open_max = min((size_t)INT_MAX, ~(size_t)0/sizeof(void *)) &
+ -BITS_PER_LONG;
}
struct files_struct init_files = {
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index d7ffdc59816a..29116652dca8 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -81,6 +81,7 @@ extern int compat_log;
extern int maps_protect;
extern int sysctl_stat_interval;
extern int latencytop_enabled;
+extern int sysctl_nr_open_min, sysctl_nr_open_max;
/* Constants used for minimum and maximum */
#if defined(CONFIG_DETECT_SOFTLOCKUP) || defined(CONFIG_HIGHMEM)
@@ -1190,7 +1191,9 @@ static struct ctl_table fs_table[] = {
.data = &sysctl_nr_open,
.maxlen = sizeof(int),
.mode = 0644,
- .proc_handler = &proc_dointvec,
+ .proc_handler = &proc_dointvec_minmax,
+ .extra1 = &sysctl_nr_open_min,
+ .extra2 = &sysctl_nr_open_max,
},
{
.ctl_name = FS_DENTRY,