diff options
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/cipso_ipv4.c | 168 |
1 files changed, 69 insertions, 99 deletions
diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c index f3957cfaed42..08144f8fc911 100644 --- a/net/ipv4/cipso_ipv4.c +++ b/net/ipv4/cipso_ipv4.c | |||
@@ -819,8 +819,7 @@ static int cipso_v4_map_cat_rbm_valid(const struct cipso_v4_doi *doi_def, | |||
819 | /** | 819 | /** |
820 | * cipso_v4_map_cat_rbm_hton - Perform a category mapping from host to network | 820 | * cipso_v4_map_cat_rbm_hton - Perform a category mapping from host to network |
821 | * @doi_def: the DOI definition | 821 | * @doi_def: the DOI definition |
822 | * @host_cat: the category bitmap in host format | 822 | * @secattr: the security attributes |
823 | * @host_cat_len: the length of the host's category bitmap in bytes | ||
824 | * @net_cat: the zero'd out category bitmap in network/CIPSO format | 823 | * @net_cat: the zero'd out category bitmap in network/CIPSO format |
825 | * @net_cat_len: the length of the CIPSO bitmap in bytes | 824 | * @net_cat_len: the length of the CIPSO bitmap in bytes |
826 | * | 825 | * |
@@ -831,61 +830,51 @@ static int cipso_v4_map_cat_rbm_valid(const struct cipso_v4_doi *doi_def, | |||
831 | * | 830 | * |
832 | */ | 831 | */ |
833 | static int cipso_v4_map_cat_rbm_hton(const struct cipso_v4_doi *doi_def, | 832 | static int cipso_v4_map_cat_rbm_hton(const struct cipso_v4_doi *doi_def, |
834 | const unsigned char *host_cat, | 833 | const struct netlbl_lsm_secattr *secattr, |
835 | u32 host_cat_len, | ||
836 | unsigned char *net_cat, | 834 | unsigned char *net_cat, |
837 | u32 net_cat_len) | 835 | u32 net_cat_len) |
838 | { | 836 | { |
839 | int host_spot = -1; | 837 | int host_spot = -1; |
840 | u32 net_spot; | 838 | u32 net_spot = CIPSO_V4_INV_CAT; |
841 | u32 net_spot_max = 0; | 839 | u32 net_spot_max = 0; |
842 | u32 host_clen_bits = host_cat_len * 8; | ||
843 | u32 net_clen_bits = net_cat_len * 8; | 840 | u32 net_clen_bits = net_cat_len * 8; |
844 | u32 host_cat_size; | 841 | u32 host_cat_size = 0; |
845 | u32 *host_cat_array; | 842 | u32 *host_cat_array = NULL; |
846 | 843 | ||
847 | switch (doi_def->type) { | 844 | if (doi_def->type == CIPSO_V4_MAP_STD) { |
848 | case CIPSO_V4_MAP_PASS: | ||
849 | net_spot_max = host_cat_len; | ||
850 | while (net_spot_max > 0 && host_cat[net_spot_max - 1] == 0) | ||
851 | net_spot_max--; | ||
852 | if (net_spot_max > net_cat_len) | ||
853 | return -EINVAL; | ||
854 | memcpy(net_cat, host_cat, net_spot_max); | ||
855 | return net_spot_max; | ||
856 | case CIPSO_V4_MAP_STD: | ||
857 | host_cat_size = doi_def->map.std->cat.local_size; | 845 | host_cat_size = doi_def->map.std->cat.local_size; |
858 | host_cat_array = doi_def->map.std->cat.local; | 846 | host_cat_array = doi_def->map.std->cat.local; |
859 | for (;;) { | 847 | } |
860 | host_spot = cipso_v4_bitmap_walk(host_cat, | 848 | |
861 | host_clen_bits, | 849 | for (;;) { |
862 | host_spot + 1, | 850 | host_spot = netlbl_secattr_catmap_walk(secattr->mls_cat, |
863 | 1); | 851 | host_spot + 1); |
864 | if (host_spot < 0) | 852 | if (host_spot < 0) |
865 | break; | 853 | break; |
854 | |||
855 | switch (doi_def->type) { | ||
856 | case CIPSO_V4_MAP_PASS: | ||
857 | net_spot = host_spot; | ||
858 | break; | ||
859 | case CIPSO_V4_MAP_STD: | ||
866 | if (host_spot >= host_cat_size) | 860 | if (host_spot >= host_cat_size) |
867 | return -EPERM; | 861 | return -EPERM; |
868 | |||
869 | net_spot = host_cat_array[host_spot]; | 862 | net_spot = host_cat_array[host_spot]; |
870 | if (net_spot >= CIPSO_V4_INV_CAT) | 863 | if (net_spot >= CIPSO_V4_INV_CAT) |
871 | return -EPERM; | 864 | return -EPERM; |
872 | if (net_spot >= net_clen_bits) | 865 | break; |
873 | return -ENOSPC; | ||
874 | cipso_v4_bitmap_setbit(net_cat, net_spot, 1); | ||
875 | |||
876 | if (net_spot > net_spot_max) | ||
877 | net_spot_max = net_spot; | ||
878 | } | 866 | } |
867 | if (net_spot >= net_clen_bits) | ||
868 | return -ENOSPC; | ||
869 | cipso_v4_bitmap_setbit(net_cat, net_spot, 1); | ||
879 | 870 | ||
880 | if (host_spot == -2) | 871 | if (net_spot > net_spot_max) |
881 | return -EFAULT; | 872 | net_spot_max = net_spot; |
882 | |||
883 | if (++net_spot_max % 8) | ||
884 | return net_spot_max / 8 + 1; | ||
885 | return net_spot_max / 8; | ||
886 | } | 873 | } |
887 | 874 | ||
888 | return -EINVAL; | 875 | if (++net_spot_max % 8) |
876 | return net_spot_max / 8 + 1; | ||
877 | return net_spot_max / 8; | ||
889 | } | 878 | } |
890 | 879 | ||
891 | /** | 880 | /** |
@@ -893,66 +882,59 @@ static int cipso_v4_map_cat_rbm_hton(const struct cipso_v4_doi *doi_def, | |||
893 | * @doi_def: the DOI definition | 882 | * @doi_def: the DOI definition |
894 | * @net_cat: the category bitmap in network/CIPSO format | 883 | * @net_cat: the category bitmap in network/CIPSO format |
895 | * @net_cat_len: the length of the CIPSO bitmap in bytes | 884 | * @net_cat_len: the length of the CIPSO bitmap in bytes |
896 | * @host_cat: the zero'd out category bitmap in host format | 885 | * @secattr: the security attributes |
897 | * @host_cat_len: the length of the host's category bitmap in bytes | ||
898 | * | 886 | * |
899 | * Description: | 887 | * Description: |
900 | * Perform a label mapping to translate a CIPSO bitmap to the correct local | 888 | * Perform a label mapping to translate a CIPSO bitmap to the correct local |
901 | * MLS category bitmap using the given DOI definition. Returns the minimum | 889 | * MLS category bitmap using the given DOI definition. Returns zero on |
902 | * size in bytes of the host bitmap on success, negative values otherwise. | 890 | * success, negative values on failure. |
903 | * | 891 | * |
904 | */ | 892 | */ |
905 | static int cipso_v4_map_cat_rbm_ntoh(const struct cipso_v4_doi *doi_def, | 893 | static int cipso_v4_map_cat_rbm_ntoh(const struct cipso_v4_doi *doi_def, |
906 | const unsigned char *net_cat, | 894 | const unsigned char *net_cat, |
907 | u32 net_cat_len, | 895 | u32 net_cat_len, |
908 | unsigned char *host_cat, | 896 | struct netlbl_lsm_secattr *secattr) |
909 | u32 host_cat_len) | ||
910 | { | 897 | { |
911 | u32 host_spot; | 898 | int ret_val; |
912 | u32 host_spot_max = 0; | ||
913 | int net_spot = -1; | 899 | int net_spot = -1; |
900 | u32 host_spot = CIPSO_V4_INV_CAT; | ||
914 | u32 net_clen_bits = net_cat_len * 8; | 901 | u32 net_clen_bits = net_cat_len * 8; |
915 | u32 host_clen_bits = host_cat_len * 8; | 902 | u32 net_cat_size = 0; |
916 | u32 net_cat_size; | 903 | u32 *net_cat_array = NULL; |
917 | u32 *net_cat_array; | ||
918 | 904 | ||
919 | switch (doi_def->type) { | 905 | if (doi_def->type == CIPSO_V4_MAP_STD) { |
920 | case CIPSO_V4_MAP_PASS: | ||
921 | if (net_cat_len > host_cat_len) | ||
922 | return -EINVAL; | ||
923 | memcpy(host_cat, net_cat, net_cat_len); | ||
924 | return net_cat_len; | ||
925 | case CIPSO_V4_MAP_STD: | ||
926 | net_cat_size = doi_def->map.std->cat.cipso_size; | 906 | net_cat_size = doi_def->map.std->cat.cipso_size; |
927 | net_cat_array = doi_def->map.std->cat.cipso; | 907 | net_cat_array = doi_def->map.std->cat.cipso; |
928 | for (;;) { | 908 | } |
929 | net_spot = cipso_v4_bitmap_walk(net_cat, | ||
930 | net_clen_bits, | ||
931 | net_spot + 1, | ||
932 | 1); | ||
933 | if (net_spot < 0) | ||
934 | break; | ||
935 | if (net_spot >= net_cat_size || | ||
936 | net_cat_array[net_spot] >= CIPSO_V4_INV_CAT) | ||
937 | return -EPERM; | ||
938 | 909 | ||
910 | for (;;) { | ||
911 | net_spot = cipso_v4_bitmap_walk(net_cat, | ||
912 | net_clen_bits, | ||
913 | net_spot + 1, | ||
914 | 1); | ||
915 | if (net_spot < 0) { | ||
916 | if (net_spot == -2) | ||
917 | return -EFAULT; | ||
918 | return 0; | ||
919 | } | ||
920 | |||
921 | switch (doi_def->type) { | ||
922 | case CIPSO_V4_MAP_PASS: | ||
923 | host_spot = net_spot; | ||
924 | break; | ||
925 | case CIPSO_V4_MAP_STD: | ||
926 | if (net_spot >= net_cat_size) | ||
927 | return -EPERM; | ||
939 | host_spot = net_cat_array[net_spot]; | 928 | host_spot = net_cat_array[net_spot]; |
940 | if (host_spot >= CIPSO_V4_INV_CAT) | 929 | if (host_spot >= CIPSO_V4_INV_CAT) |
941 | return -EPERM; | 930 | return -EPERM; |
942 | if (host_spot >= host_clen_bits) | 931 | break; |
943 | return -ENOSPC; | ||
944 | cipso_v4_bitmap_setbit(host_cat, host_spot, 1); | ||
945 | |||
946 | if (host_spot > host_spot_max) | ||
947 | host_spot_max = host_spot; | ||
948 | } | 932 | } |
949 | 933 | ret_val = netlbl_secattr_catmap_setbit(secattr->mls_cat, | |
950 | if (net_spot == -2) | 934 | host_spot, |
951 | return -EFAULT; | 935 | GFP_ATOMIC); |
952 | 936 | if (ret_val != 0) | |
953 | if (++host_spot_max % 8) | 937 | return ret_val; |
954 | return host_spot_max / 8 + 1; | ||
955 | return host_spot_max / 8; | ||
956 | } | 938 | } |
957 | 939 | ||
958 | return -EINVAL; | 940 | return -EINVAL; |
@@ -1016,8 +998,7 @@ static int cipso_v4_gentag_rbm(const struct cipso_v4_doi *doi_def, | |||
1016 | 998 | ||
1017 | if (secattr->flags & NETLBL_SECATTR_MLS_CAT) { | 999 | if (secattr->flags & NETLBL_SECATTR_MLS_CAT) { |
1018 | ret_val = cipso_v4_map_cat_rbm_hton(doi_def, | 1000 | ret_val = cipso_v4_map_cat_rbm_hton(doi_def, |
1019 | secattr->mls_cat, | 1001 | secattr, |
1020 | secattr->mls_cat_len, | ||
1021 | &buffer[4], | 1002 | &buffer[4], |
1022 | buffer_len - 4); | 1003 | buffer_len - 4); |
1023 | if (ret_val < 0) | 1004 | if (ret_val < 0) |
@@ -1067,31 +1048,20 @@ static int cipso_v4_parsetag_rbm(const struct cipso_v4_doi *doi_def, | |||
1067 | secattr->flags |= NETLBL_SECATTR_MLS_LVL; | 1048 | secattr->flags |= NETLBL_SECATTR_MLS_LVL; |
1068 | 1049 | ||
1069 | if (tag_len > 4) { | 1050 | if (tag_len > 4) { |
1070 | switch (doi_def->type) { | 1051 | secattr->mls_cat = netlbl_secattr_catmap_alloc(GFP_ATOMIC); |
1071 | case CIPSO_V4_MAP_PASS: | ||
1072 | secattr->mls_cat_len = tag_len - 4; | ||
1073 | break; | ||
1074 | case CIPSO_V4_MAP_STD: | ||
1075 | secattr->mls_cat_len = | ||
1076 | doi_def->map.std->cat.local_size; | ||
1077 | break; | ||
1078 | } | ||
1079 | secattr->mls_cat = kzalloc(secattr->mls_cat_len, GFP_ATOMIC); | ||
1080 | if (secattr->mls_cat == NULL) | 1052 | if (secattr->mls_cat == NULL) |
1081 | return -ENOMEM; | 1053 | return -ENOMEM; |
1082 | 1054 | ||
1083 | ret_val = cipso_v4_map_cat_rbm_ntoh(doi_def, | 1055 | ret_val = cipso_v4_map_cat_rbm_ntoh(doi_def, |
1084 | &tag[4], | 1056 | &tag[4], |
1085 | tag_len - 4, | 1057 | tag_len - 4, |
1086 | secattr->mls_cat, | 1058 | secattr); |
1087 | secattr->mls_cat_len); | 1059 | if (ret_val != 0) { |
1088 | if (ret_val < 0) { | 1060 | netlbl_secattr_catmap_free(secattr->mls_cat); |
1089 | kfree(secattr->mls_cat); | ||
1090 | return ret_val; | 1061 | return ret_val; |
1091 | } else if (ret_val > 0) { | ||
1092 | secattr->mls_cat_len = ret_val; | ||
1093 | secattr->flags |= NETLBL_SECATTR_MLS_CAT; | ||
1094 | } | 1062 | } |
1063 | |||
1064 | secattr->flags |= NETLBL_SECATTR_MLS_CAT; | ||
1095 | } | 1065 | } |
1096 | 1066 | ||
1097 | return 0; | 1067 | return 0; |