diff options
author | Daniel Xu <dxu@dxuuu.xyz> | 2022-11-09 12:39:07 -0700 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2022-11-18 15:21:00 +0100 |
commit | 52d1aa8b8249ff477aaa38b6f74a8ced780d079c (patch) | |
tree | ac248cfe960bc3483f2aeea8a9e0257907952e83 /net/sched/act_ctinfo.c | |
parent | 40b9d1ab63f5c4f3cb69450044d07b45e5af72e1 (diff) | |
download | linux-52d1aa8b8249ff477aaa38b6f74a8ced780d079c.tar.gz linux-52d1aa8b8249ff477aaa38b6f74a8ced780d079c.tar.bz2 linux-52d1aa8b8249ff477aaa38b6f74a8ced780d079c.zip |
netfilter: conntrack: Fix data-races around ct mark
nf_conn:mark can be read from and written to in parallel. Use
READ_ONCE()/WRITE_ONCE() for reads and writes to prevent unwanted
compiler optimizations.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Daniel Xu <dxu@dxuuu.xyz>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net/sched/act_ctinfo.c')
-rw-r--r-- | net/sched/act_ctinfo.c | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/net/sched/act_ctinfo.c b/net/sched/act_ctinfo.c index d4102f0a9abd..eaa02f098d1c 100644 --- a/net/sched/act_ctinfo.c +++ b/net/sched/act_ctinfo.c @@ -32,7 +32,7 @@ static void tcf_ctinfo_dscp_set(struct nf_conn *ct, struct tcf_ctinfo *ca, { u8 dscp, newdscp; - newdscp = (((ct->mark & cp->dscpmask) >> cp->dscpmaskshift) << 2) & + newdscp = (((READ_ONCE(ct->mark) & cp->dscpmask) >> cp->dscpmaskshift) << 2) & ~INET_ECN_MASK; switch (proto) { @@ -72,7 +72,7 @@ static void tcf_ctinfo_cpmark_set(struct nf_conn *ct, struct tcf_ctinfo *ca, struct sk_buff *skb) { ca->stats_cpmark_set++; - skb->mark = ct->mark & cp->cpmarkmask; + skb->mark = READ_ONCE(ct->mark) & cp->cpmarkmask; } static int tcf_ctinfo_act(struct sk_buff *skb, const struct tc_action *a, @@ -130,7 +130,7 @@ static int tcf_ctinfo_act(struct sk_buff *skb, const struct tc_action *a, } if (cp->mode & CTINFO_MODE_DSCP) - if (!cp->dscpstatemask || (ct->mark & cp->dscpstatemask)) + if (!cp->dscpstatemask || (READ_ONCE(ct->mark) & cp->dscpstatemask)) tcf_ctinfo_dscp_set(ct, ca, cp, skb, wlen, proto); if (cp->mode & CTINFO_MODE_CPMARK) |