Skip to content

Commit ec0acb0

Browse files
lxindavem330
authored andcommitted
net: sched: set xt_tgchk_param par.net properly in ipt_init_target
Now xt_tgchk_param par in ipt_init_target is a local varibale, par.net is not initialized there. Later when xt_check_target calls target's checkentry in which it may access par.net, it would cause kernel panic. Jaroslav found this panic when running: # ip link add TestIface type dummy # tc qd add dev TestIface ingress handle ffff: # tc filter add dev TestIface parent ffff: u32 match u32 0 0 \ action xt -j CONNMARK --set-mark 4 This patch is to pass net param into ipt_init_target and set par.net with it properly in there. v1->v2: As Wang Cong pointed, I missed ipt_net_id != xt_net_id, so fix it by also passing net_id to __tcf_ipt_init. v2->v3: Missed the fixes tag, so add it. Fixes: ecb2421 ("netfilter: add and use nf_ct_netns_get/put") Reported-by: Jaroslav Aster <[email protected]> Signed-off-by: Xin Long <[email protected]> Acked-by: Jiri Pirko <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 8e6f152 commit ec0acb0

File tree

1 file changed

+10
-10
lines changed

1 file changed

+10
-10
lines changed

net/sched/act_ipt.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ static struct tc_action_ops act_ipt_ops;
3636
static unsigned int xt_net_id;
3737
static struct tc_action_ops act_xt_ops;
3838

39-
static int ipt_init_target(struct xt_entry_target *t, char *table,
40-
unsigned int hook)
39+
static int ipt_init_target(struct net *net, struct xt_entry_target *t,
40+
char *table, unsigned int hook)
4141
{
4242
struct xt_tgchk_param par;
4343
struct xt_target *target;
@@ -49,6 +49,7 @@ static int ipt_init_target(struct xt_entry_target *t, char *table,
4949
return PTR_ERR(target);
5050

5151
t->u.kernel.target = target;
52+
par.net = net;
5253
par.table = table;
5354
par.entryinfo = NULL;
5455
par.target = target;
@@ -91,10 +92,11 @@ static const struct nla_policy ipt_policy[TCA_IPT_MAX + 1] = {
9192
[TCA_IPT_TARG] = { .len = sizeof(struct xt_entry_target) },
9293
};
9394

94-
static int __tcf_ipt_init(struct tc_action_net *tn, struct nlattr *nla,
95+
static int __tcf_ipt_init(struct net *net, unsigned int id, struct nlattr *nla,
9596
struct nlattr *est, struct tc_action **a,
9697
const struct tc_action_ops *ops, int ovr, int bind)
9798
{
99+
struct tc_action_net *tn = net_generic(net, id);
98100
struct nlattr *tb[TCA_IPT_MAX + 1];
99101
struct tcf_ipt *ipt;
100102
struct xt_entry_target *td, *t;
@@ -159,7 +161,7 @@ static int __tcf_ipt_init(struct tc_action_net *tn, struct nlattr *nla,
159161
if (unlikely(!t))
160162
goto err2;
161163

162-
err = ipt_init_target(t, tname, hook);
164+
err = ipt_init_target(net, t, tname, hook);
163165
if (err < 0)
164166
goto err3;
165167

@@ -193,18 +195,16 @@ static int tcf_ipt_init(struct net *net, struct nlattr *nla,
193195
struct nlattr *est, struct tc_action **a, int ovr,
194196
int bind)
195197
{
196-
struct tc_action_net *tn = net_generic(net, ipt_net_id);
197-
198-
return __tcf_ipt_init(tn, nla, est, a, &act_ipt_ops, ovr, bind);
198+
return __tcf_ipt_init(net, ipt_net_id, nla, est, a, &act_ipt_ops, ovr,
199+
bind);
199200
}
200201

201202
static int tcf_xt_init(struct net *net, struct nlattr *nla,
202203
struct nlattr *est, struct tc_action **a, int ovr,
203204
int bind)
204205
{
205-
struct tc_action_net *tn = net_generic(net, xt_net_id);
206-
207-
return __tcf_ipt_init(tn, nla, est, a, &act_xt_ops, ovr, bind);
206+
return __tcf_ipt_init(net, xt_net_id, nla, est, a, &act_xt_ops, ovr,
207+
bind);
208208
}
209209

210210
static int tcf_ipt(struct sk_buff *skb, const struct tc_action *a,

0 commit comments

Comments
 (0)