Skip to content

Commit 8b5995d

Browse files
gfreewindummakynes
authored andcommitted
netfilter: helper: Add the rcu lock when call __nf_conntrack_helper_find
When invoke __nf_conntrack_helper_find, it needs the rcu lock to protect the helper module which would not be unloaded. Now there are two caller nf_conntrack_helper_try_module_get and ctnetlink_create_expect which don't hold rcu lock. And the other callers left like ctnetlink_change_helper, ctnetlink_create_conntrack, and ctnetlink_glue_attach_expect, they already hold the rcu lock or spin_lock_bh. Remove the rcu lock in functions nf_ct_helper_expectfn_find_by_name and nf_ct_helper_expectfn_find_by_symbol. Because they return one pointer which needs rcu lock, so their caller should hold the rcu lock, not in these two functions. Signed-off-by: Gao Feng <[email protected]> Signed-off-by: Pablo Neira Ayuso <[email protected]>
1 parent 97aae0d commit 8b5995d

File tree

2 files changed

+20
-7
lines changed

2 files changed

+20
-7
lines changed

net/netfilter/nf_conntrack_helper.c

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -158,16 +158,25 @@ nf_conntrack_helper_try_module_get(const char *name, u16 l3num, u8 protonum)
158158
{
159159
struct nf_conntrack_helper *h;
160160

161+
rcu_read_lock();
162+
161163
h = __nf_conntrack_helper_find(name, l3num, protonum);
162164
#ifdef CONFIG_MODULES
163165
if (h == NULL) {
164-
if (request_module("nfct-helper-%s", name) == 0)
166+
rcu_read_unlock();
167+
if (request_module("nfct-helper-%s", name) == 0) {
168+
rcu_read_lock();
165169
h = __nf_conntrack_helper_find(name, l3num, protonum);
170+
} else {
171+
return h;
172+
}
166173
}
167174
#endif
168175
if (h != NULL && !try_module_get(h->me))
169176
h = NULL;
170177

178+
rcu_read_unlock();
179+
171180
return h;
172181
}
173182
EXPORT_SYMBOL_GPL(nf_conntrack_helper_try_module_get);
@@ -311,38 +320,36 @@ void nf_ct_helper_expectfn_unregister(struct nf_ct_helper_expectfn *n)
311320
}
312321
EXPORT_SYMBOL_GPL(nf_ct_helper_expectfn_unregister);
313322

323+
/* Caller should hold the rcu lock */
314324
struct nf_ct_helper_expectfn *
315325
nf_ct_helper_expectfn_find_by_name(const char *name)
316326
{
317327
struct nf_ct_helper_expectfn *cur;
318328
bool found = false;
319329

320-
rcu_read_lock();
321330
list_for_each_entry_rcu(cur, &nf_ct_helper_expectfn_list, head) {
322331
if (!strcmp(cur->name, name)) {
323332
found = true;
324333
break;
325334
}
326335
}
327-
rcu_read_unlock();
328336
return found ? cur : NULL;
329337
}
330338
EXPORT_SYMBOL_GPL(nf_ct_helper_expectfn_find_by_name);
331339

340+
/* Caller should hold the rcu lock */
332341
struct nf_ct_helper_expectfn *
333342
nf_ct_helper_expectfn_find_by_symbol(const void *symbol)
334343
{
335344
struct nf_ct_helper_expectfn *cur;
336345
bool found = false;
337346

338-
rcu_read_lock();
339347
list_for_each_entry_rcu(cur, &nf_ct_helper_expectfn_list, head) {
340348
if (cur->expectfn == symbol) {
341349
found = true;
342350
break;
343351
}
344352
}
345-
rcu_read_unlock();
346353
return found ? cur : NULL;
347354
}
348355
EXPORT_SYMBOL_GPL(nf_ct_helper_expectfn_find_by_symbol);

net/netfilter/nf_conntrack_netlink.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3133,23 +3133,27 @@ ctnetlink_create_expect(struct net *net,
31333133
return -ENOENT;
31343134
ct = nf_ct_tuplehash_to_ctrack(h);
31353135

3136+
rcu_read_lock();
31363137
if (cda[CTA_EXPECT_HELP_NAME]) {
31373138
const char *helpname = nla_data(cda[CTA_EXPECT_HELP_NAME]);
31383139

31393140
helper = __nf_conntrack_helper_find(helpname, u3,
31403141
nf_ct_protonum(ct));
31413142
if (helper == NULL) {
3143+
rcu_read_unlock();
31423144
#ifdef CONFIG_MODULES
31433145
if (request_module("nfct-helper-%s", helpname) < 0) {
31443146
err = -EOPNOTSUPP;
31453147
goto err_ct;
31463148
}
3149+
rcu_read_lock();
31473150
helper = __nf_conntrack_helper_find(helpname, u3,
31483151
nf_ct_protonum(ct));
31493152
if (helper) {
31503153
err = -EAGAIN;
3151-
goto err_ct;
3154+
goto err_rcu;
31523155
}
3156+
rcu_read_unlock();
31533157
#endif
31543158
err = -EOPNOTSUPP;
31553159
goto err_ct;
@@ -3159,11 +3163,13 @@ ctnetlink_create_expect(struct net *net,
31593163
exp = ctnetlink_alloc_expect(cda, ct, helper, &tuple, &mask);
31603164
if (IS_ERR(exp)) {
31613165
err = PTR_ERR(exp);
3162-
goto err_ct;
3166+
goto err_rcu;
31633167
}
31643168

31653169
err = nf_ct_expect_related_report(exp, portid, report);
31663170
nf_ct_expect_put(exp);
3171+
err_rcu:
3172+
rcu_read_unlock();
31673173
err_ct:
31683174
nf_ct_put(ct);
31693175
return err;

0 commit comments

Comments
 (0)