Skip to content

Commit

Permalink
netfilter: ctnetlink: acquire ct->lock before operating nf_ct_seqadj
Browse files Browse the repository at this point in the history
We should acquire the ct->lock before accessing or modifying the
nf_ct_seqadj, as another CPU may modify the nf_ct_seqadj at the same
time during its packet proccessing.

Signed-off-by: Liping Zhang <zlpnobody@gmail.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
  • Loading branch information
Liping Zhang authored and Pablo Neira Ayuso committed Apr 24, 2017
1 parent 53b56da commit 64f3967
Showing 1 changed file with 15 additions and 6 deletions.
21 changes: 15 additions & 6 deletions net/netfilter/nf_conntrack_netlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -417,24 +417,28 @@ dump_ct_seq_adj(struct sk_buff *skb, const struct nf_ct_seqadj *seq, int type)
return -1;
}

static int ctnetlink_dump_ct_seq_adj(struct sk_buff *skb,
const struct nf_conn *ct)
static int ctnetlink_dump_ct_seq_adj(struct sk_buff *skb, struct nf_conn *ct)
{
struct nf_conn_seqadj *seqadj = nfct_seqadj(ct);
struct nf_ct_seqadj *seq;

if (!(ct->status & IPS_SEQ_ADJUST) || !seqadj)
return 0;

spin_lock_bh(&ct->lock);
seq = &seqadj->seq[IP_CT_DIR_ORIGINAL];
if (dump_ct_seq_adj(skb, seq, CTA_SEQ_ADJ_ORIG) == -1)
return -1;
goto err;

seq = &seqadj->seq[IP_CT_DIR_REPLY];
if (dump_ct_seq_adj(skb, seq, CTA_SEQ_ADJ_REPLY) == -1)
return -1;
goto err;

spin_unlock_bh(&ct->lock);
return 0;
err:
spin_unlock_bh(&ct->lock);
return -1;
}

static int ctnetlink_dump_id(struct sk_buff *skb, const struct nf_conn *ct)
Expand Down Expand Up @@ -1637,11 +1641,12 @@ ctnetlink_change_seq_adj(struct nf_conn *ct,
if (!seqadj)
return 0;

spin_lock_bh(&ct->lock);
if (cda[CTA_SEQ_ADJ_ORIG]) {
ret = change_seq_adj(&seqadj->seq[IP_CT_DIR_ORIGINAL],
cda[CTA_SEQ_ADJ_ORIG]);
if (ret < 0)
return ret;
goto err;

set_bit(IPS_SEQ_ADJUST_BIT, &ct->status);
}
Expand All @@ -1650,12 +1655,16 @@ ctnetlink_change_seq_adj(struct nf_conn *ct,
ret = change_seq_adj(&seqadj->seq[IP_CT_DIR_REPLY],
cda[CTA_SEQ_ADJ_REPLY]);
if (ret < 0)
return ret;
goto err;

set_bit(IPS_SEQ_ADJUST_BIT, &ct->status);
}

spin_unlock_bh(&ct->lock);
return 0;
err:
spin_unlock_bh(&ct->lock);
return ret;
}

static int
Expand Down

0 comments on commit 64f3967

Please sign in to comment.