Re: [PATCH net] net: sched: set xt_tgchk_param par.net properly in ipt_init_target

2017-08-07 Thread Xin Long
On Tue, Aug 8, 2017 at 9:00 AM, Cong Wang  wrote:
> On Sat, Aug 5, 2017 at 1:48 AM, Xin Long  wrote:
>> -static int __tcf_ipt_init(struct tc_action_net *tn, struct nlattr *nla,
>> +static int __tcf_ipt_init(struct net *net, struct nlattr *nla,
>>   struct nlattr *est, struct tc_action **a,
>>   const struct tc_action_ops *ops, int ovr, int bind)
>>  {
>> +   struct tc_action_net *tn = net_generic(net, xt_net_id);
>
> ...
>
>> @@ -193,18 +195,14 @@ static int tcf_ipt_init(struct net *net, struct nlattr 
>> *nla,
>> struct nlattr *est, struct tc_action **a, int ovr,
>> int bind)
>>  {
>> -   struct tc_action_net *tn = net_generic(net, ipt_net_id);
>> -
>> -   return __tcf_ipt_init(tn, nla, est, a, _ipt_ops, ovr, bind);
>> +   return __tcf_ipt_init(net, nla, est, a, _ipt_ops, ovr, bind);
>>  }
>>
>>  static int tcf_xt_init(struct net *net, struct nlattr *nla,
>>struct nlattr *est, struct tc_action **a, int ovr,
>>int bind)
>>  {
>> -   struct tc_action_net *tn = net_generic(net, xt_net_id);
>> -
>> -   return __tcf_ipt_init(tn, nla, est, a, _xt_ops, ovr, bind);
>> +   return __tcf_ipt_init(net, nla, est, a, _xt_ops, ovr, bind);
>
> This is not correct.
>
> You miss ipt_net_id != xt_net_id.
right, that's a silly mistake. seems no better way but to pass both
net and net_id to __tcf_ipt_init. will send v2. thanks.


Re: [PATCH net] net: sched: set xt_tgchk_param par.net properly in ipt_init_target

2017-08-07 Thread Cong Wang
On Sat, Aug 5, 2017 at 1:48 AM, Xin Long  wrote:
> -static int __tcf_ipt_init(struct tc_action_net *tn, struct nlattr *nla,
> +static int __tcf_ipt_init(struct net *net, struct nlattr *nla,
>   struct nlattr *est, struct tc_action **a,
>   const struct tc_action_ops *ops, int ovr, int bind)
>  {
> +   struct tc_action_net *tn = net_generic(net, xt_net_id);

...

> @@ -193,18 +195,14 @@ static int tcf_ipt_init(struct net *net, struct nlattr 
> *nla,
> struct nlattr *est, struct tc_action **a, int ovr,
> int bind)
>  {
> -   struct tc_action_net *tn = net_generic(net, ipt_net_id);
> -
> -   return __tcf_ipt_init(tn, nla, est, a, _ipt_ops, ovr, bind);
> +   return __tcf_ipt_init(net, nla, est, a, _ipt_ops, ovr, bind);
>  }
>
>  static int tcf_xt_init(struct net *net, struct nlattr *nla,
>struct nlattr *est, struct tc_action **a, int ovr,
>int bind)
>  {
> -   struct tc_action_net *tn = net_generic(net, xt_net_id);
> -
> -   return __tcf_ipt_init(tn, nla, est, a, _xt_ops, ovr, bind);
> +   return __tcf_ipt_init(net, nla, est, a, _xt_ops, ovr, bind);

This is not correct.

You miss ipt_net_id != xt_net_id.


[PATCH net] net: sched: set xt_tgchk_param par.net properly in ipt_init_target

2017-08-05 Thread Xin Long
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 :
  # tc filter add dev TestIface parent : 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.

Reported-by: Jaroslav Aster 
Signed-off-by: Xin Long 
---
 net/sched/act_ipt.c | 18 --
 1 file changed, 8 insertions(+), 10 deletions(-)

diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c
index 36f0ced..bb06d2ed 100644
--- a/net/sched/act_ipt.c
+++ b/net/sched/act_ipt.c
@@ -36,8 +36,8 @@ static struct tc_action_ops act_ipt_ops;
 static unsigned int xt_net_id;
 static struct tc_action_ops act_xt_ops;
 
-static int ipt_init_target(struct xt_entry_target *t, char *table,
-  unsigned int hook)
+static int ipt_init_target(struct net *net, struct xt_entry_target *t,
+  char *table, unsigned int hook)
 {
struct xt_tgchk_param par;
struct xt_target *target;
@@ -49,6 +49,7 @@ static int ipt_init_target(struct xt_entry_target *t, char 
*table,
return PTR_ERR(target);
 
t->u.kernel.target = target;
+   par.net   = net;
par.table = table;
par.entryinfo = NULL;
par.target= target;
@@ -91,10 +92,11 @@ static const struct nla_policy ipt_policy[TCA_IPT_MAX + 1] 
= {
[TCA_IPT_TARG]  = { .len = sizeof(struct xt_entry_target) },
 };
 
-static int __tcf_ipt_init(struct tc_action_net *tn, struct nlattr *nla,
+static int __tcf_ipt_init(struct net *net, struct nlattr *nla,
  struct nlattr *est, struct tc_action **a,
  const struct tc_action_ops *ops, int ovr, int bind)
 {
+   struct tc_action_net *tn = net_generic(net, xt_net_id);
struct nlattr *tb[TCA_IPT_MAX + 1];
struct tcf_ipt *ipt;
struct xt_entry_target *td, *t;
@@ -159,7 +161,7 @@ static int __tcf_ipt_init(struct tc_action_net *tn, struct 
nlattr *nla,
if (unlikely(!t))
goto err2;
 
-   err = ipt_init_target(t, tname, hook);
+   err = ipt_init_target(net, t, tname, hook);
if (err < 0)
goto err3;
 
@@ -193,18 +195,14 @@ static int tcf_ipt_init(struct net *net, struct nlattr 
*nla,
struct nlattr *est, struct tc_action **a, int ovr,
int bind)
 {
-   struct tc_action_net *tn = net_generic(net, ipt_net_id);
-
-   return __tcf_ipt_init(tn, nla, est, a, _ipt_ops, ovr, bind);
+   return __tcf_ipt_init(net, nla, est, a, _ipt_ops, ovr, bind);
 }
 
 static int tcf_xt_init(struct net *net, struct nlattr *nla,
   struct nlattr *est, struct tc_action **a, int ovr,
   int bind)
 {
-   struct tc_action_net *tn = net_generic(net, xt_net_id);
-
-   return __tcf_ipt_init(tn, nla, est, a, _xt_ops, ovr, bind);
+   return __tcf_ipt_init(net, nla, est, a, _xt_ops, ovr, bind);
 }
 
 static int tcf_ipt(struct sk_buff *skb, const struct tc_action *a,
-- 
2.1.0