diff options
author | David S. Miller <davem@davemloft.net> | 2018-10-23 05:42:58 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-10-23 05:42:58 +0300 |
commit | ec7f0ee2c10539c6ae1e87be8711562ffbea1563 (patch) | |
tree | 3f8ec7bf23a3aff1f50523acd41000f852de2e88 | |
parent | 92c9d5627a79b02299dd13e3e0ec695475726cf8 (diff) | |
parent | 246e886d22e2a8ceceec1f4f66138f93eafddbaa (diff) | |
download | linux-ec7f0ee2c10539c6ae1e87be8711562ffbea1563.tar.xz |
Merge branch 'forbid-goto_chain-fallback'
Davide Caratti says:
====================
net/sched: forbid 'goto_chain' on fallback actions
the following command:
# tc actions add action police rate 1mbit burst 1k conform-exceed \
> pass / goto chain 42
generates a NULL pointer dereference when packets exceed the configured
rate. Similarly, the following command:
# tc actions add action pass random determ goto chain 42 2
makes the kernel crash with NULL dereference when the first packet does
not match the 'pass' action.
gact and police allow users to specify a fallback control action, that is
stored in the action private data. 'goto chain x' never worked for these
cases, since a->goto_chain handle was never initialized. There is only one
goto_chain handle per TC action, and it is designed to be non-NULL only if
tcf_action contains a 'goto chain' command. So, let's forbid 'goto chain'
on fallback actions.
Patch 1/4 and 2/4 change the .init() functions of police and gact, to let
them return an error when users try to set 'goto chain x' in the fallback
action. Patch 3/4 and 4/4 add TDC selftest coverage to this new behavior.
====================
Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/sched/act_gact.c | 5 | ||||
-rw-r--r-- | net/sched/act_police.c | 12 | ||||
-rw-r--r-- | tools/testing/selftests/tc-testing/tc-tests/actions/gact.json | 24 | ||||
-rw-r--r-- | tools/testing/selftests/tc-testing/tc-tests/actions/police.json | 24 |
4 files changed, 63 insertions, 2 deletions
diff --git a/net/sched/act_gact.c b/net/sched/act_gact.c index c89a7fa43d1b..b61c20ebb314 100644 --- a/net/sched/act_gact.c +++ b/net/sched/act_gact.c @@ -88,6 +88,11 @@ static int tcf_gact_init(struct net *net, struct nlattr *nla, p_parm = nla_data(tb[TCA_GACT_PROB]); if (p_parm->ptype >= MAX_RAND) return -EINVAL; + if (TC_ACT_EXT_CMP(p_parm->paction, TC_ACT_GOTO_CHAIN)) { + NL_SET_ERR_MSG(extack, + "goto chain not allowed on fallback"); + return -EINVAL; + } } #endif diff --git a/net/sched/act_police.c b/net/sched/act_police.c index 92649d2667ed..052855d47354 100644 --- a/net/sched/act_police.c +++ b/net/sched/act_police.c @@ -185,8 +185,6 @@ static int tcf_police_init(struct net *net, struct nlattr *nla, new->peak_present = false; } - if (tb[TCA_POLICE_RESULT]) - new->tcfp_result = nla_get_u32(tb[TCA_POLICE_RESULT]); new->tcfp_burst = PSCHED_TICKS2NS(parm->burst); new->tcfp_toks = new->tcfp_burst; if (new->peak_present) { @@ -198,6 +196,16 @@ static int tcf_police_init(struct net *net, struct nlattr *nla, if (tb[TCA_POLICE_AVRATE]) new->tcfp_ewma_rate = nla_get_u32(tb[TCA_POLICE_AVRATE]); + if (tb[TCA_POLICE_RESULT]) { + new->tcfp_result = nla_get_u32(tb[TCA_POLICE_RESULT]); + if (TC_ACT_EXT_CMP(new->tcfp_result, TC_ACT_GOTO_CHAIN)) { + NL_SET_ERR_MSG(extack, + "goto chain not allowed on fallback"); + err = -EINVAL; + goto failure; + } + } + spin_lock_bh(&police->tcf_lock); new->tcfp_t_c = ktime_get_ns(); police->tcf_action = parm->action; diff --git a/tools/testing/selftests/tc-testing/tc-tests/actions/gact.json b/tools/testing/selftests/tc-testing/tc-tests/actions/gact.json index 68c91023cdb9..89189a03ce3d 100644 --- a/tools/testing/selftests/tc-testing/tc-tests/actions/gact.json +++ b/tools/testing/selftests/tc-testing/tc-tests/actions/gact.json @@ -536,5 +536,29 @@ "matchPattern": "^[ \t]+index [0-9]+ ref", "matchCount": "0", "teardown": [] + }, + { + "id": "8e47", + "name": "Add gact action with random determ goto chain control action", + "category": [ + "actions", + "gact" + ], + "setup": [ + [ + "$TC actions flush action gact", + 0, + 1, + 255 + ] + ], + "cmdUnderTest": "$TC actions add action pass random determ goto chain 1 2 index 90", + "expExitCode": "255", + "verifyCmd": "$TC actions list action gact", + "matchPattern": "action order [0-9]*: gact action pass random type determ goto chain 1 val 2.*index 90 ref", + "matchCount": "0", + "teardown": [ + "$TC actions flush action gact" + ] } ] diff --git a/tools/testing/selftests/tc-testing/tc-tests/actions/police.json b/tools/testing/selftests/tc-testing/tc-tests/actions/police.json index 30f9b54bd666..4086a50a670e 100644 --- a/tools/testing/selftests/tc-testing/tc-tests/actions/police.json +++ b/tools/testing/selftests/tc-testing/tc-tests/actions/police.json @@ -715,5 +715,29 @@ "teardown": [ "$TC actions flush action police" ] + }, + { + "id": "b48b", + "name": "Add police action with exceed goto chain control action", + "category": [ + "actions", + "police" + ], + "setup": [ + [ + "$TC actions flush action police", + 0, + 1, + 255 + ] + ], + "cmdUnderTest": "$TC actions add action police rate 1mbit burst 1k conform-exceed pass / goto chain 42", + "expExitCode": "255", + "verifyCmd": "$TC actions ls action police", + "matchPattern": "action order [0-9]*: police 0x1 rate 1Mbit burst 1Kb mtu 2Kb action pass/goto chain 42", + "matchCount": "0", + "teardown": [ + "$TC actions flush action police" + ] } ] |