Commit 52b33b4f authored by Pablo Neira Ayuso's avatar Pablo Neira Ayuso
Browse files


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: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parents a69a85da c24b75e0
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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 */
+10 −2
Original line number Diff line number Diff line
@@ -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);
+11 −18
Original line number Diff line number Diff line
@@ -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;
@@ -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);
@@ -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")) {
@@ -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) {
@@ -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);
@@ -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;
}

+2 −1
Original line number Diff line number Diff line
@@ -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
+2 −1
Original line number Diff line number Diff line
@@ -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);

Loading