diff options
| author | Davide Caratti <dcaratti@redhat.com> | 2018-06-07 23:02:31 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2018-06-08 18:49:19 -0400 |
| commit | 8d499533e0bc02d44283dbdab03142b599b8ba16 (patch) | |
| tree | eaf7ec1426a9c9625b43711b6578109f22358ffc | |
| parent | 6310a882fbe0b87e0950222f2ac197ed92e11792 (diff) | |
net/sched: act_simple: fix parsing of TCA_DEF_DATA
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>
| -rw-r--r-- | net/sched/act_simple.c | 15 |
1 files changed, 6 insertions, 9 deletions
diff --git a/net/sched/act_simple.c b/net/sched/act_simple.c index 9618b4a83cee..98c4afe7c15b 100644 --- a/net/sched/act_simple.c +++ b/net/sched/act_simple.c | |||
| @@ -53,22 +53,22 @@ static void tcf_simp_release(struct tc_action *a) | |||
| 53 | kfree(d->tcfd_defdata); | 53 | kfree(d->tcfd_defdata); |
| 54 | } | 54 | } |
| 55 | 55 | ||
| 56 | static int alloc_defdata(struct tcf_defact *d, char *defdata) | 56 | static int alloc_defdata(struct tcf_defact *d, const struct nlattr *defdata) |
| 57 | { | 57 | { |
| 58 | d->tcfd_defdata = kzalloc(SIMP_MAX_DATA, GFP_KERNEL); | 58 | d->tcfd_defdata = kzalloc(SIMP_MAX_DATA, GFP_KERNEL); |
| 59 | if (unlikely(!d->tcfd_defdata)) | 59 | if (unlikely(!d->tcfd_defdata)) |
| 60 | return -ENOMEM; | 60 | return -ENOMEM; |
| 61 | strlcpy(d->tcfd_defdata, defdata, SIMP_MAX_DATA); | 61 | nla_strlcpy(d->tcfd_defdata, defdata, SIMP_MAX_DATA); |
| 62 | return 0; | 62 | return 0; |
| 63 | } | 63 | } |
| 64 | 64 | ||
| 65 | static void reset_policy(struct tcf_defact *d, char *defdata, | 65 | static void reset_policy(struct tcf_defact *d, const struct nlattr *defdata, |
| 66 | struct tc_defact *p) | 66 | struct tc_defact *p) |
| 67 | { | 67 | { |
| 68 | spin_lock_bh(&d->tcf_lock); | 68 | spin_lock_bh(&d->tcf_lock); |
| 69 | d->tcf_action = p->action; | 69 | d->tcf_action = p->action; |
| 70 | memset(d->tcfd_defdata, 0, SIMP_MAX_DATA); | 70 | memset(d->tcfd_defdata, 0, SIMP_MAX_DATA); |
| 71 | strlcpy(d->tcfd_defdata, defdata, SIMP_MAX_DATA); | 71 | nla_strlcpy(d->tcfd_defdata, defdata, SIMP_MAX_DATA); |
| 72 | spin_unlock_bh(&d->tcf_lock); | 72 | spin_unlock_bh(&d->tcf_lock); |
| 73 | } | 73 | } |
| 74 | 74 | ||
| @@ -87,7 +87,6 @@ static int tcf_simp_init(struct net *net, struct nlattr *nla, | |||
| 87 | struct tcf_defact *d; | 87 | struct tcf_defact *d; |
| 88 | bool exists = false; | 88 | bool exists = false; |
| 89 | int ret = 0, err; | 89 | int ret = 0, err; |
| 90 | char *defdata; | ||
| 91 | 90 | ||
| 92 | if (nla == NULL) | 91 | if (nla == NULL) |
| 93 | return -EINVAL; | 92 | return -EINVAL; |
| @@ -110,8 +109,6 @@ static int tcf_simp_init(struct net *net, struct nlattr *nla, | |||
| 110 | return -EINVAL; | 109 | return -EINVAL; |
| 111 | } | 110 | } |
| 112 | 111 | ||
| 113 | defdata = nla_data(tb[TCA_DEF_DATA]); | ||
| 114 | |||
| 115 | if (!exists) { | 112 | if (!exists) { |
| 116 | ret = tcf_idr_create(tn, parm->index, est, a, | 113 | ret = tcf_idr_create(tn, parm->index, est, a, |
| 117 | &act_simp_ops, bind, false); | 114 | &act_simp_ops, bind, false); |
| @@ -119,7 +116,7 @@ static int tcf_simp_init(struct net *net, struct nlattr *nla, | |||
| 119 | return ret; | 116 | return ret; |
| 120 | 117 | ||
| 121 | d = to_defact(*a); | 118 | d = to_defact(*a); |
| 122 | ret = alloc_defdata(d, defdata); | 119 | ret = alloc_defdata(d, tb[TCA_DEF_DATA]); |
| 123 | if (ret < 0) { | 120 | if (ret < 0) { |
| 124 | tcf_idr_release(*a, bind); | 121 | tcf_idr_release(*a, bind); |
| 125 | return ret; | 122 | return ret; |
| @@ -133,7 +130,7 @@ static int tcf_simp_init(struct net *net, struct nlattr *nla, | |||
| 133 | if (!ovr) | 130 | if (!ovr) |
| 134 | return -EEXIST; | 131 | return -EEXIST; |
| 135 | 132 | ||
| 136 | reset_policy(d, defdata, parm); | 133 | reset_policy(d, tb[TCA_DEF_DATA], parm); |
| 137 | } | 134 | } |
| 138 | 135 | ||
| 139 | if (ret == ACT_P_CREATED) | 136 | if (ret == ACT_P_CREATED) |
