Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 76b61acc authored by Sishuai Gong's avatar Sishuai Gong Committed by Greg Kroah-Hartman
Browse files

ipvs: fix racy memcpy in proc_do_sync_threshold

commit 5310760af1d4fbea1452bfc77db5f9a680f7ae47 upstream.

When two threads run proc_do_sync_threshold() in parallel,
data races could happen between the two memcpy():

Thread-1			Thread-2
memcpy(val, valp, sizeof(val));
				memcpy(valp, val, sizeof(val));

This race might mess up the (struct ctl_table *) table->data,
so we add a mutex lock to serialize them.

Fixes: 1da177e4 ("Linux-2.6.12-rc2")
Link: https://lore.kernel.org/netdev/B6988E90-0A1E-4B85-BF26-2DAF6D482433@gmail.com/


Signed-off-by: default avatarSishuai Gong <sishuai.system@gmail.com>
Acked-by: default avatarSimon Horman <horms@kernel.org>
Acked-by: default avatarJulian Anastasov <ja@ssi.bg>
Signed-off-by: default avatarFlorian Westphal <fw@strlen.de>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 005261c5
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -1690,6 +1690,7 @@ static int
proc_do_sync_threshold(struct ctl_table *table, int write,
		       void __user *buffer, size_t *lenp, loff_t *ppos)
{
	struct netns_ipvs *ipvs = table->extra2;
	int *valp = table->data;
	int val[2];
	int rc;
@@ -1699,6 +1700,7 @@ proc_do_sync_threshold(struct ctl_table *table, int write,
		.mode = table->mode,
	};

	mutex_lock(&ipvs->sync_mutex);
	memcpy(val, valp, sizeof(val));
	rc = proc_dointvec(&tmp, write, buffer, lenp, ppos);
	if (write) {
@@ -1708,6 +1710,7 @@ proc_do_sync_threshold(struct ctl_table *table, int write,
		else
			memcpy(valp, val, sizeof(val));
	}
	mutex_unlock(&ipvs->sync_mutex);
	return rc;
}

@@ -3944,6 +3947,7 @@ static int __net_init ip_vs_control_net_init_sysctl(struct netns_ipvs *ipvs)
	ipvs->sysctl_sync_threshold[0] = DEFAULT_SYNC_THRESHOLD;
	ipvs->sysctl_sync_threshold[1] = DEFAULT_SYNC_PERIOD;
	tbl[idx].data = &ipvs->sysctl_sync_threshold;
	tbl[idx].extra2 = ipvs;
	tbl[idx++].maxlen = sizeof(ipvs->sysctl_sync_threshold);
	ipvs->sysctl_sync_refresh_period = DEFAULT_SYNC_REFRESH_PERIOD;
	tbl[idx++].data = &ipvs->sysctl_sync_refresh_period;