aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavide Caratti <dcaratti@redhat.com>2018-06-07 23:02:31 -0400
committerDavid S. Miller <davem@davemloft.net>2018-06-08 18:49:19 -0400
commit8d499533e0bc02d44283dbdab03142b599b8ba16 (patch)
treeeaf7ec1426a9c9625b43711b6578109f22358ffc
parent6310a882fbe0b87e0950222f2ac197ed92e11792 (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.c15
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
56static int alloc_defdata(struct tcf_defact *d, char *defdata) 56static 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
65static void reset_policy(struct tcf_defact *d, char *defdata, 65static 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)