diff options
author | Davide Caratti <dcaratti@redhat.com> | 2018-06-08 06:02:31 +0300 |
---|---|---|
committer | Ben Hutchings <ben@decadent.org.uk> | 2018-11-20 21:05:12 +0300 |
commit | 2399cf5799a0027a0a7f72f70d30ba4d3a1c3c53 (patch) | |
tree | f8785730f01430b464c0ab4ea5474cfe2e6d7189 /net/sched/act_simple.c | |
parent | 770e086ea7887427376cbb9fe93a5391224aba12 (diff) | |
download | linux-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.c | 14 |
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) |