Commit fa1b1cff3d06550d23ef540c4f97ca83c021b473

Authored by Jamal Hadi Salim
Committed by David S. Miller
1 parent 5ffc02a158

net_cls_act: Make act_simple use of netlink policy.

Convert to netlink helpers by using netlink policy validation.
As a side effect fixes a leak.

Signed-off-by: Jamal Hadi Salim <hadi@cyberus.ca>
Signed-off-by: David S. Miller <davem@davemloft.net>

Showing 1 changed file with 16 additions and 18 deletions Side-by-side Diff

net/sched/act_simple.c
... ... @@ -6,7 +6,7 @@
6 6 * as published by the Free Software Foundation; either version
7 7 * 2 of the License, or (at your option) any later version.
8 8 *
9   - * Authors: Jamal Hadi Salim (2005)
  9 + * Authors: Jamal Hadi Salim (2005-8)
10 10 *
11 11 */
12 12  
... ... @@ -34,6 +34,7 @@
34 34 .lock = &simp_lock,
35 35 };
36 36  
  37 +#define SIMP_MAX_DATA 32
37 38 static int tcf_simp(struct sk_buff *skb, struct tc_action *a, struct tcf_result *res)
38 39 {
39 40 struct tcf_defact *d = a->priv;
40 41  
41 42  
42 43  
43 44  
44 45  
... ... @@ -69,23 +70,24 @@
69 70 return ret;
70 71 }
71 72  
72   -static int alloc_defdata(struct tcf_defact *d, u32 datalen, void *defdata)
  73 +static int alloc_defdata(struct tcf_defact *d, char *defdata)
73 74 {
74   - d->tcfd_defdata = kmemdup(defdata, datalen, GFP_KERNEL);
  75 + d->tcfd_defdata = kstrndup(defdata, SIMP_MAX_DATA, GFP_KERNEL);
75 76 if (unlikely(!d->tcfd_defdata))
76 77 return -ENOMEM;
77   - d->tcfd_datalen = datalen;
  78 +
78 79 return 0;
79 80 }
80 81  
81   -static int realloc_defdata(struct tcf_defact *d, u32 datalen, void *defdata)
  82 +static int realloc_defdata(struct tcf_defact *d, char *defdata)
82 83 {
83 84 kfree(d->tcfd_defdata);
84   - return alloc_defdata(d, datalen, defdata);
  85 + return alloc_defdata(d, defdata);
85 86 }
86 87  
87 88 static const struct nla_policy simple_policy[TCA_DEF_MAX + 1] = {
88 89 [TCA_DEF_PARMS] = { .len = sizeof(struct tc_defact) },
  90 + [TCA_DEF_DATA] = { .type = NLA_STRING, .len = SIMP_MAX_DATA },
89 91 };
90 92  
91 93 static int tcf_simp_init(struct nlattr *nla, struct nlattr *est,
92 94  
93 95  
94 96  
95 97  
... ... @@ -95,29 +97,25 @@
95 97 struct tc_defact *parm;
96 98 struct tcf_defact *d;
97 99 struct tcf_common *pc;
98   - void *defdata;
99   - u32 datalen = 0;
  100 + char *defdata;
100 101 int ret = 0, err;
101 102  
102 103 if (nla == NULL)
103 104 return -EINVAL;
104 105  
105   - err = nla_parse_nested(tb, TCA_DEF_MAX, nla, NULL);
  106 + err = nla_parse_nested(tb, TCA_DEF_MAX, nla, simple_policy);
106 107 if (err < 0)
107 108 return err;
108 109  
109 110 if (tb[TCA_DEF_PARMS] == NULL)
110 111 return -EINVAL;
111 112  
  113 + if (tb[TCA_DEF_DATA] == NULL)
  114 + return -EINVAL;
  115 +
112 116 parm = nla_data(tb[TCA_DEF_PARMS]);
113 117 defdata = nla_data(tb[TCA_DEF_DATA]);
114   - if (defdata == NULL)
115   - return -EINVAL;
116 118  
117   - datalen = nla_len(tb[TCA_DEF_DATA]);
118   - if (datalen == 0)
119   - return -EINVAL;
120   -
121 119 pc = tcf_hash_check(parm->index, a, bind, &simp_hash_info);
122 120 if (!pc) {
123 121 pc = tcf_hash_create(parm->index, est, a, sizeof(*d), bind,
... ... @@ -126,7 +124,7 @@
126 124 return -ENOMEM;
127 125  
128 126 d = to_defact(pc);
129   - ret = alloc_defdata(d, datalen, defdata);
  127 + ret = alloc_defdata(d, defdata);
130 128 if (ret < 0) {
131 129 kfree(pc);
132 130 return ret;
... ... @@ -138,7 +136,7 @@
138 136 tcf_simp_release(d, bind);
139 137 return -EEXIST;
140 138 }
141   - realloc_defdata(d, datalen, defdata);
  139 + realloc_defdata(d, defdata);
142 140 }
143 141  
144 142 spin_lock_bh(&d->tcf_lock);
... ... @@ -172,7 +170,7 @@
172 170 opt.bindcnt = d->tcf_bindcnt - bind;
173 171 opt.action = d->tcf_action;
174 172 NLA_PUT(skb, TCA_DEF_PARMS, sizeof(opt), &opt);
175   - NLA_PUT(skb, TCA_DEF_DATA, d->tcfd_datalen, d->tcfd_defdata);
  173 + NLA_PUT_STRING(skb, TCA_DEF_DATA, d->tcfd_defdata);
176 174 t.install = jiffies_to_clock_t(jiffies - d->tcf_tm.install);
177 175 t.lastuse = jiffies_to_clock_t(jiffies - d->tcf_tm.lastuse);
178 176 t.expires = jiffies_to_clock_t(d->tcf_tm.expires);