Skip to content

Commit f017941

Browse files
committed
netfilter: nf_conntrack_expect: use expect->helper
Use expect->helper in ctnetlink and /proc to dump the helper name. Using nfct_help() without holding a reference to the master conntrack is unsafe. Use exp->master->helper in ctnetlink path if userspace does not provide an explicit helper when creating an expectation to retain the existing behaviour. The ctnetlink expectation path holds the reference on the master conntrack and nf_conntrack_expect lock and the nfnetlink glue path refers to the master ct that is attached to the skb. Reported-by: Hyunwoo Kim <[email protected]> Signed-off-by: Florian Westphal <[email protected]> Signed-off-by: Pablo Neira Ayuso <[email protected]>
1 parent 9c42bc9 commit f017941

4 files changed

Lines changed: 13 additions & 21 deletions

File tree

net/netfilter/nf_conntrack_expect.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -666,7 +666,7 @@ static int exp_seq_show(struct seq_file *s, void *v)
666666
if (expect->flags & NF_CT_EXPECT_USERSPACE)
667667
seq_printf(s, "%sUSERSPACE", delim);
668668

669-
helper = rcu_dereference(nfct_help(expect->master)->helper);
669+
helper = rcu_dereference(expect->helper);
670670
if (helper) {
671671
seq_printf(s, "%s%s", expect->flags ? " " : "", helper->name);
672672
if (helper->expect_policy[expect->class].name[0])

net/netfilter/nf_conntrack_helper.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -395,14 +395,10 @@ EXPORT_SYMBOL_GPL(nf_conntrack_helper_register);
395395

396396
static bool expect_iter_me(struct nf_conntrack_expect *exp, void *data)
397397
{
398-
struct nf_conn_help *help = nfct_help(exp->master);
399398
const struct nf_conntrack_helper *me = data;
400399
const struct nf_conntrack_helper *this;
401400

402-
if (rcu_access_pointer(exp->helper) == me)
403-
return true;
404-
405-
this = rcu_dereference_protected(help->helper,
401+
this = rcu_dereference_protected(exp->helper,
406402
lockdep_is_held(&nf_conntrack_expect_lock));
407403
return this == me;
408404
}

net/netfilter/nf_conntrack_netlink.c

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3012,7 +3012,7 @@ ctnetlink_exp_dump_expect(struct sk_buff *skb,
30123012
{
30133013
struct nf_conn *master = exp->master;
30143014
long timeout = ((long)exp->timeout.expires - (long)jiffies) / HZ;
3015-
struct nf_conn_help *help;
3015+
struct nf_conntrack_helper *helper;
30163016
#if IS_ENABLED(CONFIG_NF_NAT)
30173017
struct nlattr *nest_parms;
30183018
struct nf_conntrack_tuple nat_tuple = {};
@@ -3057,15 +3057,12 @@ ctnetlink_exp_dump_expect(struct sk_buff *skb,
30573057
nla_put_be32(skb, CTA_EXPECT_FLAGS, htonl(exp->flags)) ||
30583058
nla_put_be32(skb, CTA_EXPECT_CLASS, htonl(exp->class)))
30593059
goto nla_put_failure;
3060-
help = nfct_help(master);
3061-
if (help) {
3062-
struct nf_conntrack_helper *helper;
30633060

3064-
helper = rcu_dereference(help->helper);
3065-
if (helper &&
3066-
nla_put_string(skb, CTA_EXPECT_HELP_NAME, helper->name))
3067-
goto nla_put_failure;
3068-
}
3061+
helper = rcu_dereference(exp->helper);
3062+
if (helper &&
3063+
nla_put_string(skb, CTA_EXPECT_HELP_NAME, helper->name))
3064+
goto nla_put_failure;
3065+
30693066
expfn = nf_ct_helper_expectfn_find_by_symbol(exp->expectfn);
30703067
if (expfn != NULL &&
30713068
nla_put_string(skb, CTA_EXPECT_FN, expfn->name))
@@ -3394,12 +3391,9 @@ static int ctnetlink_get_expect(struct sk_buff *skb,
33943391
static bool expect_iter_name(struct nf_conntrack_expect *exp, void *data)
33953392
{
33963393
struct nf_conntrack_helper *helper;
3397-
const struct nf_conn_help *m_help;
33983394
const char *name = data;
33993395

3400-
m_help = nfct_help(exp->master);
3401-
3402-
helper = rcu_dereference(m_help->helper);
3396+
helper = rcu_dereference(exp->helper);
34033397
if (!helper)
34043398
return false;
34053399

@@ -3534,9 +3528,9 @@ ctnetlink_alloc_expect(const struct nlattr * const cda[], struct nf_conn *ct,
35343528
struct nf_conntrack_tuple *tuple,
35353529
struct nf_conntrack_tuple *mask)
35363530
{
3537-
u_int32_t class = 0;
35383531
struct nf_conntrack_expect *exp;
35393532
struct nf_conn_help *help;
3533+
u32 class = 0;
35403534
int err;
35413535

35423536
help = nfct_help(ct);
@@ -3573,6 +3567,8 @@ ctnetlink_alloc_expect(const struct nlattr * const cda[], struct nf_conn *ct,
35733567

35743568
exp->class = class;
35753569
exp->master = ct;
3570+
if (!helper)
3571+
helper = rcu_dereference(help->helper);
35763572
rcu_assign_pointer(exp->helper, helper);
35773573
exp->tuple = *tuple;
35783574
exp->mask.src.u3 = mask->src.u3;

net/netfilter/nf_conntrack_sip.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -924,7 +924,7 @@ static int set_expected_rtp_rtcp(struct sk_buff *skb, unsigned int protoff,
924924
exp = __nf_ct_expect_find(net, nf_ct_zone(ct), &tuple);
925925

926926
if (!exp || exp->master == ct ||
927-
nfct_help(exp->master)->helper != nfct_help(ct)->helper ||
927+
exp->helper != nfct_help(ct)->helper ||
928928
exp->class != class)
929929
break;
930930
#if IS_ENABLED(CONFIG_NF_NAT)

0 commit comments

Comments
 (0)