aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorEduardo Blanco <ejblanco@google.com>2010-10-19 05:26:47 -0400
committerSimon Horman <horms@verge.net.au>2010-10-19 11:13:16 -0400
commitd86bef73b4a24e59e7c1f896a72bbf38430ac2c6 (patch)
tree724097038b8d5bf76da75b55af13de23b46365f1 /net
parent714f095f74582764d629785f03b459a3d0503624 (diff)
Fixed race condition at ip_vs.ko module init.
Lists were initialized after the module was registered. Multiple ipvsadm processes at module load triggered a race condition that resulted in a null pointer dereference in do_ip_vs_get_ctl(). As a result, __ip_vs_mutex was left locked preventing all further ipvsadm commands. Signed-off-by: Eduardo J. Blanco <ejblanco@google.com> Signed-off-by: Simon Horman <horms@verge.net.au>
Diffstat (limited to 'net')
-rw-r--r--net/netfilter/ipvs/ip_vs_ctl.c19
1 files changed, 10 insertions, 9 deletions
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
index a697591d0e23..0b884d3e192f 100644
--- a/net/netfilter/ipvs/ip_vs_ctl.c
+++ b/net/netfilter/ipvs/ip_vs_ctl.c
@@ -3400,6 +3400,16 @@ int __init ip_vs_control_init(void)
3400 3400
3401 EnterFunction(2); 3401 EnterFunction(2);
3402 3402
3403 /* Initialize ip_vs_svc_table, ip_vs_svc_fwm_table, ip_vs_rtable */
3404 for(idx = 0; idx < IP_VS_SVC_TAB_SIZE; idx++) {
3405 INIT_LIST_HEAD(&ip_vs_svc_table[idx]);
3406 INIT_LIST_HEAD(&ip_vs_svc_fwm_table[idx]);
3407 }
3408 for(idx = 0; idx < IP_VS_RTAB_SIZE; idx++) {
3409 INIT_LIST_HEAD(&ip_vs_rtable[idx]);
3410 }
3411 smp_wmb();
3412
3403 ret = nf_register_sockopt(&ip_vs_sockopts); 3413 ret = nf_register_sockopt(&ip_vs_sockopts);
3404 if (ret) { 3414 if (ret) {
3405 pr_err("cannot register sockopt.\n"); 3415 pr_err("cannot register sockopt.\n");
@@ -3418,15 +3428,6 @@ int __init ip_vs_control_init(void)
3418 3428
3419 sysctl_header = register_sysctl_paths(net_vs_ctl_path, vs_vars); 3429 sysctl_header = register_sysctl_paths(net_vs_ctl_path, vs_vars);
3420 3430
3421 /* Initialize ip_vs_svc_table, ip_vs_svc_fwm_table, ip_vs_rtable */
3422 for(idx = 0; idx < IP_VS_SVC_TAB_SIZE; idx++) {
3423 INIT_LIST_HEAD(&ip_vs_svc_table[idx]);
3424 INIT_LIST_HEAD(&ip_vs_svc_fwm_table[idx]);
3425 }
3426 for(idx = 0; idx < IP_VS_RTAB_SIZE; idx++) {
3427 INIT_LIST_HEAD(&ip_vs_rtable[idx]);
3428 }
3429
3430 ip_vs_new_estimator(&ip_vs_stats); 3431 ip_vs_new_estimator(&ip_vs_stats);
3431 3432
3432 /* Hook the defense timer */ 3433 /* Hook the defense timer */