Re: [PATCH net-next v5 1/4] net/sched: user-space can't set unknown tcfa_action values

2018-08-01 Thread Jamal Hadi Salim

On 31/07/18 10:40 AM, Paolo Abeni wrote:


If we choose to reject unknown opcodes, such user-space configuration
will fail.



I think that is a good thing. The kernel should not be accepting things
it doesnt understand. This is a good opportunity to enforce that.


What would happen before this patch is that configurations using such
TC_ACT_ value would be successful. This is why I proposed to keep
the fixup.



Note: Such behavior can only occur if tc(user space) allows you
to pass illegitimate values which today can only happen when you have a 
new user space but older kernel (with "old" starting with your current

changes).
iow, fixing a policy in a kernel which has no support for TC_ACT_
to translate intent to be TC_ACT_OK/PIPE is problematic (as i was
showing earlier).


I initially thought the kernel behavior in the above scenario would
match exactly TC_ACT_UNSPEC processing, but as you noted with the
example in your previous email, TC_ACT_UNSPEC processing is actually a
bit different.



I worry: I dont think we can get a good default for most use
cases. No point in maintaining faulty  expectations
(because  IMO: the user will - eventually - fix their scripts if they
dont see expected behavior).

cheers,
jamal


Re: [PATCH net-next v5 1/4] net/sched: user-space can't set unknown tcfa_action values

2018-07-31 Thread Paolo Abeni
On Tue, 2018-07-31 at 09:53 -0400, Jamal Hadi Salim wrote:
> BTW, I asked this earlier and Jiri said it was addressed in patch 2.
> I just looked again and i may be missing something basic:
> Lets say tomorrow in a new kernel we add new TC_ACT_XXX that then gets 
> exposed to uapi - so user space tc is updated.
> You then use the new tc specifying TC_ACT_XXX policy on kernel with your
> changes.
> If i read correctly because TC_ACT_XXX is out of bounds for current
> kernel(which has your changes) you will fix it to be UNSPEC, no?

You are right.

If we choose to reject unknown opcodes, such user-space configuration
will fail.

What would happen before this patch is that configurations using such
TC_ACT_ value would be successful. This is why I proposed to keep
the fixup.

I initially thought the kernel behavior in the above scenario would
match exactly TC_ACT_UNSPEC processing, but as you noted with the
example in your previous email, TC_ACT_UNSPEC processing is actually a
bit different.

Cheers,

Paolo





Re: [PATCH net-next v5 1/4] net/sched: user-space can't set unknown tcfa_action values

2018-07-31 Thread Jamal Hadi Salim

On 31/07/18 05:41 AM, Paolo Abeni wrote:


Before this patch, the kernel exposed the same behaviour for negative
value of 'bar', while, for positive 'bar' values, the overall behaviour
was more complex (some classifier always stops with unknown positive
action value, others go to lower prio).


>

Overall, the kernel behavior should be more well-defined now, but yes,
there is a change of behavior under some circumstances.

What about instead mapping undefined/unknown actions value to TC_ACT_OK
(still at initialization time)? >
this is what is already done by
tcf_action_exec() for faulty opcodes/graphs and by tcf_ipt() and would
handle the above example more conistently.



I think PIPE maybe more reasonable. You still continue the action graph
even on such a mis-configuration.

But let me see if i can make a convincing arguement for rejecting at
init time:
I would be _very suprised_ if someone is depending on a misconfiguration 
such as this in a deployment because they would get different results 
than what they are expecting and sooner or later fix it after a lot of

debugging and cursing. Your patch helps them notice it sooner. And a
rejection even much much sooner. With a rejection you dont get to
execute a "fixup" the kernel assumes for you.

BTW, I asked this earlier and Jiri said it was addressed in patch 2.
I just looked again and i may be missing something basic:
Lets say tomorrow in a new kernel we add new TC_ACT_XXX that then gets 
exposed to uapi - so user space tc is updated.

You then use the new tc specifying TC_ACT_XXX policy on kernel with your
changes.
If i read correctly because TC_ACT_XXX is out of bounds for current
kernel(which has your changes) you will fix it to be UNSPEC, no?

cheers,
jamal


Re: [PATCH net-next v5 1/4] net/sched: user-space can't set unknown tcfa_action values

2018-07-31 Thread Paolo Abeni
On Mon, 2018-07-30 at 15:31 -0400, Jamal Hadi Salim wrote:
> On 30/07/18 12:41 PM, Paolo Abeni wrote:
> > On Mon, 2018-07-30 at 10:03 -0400, Jamal Hadi Salim wrote:
> > > On 30/07/18 08:30 AM, Paolo Abeni wrote:
> > > > }
> > > >
> > > > +   if (!tcf_action_valid(a->tcfa_action)) {
> > > > +   NL_SET_ERR_MSG(extack, "invalid action value, using 
> > > > TC_ACT_UNSPEC instead");
> > > > +   a->tcfa_action = TC_ACT_UNSPEC;
> > > > +   }
> > > > +
> > > > return a;
> > > >
> > > 
> > > 
> > > I think it would make a lot more sense to just reject the entry than
> > > changing it underneath the user to a default value. Least element of
> > > suprise.
> > 
> > I fear that would break existing (bad) users ?!? This way, such users
> > are notified they are doing something uncorrect, but still continue to
> > work.
> 
> 
> By "bad users" I think you mean someone setting a policy expecting
> one behavior but getting a different one? 

Generally speaking I thought about user-space pushing to the kernel
some uninitialized/random value for 'tcfa_action'.

> If yes, that policy was
> already wrong/buggy. As an example, if i configured:
> 
> match xxx action foo action goo action bar action gah
> 
> where action goo has a bad opcode
> If  you "fix it"  with TC_ACT_UNSPEC then basically the above
> policy is now equivalent to:
> 
> match xxx action foo action goo
> 
> Infact if there was a lower prio rule in the chain
> then lookup will continue there and produce even stranger
> results.

I see. 

Before this patch, the kernel exposed the same behaviour for negative
value of 'bar', while, for positive 'bar' values, the overall behaviour
was more complex (some classifier always stops with unknown positive
action value, others go to lower prio).

Overall, the kernel behavior should be more well-defined now, but yes,
there is a change of behavior under some circumstances.

What about instead mapping undefined/unknown actions value to TC_ACT_OK
(still at initialization time)? this is what is already done by
tcf_action_exec() for faulty opcodes/graphs and by tcf_ipt() and would
handle the above example more conistently.

Cheers,

Paolo



Re: [PATCH net-next v5 1/4] net/sched: user-space can't set unknown tcfa_action values

2018-07-30 Thread Jamal Hadi Salim

On 30/07/18 12:41 PM, Paolo Abeni wrote:

On Mon, 2018-07-30 at 10:03 -0400, Jamal Hadi Salim wrote:

On 30/07/18 08:30 AM, Paolo Abeni wrote:

}
   
+	if (!tcf_action_valid(a->tcfa_action)) {

+   NL_SET_ERR_MSG(extack, "invalid action value, using TC_ACT_UNSPEC 
instead");
+   a->tcfa_action = TC_ACT_UNSPEC;
+   }
+
return a;
   



I think it would make a lot more sense to just reject the entry than
changing it underneath the user to a default value. Least element of
suprise.


I fear that would break existing (bad) users ?!? This way, such users
are notified they are doing something uncorrect, but still continue to
work.



By "bad users" I think you mean someone setting a policy expecting
one behavior but getting a different one? If yes, that policy was
already wrong/buggy. As an example, if i configured:

match xxx action foo action goo action bar action gah

where action goo has a bad opcode
If  you "fix it"  with TC_ACT_UNSPEC then basically the above
policy is now equivalent to:

match xxx action foo action goo

Infact if there was a lower prio rule in the chain
then lookup will continue there and produce even stranger
results.


cheers,
jamal




The patch can be changed to reject bad actions, if there is agreement,
but it would not look as the safest way to me.


Re: [PATCH net-next v5 1/4] net/sched: user-space can't set unknown tcfa_action values

2018-07-30 Thread Paolo Abeni
On Mon, 2018-07-30 at 10:03 -0400, Jamal Hadi Salim wrote:
> On 30/07/18 08:30 AM, Paolo Abeni wrote:
> > }
> >   
> > +   if (!tcf_action_valid(a->tcfa_action)) {
> > +   NL_SET_ERR_MSG(extack, "invalid action value, using 
> > TC_ACT_UNSPEC instead");
> > +   a->tcfa_action = TC_ACT_UNSPEC;
> > +   }
> > +
> > return a;
> >   
> 
> 
> I think it would make a lot more sense to just reject the entry than
> changing it underneath the user to a default value. Least element of
> suprise.

I fear that would break existing (bad) users ?!? This way, such users
are notified they are doing something uncorrect, but still continue to
work.

The patch can be changed to reject bad actions, if there is agreement,
but it would not look as the safest way to me.

Thanks,

Paolo



Re: [PATCH net-next v5 1/4] net/sched: user-space can't set unknown tcfa_action values

2018-07-30 Thread Jiri Pirko
Mon, Jul 30, 2018 at 04:03:50PM CEST, j...@mojatatu.com wrote:
>On 30/07/18 08:30 AM, Paolo Abeni wrote:
>>  }
>> +if (!tcf_action_valid(a->tcfa_action)) {
>> +NL_SET_ERR_MSG(extack, "invalid action value, using 
>> TC_ACT_UNSPEC instead");
>> +a->tcfa_action = TC_ACT_UNSPEC;
>> +}
>> +
>>  return a;
>
>
>I think it would make a lot more sense to just reject the entry than
>changing it underneath the user to a default value. Least element of
>suprise.

It might break existing user who is incorrectly doing it. But I'm okay
with both solutions.

>
>cheers,
>jamal


Re: [PATCH net-next v5 1/4] net/sched: user-space can't set unknown tcfa_action values

2018-07-30 Thread Jamal Hadi Salim

On 30/07/18 08:30 AM, Paolo Abeni wrote:

}
  
+	if (!tcf_action_valid(a->tcfa_action)) {

+   NL_SET_ERR_MSG(extack, "invalid action value, using TC_ACT_UNSPEC 
instead");
+   a->tcfa_action = TC_ACT_UNSPEC;
+   }
+
return a;
  



I think it would make a lot more sense to just reject the entry than
changing it underneath the user to a default value. Least element of
suprise.

cheers,
jamal


Re: [PATCH net-next v5 1/4] net/sched: user-space can't set unknown tcfa_action values

2018-07-30 Thread Jiri Pirko
Mon, Jul 30, 2018 at 02:30:42PM CEST, pab...@redhat.com wrote:
>Currently, when initializing an action, the user-space can specify
>and use arbitrary values for the tcfa_action field. If the value
>is unknown by the kernel, is implicitly threaded as TC_ACT_UNSPEC.
>
>This change explicitly checks for unknown values at action creation
>time, and explicitly convert them to TC_ACT_UNSPEC. No functional
>changes are introduced, but this will allow introducing tcfa_action
>values not exposed to user-space in a later patch.
>
>Note: we can't use the above to hide TC_ACT_REDIRECT from user-space,
>as the latter is already part of uAPI.
>
>v3 -> v4:
> - use an helper to check for action validity (JiriP)
> - emit an extack for invalid actions (JiriP)
>v4 -> v5:
> - keep messages on a single line, drop net_warn (Marcelo)

Little nitpick: The changelog should be in the reverse order.

>
>Signed-off-by: Paolo Abeni 

Acked-by: Jiri Pirko 


[PATCH net-next v5 1/4] net/sched: user-space can't set unknown tcfa_action values

2018-07-30 Thread Paolo Abeni
Currently, when initializing an action, the user-space can specify
and use arbitrary values for the tcfa_action field. If the value
is unknown by the kernel, is implicitly threaded as TC_ACT_UNSPEC.

This change explicitly checks for unknown values at action creation
time, and explicitly convert them to TC_ACT_UNSPEC. No functional
changes are introduced, but this will allow introducing tcfa_action
values not exposed to user-space in a later patch.

Note: we can't use the above to hide TC_ACT_REDIRECT from user-space,
as the latter is already part of uAPI.

v3 -> v4:
 - use an helper to check for action validity (JiriP)
 - emit an extack for invalid actions (JiriP)
v4 -> v5:
 - keep messages on a single line, drop net_warn (Marcelo)

Signed-off-by: Paolo Abeni 
---
 include/uapi/linux/pkt_cls.h |  6 --
 net/sched/act_api.c  | 14 ++
 2 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/include/uapi/linux/pkt_cls.h b/include/uapi/linux/pkt_cls.h
index b4512254036b..48e5b5d49a34 100644
--- a/include/uapi/linux/pkt_cls.h
+++ b/include/uapi/linux/pkt_cls.h
@@ -45,6 +45,7 @@ enum {
   * the skb and act like everything
   * is alright.
   */
+#define TC_ACT_VALUE_MAX   TC_ACT_TRAP
 
 /* There is a special kind of actions called "extended actions",
  * which need a value parameter. These have a local opcode located in
@@ -55,11 +56,12 @@ enum {
 #define __TC_ACT_EXT_SHIFT 28
 #define __TC_ACT_EXT(local) ((local) << __TC_ACT_EXT_SHIFT)
 #define TC_ACT_EXT_VAL_MASK ((1 << __TC_ACT_EXT_SHIFT) - 1)
-#define TC_ACT_EXT_CMP(combined, opcode) \
-   (((combined) & (~TC_ACT_EXT_VAL_MASK)) == opcode)
+#define TC_ACT_EXT_OPCODE(combined) ((combined) & (~TC_ACT_EXT_VAL_MASK))
+#define TC_ACT_EXT_CMP(combined, opcode) (TC_ACT_EXT_OPCODE(combined) == 
opcode)
 
 #define TC_ACT_JUMP __TC_ACT_EXT(1)
 #define TC_ACT_GOTO_CHAIN __TC_ACT_EXT(2)
+#define TC_ACT_EXT_OPCODE_MAX  TC_ACT_GOTO_CHAIN
 
 /* Action type identifiers*/
 enum {
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index b43df1e25c6d..229d63c99be2 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -786,6 +786,15 @@ static struct tc_cookie *nla_memdup_cookie(struct nlattr 
**tb)
return c;
 }
 
+static bool tcf_action_valid(int action)
+{
+   int opcode = TC_ACT_EXT_OPCODE(action);
+
+   if (!opcode)
+   return action <= TC_ACT_VALUE_MAX;
+   return opcode <= TC_ACT_EXT_OPCODE_MAX || action == TC_ACT_UNSPEC;
+}
+
 struct tc_action *tcf_action_init_1(struct net *net, struct tcf_proto *tp,
struct nlattr *nla, struct nlattr *est,
char *name, int ovr, int bind,
@@ -895,6 +904,11 @@ struct tc_action *tcf_action_init_1(struct net *net, 
struct tcf_proto *tp,
}
}
 
+   if (!tcf_action_valid(a->tcfa_action)) {
+   NL_SET_ERR_MSG(extack, "invalid action value, using 
TC_ACT_UNSPEC instead");
+   a->tcfa_action = TC_ACT_UNSPEC;
+   }
+
return a;
 
 err_mod:
-- 
2.17.1