mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 17:47:41 +02:00
netfilter: nf_conntrack_expect: store master_tuple in expectation
Store master conntrack tuple in the expectation since exp->master might
refer to a different conntrack when accessed from rcu read side lock
area due to typesafe rcu rules.
Fixes: 02a3231b6d ("netfilter: nf_conntrack_expect: store netns and zone in expectation")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
parent
57f940017a
commit
979c13114c
|
|
@ -26,6 +26,7 @@ struct nf_conntrack_expect {
|
|||
possible_net_t net;
|
||||
|
||||
/* We expect this tuple, with the following mask */
|
||||
struct nf_conntrack_tuple master_tuple;
|
||||
struct nf_conntrack_tuple tuple;
|
||||
struct nf_conntrack_tuple_mask mask;
|
||||
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ int nf_conntrack_broadcast_help(struct sk_buff *skb,
|
|||
if (exp == NULL)
|
||||
goto out;
|
||||
|
||||
exp->master_tuple = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
|
||||
exp->tuple = ct->tuplehash[IP_CT_DIR_REPLY].tuple;
|
||||
|
||||
helper = rcu_dereference(help->helper);
|
||||
|
|
|
|||
|
|
@ -355,6 +355,8 @@ void nf_ct_expect_init(struct nf_conntrack_expect *exp, unsigned int class,
|
|||
exp->tuple.src.l3num = family;
|
||||
exp->tuple.dst.protonum = proto;
|
||||
|
||||
exp->master_tuple = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
|
||||
|
||||
if (saddr) {
|
||||
memcpy(&exp->tuple.src.u3, saddr, len);
|
||||
if (sizeof(exp->tuple.src.u3) > len)
|
||||
|
|
|
|||
|
|
@ -3002,7 +3002,6 @@ ctnetlink_exp_dump_expect(struct sk_buff *skb,
|
|||
const struct nf_conntrack_expect *exp)
|
||||
{
|
||||
__s32 timeout = (__s32)(READ_ONCE(exp->timeout) - nfct_time_stamp) / HZ;
|
||||
struct nf_conn *master = exp->master;
|
||||
struct nf_conntrack_helper *helper;
|
||||
#if IS_ENABLED(CONFIG_NF_NAT)
|
||||
struct nlattr *nest_parms;
|
||||
|
|
@ -3017,9 +3016,7 @@ ctnetlink_exp_dump_expect(struct sk_buff *skb,
|
|||
goto nla_put_failure;
|
||||
if (ctnetlink_exp_dump_mask(skb, &exp->tuple, &exp->mask) < 0)
|
||||
goto nla_put_failure;
|
||||
if (ctnetlink_exp_dump_tuple(skb,
|
||||
&master->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
|
||||
CTA_EXPECT_MASTER) < 0)
|
||||
if (ctnetlink_exp_dump_tuple(skb, &exp->master_tuple, CTA_EXPECT_MASTER) < 0)
|
||||
goto nla_put_failure;
|
||||
|
||||
#if IS_ENABLED(CONFIG_NF_NAT)
|
||||
|
|
@ -3032,9 +3029,9 @@ ctnetlink_exp_dump_expect(struct sk_buff *skb,
|
|||
if (nla_put_be32(skb, CTA_EXPECT_NAT_DIR, htonl(exp->dir)))
|
||||
goto nla_put_failure;
|
||||
|
||||
nat_tuple.src.l3num = nf_ct_l3num(master);
|
||||
nat_tuple.src.l3num = exp->master_tuple.src.l3num;
|
||||
nat_tuple.src.u3 = exp->saved_addr;
|
||||
nat_tuple.dst.protonum = nf_ct_protonum(master);
|
||||
nat_tuple.dst.protonum = exp->master_tuple.dst.protonum;
|
||||
nat_tuple.src.u = exp->saved_proto;
|
||||
|
||||
if (ctnetlink_exp_dump_tuple(skb, &nat_tuple,
|
||||
|
|
@ -3576,6 +3573,7 @@ ctnetlink_alloc_expect(const struct nlattr * const cda[], struct nf_conn *ct,
|
|||
#endif
|
||||
rcu_assign_pointer(exp->helper, helper);
|
||||
rcu_assign_pointer(exp->assign_helper, assign_helper);
|
||||
exp->master_tuple = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
|
||||
exp->tuple = *tuple;
|
||||
exp->mask.src.u3 = mask->src.u3;
|
||||
exp->mask.src.u.all = mask->src.u.all;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user