Merge tag 'ipvs-fixes-for-v5.4' of https://git.kernel.org/pub/scm/linux/kernel/git/horms/ipvs
Simon Horman says: ==================== IPVS fixes for v5.4 * Eric Dumazet resolves a race condition in switching the defense level * Davide Caratti resolves a race condition in module removal ==================== Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
commit
52b33b4f81
|
@ -889,6 +889,7 @@ struct netns_ipvs {
|
||||||
struct delayed_work defense_work; /* Work handler */
|
struct delayed_work defense_work; /* Work handler */
|
||||||
int drop_rate;
|
int drop_rate;
|
||||||
int drop_counter;
|
int drop_counter;
|
||||||
|
int old_secure_tcp;
|
||||||
atomic_t dropentry;
|
atomic_t dropentry;
|
||||||
/* locks in ctl.c */
|
/* locks in ctl.c */
|
||||||
spinlock_t dropentry_lock; /* drop entry handling */
|
spinlock_t dropentry_lock; /* drop entry handling */
|
||||||
|
|
|
@ -193,21 +193,29 @@ struct ip_vs_app *register_ip_vs_app(struct netns_ipvs *ipvs, struct ip_vs_app *
|
||||||
|
|
||||||
mutex_lock(&__ip_vs_app_mutex);
|
mutex_lock(&__ip_vs_app_mutex);
|
||||||
|
|
||||||
|
/* increase the module use count */
|
||||||
|
if (!ip_vs_use_count_inc()) {
|
||||||
|
err = -ENOENT;
|
||||||
|
goto out_unlock;
|
||||||
|
}
|
||||||
|
|
||||||
list_for_each_entry(a, &ipvs->app_list, a_list) {
|
list_for_each_entry(a, &ipvs->app_list, a_list) {
|
||||||
if (!strcmp(app->name, a->name)) {
|
if (!strcmp(app->name, a->name)) {
|
||||||
err = -EEXIST;
|
err = -EEXIST;
|
||||||
|
/* decrease the module use count */
|
||||||
|
ip_vs_use_count_dec();
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
a = kmemdup(app, sizeof(*app), GFP_KERNEL);
|
a = kmemdup(app, sizeof(*app), GFP_KERNEL);
|
||||||
if (!a) {
|
if (!a) {
|
||||||
err = -ENOMEM;
|
err = -ENOMEM;
|
||||||
|
/* decrease the module use count */
|
||||||
|
ip_vs_use_count_dec();
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
}
|
}
|
||||||
INIT_LIST_HEAD(&a->incs_list);
|
INIT_LIST_HEAD(&a->incs_list);
|
||||||
list_add(&a->a_list, &ipvs->app_list);
|
list_add(&a->a_list, &ipvs->app_list);
|
||||||
/* increase the module use count */
|
|
||||||
ip_vs_use_count_inc();
|
|
||||||
|
|
||||||
out_unlock:
|
out_unlock:
|
||||||
mutex_unlock(&__ip_vs_app_mutex);
|
mutex_unlock(&__ip_vs_app_mutex);
|
||||||
|
|
|
@ -93,7 +93,6 @@ static bool __ip_vs_addr_is_local_v6(struct net *net,
|
||||||
static void update_defense_level(struct netns_ipvs *ipvs)
|
static void update_defense_level(struct netns_ipvs *ipvs)
|
||||||
{
|
{
|
||||||
struct sysinfo i;
|
struct sysinfo i;
|
||||||
static int old_secure_tcp = 0;
|
|
||||||
int availmem;
|
int availmem;
|
||||||
int nomem;
|
int nomem;
|
||||||
int to_change = -1;
|
int to_change = -1;
|
||||||
|
@ -174,35 +173,35 @@ static void update_defense_level(struct netns_ipvs *ipvs)
|
||||||
spin_lock(&ipvs->securetcp_lock);
|
spin_lock(&ipvs->securetcp_lock);
|
||||||
switch (ipvs->sysctl_secure_tcp) {
|
switch (ipvs->sysctl_secure_tcp) {
|
||||||
case 0:
|
case 0:
|
||||||
if (old_secure_tcp >= 2)
|
if (ipvs->old_secure_tcp >= 2)
|
||||||
to_change = 0;
|
to_change = 0;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
if (nomem) {
|
if (nomem) {
|
||||||
if (old_secure_tcp < 2)
|
if (ipvs->old_secure_tcp < 2)
|
||||||
to_change = 1;
|
to_change = 1;
|
||||||
ipvs->sysctl_secure_tcp = 2;
|
ipvs->sysctl_secure_tcp = 2;
|
||||||
} else {
|
} else {
|
||||||
if (old_secure_tcp >= 2)
|
if (ipvs->old_secure_tcp >= 2)
|
||||||
to_change = 0;
|
to_change = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
if (nomem) {
|
if (nomem) {
|
||||||
if (old_secure_tcp < 2)
|
if (ipvs->old_secure_tcp < 2)
|
||||||
to_change = 1;
|
to_change = 1;
|
||||||
} else {
|
} else {
|
||||||
if (old_secure_tcp >= 2)
|
if (ipvs->old_secure_tcp >= 2)
|
||||||
to_change = 0;
|
to_change = 0;
|
||||||
ipvs->sysctl_secure_tcp = 1;
|
ipvs->sysctl_secure_tcp = 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
if (old_secure_tcp < 2)
|
if (ipvs->old_secure_tcp < 2)
|
||||||
to_change = 1;
|
to_change = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
old_secure_tcp = ipvs->sysctl_secure_tcp;
|
ipvs->old_secure_tcp = ipvs->sysctl_secure_tcp;
|
||||||
if (to_change >= 0)
|
if (to_change >= 0)
|
||||||
ip_vs_protocol_timeout_change(ipvs,
|
ip_vs_protocol_timeout_change(ipvs,
|
||||||
ipvs->sysctl_secure_tcp > 1);
|
ipvs->sysctl_secure_tcp > 1);
|
||||||
|
@ -1275,7 +1274,8 @@ ip_vs_add_service(struct netns_ipvs *ipvs, struct ip_vs_service_user_kern *u,
|
||||||
struct ip_vs_service *svc = NULL;
|
struct ip_vs_service *svc = NULL;
|
||||||
|
|
||||||
/* increase the module use count */
|
/* increase the module use count */
|
||||||
ip_vs_use_count_inc();
|
if (!ip_vs_use_count_inc())
|
||||||
|
return -ENOPROTOOPT;
|
||||||
|
|
||||||
/* Lookup the scheduler by 'u->sched_name' */
|
/* Lookup the scheduler by 'u->sched_name' */
|
||||||
if (strcmp(u->sched_name, "none")) {
|
if (strcmp(u->sched_name, "none")) {
|
||||||
|
@ -2435,9 +2435,6 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)
|
||||||
if (copy_from_user(arg, user, len) != 0)
|
if (copy_from_user(arg, user, len) != 0)
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
/* increase the module use count */
|
|
||||||
ip_vs_use_count_inc();
|
|
||||||
|
|
||||||
/* Handle daemons since they have another lock */
|
/* Handle daemons since they have another lock */
|
||||||
if (cmd == IP_VS_SO_SET_STARTDAEMON ||
|
if (cmd == IP_VS_SO_SET_STARTDAEMON ||
|
||||||
cmd == IP_VS_SO_SET_STOPDAEMON) {
|
cmd == IP_VS_SO_SET_STOPDAEMON) {
|
||||||
|
@ -2450,13 +2447,13 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
if (strscpy(cfg.mcast_ifn, dm->mcast_ifn,
|
if (strscpy(cfg.mcast_ifn, dm->mcast_ifn,
|
||||||
sizeof(cfg.mcast_ifn)) <= 0)
|
sizeof(cfg.mcast_ifn)) <= 0)
|
||||||
goto out_dec;
|
return ret;
|
||||||
cfg.syncid = dm->syncid;
|
cfg.syncid = dm->syncid;
|
||||||
ret = start_sync_thread(ipvs, &cfg, dm->state);
|
ret = start_sync_thread(ipvs, &cfg, dm->state);
|
||||||
} else {
|
} else {
|
||||||
ret = stop_sync_thread(ipvs, dm->state);
|
ret = stop_sync_thread(ipvs, dm->state);
|
||||||
}
|
}
|
||||||
goto out_dec;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_lock(&__ip_vs_mutex);
|
mutex_lock(&__ip_vs_mutex);
|
||||||
|
@ -2551,10 +2548,6 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)
|
||||||
|
|
||||||
out_unlock:
|
out_unlock:
|
||||||
mutex_unlock(&__ip_vs_mutex);
|
mutex_unlock(&__ip_vs_mutex);
|
||||||
out_dec:
|
|
||||||
/* decrease the module use count */
|
|
||||||
ip_vs_use_count_dec();
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -68,7 +68,8 @@ int register_ip_vs_pe(struct ip_vs_pe *pe)
|
||||||
struct ip_vs_pe *tmp;
|
struct ip_vs_pe *tmp;
|
||||||
|
|
||||||
/* increase the module use count */
|
/* increase the module use count */
|
||||||
ip_vs_use_count_inc();
|
if (!ip_vs_use_count_inc())
|
||||||
|
return -ENOENT;
|
||||||
|
|
||||||
mutex_lock(&ip_vs_pe_mutex);
|
mutex_lock(&ip_vs_pe_mutex);
|
||||||
/* Make sure that the pe with this name doesn't exist
|
/* Make sure that the pe with this name doesn't exist
|
||||||
|
|
|
@ -179,7 +179,8 @@ int register_ip_vs_scheduler(struct ip_vs_scheduler *scheduler)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* increase the module use count */
|
/* increase the module use count */
|
||||||
ip_vs_use_count_inc();
|
if (!ip_vs_use_count_inc())
|
||||||
|
return -ENOENT;
|
||||||
|
|
||||||
mutex_lock(&ip_vs_sched_mutex);
|
mutex_lock(&ip_vs_sched_mutex);
|
||||||
|
|
||||||
|
|
|
@ -1762,6 +1762,10 @@ int start_sync_thread(struct netns_ipvs *ipvs, struct ipvs_sync_daemon_cfg *c,
|
||||||
IP_VS_DBG(7, "Each ip_vs_sync_conn entry needs %zd bytes\n",
|
IP_VS_DBG(7, "Each ip_vs_sync_conn entry needs %zd bytes\n",
|
||||||
sizeof(struct ip_vs_sync_conn_v0));
|
sizeof(struct ip_vs_sync_conn_v0));
|
||||||
|
|
||||||
|
/* increase the module use count */
|
||||||
|
if (!ip_vs_use_count_inc())
|
||||||
|
return -ENOPROTOOPT;
|
||||||
|
|
||||||
/* Do not hold one mutex and then to block on another */
|
/* Do not hold one mutex and then to block on another */
|
||||||
for (;;) {
|
for (;;) {
|
||||||
rtnl_lock();
|
rtnl_lock();
|
||||||
|
@ -1892,9 +1896,6 @@ int start_sync_thread(struct netns_ipvs *ipvs, struct ipvs_sync_daemon_cfg *c,
|
||||||
mutex_unlock(&ipvs->sync_mutex);
|
mutex_unlock(&ipvs->sync_mutex);
|
||||||
rtnl_unlock();
|
rtnl_unlock();
|
||||||
|
|
||||||
/* increase the module use count */
|
|
||||||
ip_vs_use_count_inc();
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
@ -1924,11 +1925,17 @@ out:
|
||||||
}
|
}
|
||||||
kfree(ti);
|
kfree(ti);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* decrease the module use count */
|
||||||
|
ip_vs_use_count_dec();
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
out_early:
|
out_early:
|
||||||
mutex_unlock(&ipvs->sync_mutex);
|
mutex_unlock(&ipvs->sync_mutex);
|
||||||
rtnl_unlock();
|
rtnl_unlock();
|
||||||
|
|
||||||
|
/* decrease the module use count */
|
||||||
|
ip_vs_use_count_dec();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue