aboutsummaryrefslogtreecommitdiffstats
path: root/net/netlabel
diff options
context:
space:
mode:
authorPaul Moore <paul.moore@hp.com>2006-12-15 16:49:27 -0500
committerDavid S. Miller <davem@sunset.davemloft.net>2006-12-22 14:11:56 -0500
commit1fd2a25b77bb6755d38aca50b826ff8dca81d762 (patch)
tree9f5f8bd5cb99cefa8db812f7182b22da6ecf993c /net/netlabel
parentc2fda5fed81eea077363b285b66eafce20dfd45a (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')
-rw-r--r--net/netlabel/netlabel_cipso_v4.c28
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),