[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <7673fdb060c9b44656d7ef356c318db4ad197080.1550271080.git.dcaratti@redhat.com>
Date: Sat, 16 Feb 2019 00:06:29 +0100
From: Davide Caratti <dcaratti@...hat.com>
To: Jamal Hadi Salim <jhs@...atatu.com>,
Cong Wang <xiyou.wangcong@...il.com>,
Jiri Pirko <jiri@...nulli.us>
Cc: "David S. Miller" <davem@...emloft.net>,
Vlad Buslov <vladbu@...lanox.com>,
Paolo Abeni <pabeni@...hat.com>, netdev@...r.kernel.org
Subject: [PATCH RFC 3/5] net/sched: act_bpf: validate the control action inside init()
Don't overwrite act_bpf data if the control control action is not valid,
to prevent loosing the previous configuration in case validation failed.
Not doing that caused NULL dereference in the data path if 'goto chain'
is used.
Tested with:
# ./tdc.py -c bpf
Fixes: db50514f9a9c ("net: sched: add termination action to allow goto chain")
Fixes: 97763dc0f401 ("net_sched: reject unknown tcfa_action values")
Signed-off-by: Davide Caratti <dcaratti@...hat.com>
---
net/sched/act_bpf.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/net/sched/act_bpf.c b/net/sched/act_bpf.c
index 88a729bdab25..e2c2ba5faeb3 100644
--- a/net/sched/act_bpf.c
+++ b/net/sched/act_bpf.c
@@ -17,6 +17,7 @@
#include <net/netlink.h>
#include <net/pkt_sched.h>
+#include <net/pkt_cls.h>
#include <linux/tc_act/tc_bpf.h>
#include <net/tc_act/tc_bpf.h>
@@ -282,6 +283,7 @@ static int tcf_bpf_init(struct net *net, struct nlattr *nla,
{
struct tc_action_net *tn = net_generic(net, bpf_net_id);
struct nlattr *tb[TCA_ACT_BPF_MAX + 1];
+ struct tcf_chain *newchain = NULL;
struct tcf_bpf_cfg cfg, old;
struct tc_act_bpf *parm;
struct tcf_bpf *prog;
@@ -323,6 +325,10 @@ static int tcf_bpf_init(struct net *net, struct nlattr *nla,
return ret;
}
+ ret = tcf_action_check_ctrlact(parm->action, tp, &newchain, extack);
+ if (ret < 0)
+ goto out;
+
is_bpf = tb[TCA_ACT_BPF_OPS_LEN] && tb[TCA_ACT_BPF_OPS];
is_ebpf = tb[TCA_ACT_BPF_FD];
@@ -350,7 +356,7 @@ static int tcf_bpf_init(struct net *net, struct nlattr *nla,
if (cfg.bpf_num_ops)
prog->bpf_num_ops = cfg.bpf_num_ops;
- prog->tcf_action = parm->action;
+ tcf_action_set_ctrlact(*act, parm->action, newchain);
rcu_assign_pointer(prog->filter, cfg.filter);
spin_unlock_bh(&prog->tcf_lock);
@@ -364,6 +370,8 @@ static int tcf_bpf_init(struct net *net, struct nlattr *nla,
return res;
out:
+ if (newchain)
+ tcf_chain_put_by_act(newchain);
tcf_idr_release(*act, bind);
return ret;
--
2.20.1
Powered by blists - more mailing lists