Skip to content

Commit 917b61f

Browse files
committed
netfilter: ctnetlink: ignore explicit helper on new expectations
Use the existing master conntrack helper, anything else is not really supported and it just makes validation more complicated, so just ignore what helper userspace suggests for this expectation. This was uncovered when validating CTA_EXPECT_CLASS via different helper provided by userspace than the existing master conntrack helper: BUG: KASAN: slab-out-of-bounds in nf_ct_expect_related_report+0x2479/0x27c0 Read of size 4 at addr ffff8880043fe408 by task poc/102 Call Trace: nf_ct_expect_related_report+0x2479/0x27c0 ctnetlink_create_expect+0x22b/0x3b0 ctnetlink_new_expect+0x4bd/0x5c0 nfnetlink_rcv_msg+0x67a/0x950 netlink_rcv_skb+0x120/0x350 Allowing to read kernel memory bytes off the expectation boundary. CTA_EXPECT_HELP_NAME is still used to offer the helper name to userspace via netlink dump. Fixes: bd07793 ("netfilter: nfnetlink_queue: allow to attach expectations to conntracks") Reported-by: Qi Tang <tpluszz77@gmail.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
1 parent 35177c6 commit 917b61f

1 file changed

Lines changed: 9 additions & 45 deletions

File tree

net/netfilter/nf_conntrack_netlink.c

Lines changed: 9 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -2636,7 +2636,6 @@ static const struct nla_policy exp_nla_policy[CTA_EXPECT_MAX+1] = {
26362636

26372637
static struct nf_conntrack_expect *
26382638
ctnetlink_alloc_expect(const struct nlattr *const cda[], struct nf_conn *ct,
2639-
struct nf_conntrack_helper *helper,
26402639
struct nf_conntrack_tuple *tuple,
26412640
struct nf_conntrack_tuple *mask);
26422641

@@ -2865,7 +2864,6 @@ ctnetlink_glue_attach_expect(const struct nlattr *attr, struct nf_conn *ct,
28652864
{
28662865
struct nlattr *cda[CTA_EXPECT_MAX+1];
28672866
struct nf_conntrack_tuple tuple, mask;
2868-
struct nf_conntrack_helper *helper = NULL;
28692867
struct nf_conntrack_expect *exp;
28702868
int err;
28712869

@@ -2879,17 +2877,8 @@ ctnetlink_glue_attach_expect(const struct nlattr *attr, struct nf_conn *ct,
28792877
if (err < 0)
28802878
return err;
28812879

2882-
if (cda[CTA_EXPECT_HELP_NAME]) {
2883-
const char *helpname = nla_data(cda[CTA_EXPECT_HELP_NAME]);
2884-
2885-
helper = __nf_conntrack_helper_find(helpname, nf_ct_l3num(ct),
2886-
nf_ct_protonum(ct));
2887-
if (helper == NULL)
2888-
return -EOPNOTSUPP;
2889-
}
2890-
28912880
exp = ctnetlink_alloc_expect((const struct nlattr * const *)cda, ct,
2892-
helper, &tuple, &mask);
2881+
&tuple, &mask);
28932882
if (IS_ERR(exp))
28942883
return PTR_ERR(exp);
28952884

@@ -3528,11 +3517,11 @@ ctnetlink_parse_expect_nat(const struct nlattr *attr,
35283517

35293518
static struct nf_conntrack_expect *
35303519
ctnetlink_alloc_expect(const struct nlattr * const cda[], struct nf_conn *ct,
3531-
struct nf_conntrack_helper *helper,
35323520
struct nf_conntrack_tuple *tuple,
35333521
struct nf_conntrack_tuple *mask)
35343522
{
35353523
struct net *net = read_pnet(&ct->ct_net);
3524+
struct nf_conntrack_helper *helper;
35363525
struct nf_conntrack_expect *exp;
35373526
struct nf_conn_help *help;
35383527
u32 class = 0;
@@ -3542,7 +3531,11 @@ ctnetlink_alloc_expect(const struct nlattr * const cda[], struct nf_conn *ct,
35423531
if (!help)
35433532
return ERR_PTR(-EOPNOTSUPP);
35443533

3545-
if (cda[CTA_EXPECT_CLASS] && helper) {
3534+
helper = rcu_dereference(help->helper);
3535+
if (!helper)
3536+
return ERR_PTR(-EOPNOTSUPP);
3537+
3538+
if (cda[CTA_EXPECT_CLASS]) {
35463539
class = ntohl(nla_get_be32(cda[CTA_EXPECT_CLASS]));
35473540
if (class > helper->expect_class_max)
35483541
return ERR_PTR(-EINVAL);
@@ -3576,8 +3569,6 @@ ctnetlink_alloc_expect(const struct nlattr * const cda[], struct nf_conn *ct,
35763569
#ifdef CONFIG_NF_CONNTRACK_ZONES
35773570
exp->zone = ct->zone;
35783571
#endif
3579-
if (!helper)
3580-
helper = rcu_dereference(help->helper);
35813572
rcu_assign_pointer(exp->helper, helper);
35823573
exp->tuple = *tuple;
35833574
exp->mask.src.u3 = mask->src.u3;
@@ -3609,7 +3600,6 @@ ctnetlink_create_expect(struct net *net,
36093600
{
36103601
struct nf_conntrack_tuple tuple, mask, master_tuple;
36113602
struct nf_conntrack_tuple_hash *h = NULL;
3612-
struct nf_conntrack_helper *helper = NULL;
36133603
struct nf_conntrack_expect *exp;
36143604
struct nf_conn *ct;
36153605
int err;
@@ -3635,33 +3625,7 @@ ctnetlink_create_expect(struct net *net,
36353625
ct = nf_ct_tuplehash_to_ctrack(h);
36363626

36373627
rcu_read_lock();
3638-
if (cda[CTA_EXPECT_HELP_NAME]) {
3639-
const char *helpname = nla_data(cda[CTA_EXPECT_HELP_NAME]);
3640-
3641-
helper = __nf_conntrack_helper_find(helpname, u3,
3642-
nf_ct_protonum(ct));
3643-
if (helper == NULL) {
3644-
rcu_read_unlock();
3645-
#ifdef CONFIG_MODULES
3646-
if (request_module("nfct-helper-%s", helpname) < 0) {
3647-
err = -EOPNOTSUPP;
3648-
goto err_ct;
3649-
}
3650-
rcu_read_lock();
3651-
helper = __nf_conntrack_helper_find(helpname, u3,
3652-
nf_ct_protonum(ct));
3653-
if (helper) {
3654-
err = -EAGAIN;
3655-
goto err_rcu;
3656-
}
3657-
rcu_read_unlock();
3658-
#endif
3659-
err = -EOPNOTSUPP;
3660-
goto err_ct;
3661-
}
3662-
}
3663-
3664-
exp = ctnetlink_alloc_expect(cda, ct, helper, &tuple, &mask);
3628+
exp = ctnetlink_alloc_expect(cda, ct, &tuple, &mask);
36653629
if (IS_ERR(exp)) {
36663630
err = PTR_ERR(exp);
36673631
goto err_rcu;
@@ -3671,8 +3635,8 @@ ctnetlink_create_expect(struct net *net,
36713635
nf_ct_expect_put(exp);
36723636
err_rcu:
36733637
rcu_read_unlock();
3674-
err_ct:
36753638
nf_ct_put(ct);
3639+
36763640
return err;
36773641
}
36783642

0 commit comments

Comments
 (0)