浏览代码

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>
David S. Miller 7 年之前
父节点
当前提交
78f1b04fa2
共有 5 个文件被更改,包括 13 次插入8 次删除
  1. 2 1
      net/sched/act_csum.c
  2. 2 1
      net/sched/act_sample.c
  3. 2 1
      net/sched/act_skbmod.c
  4. 5 4
      net/sched/act_tunnel_key.c
  5. 2 1
      net/sched/act_vlan.c

+ 2 - 1
net/sched/act_csum.c

@@ -626,7 +626,8 @@ static void tcf_csum_cleanup(struct tc_action *a)
 	struct tcf_csum_params *params;
 	struct tcf_csum_params *params;
 
 
 	params = rcu_dereference_protected(p->params, 1);
 	params = rcu_dereference_protected(p->params, 1);
-	kfree_rcu(params, rcu);
+	if (params)
+		kfree_rcu(params, rcu);
 }
 }
 
 
 static int tcf_csum_walker(struct net *net, struct sk_buff *skb,
 static int tcf_csum_walker(struct net *net, struct sk_buff *skb,

+ 2 - 1
net/sched/act_sample.c

@@ -103,7 +103,8 @@ static void tcf_sample_cleanup(struct tc_action *a)
 
 
 	psample_group = rtnl_dereference(s->psample_group);
 	psample_group = rtnl_dereference(s->psample_group);
 	RCU_INIT_POINTER(s->psample_group, NULL);
 	RCU_INIT_POINTER(s->psample_group, NULL);
-	psample_group_put(psample_group);
+	if (psample_group)
+		psample_group_put(psample_group);
 }
 }
 
 
 static bool tcf_sample_dev_ok_push(struct net_device *dev)
 static bool tcf_sample_dev_ok_push(struct net_device *dev)

+ 2 - 1
net/sched/act_skbmod.c

@@ -190,7 +190,8 @@ static void tcf_skbmod_cleanup(struct tc_action *a)
 	struct tcf_skbmod_params  *p;
 	struct tcf_skbmod_params  *p;
 
 
 	p = rcu_dereference_protected(d->skbmod_p, 1);
 	p = rcu_dereference_protected(d->skbmod_p, 1);
-	kfree_rcu(p, rcu);
+	if (p)
+		kfree_rcu(p, rcu);
 }
 }
 
 
 static int tcf_skbmod_dump(struct sk_buff *skb, struct tc_action *a,
 static int tcf_skbmod_dump(struct sk_buff *skb, struct tc_action *a,

+ 5 - 4
net/sched/act_tunnel_key.c

@@ -208,11 +208,12 @@ static void tunnel_key_release(struct tc_action *a)
 	struct tcf_tunnel_key_params *params;
 	struct tcf_tunnel_key_params *params;
 
 
 	params = rcu_dereference_protected(t->params, 1);
 	params = rcu_dereference_protected(t->params, 1);
+	if (params) {
+		if (params->tcft_action == TCA_TUNNEL_KEY_ACT_SET)
+			dst_release(&params->tcft_enc_metadata->dst);
 
 
-	if (params->tcft_action == TCA_TUNNEL_KEY_ACT_SET)
-		dst_release(&params->tcft_enc_metadata->dst);
-
-	kfree_rcu(params, rcu);
+		kfree_rcu(params, rcu);
+	}
 }
 }
 
 
 static int tunnel_key_dump_addresses(struct sk_buff *skb,
 static int tunnel_key_dump_addresses(struct sk_buff *skb,

+ 2 - 1
net/sched/act_vlan.c

@@ -225,7 +225,8 @@ static void tcf_vlan_cleanup(struct tc_action *a)
 	struct tcf_vlan_params *p;
 	struct tcf_vlan_params *p;
 
 
 	p = rcu_dereference_protected(v->vlan_p, 1);
 	p = rcu_dereference_protected(v->vlan_p, 1);
-	kfree_rcu(p, rcu);
+	if (p)
+		kfree_rcu(p, rcu);
 }
 }
 
 
 static int tcf_vlan_dump(struct sk_buff *skb, struct tc_action *a,
 static int tcf_vlan_dump(struct sk_buff *skb, struct tc_action *a,