diff options
author | David S. Miller <davem@davemloft.net> | 2018-03-17 19:53:29 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-03-17 19:53:29 -0400 |
commit | 78f1b04fa20d414ff3aa749b2c303324c7db2c26 (patch) | |
tree | cff5b5cd7ea1c187cbe8d6f19f7a10fc6e79824b | |
parent | f9db50691db4a7d860fce985f080bb3fc23a7ede (diff) | |
parent | 2d433610176d6569e8b3a28f67bc72235bf69efc (diff) |
Merge branch 'tcf_foo_init-NULL-deref'
Davide Caratti says:
====================
net/sched: fix NULL dereference in the error path of .init()
with several TC actions it's possible to see NULL pointer dereference,
when the .init() function calls tcf_idr_alloc(), fails at some point and
then calls tcf_idr_release(): this series fixes all them introducing
non-NULL tests in the .cleanup() function.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/sched/act_csum.c | 3 | ||||
-rw-r--r-- | net/sched/act_sample.c | 3 | ||||
-rw-r--r-- | net/sched/act_skbmod.c | 3 | ||||
-rw-r--r-- | net/sched/act_tunnel_key.c | 9 | ||||
-rw-r--r-- | net/sched/act_vlan.c | 3 |
5 files changed, 13 insertions, 8 deletions
diff --git a/net/sched/act_csum.c b/net/sched/act_csum.c index 24b2e8e681cf..2a5c8fd860cf 100644 --- a/net/sched/act_csum.c +++ b/net/sched/act_csum.c | |||
@@ -626,7 +626,8 @@ static void tcf_csum_cleanup(struct tc_action *a) | |||
626 | struct tcf_csum_params *params; | 626 | struct tcf_csum_params *params; |
627 | 627 | ||
628 | params = rcu_dereference_protected(p->params, 1); | 628 | params = rcu_dereference_protected(p->params, 1); |
629 | kfree_rcu(params, rcu); | 629 | if (params) |
630 | kfree_rcu(params, rcu); | ||
630 | } | 631 | } |
631 | 632 | ||
632 | static int tcf_csum_walker(struct net *net, struct sk_buff *skb, | 633 | static int tcf_csum_walker(struct net *net, struct sk_buff *skb, |
diff --git a/net/sched/act_sample.c b/net/sched/act_sample.c index 1ba0df238756..74c5d7e6a0fa 100644 --- a/net/sched/act_sample.c +++ b/net/sched/act_sample.c | |||
@@ -103,7 +103,8 @@ static void tcf_sample_cleanup(struct tc_action *a) | |||
103 | 103 | ||
104 | psample_group = rtnl_dereference(s->psample_group); | 104 | psample_group = rtnl_dereference(s->psample_group); |
105 | RCU_INIT_POINTER(s->psample_group, NULL); | 105 | RCU_INIT_POINTER(s->psample_group, NULL); |
106 | psample_group_put(psample_group); | 106 | if (psample_group) |
107 | psample_group_put(psample_group); | ||
107 | } | 108 | } |
108 | 109 | ||
109 | static bool tcf_sample_dev_ok_push(struct net_device *dev) | 110 | static bool tcf_sample_dev_ok_push(struct net_device *dev) |
diff --git a/net/sched/act_skbmod.c b/net/sched/act_skbmod.c index fa975262dbac..d09565d6433e 100644 --- a/net/sched/act_skbmod.c +++ b/net/sched/act_skbmod.c | |||
@@ -190,7 +190,8 @@ static void tcf_skbmod_cleanup(struct tc_action *a) | |||
190 | struct tcf_skbmod_params *p; | 190 | struct tcf_skbmod_params *p; |
191 | 191 | ||
192 | p = rcu_dereference_protected(d->skbmod_p, 1); | 192 | p = rcu_dereference_protected(d->skbmod_p, 1); |
193 | kfree_rcu(p, rcu); | 193 | if (p) |
194 | kfree_rcu(p, rcu); | ||
194 | } | 195 | } |
195 | 196 | ||
196 | static int tcf_skbmod_dump(struct sk_buff *skb, struct tc_action *a, | 197 | static int tcf_skbmod_dump(struct sk_buff *skb, struct tc_action *a, |
diff --git a/net/sched/act_tunnel_key.c b/net/sched/act_tunnel_key.c index fea772e66e62..1281ca463727 100644 --- a/net/sched/act_tunnel_key.c +++ b/net/sched/act_tunnel_key.c | |||
@@ -208,11 +208,12 @@ static void tunnel_key_release(struct tc_action *a) | |||
208 | struct tcf_tunnel_key_params *params; | 208 | struct tcf_tunnel_key_params *params; |
209 | 209 | ||
210 | params = rcu_dereference_protected(t->params, 1); | 210 | params = rcu_dereference_protected(t->params, 1); |
211 | if (params) { | ||
212 | if (params->tcft_action == TCA_TUNNEL_KEY_ACT_SET) | ||
213 | dst_release(¶ms->tcft_enc_metadata->dst); | ||
211 | 214 | ||
212 | if (params->tcft_action == TCA_TUNNEL_KEY_ACT_SET) | 215 | kfree_rcu(params, rcu); |
213 | dst_release(¶ms->tcft_enc_metadata->dst); | 216 | } |
214 | |||
215 | kfree_rcu(params, rcu); | ||
216 | } | 217 | } |
217 | 218 | ||
218 | static int tunnel_key_dump_addresses(struct sk_buff *skb, | 219 | static int tunnel_key_dump_addresses(struct sk_buff *skb, |
diff --git a/net/sched/act_vlan.c b/net/sched/act_vlan.c index e1a1b3f3983a..c2914e9a4a6f 100644 --- a/net/sched/act_vlan.c +++ b/net/sched/act_vlan.c | |||
@@ -225,7 +225,8 @@ static void tcf_vlan_cleanup(struct tc_action *a) | |||
225 | struct tcf_vlan_params *p; | 225 | struct tcf_vlan_params *p; |
226 | 226 | ||
227 | p = rcu_dereference_protected(v->vlan_p, 1); | 227 | p = rcu_dereference_protected(v->vlan_p, 1); |
228 | kfree_rcu(p, rcu); | 228 | if (p) |
229 | kfree_rcu(p, rcu); | ||
229 | } | 230 | } |
230 | 231 | ||
231 | static int tcf_vlan_dump(struct sk_buff *skb, struct tc_action *a, | 232 | static int tcf_vlan_dump(struct sk_buff *skb, struct tc_action *a, |