aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/cipso_ipv4.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/cipso_ipv4.c')
-rw-r--r--net/ipv4/cipso_ipv4.c113
1 files changed, 53 insertions, 60 deletions
diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c
index 23a968f754be..a056278ad626 100644
--- a/net/ipv4/cipso_ipv4.c
+++ b/net/ipv4/cipso_ipv4.c
@@ -958,35 +958,28 @@ static int cipso_v4_map_cat_rbm_ntoh(const struct cipso_v4_doi *doi_def,
958 * Protocol Handling Functions 958 * Protocol Handling Functions
959 */ 959 */
960 960
961#define CIPSO_V4_OPT_LEN_MAX 40
961#define CIPSO_V4_HDR_LEN 6 962#define CIPSO_V4_HDR_LEN 6
962 963
963/** 964/**
964 * cipso_v4_gentag_hdr - Generate a CIPSO option header 965 * cipso_v4_gentag_hdr - Generate a CIPSO option header
965 * @doi_def: the DOI definition 966 * @doi_def: the DOI definition
966 * @len: the total tag length in bytes 967 * @len: the total tag length in bytes, not including this header
967 * @buf: the CIPSO option buffer 968 * @buf: the CIPSO option buffer
968 * 969 *
969 * Description: 970 * Description:
970 * Write a CIPSO header into the beginning of @buffer. Return zero on success, 971 * Write a CIPSO header into the beginning of @buffer.
971 * negative values on failure.
972 * 972 *
973 */ 973 */
974static int cipso_v4_gentag_hdr(const struct cipso_v4_doi *doi_def, 974static void cipso_v4_gentag_hdr(const struct cipso_v4_doi *doi_def,
975 u32 len, 975 unsigned char *buf,
976 unsigned char *buf) 976 u32 len)
977{ 977{
978 if (CIPSO_V4_HDR_LEN + len > 40)
979 return -ENOSPC;
980
981 buf[0] = IPOPT_CIPSO; 978 buf[0] = IPOPT_CIPSO;
982 buf[1] = CIPSO_V4_HDR_LEN + len; 979 buf[1] = CIPSO_V4_HDR_LEN + len;
983 *(__be32 *)&buf[2] = htonl(doi_def->doi); 980 *(__be32 *)&buf[2] = htonl(doi_def->doi);
984
985 return 0;
986} 981}
987 982
988#define CIPSO_V4_TAG1_CAT_LEN 30
989
990/** 983/**
991 * cipso_v4_gentag_rbm - Generate a CIPSO restricted bitmap tag (type #1) 984 * cipso_v4_gentag_rbm - Generate a CIPSO restricted bitmap tag (type #1)
992 * @doi_def: the DOI definition 985 * @doi_def: the DOI definition
@@ -997,71 +990,50 @@ static int cipso_v4_gentag_hdr(const struct cipso_v4_doi *doi_def,
997 * Description: 990 * Description:
998 * Generate a CIPSO option using the restricted bitmap tag, tag type #1. The 991 * Generate a CIPSO option using the restricted bitmap tag, tag type #1. The
999 * actual buffer length may be larger than the indicated size due to 992 * actual buffer length may be larger than the indicated size due to
1000 * translation between host and network category bitmaps. Returns zero on 993 * translation between host and network category bitmaps. Returns the size of
1001 * success, negative values on failure. 994 * the tag on success, negative values on failure.
1002 * 995 *
1003 */ 996 */
1004static int cipso_v4_gentag_rbm(const struct cipso_v4_doi *doi_def, 997static int cipso_v4_gentag_rbm(const struct cipso_v4_doi *doi_def,
1005 const struct netlbl_lsm_secattr *secattr, 998 const struct netlbl_lsm_secattr *secattr,
1006 unsigned char **buffer, 999 unsigned char *buffer,
1007 u32 *buffer_len) 1000 u32 buffer_len)
1008{ 1001{
1009 int ret_val; 1002 int ret_val;
1010 unsigned char *buf = NULL; 1003 u32 tag_len;
1011 u32 buf_len;
1012 u32 level; 1004 u32 level;
1013 1005
1014 if ((secattr->flags & NETLBL_SECATTR_MLS_LVL) == 0) 1006 if ((secattr->flags & NETLBL_SECATTR_MLS_LVL) == 0)
1015 return -EPERM; 1007 return -EPERM;
1016 1008
1017 if (secattr->flags & NETLBL_SECATTR_MLS_CAT) { 1009 ret_val = cipso_v4_map_lvl_hton(doi_def, secattr->mls_lvl, &level);
1018 buf = kzalloc(CIPSO_V4_HDR_LEN + 4 + CIPSO_V4_TAG1_CAT_LEN, 1010 if (ret_val != 0)
1019 GFP_ATOMIC); 1011 return ret_val;
1020 if (buf == NULL)
1021 return -ENOMEM;
1022 1012
1013 if (secattr->flags & NETLBL_SECATTR_MLS_CAT) {
1023 ret_val = cipso_v4_map_cat_rbm_hton(doi_def, 1014 ret_val = cipso_v4_map_cat_rbm_hton(doi_def,
1024 secattr->mls_cat, 1015 secattr->mls_cat,
1025 secattr->mls_cat_len, 1016 secattr->mls_cat_len,
1026 &buf[CIPSO_V4_HDR_LEN + 4], 1017 &buffer[4],
1027 CIPSO_V4_TAG1_CAT_LEN); 1018 buffer_len - 4);
1028 if (ret_val < 0) 1019 if (ret_val < 0)
1029 goto gentag_failure; 1020 return ret_val;
1030 1021
1031 /* This will send packets using the "optimized" format when 1022 /* This will send packets using the "optimized" format when
1032 * possibile as specified in section 3.4.2.6 of the 1023 * possibile as specified in section 3.4.2.6 of the
1033 * CIPSO draft. */ 1024 * CIPSO draft. */
1034 if (cipso_v4_rbm_optfmt && ret_val > 0 && ret_val <= 10) 1025 if (cipso_v4_rbm_optfmt && ret_val > 0 && ret_val <= 10)
1035 buf_len = 14; 1026 tag_len = 14;
1036 else 1027 else
1037 buf_len = 4 + ret_val; 1028 tag_len = 4 + ret_val;
1038 } else { 1029 } else
1039 buf = kzalloc(CIPSO_V4_HDR_LEN + 4, GFP_ATOMIC); 1030 tag_len = 4;
1040 if (buf == NULL)
1041 return -ENOMEM;
1042 buf_len = 4;
1043 }
1044
1045 ret_val = cipso_v4_map_lvl_hton(doi_def, secattr->mls_lvl, &level);
1046 if (ret_val != 0)
1047 goto gentag_failure;
1048
1049 ret_val = cipso_v4_gentag_hdr(doi_def, buf_len, buf);
1050 if (ret_val != 0)
1051 goto gentag_failure;
1052
1053 buf[CIPSO_V4_HDR_LEN] = 0x01;
1054 buf[CIPSO_V4_HDR_LEN + 1] = buf_len;
1055 buf[CIPSO_V4_HDR_LEN + 3] = level;
1056 1031
1057 *buffer = buf; 1032 buffer[0] = 0x01;
1058 *buffer_len = CIPSO_V4_HDR_LEN + buf_len; 1033 buffer[1] = tag_len;
1034 buffer[3] = level;
1059 1035
1060 return 0; 1036 return tag_len;
1061
1062gentag_failure:
1063 kfree(buf);
1064 return ret_val;
1065} 1037}
1066 1038
1067/** 1039/**
@@ -1284,7 +1256,7 @@ int cipso_v4_socket_setattr(const struct socket *sock,
1284{ 1256{
1285 int ret_val = -EPERM; 1257 int ret_val = -EPERM;
1286 u32 iter; 1258 u32 iter;
1287 unsigned char *buf = NULL; 1259 unsigned char *buf;
1288 u32 buf_len = 0; 1260 u32 buf_len = 0;
1289 u32 opt_len; 1261 u32 opt_len;
1290 struct ip_options *opt = NULL; 1262 struct ip_options *opt = NULL;
@@ -1300,17 +1272,28 @@ int cipso_v4_socket_setattr(const struct socket *sock,
1300 if (sk == NULL) 1272 if (sk == NULL)
1301 return 0; 1273 return 0;
1302 1274
1275 /* We allocate the maximum CIPSO option size here so we are probably
1276 * being a little wasteful, but it makes our life _much_ easier later
1277 * on and after all we are only talking about 40 bytes. */
1278 buf_len = CIPSO_V4_OPT_LEN_MAX;
1279 buf = kmalloc(buf_len, GFP_ATOMIC);
1280 if (buf == NULL) {
1281 ret_val = -ENOMEM;
1282 goto socket_setattr_failure;
1283 }
1284
1303 /* XXX - This code assumes only one tag per CIPSO option which isn't 1285 /* XXX - This code assumes only one tag per CIPSO option which isn't
1304 * really a good assumption to make but since we only support the MAC 1286 * really a good assumption to make but since we only support the MAC
1305 * tags right now it is a safe assumption. */ 1287 * tags right now it is a safe assumption. */
1306 iter = 0; 1288 iter = 0;
1307 do { 1289 do {
1290 memset(buf, 0, buf_len);
1308 switch (doi_def->tags[iter]) { 1291 switch (doi_def->tags[iter]) {
1309 case CIPSO_V4_TAG_RBITMAP: 1292 case CIPSO_V4_TAG_RBITMAP:
1310 ret_val = cipso_v4_gentag_rbm(doi_def, 1293 ret_val = cipso_v4_gentag_rbm(doi_def,
1311 secattr, 1294 secattr,
1312 &buf, 1295 &buf[CIPSO_V4_HDR_LEN],
1313 &buf_len); 1296 buf_len - CIPSO_V4_HDR_LEN);
1314 break; 1297 break;
1315 default: 1298 default:
1316 ret_val = -EPERM; 1299 ret_val = -EPERM;
@@ -1318,11 +1301,13 @@ int cipso_v4_socket_setattr(const struct socket *sock,
1318 } 1301 }
1319 1302
1320 iter++; 1303 iter++;
1321 } while (ret_val != 0 && 1304 } while (ret_val < 0 &&
1322 iter < CIPSO_V4_TAG_MAXCNT && 1305 iter < CIPSO_V4_TAG_MAXCNT &&
1323 doi_def->tags[iter] != CIPSO_V4_TAG_INVALID); 1306 doi_def->tags[iter] != CIPSO_V4_TAG_INVALID);
1324 if (ret_val != 0) 1307 if (ret_val < 0)
1325 goto socket_setattr_failure; 1308 goto socket_setattr_failure;
1309 cipso_v4_gentag_hdr(doi_def, buf, ret_val);
1310 buf_len = CIPSO_V4_HDR_LEN + ret_val;
1326 1311
1327 /* We can't use ip_options_get() directly because it makes a call to 1312 /* We can't use ip_options_get() directly because it makes a call to
1328 * ip_options_get_alloc() which allocates memory with GFP_KERNEL and 1313 * ip_options_get_alloc() which allocates memory with GFP_KERNEL and
@@ -1396,6 +1381,10 @@ int cipso_v4_sock_getattr(struct sock *sk, struct netlbl_lsm_secattr *secattr)
1396 rcu_read_unlock(); 1381 rcu_read_unlock();
1397 return -ENOMSG; 1382 return -ENOMSG;
1398 } 1383 }
1384
1385 /* XXX - This code assumes only one tag per CIPSO option which isn't
1386 * really a good assumption to make but since we only support the MAC
1387 * tags right now it is a safe assumption. */
1399 switch (cipso_ptr[6]) { 1388 switch (cipso_ptr[6]) {
1400 case CIPSO_V4_TAG_RBITMAP: 1389 case CIPSO_V4_TAG_RBITMAP:
1401 ret_val = cipso_v4_parsetag_rbm(doi_def, 1390 ret_val = cipso_v4_parsetag_rbm(doi_def,
@@ -1458,6 +1447,10 @@ int cipso_v4_skbuff_getattr(const struct sk_buff *skb,
1458 doi_def = cipso_v4_doi_getdef(doi); 1447 doi_def = cipso_v4_doi_getdef(doi);
1459 if (doi_def == NULL) 1448 if (doi_def == NULL)
1460 goto skbuff_getattr_return; 1449 goto skbuff_getattr_return;
1450
1451 /* XXX - This code assumes only one tag per CIPSO option which isn't
1452 * really a good assumption to make but since we only support the MAC
1453 * tags right now it is a safe assumption. */
1461 switch (cipso_ptr[6]) { 1454 switch (cipso_ptr[6]) {
1462 case CIPSO_V4_TAG_RBITMAP: 1455 case CIPSO_V4_TAG_RBITMAP:
1463 ret_val = cipso_v4_parsetag_rbm(doi_def, 1456 ret_val = cipso_v4_parsetag_rbm(doi_def,