Skip to content

Commit

Permalink
Merge tag 'ipvs-fixes-for-v5.4' of https://git.kernel.org/pub/scm/lin…
Browse files Browse the repository at this point in the history
…ux/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>
  • Loading branch information
Pablo Neira Ayuso committed Oct 26, 2019
2 parents a69a85d + c24b75e commit 52b33b4
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 25 deletions.
1 change: 1 addition & 0 deletions include/net/ip_vs.h
Original file line number Diff line number Diff line change
Expand Up @@ -889,6 +889,7 @@ struct netns_ipvs {
struct delayed_work defense_work; /* Work handler */
int drop_rate;
int drop_counter;
int old_secure_tcp;
atomic_t dropentry;
/* locks in ctl.c */
spinlock_t dropentry_lock; /* drop entry handling */
Expand Down
12 changes: 10 additions & 2 deletions net/netfilter/ipvs/ip_vs_app.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

/* 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) {
if (!strcmp(app->name, a->name)) {
err = -EEXIST;
/* decrease the module use count */
ip_vs_use_count_dec();
goto out_unlock;
}
}
a = kmemdup(app, sizeof(*app), GFP_KERNEL);
if (!a) {
err = -ENOMEM;
/* decrease the module use count */
ip_vs_use_count_dec();
goto out_unlock;
}
INIT_LIST_HEAD(&a->incs_list);
list_add(&a->a_list, &ipvs->app_list);
/* increase the module use count */
ip_vs_use_count_inc();

out_unlock:
mutex_unlock(&__ip_vs_app_mutex);
Expand Down
29 changes: 11 additions & 18 deletions net/netfilter/ipvs/ip_vs_ctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,6 @@ static bool __ip_vs_addr_is_local_v6(struct net *net,
static void update_defense_level(struct netns_ipvs *ipvs)
{
struct sysinfo i;
static int old_secure_tcp = 0;
int availmem;
int nomem;
int to_change = -1;
Expand Down Expand Up @@ -174,35 +173,35 @@ static void update_defense_level(struct netns_ipvs *ipvs)
spin_lock(&ipvs->securetcp_lock);
switch (ipvs->sysctl_secure_tcp) {
case 0:
if (old_secure_tcp >= 2)
if (ipvs->old_secure_tcp >= 2)
to_change = 0;
break;
case 1:
if (nomem) {
if (old_secure_tcp < 2)
if (ipvs->old_secure_tcp < 2)
to_change = 1;
ipvs->sysctl_secure_tcp = 2;
} else {
if (old_secure_tcp >= 2)
if (ipvs->old_secure_tcp >= 2)
to_change = 0;
}
break;
case 2:
if (nomem) {
if (old_secure_tcp < 2)
if (ipvs->old_secure_tcp < 2)
to_change = 1;
} else {
if (old_secure_tcp >= 2)
if (ipvs->old_secure_tcp >= 2)
to_change = 0;
ipvs->sysctl_secure_tcp = 1;
}
break;
case 3:
if (old_secure_tcp < 2)
if (ipvs->old_secure_tcp < 2)
to_change = 1;
break;
}
old_secure_tcp = ipvs->sysctl_secure_tcp;
ipvs->old_secure_tcp = ipvs->sysctl_secure_tcp;
if (to_change >= 0)
ip_vs_protocol_timeout_change(ipvs,
ipvs->sysctl_secure_tcp > 1);
Expand Down Expand Up @@ -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;

/* 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' */
if (strcmp(u->sched_name, "none")) {
Expand Down Expand Up @@ -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)
return -EFAULT;

/* increase the module use count */
ip_vs_use_count_inc();

/* Handle daemons since they have another lock */
if (cmd == IP_VS_SO_SET_STARTDAEMON ||
cmd == IP_VS_SO_SET_STOPDAEMON) {
Expand All @@ -2450,13 +2447,13 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)
ret = -EINVAL;
if (strscpy(cfg.mcast_ifn, dm->mcast_ifn,
sizeof(cfg.mcast_ifn)) <= 0)
goto out_dec;
return ret;
cfg.syncid = dm->syncid;
ret = start_sync_thread(ipvs, &cfg, dm->state);
} else {
ret = stop_sync_thread(ipvs, dm->state);
}
goto out_dec;
return ret;
}

mutex_lock(&__ip_vs_mutex);
Expand Down Expand Up @@ -2551,10 +2548,6 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)

out_unlock:
mutex_unlock(&__ip_vs_mutex);
out_dec:
/* decrease the module use count */
ip_vs_use_count_dec();

return ret;
}

Expand Down
3 changes: 2 additions & 1 deletion net/netfilter/ipvs/ip_vs_pe.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ int register_ip_vs_pe(struct ip_vs_pe *pe)
struct ip_vs_pe *tmp;

/* increase the module use count */
ip_vs_use_count_inc();
if (!ip_vs_use_count_inc())
return -ENOENT;

mutex_lock(&ip_vs_pe_mutex);
/* Make sure that the pe with this name doesn't exist
Expand Down
3 changes: 2 additions & 1 deletion net/netfilter/ipvs/ip_vs_sched.c
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,8 @@ int register_ip_vs_scheduler(struct ip_vs_scheduler *scheduler)
}

/* increase the module use count */
ip_vs_use_count_inc();
if (!ip_vs_use_count_inc())
return -ENOENT;

mutex_lock(&ip_vs_sched_mutex);

Expand Down
13 changes: 10 additions & 3 deletions net/netfilter/ipvs/ip_vs_sync.c
Original file line number Diff line number Diff line change
Expand Up @@ -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",
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 */
for (;;) {
rtnl_lock();
Expand Down Expand Up @@ -1892,9 +1896,6 @@ int start_sync_thread(struct netns_ipvs *ipvs, struct ipvs_sync_daemon_cfg *c,
mutex_unlock(&ipvs->sync_mutex);
rtnl_unlock();

/* increase the module use count */
ip_vs_use_count_inc();

return 0;

out:
Expand Down Expand Up @@ -1924,11 +1925,17 @@ int start_sync_thread(struct netns_ipvs *ipvs, struct ipvs_sync_daemon_cfg *c,
}
kfree(ti);
}

/* decrease the module use count */
ip_vs_use_count_dec();
return result;

out_early:
mutex_unlock(&ipvs->sync_mutex);
rtnl_unlock();

/* decrease the module use count */
ip_vs_use_count_dec();
return result;
}

Expand Down

0 comments on commit 52b33b4

Please sign in to comment.