summaryrefslogtreecommitdiff
path: root/net/sched/act_simple.c
diff options
context:
space:
mode:
authorDavide Caratti <dcaratti@redhat.com>2018-06-08 06:02:31 +0300
committerBen Hutchings <ben@decadent.org.uk>2018-11-20 21:05:12 +0300
commit2399cf5799a0027a0a7f72f70d30ba4d3a1c3c53 (patch)
treef8785730f01430b464c0ab4ea5474cfe2e6d7189 /net/sched/act_simple.c
parent770e086ea7887427376cbb9fe93a5391224aba12 (diff)
downloadlinux-2399cf5799a0027a0a7f72f70d30ba4d3a1c3c53.tar.xz
net/sched: act_simple: fix parsing of TCA_DEF_DATA
commit 8d499533e0bc02d44283dbdab03142b599b8ba16 upstream. use nla_strlcpy() to avoid copying data beyond the length of TCA_DEF_DATA netlink attribute, in case it is less than SIMP_MAX_DATA and it does not end with '\0' character. v2: fix errors in the commit message, thanks Hangbin Liu Fixes: fa1b1cff3d06 ("net_cls_act: Make act_simple use of netlink policy.") Signed-off-by: Davide Caratti <dcaratti@redhat.com> Reviewed-by: Simon Horman <simon.horman@netronome.com> Signed-off-by: David S. Miller <davem@davemloft.net> [bwh: Backported to 3.16: adjust context] Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Diffstat (limited to 'net/sched/act_simple.c')
-rw-r--r--net/sched/act_simple.c14
1 files changed, 6 insertions, 8 deletions
diff --git a/net/sched/act_simple.c b/net/sched/act_simple.c
index 992c2317ce88..a4cde1e94b6a 100644
--- a/net/sched/act_simple.c
+++ b/net/sched/act_simple.c
@@ -52,22 +52,22 @@ static void tcf_simp_release(struct tc_action *a, int bind)
kfree(d->tcfd_defdata);
}
-static int alloc_defdata(struct tcf_defact *d, char *defdata)
+static int alloc_defdata(struct tcf_defact *d, const struct nlattr *defdata)
{
d->tcfd_defdata = kzalloc(SIMP_MAX_DATA, GFP_KERNEL);
if (unlikely(!d->tcfd_defdata))
return -ENOMEM;
- strlcpy(d->tcfd_defdata, defdata, SIMP_MAX_DATA);
+ nla_strlcpy(d->tcfd_defdata, defdata, SIMP_MAX_DATA);
return 0;
}
-static void reset_policy(struct tcf_defact *d, char *defdata,
+static void reset_policy(struct tcf_defact *d, const struct nlattr *defdata,
struct tc_defact *p)
{
spin_lock_bh(&d->tcf_lock);
d->tcf_action = p->action;
memset(d->tcfd_defdata, 0, SIMP_MAX_DATA);
- strlcpy(d->tcfd_defdata, defdata, SIMP_MAX_DATA);
+ nla_strlcpy(d->tcfd_defdata, defdata, SIMP_MAX_DATA);
spin_unlock_bh(&d->tcf_lock);
}
@@ -83,7 +83,6 @@ static int tcf_simp_init(struct net *net, struct nlattr *nla,
struct nlattr *tb[TCA_DEF_MAX + 1];
struct tc_defact *parm;
struct tcf_defact *d;
- char *defdata;
int ret = 0, err;
if (nla == NULL)
@@ -100,7 +99,6 @@ static int tcf_simp_init(struct net *net, struct nlattr *nla,
return -EINVAL;
parm = nla_data(tb[TCA_DEF_PARMS]);
- defdata = nla_data(tb[TCA_DEF_DATA]);
if (!tcf_hash_check(parm->index, a, bind)) {
ret = tcf_hash_create(parm->index, est, a, sizeof(*d), bind);
@@ -108,7 +106,7 @@ static int tcf_simp_init(struct net *net, struct nlattr *nla,
return ret;
d = to_defact(a);
- ret = alloc_defdata(d, defdata);
+ ret = alloc_defdata(d, tb[TCA_DEF_DATA]);
if (ret < 0) {
tcf_hash_cleanup(a, est);
return ret;
@@ -124,7 +122,7 @@ static int tcf_simp_init(struct net *net, struct nlattr *nla,
if (!ovr)
return -EEXIST;
- reset_policy(d, defdata, parm);
+ reset_policy(d, tb[TCA_DEF_DATA], parm);
}
if (ret == ACT_P_CREATED)