Skip to content

Commit 52b33b4

Browse files
committed
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 <[email protected]>
2 parents a69a85d + c24b75e commit 52b33b4

File tree

6 files changed

+36
-25
lines changed

6 files changed

+36
-25
lines changed

include/net/ip_vs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -889,6 +889,7 @@ struct netns_ipvs {
889889
struct delayed_work defense_work; /* Work handler */
890890
int drop_rate;
891891
int drop_counter;
892+
int old_secure_tcp;
892893
atomic_t dropentry;
893894
/* locks in ctl.c */
894895
spinlock_t dropentry_lock; /* drop entry handling */

net/netfilter/ipvs/ip_vs_app.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -193,21 +193,29 @@ struct ip_vs_app *register_ip_vs_app(struct netns_ipvs *ipvs, struct ip_vs_app *
193193

194194
mutex_lock(&__ip_vs_app_mutex);
195195

196+
/* increase the module use count */
197+
if (!ip_vs_use_count_inc()) {
198+
err = -ENOENT;
199+
goto out_unlock;
200+
}
201+
196202
list_for_each_entry(a, &ipvs->app_list, a_list) {
197203
if (!strcmp(app->name, a->name)) {
198204
err = -EEXIST;
205+
/* decrease the module use count */
206+
ip_vs_use_count_dec();
199207
goto out_unlock;
200208
}
201209
}
202210
a = kmemdup(app, sizeof(*app), GFP_KERNEL);
203211
if (!a) {
204212
err = -ENOMEM;
213+
/* decrease the module use count */
214+
ip_vs_use_count_dec();
205215
goto out_unlock;
206216
}
207217
INIT_LIST_HEAD(&a->incs_list);
208218
list_add(&a->a_list, &ipvs->app_list);
209-
/* increase the module use count */
210-
ip_vs_use_count_inc();
211219

212220
out_unlock:
213221
mutex_unlock(&__ip_vs_app_mutex);

net/netfilter/ipvs/ip_vs_ctl.c

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,6 @@ static bool __ip_vs_addr_is_local_v6(struct net *net,
9393
static void update_defense_level(struct netns_ipvs *ipvs)
9494
{
9595
struct sysinfo i;
96-
static int old_secure_tcp = 0;
9796
int availmem;
9897
int nomem;
9998
int to_change = -1;
@@ -174,35 +173,35 @@ static void update_defense_level(struct netns_ipvs *ipvs)
174173
spin_lock(&ipvs->securetcp_lock);
175174
switch (ipvs->sysctl_secure_tcp) {
176175
case 0:
177-
if (old_secure_tcp >= 2)
176+
if (ipvs->old_secure_tcp >= 2)
178177
to_change = 0;
179178
break;
180179
case 1:
181180
if (nomem) {
182-
if (old_secure_tcp < 2)
181+
if (ipvs->old_secure_tcp < 2)
183182
to_change = 1;
184183
ipvs->sysctl_secure_tcp = 2;
185184
} else {
186-
if (old_secure_tcp >= 2)
185+
if (ipvs->old_secure_tcp >= 2)
187186
to_change = 0;
188187
}
189188
break;
190189
case 2:
191190
if (nomem) {
192-
if (old_secure_tcp < 2)
191+
if (ipvs->old_secure_tcp < 2)
193192
to_change = 1;
194193
} else {
195-
if (old_secure_tcp >= 2)
194+
if (ipvs->old_secure_tcp >= 2)
196195
to_change = 0;
197196
ipvs->sysctl_secure_tcp = 1;
198197
}
199198
break;
200199
case 3:
201-
if (old_secure_tcp < 2)
200+
if (ipvs->old_secure_tcp < 2)
202201
to_change = 1;
203202
break;
204203
}
205-
old_secure_tcp = ipvs->sysctl_secure_tcp;
204+
ipvs->old_secure_tcp = ipvs->sysctl_secure_tcp;
206205
if (to_change >= 0)
207206
ip_vs_protocol_timeout_change(ipvs,
208207
ipvs->sysctl_secure_tcp > 1);
@@ -1275,7 +1274,8 @@ ip_vs_add_service(struct netns_ipvs *ipvs, struct ip_vs_service_user_kern *u,
12751274
struct ip_vs_service *svc = NULL;
12761275

12771276
/* increase the module use count */
1278-
ip_vs_use_count_inc();
1277+
if (!ip_vs_use_count_inc())
1278+
return -ENOPROTOOPT;
12791279

12801280
/* Lookup the scheduler by 'u->sched_name' */
12811281
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)
24352435
if (copy_from_user(arg, user, len) != 0)
24362436
return -EFAULT;
24372437

2438-
/* increase the module use count */
2439-
ip_vs_use_count_inc();
2440-
24412438
/* Handle daemons since they have another lock */
24422439
if (cmd == IP_VS_SO_SET_STARTDAEMON ||
24432440
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)
24502447
ret = -EINVAL;
24512448
if (strscpy(cfg.mcast_ifn, dm->mcast_ifn,
24522449
sizeof(cfg.mcast_ifn)) <= 0)
2453-
goto out_dec;
2450+
return ret;
24542451
cfg.syncid = dm->syncid;
24552452
ret = start_sync_thread(ipvs, &cfg, dm->state);
24562453
} else {
24572454
ret = stop_sync_thread(ipvs, dm->state);
24582455
}
2459-
goto out_dec;
2456+
return ret;
24602457
}
24612458

24622459
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)
25512548

25522549
out_unlock:
25532550
mutex_unlock(&__ip_vs_mutex);
2554-
out_dec:
2555-
/* decrease the module use count */
2556-
ip_vs_use_count_dec();
2557-
25582551
return ret;
25592552
}
25602553

net/netfilter/ipvs/ip_vs_pe.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,8 @@ int register_ip_vs_pe(struct ip_vs_pe *pe)
6868
struct ip_vs_pe *tmp;
6969

7070
/* increase the module use count */
71-
ip_vs_use_count_inc();
71+
if (!ip_vs_use_count_inc())
72+
return -ENOENT;
7273

7374
mutex_lock(&ip_vs_pe_mutex);
7475
/* Make sure that the pe with this name doesn't exist

net/netfilter/ipvs/ip_vs_sched.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,8 @@ int register_ip_vs_scheduler(struct ip_vs_scheduler *scheduler)
179179
}
180180

181181
/* increase the module use count */
182-
ip_vs_use_count_inc();
182+
if (!ip_vs_use_count_inc())
183+
return -ENOENT;
183184

184185
mutex_lock(&ip_vs_sched_mutex);
185186

net/netfilter/ipvs/ip_vs_sync.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1762,6 +1762,10 @@ int start_sync_thread(struct netns_ipvs *ipvs, struct ipvs_sync_daemon_cfg *c,
17621762
IP_VS_DBG(7, "Each ip_vs_sync_conn entry needs %zd bytes\n",
17631763
sizeof(struct ip_vs_sync_conn_v0));
17641764

1765+
/* increase the module use count */
1766+
if (!ip_vs_use_count_inc())
1767+
return -ENOPROTOOPT;
1768+
17651769
/* Do not hold one mutex and then to block on another */
17661770
for (;;) {
17671771
rtnl_lock();
@@ -1892,9 +1896,6 @@ int start_sync_thread(struct netns_ipvs *ipvs, struct ipvs_sync_daemon_cfg *c,
18921896
mutex_unlock(&ipvs->sync_mutex);
18931897
rtnl_unlock();
18941898

1895-
/* increase the module use count */
1896-
ip_vs_use_count_inc();
1897-
18981899
return 0;
18991900

19001901
out:
@@ -1924,11 +1925,17 @@ int start_sync_thread(struct netns_ipvs *ipvs, struct ipvs_sync_daemon_cfg *c,
19241925
}
19251926
kfree(ti);
19261927
}
1928+
1929+
/* decrease the module use count */
1930+
ip_vs_use_count_dec();
19271931
return result;
19281932

19291933
out_early:
19301934
mutex_unlock(&ipvs->sync_mutex);
19311935
rtnl_unlock();
1936+
1937+
/* decrease the module use count */
1938+
ip_vs_use_count_dec();
19321939
return result;
19331940
}
19341941

0 commit comments

Comments
 (0)