aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/cipso_ipv4.c
diff options
context:
space:
mode:
authorPaul Moore <paul.moore@hp.com>2006-11-29 13:18:18 -0500
committerDavid S. Miller <davem@sunset.davemloft.net>2006-12-03 00:31:36 -0500
commit02752760359db6b00a3ffb1acfc13ef8d9eb1e3f (patch)
tree796cd65fd4cd732b295e61dac194efbf36b78842 /net/ipv4/cipso_ipv4.c
parentef91fd522ba3c88d9c68261c243567bc4c5a8f55 (diff)
NetLabel: convert to an extensibile/sparse category bitmap
The original NetLabel category bitmap was a straight char bitmap which worked fine for the initial release as it only supported 240 bits due to limitations in the CIPSO restricted bitmap tag (tag type 0x01). This patch converts that straight char bitmap into an extensibile/sparse bitmap in order to lay the foundation for other CIPSO tag types and protocols. This patch also has a nice side effect in that all of the security attributes passed by NetLabel into the LSM are now in a format which is in the host's native byte/bit ordering which makes the LSM specific code much simpler; look at the changes in security/selinux/ss/ebitmap.c as an example. Signed-off-by: Paul Moore <paul.moore@hp.com> Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'net/ipv4/cipso_ipv4.c')
-rw-r--r--net/ipv4/cipso_ipv4.c168
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 */
833static int cipso_v4_map_cat_rbm_hton(const struct cipso_v4_doi *doi_def, 832static 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 */
905static int cipso_v4_map_cat_rbm_ntoh(const struct cipso_v4_doi *doi_def, 893static 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;