Commit 1fd2a25b authored by Paul Moore's avatar Paul Moore Committed by David S. Miller

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: default avatarPaul Moore <paul.moore@hp.com>
Signed-off-by: default avatarJames Morris <jmorris@namei.org>
parent c2fda5fe
...@@ -185,20 +185,31 @@ static int netlbl_cipsov4_add_std(struct genl_info *info) ...@@ -185,20 +185,31 @@ static int netlbl_cipsov4_add_std(struct genl_info *info)
ret_val = netlbl_cipsov4_add_common(info, doi_def); ret_val = netlbl_cipsov4_add_common(info, doi_def);
if (ret_val != 0) if (ret_val != 0)
goto add_std_failure; goto add_std_failure;
ret_val = -EINVAL;
nla_for_each_nested(nla_a, nla_for_each_nested(nla_a,
info->attrs[NLBL_CIPSOV4_A_MLSLVLLST], info->attrs[NLBL_CIPSOV4_A_MLSLVLLST],
nla_a_rem) nla_a_rem)
if (nla_a->nla_type == NLBL_CIPSOV4_A_MLSLVL) { if (nla_a->nla_type == NLBL_CIPSOV4_A_MLSLVL) {
if (nla_validate_nested(nla_a,
NLBL_CIPSOV4_A_MAX,
netlbl_cipsov4_genl_policy) != 0)
goto add_std_failure;
nla_for_each_nested(nla_b, nla_a, nla_b_rem) nla_for_each_nested(nla_b, nla_a, nla_b_rem)
switch (nla_b->nla_type) { switch (nla_b->nla_type) {
case NLBL_CIPSOV4_A_MLSLVLLOC: case NLBL_CIPSOV4_A_MLSLVLLOC:
if (nla_get_u32(nla_b) >
CIPSO_V4_MAX_LOC_LVLS)
goto add_std_failure;
if (nla_get_u32(nla_b) >= if (nla_get_u32(nla_b) >=
doi_def->map.std->lvl.local_size) doi_def->map.std->lvl.local_size)
doi_def->map.std->lvl.local_size = doi_def->map.std->lvl.local_size =
nla_get_u32(nla_b) + 1; nla_get_u32(nla_b) + 1;
break; break;
case NLBL_CIPSOV4_A_MLSLVLREM: case NLBL_CIPSOV4_A_MLSLVLREM:
if (nla_get_u32(nla_b) >
CIPSO_V4_MAX_REM_LVLS)
goto add_std_failure;
if (nla_get_u32(nla_b) >= if (nla_get_u32(nla_b) >=
doi_def->map.std->lvl.cipso_size) doi_def->map.std->lvl.cipso_size)
doi_def->map.std->lvl.cipso_size = doi_def->map.std->lvl.cipso_size =
...@@ -206,9 +217,6 @@ static int netlbl_cipsov4_add_std(struct genl_info *info) ...@@ -206,9 +217,6 @@ static int netlbl_cipsov4_add_std(struct genl_info *info)
break; break;
} }
} }
if (doi_def->map.std->lvl.local_size > CIPSO_V4_MAX_LOC_LVLS ||
doi_def->map.std->lvl.cipso_size > CIPSO_V4_MAX_REM_LVLS)
goto add_std_failure;
doi_def->map.std->lvl.local = kcalloc(doi_def->map.std->lvl.local_size, doi_def->map.std->lvl.local = kcalloc(doi_def->map.std->lvl.local_size,
sizeof(u32), sizeof(u32),
GFP_KERNEL); GFP_KERNEL);
...@@ -230,11 +238,6 @@ static int netlbl_cipsov4_add_std(struct genl_info *info) ...@@ -230,11 +238,6 @@ static int netlbl_cipsov4_add_std(struct genl_info *info)
struct nlattr *lvl_loc; struct nlattr *lvl_loc;
struct nlattr *lvl_rem; struct nlattr *lvl_rem;
if (nla_validate_nested(nla_a,
NLBL_CIPSOV4_A_MAX,
netlbl_cipsov4_genl_policy) != 0)
goto add_std_failure;
lvl_loc = nla_find_nested(nla_a, lvl_loc = nla_find_nested(nla_a,
NLBL_CIPSOV4_A_MLSLVLLOC); NLBL_CIPSOV4_A_MLSLVLLOC);
lvl_rem = nla_find_nested(nla_a, lvl_rem = nla_find_nested(nla_a,
...@@ -264,12 +267,18 @@ static int netlbl_cipsov4_add_std(struct genl_info *info) ...@@ -264,12 +267,18 @@ static int netlbl_cipsov4_add_std(struct genl_info *info)
nla_for_each_nested(nla_b, nla_a, nla_b_rem) nla_for_each_nested(nla_b, nla_a, nla_b_rem)
switch (nla_b->nla_type) { switch (nla_b->nla_type) {
case NLBL_CIPSOV4_A_MLSCATLOC: case NLBL_CIPSOV4_A_MLSCATLOC:
if (nla_get_u32(nla_b) >
CIPSO_V4_MAX_LOC_CATS)
goto add_std_failure;
if (nla_get_u32(nla_b) >= if (nla_get_u32(nla_b) >=
doi_def->map.std->cat.local_size) doi_def->map.std->cat.local_size)
doi_def->map.std->cat.local_size = doi_def->map.std->cat.local_size =
nla_get_u32(nla_b) + 1; nla_get_u32(nla_b) + 1;
break; break;
case NLBL_CIPSOV4_A_MLSCATREM: case NLBL_CIPSOV4_A_MLSCATREM:
if (nla_get_u32(nla_b) >
CIPSO_V4_MAX_REM_CATS)
goto add_std_failure;
if (nla_get_u32(nla_b) >= if (nla_get_u32(nla_b) >=
doi_def->map.std->cat.cipso_size) doi_def->map.std->cat.cipso_size)
doi_def->map.std->cat.cipso_size = doi_def->map.std->cat.cipso_size =
...@@ -277,9 +286,6 @@ static int netlbl_cipsov4_add_std(struct genl_info *info) ...@@ -277,9 +286,6 @@ static int netlbl_cipsov4_add_std(struct genl_info *info)
break; break;
} }
} }
if (doi_def->map.std->cat.local_size > CIPSO_V4_MAX_LOC_CATS ||
doi_def->map.std->cat.cipso_size > CIPSO_V4_MAX_REM_CATS)
goto add_std_failure;
doi_def->map.std->cat.local = kcalloc( doi_def->map.std->cat.local = kcalloc(
doi_def->map.std->cat.local_size, doi_def->map.std->cat.local_size,
sizeof(u32), sizeof(u32),
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment