diff options
author | Paul Moore <paul.moore@hp.com> | 2006-12-15 16:49:27 -0500 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-12-22 14:11:56 -0500 |
commit | 1fd2a25b77bb6755d38aca50b826ff8dca81d762 (patch) | |
tree | 9f5f8bd5cb99cefa8db812f7182b22da6ecf993c /net/netlabel/netlabel_cipso_v4.c | |
parent | c2fda5fed81eea077363b285b66eafce20dfd45a (diff) |
NetLabel: perform input validation earlier on CIPSOv4 DOI add ops
There are a couple of cases where the user input for a CIPSOv4 DOI add
operation was not being done soon enough; the result was unexpected behavior
which was resulting in oops/panics/lockups on some platforms. This patch moves
the existing input validation code earlier in the code path to protect against
bogus user input.
Signed-off-by: Paul Moore <paul.moore@hp.com>
Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'net/netlabel/netlabel_cipso_v4.c')
-rw-r--r-- | net/netlabel/netlabel_cipso_v4.c | 28 |
1 files changed, 17 insertions, 11 deletions
diff --git a/net/netlabel/netlabel_cipso_v4.c b/net/netlabel/netlabel_cipso_v4.c index 743b05734a49..1fbc906a9737 100644 --- a/net/netlabel/netlabel_cipso_v4.c +++ b/net/netlabel/netlabel_cipso_v4.c | |||
@@ -185,20 +185,31 @@ static int netlbl_cipsov4_add_std(struct genl_info *info) | |||
185 | ret_val = netlbl_cipsov4_add_common(info, doi_def); | 185 | ret_val = netlbl_cipsov4_add_common(info, doi_def); |
186 | if (ret_val != 0) | 186 | if (ret_val != 0) |
187 | goto add_std_failure; | 187 | goto add_std_failure; |
188 | ret_val = -EINVAL; | ||
188 | 189 | ||
189 | nla_for_each_nested(nla_a, | 190 | nla_for_each_nested(nla_a, |
190 | info->attrs[NLBL_CIPSOV4_A_MLSLVLLST], | 191 | info->attrs[NLBL_CIPSOV4_A_MLSLVLLST], |
191 | nla_a_rem) | 192 | nla_a_rem) |
192 | if (nla_a->nla_type == NLBL_CIPSOV4_A_MLSLVL) { | 193 | if (nla_a->nla_type == NLBL_CIPSOV4_A_MLSLVL) { |
194 | if (nla_validate_nested(nla_a, | ||
195 | NLBL_CIPSOV4_A_MAX, | ||
196 | netlbl_cipsov4_genl_policy) != 0) | ||
197 | goto add_std_failure; | ||
193 | nla_for_each_nested(nla_b, nla_a, nla_b_rem) | 198 | nla_for_each_nested(nla_b, nla_a, nla_b_rem) |
194 | switch (nla_b->nla_type) { | 199 | switch (nla_b->nla_type) { |
195 | case NLBL_CIPSOV4_A_MLSLVLLOC: | 200 | case NLBL_CIPSOV4_A_MLSLVLLOC: |
201 | if (nla_get_u32(nla_b) > | ||
202 | CIPSO_V4_MAX_LOC_LVLS) | ||
203 | goto add_std_failure; | ||
196 | if (nla_get_u32(nla_b) >= | 204 | if (nla_get_u32(nla_b) >= |
197 | doi_def->map.std->lvl.local_size) | 205 | doi_def->map.std->lvl.local_size) |
198 | doi_def->map.std->lvl.local_size = | 206 | doi_def->map.std->lvl.local_size = |
199 | nla_get_u32(nla_b) + 1; | 207 | nla_get_u32(nla_b) + 1; |
200 | break; | 208 | break; |
201 | case NLBL_CIPSOV4_A_MLSLVLREM: | 209 | case NLBL_CIPSOV4_A_MLSLVLREM: |
210 | if (nla_get_u32(nla_b) > | ||
211 | CIPSO_V4_MAX_REM_LVLS) | ||
212 | goto add_std_failure; | ||
202 | if (nla_get_u32(nla_b) >= | 213 | if (nla_get_u32(nla_b) >= |
203 | doi_def->map.std->lvl.cipso_size) | 214 | doi_def->map.std->lvl.cipso_size) |
204 | doi_def->map.std->lvl.cipso_size = | 215 | doi_def->map.std->lvl.cipso_size = |
@@ -206,9 +217,6 @@ static int netlbl_cipsov4_add_std(struct genl_info *info) | |||
206 | break; | 217 | break; |
207 | } | 218 | } |
208 | } | 219 | } |
209 | if (doi_def->map.std->lvl.local_size > CIPSO_V4_MAX_LOC_LVLS || | ||
210 | doi_def->map.std->lvl.cipso_size > CIPSO_V4_MAX_REM_LVLS) | ||
211 | goto add_std_failure; | ||
212 | doi_def->map.std->lvl.local = kcalloc(doi_def->map.std->lvl.local_size, | 220 | doi_def->map.std->lvl.local = kcalloc(doi_def->map.std->lvl.local_size, |
213 | sizeof(u32), | 221 | sizeof(u32), |
214 | GFP_KERNEL); | 222 | GFP_KERNEL); |
@@ -230,11 +238,6 @@ static int netlbl_cipsov4_add_std(struct genl_info *info) | |||
230 | struct nlattr *lvl_loc; | 238 | struct nlattr *lvl_loc; |
231 | struct nlattr *lvl_rem; | 239 | struct nlattr *lvl_rem; |
232 | 240 | ||
233 | if (nla_validate_nested(nla_a, | ||
234 | NLBL_CIPSOV4_A_MAX, | ||
235 | netlbl_cipsov4_genl_policy) != 0) | ||
236 | goto add_std_failure; | ||
237 | |||
238 | lvl_loc = nla_find_nested(nla_a, | 241 | lvl_loc = nla_find_nested(nla_a, |
239 | NLBL_CIPSOV4_A_MLSLVLLOC); | 242 | NLBL_CIPSOV4_A_MLSLVLLOC); |
240 | lvl_rem = nla_find_nested(nla_a, | 243 | lvl_rem = nla_find_nested(nla_a, |
@@ -264,12 +267,18 @@ static int netlbl_cipsov4_add_std(struct genl_info *info) | |||
264 | nla_for_each_nested(nla_b, nla_a, nla_b_rem) | 267 | nla_for_each_nested(nla_b, nla_a, nla_b_rem) |
265 | switch (nla_b->nla_type) { | 268 | switch (nla_b->nla_type) { |
266 | case NLBL_CIPSOV4_A_MLSCATLOC: | 269 | case NLBL_CIPSOV4_A_MLSCATLOC: |
270 | if (nla_get_u32(nla_b) > | ||
271 | CIPSO_V4_MAX_LOC_CATS) | ||
272 | goto add_std_failure; | ||
267 | if (nla_get_u32(nla_b) >= | 273 | if (nla_get_u32(nla_b) >= |
268 | doi_def->map.std->cat.local_size) | 274 | doi_def->map.std->cat.local_size) |
269 | doi_def->map.std->cat.local_size = | 275 | doi_def->map.std->cat.local_size = |
270 | nla_get_u32(nla_b) + 1; | 276 | nla_get_u32(nla_b) + 1; |
271 | break; | 277 | break; |
272 | case NLBL_CIPSOV4_A_MLSCATREM: | 278 | case NLBL_CIPSOV4_A_MLSCATREM: |
279 | if (nla_get_u32(nla_b) > | ||
280 | CIPSO_V4_MAX_REM_CATS) | ||
281 | goto add_std_failure; | ||
273 | if (nla_get_u32(nla_b) >= | 282 | if (nla_get_u32(nla_b) >= |
274 | doi_def->map.std->cat.cipso_size) | 283 | doi_def->map.std->cat.cipso_size) |
275 | doi_def->map.std->cat.cipso_size = | 284 | doi_def->map.std->cat.cipso_size = |
@@ -277,9 +286,6 @@ static int netlbl_cipsov4_add_std(struct genl_info *info) | |||
277 | break; | 286 | break; |
278 | } | 287 | } |
279 | } | 288 | } |
280 | if (doi_def->map.std->cat.local_size > CIPSO_V4_MAX_LOC_CATS || | ||
281 | doi_def->map.std->cat.cipso_size > CIPSO_V4_MAX_REM_CATS) | ||
282 | goto add_std_failure; | ||
283 | doi_def->map.std->cat.local = kcalloc( | 289 | doi_def->map.std->cat.local = kcalloc( |
284 | doi_def->map.std->cat.local_size, | 290 | doi_def->map.std->cat.local_size, |
285 | sizeof(u32), | 291 | sizeof(u32), |