Commit 5310760a authored by Sishuai Gong's avatar Sishuai Gong Committed by Florian Westphal

ipvs: fix racy memcpy in proc_do_sync_threshold

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>
parent 9bfab6d2
...@@ -1876,6 +1876,7 @@ static int ...@@ -1876,6 +1876,7 @@ static int
proc_do_sync_threshold(struct ctl_table *table, int write, proc_do_sync_threshold(struct ctl_table *table, int write,
void *buffer, size_t *lenp, loff_t *ppos) void *buffer, size_t *lenp, loff_t *ppos)
{ {
struct netns_ipvs *ipvs = table->extra2;
int *valp = table->data; int *valp = table->data;
int val[2]; int val[2];
int rc; int rc;
...@@ -1885,6 +1886,7 @@ proc_do_sync_threshold(struct ctl_table *table, int write, ...@@ -1885,6 +1886,7 @@ proc_do_sync_threshold(struct ctl_table *table, int write,
.mode = table->mode, .mode = table->mode,
}; };
mutex_lock(&ipvs->sync_mutex);
memcpy(val, valp, sizeof(val)); memcpy(val, valp, sizeof(val));
rc = proc_dointvec(&tmp, write, buffer, lenp, ppos); rc = proc_dointvec(&tmp, write, buffer, lenp, ppos);
if (write) { if (write) {
...@@ -1894,6 +1896,7 @@ proc_do_sync_threshold(struct ctl_table *table, int write, ...@@ -1894,6 +1896,7 @@ proc_do_sync_threshold(struct ctl_table *table, int write,
else else
memcpy(valp, val, sizeof(val)); memcpy(valp, val, sizeof(val));
} }
mutex_unlock(&ipvs->sync_mutex);
return rc; return rc;
} }
...@@ -4321,6 +4324,7 @@ static int __net_init ip_vs_control_net_init_sysctl(struct netns_ipvs *ipvs) ...@@ -4321,6 +4324,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[0] = DEFAULT_SYNC_THRESHOLD;
ipvs->sysctl_sync_threshold[1] = DEFAULT_SYNC_PERIOD; ipvs->sysctl_sync_threshold[1] = DEFAULT_SYNC_PERIOD;
tbl[idx].data = &ipvs->sysctl_sync_threshold; tbl[idx].data = &ipvs->sysctl_sync_threshold;
tbl[idx].extra2 = ipvs;
tbl[idx++].maxlen = sizeof(ipvs->sysctl_sync_threshold); tbl[idx++].maxlen = sizeof(ipvs->sysctl_sync_threshold);
ipvs->sysctl_sync_refresh_period = DEFAULT_SYNC_REFRESH_PERIOD; ipvs->sysctl_sync_refresh_period = DEFAULT_SYNC_REFRESH_PERIOD;
tbl[idx++].data = &ipvs->sysctl_sync_refresh_period; tbl[idx++].data = &ipvs->sysctl_sync_refresh_period;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment