1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * CIPSO - Commercial IP Security Option 4 * 5 * This is an implementation of the CIPSO 2.2 protocol as specified in 6 * draft-ietf-cipso-ipsecurity-01.txt with additional tag types as found in 7 * FIPS-188. While CIPSO never became a full IETF RFC standard many vendors 8 * have chosen to adopt the protocol and over the years it has become a 9 * de-facto standard for labeled networking. 10 * 11 * The CIPSO draft specification can be found in the kernel's Documentation 12 * directory as well as the following URL: 13 * https://tools.ietf.org/id/draft-ietf-cipso-ipsecurity-01.txt 14 * The FIPS-188 specification can be found at the following URL: 15 * https://www.itl.nist.gov/fipspubs/fip188.htm 16 * 17 * Author: Paul Moore <paul.moore@hp.com> 18 */ 19 20/* 21 * (c) Copyright Hewlett-Packard Development Company, L.P., 2006, 2008 22 */ 23 24#include <linux/init.h> 25#include <linux/types.h> 26#include <linux/rcupdate.h> 27#include <linux/list.h> 28#include <linux/spinlock.h> 29#include <linux/string.h> 30#include <linux/jhash.h> 31#include <linux/audit.h> 32#include <linux/slab.h> 33#include <net/ip.h> 34#include <net/icmp.h> 35#include <net/tcp.h> 36#include <net/netlabel.h> 37#include <net/cipso_ipv4.h> 38#include <linux/atomic.h> 39#include <linux/bug.h> 40#include <asm/unaligned.h> 41 42/* List of available DOI definitions */ 43/* XXX - This currently assumes a minimal number of different DOIs in use, 44 * if in practice there are a lot of different DOIs this list should 45 * probably be turned into a hash table or something similar so we 46 * can do quick lookups. */ 47static DEFINE_SPINLOCK(cipso_v4_doi_list_lock); 48static LIST_HEAD(cipso_v4_doi_list); 49 50/* Label mapping cache */ 51int cipso_v4_cache_enabled = 1; 52int cipso_v4_cache_bucketsize = 10; 53#define CIPSO_V4_CACHE_BUCKETBITS 7 54#define CIPSO_V4_CACHE_BUCKETS (1 << CIPSO_V4_CACHE_BUCKETBITS) 55#define CIPSO_V4_CACHE_REORDERLIMIT 10 56struct cipso_v4_map_cache_bkt { 57 spinlock_t lock; 58 u32 size; 59 struct list_head list; 60}; 61 62struct cipso_v4_map_cache_entry { 63 u32 hash; 64 unsigned char *key; 65 size_t key_len; 66 67 struct netlbl_lsm_cache *lsm_data; 68 69 u32 activity; 70 struct list_head list; 71}; 72 73static struct cipso_v4_map_cache_bkt *cipso_v4_cache; 74 75/* Restricted bitmap (tag #1) flags */ 76int cipso_v4_rbm_optfmt = 0; 77int cipso_v4_rbm_strictvalid = 1; 78 79/* 80 * Protocol Constants 81 */ 82 83/* Maximum size of the CIPSO IP option, derived from the fact that the maximum 84 * IPv4 header size is 60 bytes and the base IPv4 header is 20 bytes long. */ 85#define CIPSO_V4_OPT_LEN_MAX 40 86 87/* Length of the base CIPSO option, this includes the option type (1 byte), the 88 * option length (1 byte), and the DOI (4 bytes). */ 89#define CIPSO_V4_HDR_LEN 6 90 91/* Base length of the restrictive category bitmap tag (tag #1). */ 92#define CIPSO_V4_TAG_RBM_BLEN 4 93 94/* Base length of the enumerated category tag (tag #2). */ 95#define CIPSO_V4_TAG_ENUM_BLEN 4 96 97/* Base length of the ranged categories bitmap tag (tag #5). */ 98#define CIPSO_V4_TAG_RNG_BLEN 4 99/* The maximum number of category ranges permitted in the ranged category tag 100 * (tag #5). You may note that the IETF draft states that the maximum number 101 * of category ranges is 7, but if the low end of the last category range is 102 * zero then it is possible to fit 8 category ranges because the zero should 103 * be omitted. */ 104#define CIPSO_V4_TAG_RNG_CAT_MAX 8 105 106/* Base length of the local tag (non-standard tag). 107 * Tag definition (may change between kernel versions) 108 * 109 * 0 8 16 24 32 110 * +----------+----------+----------+----------+ 111 * | 10000000 | 00000110 | 32-bit secid value | 112 * +----------+----------+----------+----------+ 113 * | in (host byte order)| 114 * +----------+----------+ 115 * 116 */ 117#define CIPSO_V4_TAG_LOC_BLEN 6 118 119/* 120 * Helper Functions 121 */ 122 123/** 124 * cipso_v4_cache_entry_free - Frees a cache entry 125 * @entry: the entry to free 126 * 127 * Description: 128 * This function frees the memory associated with a cache entry including the 129 * LSM cache data if there are no longer any users, i.e. reference count == 0. 130 * 131 */ 132static void cipso_v4_cache_entry_free(struct cipso_v4_map_cache_entry *entry) 133{ 134 if (entry->lsm_data) 135 netlbl_secattr_cache_free(entry->lsm_data); 136 kfree(entry->key); 137 kfree(entry); 138} 139 140/** 141 * cipso_v4_map_cache_hash - Hashing function for the CIPSO cache 142 * @key: the hash key 143 * @key_len: the length of the key in bytes 144 * 145 * Description: 146 * The CIPSO tag hashing function. Returns a 32-bit hash value. 147 * 148 */ 149static u32 cipso_v4_map_cache_hash(const unsigned char *key, u32 key_len) 150{ 151 return jhash(key, key_len, 0); 152} 153 154/* 155 * Label Mapping Cache Functions 156 */ 157 158/** 159 * cipso_v4_cache_init - Initialize the CIPSO cache 160 * 161 * Description: 162 * Initializes the CIPSO label mapping cache, this function should be called 163 * before any of the other functions defined in this file. Returns zero on 164 * success, negative values on error. 165 * 166 */ 167static int __init cipso_v4_cache_init(void) 168{ 169 u32 iter; 170 171 cipso_v4_cache = kcalloc(CIPSO_V4_CACHE_BUCKETS, 172 sizeof(struct cipso_v4_map_cache_bkt), 173 GFP_KERNEL); 174 if (!cipso_v4_cache) 175 return -ENOMEM; 176 177 for (iter = 0; iter < CIPSO_V4_CACHE_BUCKETS; iter++) { 178 spin_lock_init(&cipso_v4_cache[iter].lock); 179 cipso_v4_cache[iter].size = 0; 180 INIT_LIST_HEAD(&cipso_v4_cache[iter].list); 181 } 182 183 return 0; 184} 185 186/** 187 * cipso_v4_cache_invalidate - Invalidates the current CIPSO cache 188 * 189 * Description: 190 * Invalidates and frees any entries in the CIPSO cache. Returns zero on 191 * success and negative values on failure. 192 * 193 */ 194void cipso_v4_cache_invalidate(void) 195{ 196 struct cipso_v4_map_cache_entry *entry, *tmp_entry; 197 u32 iter; 198 199 for (iter = 0; iter < CIPSO_V4_CACHE_BUCKETS; iter++) { 200 spin_lock_bh(&cipso_v4_cache[iter].lock); 201 list_for_each_entry_safe(entry, 202 tmp_entry, 203 &cipso_v4_cache[iter].list, list) { 204 list_del(&entry->list); 205 cipso_v4_cache_entry_free(entry); 206 } 207 cipso_v4_cache[iter].size = 0; 208 spin_unlock_bh(&cipso_v4_cache[iter].lock); 209 } 210} 211 212/** 213 * cipso_v4_cache_check - Check the CIPSO cache for a label mapping 214 * @key: the buffer to check 215 * @key_len: buffer length in bytes 216 * @secattr: the security attribute struct to use 217 * 218 * Description: 219 * This function checks the cache to see if a label mapping already exists for 220 * the given key. If there is a match then the cache is adjusted and the 221 * @secattr struct is populated with the correct LSM security attributes. The 222 * cache is adjusted in the following manner if the entry is not already the 223 * first in the cache bucket: 224 * 225 * 1. The cache entry's activity counter is incremented 226 * 2. The previous (higher ranking) entry's activity counter is decremented 227 * 3. If the difference between the two activity counters is geater than 228 * CIPSO_V4_CACHE_REORDERLIMIT the two entries are swapped 229 * 230 * Returns zero on success, -ENOENT for a cache miss, and other negative values 231 * on error. 232 * 233 */ 234static int cipso_v4_cache_check(const unsigned char *key, 235 u32 key_len, 236 struct netlbl_lsm_secattr *secattr) 237{ 238 u32 bkt; 239 struct cipso_v4_map_cache_entry *entry; 240 struct cipso_v4_map_cache_entry *prev_entry = NULL; 241 u32 hash; 242 243 if (!READ_ONCE(cipso_v4_cache_enabled)) 244 return -ENOENT; 245 246 hash = cipso_v4_map_cache_hash(key, key_len); 247 bkt = hash & (CIPSO_V4_CACHE_BUCKETS - 1); 248 spin_lock_bh(&cipso_v4_cache[bkt].lock); 249 list_for_each_entry(entry, &cipso_v4_cache[bkt].list, list) { 250 if (entry->hash == hash && 251 entry->key_len == key_len && 252 memcmp(entry->key, key, key_len) == 0) { 253 entry->activity += 1; 254 refcount_inc(&entry->lsm_data->refcount); 255 secattr->cache = entry->lsm_data; 256 secattr->flags |= NETLBL_SECATTR_CACHE; 257 secattr->type = NETLBL_NLTYPE_CIPSOV4; 258 if (!prev_entry) { 259 spin_unlock_bh(&cipso_v4_cache[bkt].lock); 260 return 0; 261 } 262 263 if (prev_entry->activity > 0) 264 prev_entry->activity -= 1; 265 if (entry->activity > prev_entry->activity && 266 entry->activity - prev_entry->activity > 267 CIPSO_V4_CACHE_REORDERLIMIT) { 268 __list_del(entry->list.prev, entry->list.next); 269 __list_add(&entry->list, 270 prev_entry->list.prev, 271 &prev_entry->list); 272 } 273 274 spin_unlock_bh(&cipso_v4_cache[bkt].lock); 275 return 0; 276 } 277 prev_entry = entry; 278 } 279 spin_unlock_bh(&cipso_v4_cache[bkt].lock); 280 281 return -ENOENT; 282} 283 284/** 285 * cipso_v4_cache_add - Add an entry to the CIPSO cache 286 * @cipso_ptr: pointer to CIPSO IP option 287 * @secattr: the packet's security attributes 288 * 289 * Description: 290 * Add a new entry into the CIPSO label mapping cache. Add the new entry to 291 * head of the cache bucket's list, if the cache bucket is out of room remove 292 * the last entry in the list first. It is important to note that there is 293 * currently no checking for duplicate keys. Returns zero on success, 294 * negative values on failure. 295 * 296 */ 297int cipso_v4_cache_add(const unsigned char *cipso_ptr, 298 const struct netlbl_lsm_secattr *secattr) 299{ 300 int bkt_size = READ_ONCE(cipso_v4_cache_bucketsize); 301 int ret_val = -EPERM; 302 u32 bkt; 303 struct cipso_v4_map_cache_entry *entry = NULL; 304 struct cipso_v4_map_cache_entry *old_entry = NULL; 305 u32 cipso_ptr_len; 306 307 if (!READ_ONCE(cipso_v4_cache_enabled) || bkt_size <= 0) 308 return 0; 309 310 cipso_ptr_len = cipso_ptr[1]; 311 312 entry = kzalloc(sizeof(*entry), GFP_ATOMIC); 313 if (!entry) 314 return -ENOMEM; 315 entry->key = kmemdup(cipso_ptr, cipso_ptr_len, GFP_ATOMIC); 316 if (!entry->key) { 317 ret_val = -ENOMEM; 318 goto cache_add_failure; 319 } 320 entry->key_len = cipso_ptr_len; 321 entry->hash = cipso_v4_map_cache_hash(cipso_ptr, cipso_ptr_len); 322 refcount_inc(&secattr->cache->refcount); 323 entry->lsm_data = secattr->cache; 324 325 bkt = entry->hash & (CIPSO_V4_CACHE_BUCKETS - 1); 326 spin_lock_bh(&cipso_v4_cache[bkt].lock); 327 if (cipso_v4_cache[bkt].size < bkt_size) { 328 list_add(&entry->list, &cipso_v4_cache[bkt].list); 329 cipso_v4_cache[bkt].size += 1; 330 } else { 331 old_entry = list_entry(cipso_v4_cache[bkt].list.prev, 332 struct cipso_v4_map_cache_entry, list); 333 list_del(&old_entry->list); 334 list_add(&entry->list, &cipso_v4_cache[bkt].list); 335 cipso_v4_cache_entry_free(old_entry); 336 } 337 spin_unlock_bh(&cipso_v4_cache[bkt].lock); 338 339 return 0; 340 341cache_add_failure: 342 if (entry) 343 cipso_v4_cache_entry_free(entry); 344 return ret_val; 345} 346 347/* 348 * DOI List Functions 349 */ 350 351/** 352 * cipso_v4_doi_search - Searches for a DOI definition 353 * @doi: the DOI to search for 354 * 355 * Description: 356 * Search the DOI definition list for a DOI definition with a DOI value that 357 * matches @doi. The caller is responsible for calling rcu_read_[un]lock(). 358 * Returns a pointer to the DOI definition on success and NULL on failure. 359 */ 360static struct cipso_v4_doi *cipso_v4_doi_search(u32 doi) 361{ 362 struct cipso_v4_doi *iter; 363 364 list_for_each_entry_rcu(iter, &cipso_v4_doi_list, list) 365 if (iter->doi == doi && refcount_read(&iter->refcount)) 366 return iter; 367 return NULL; 368} 369 370/** 371 * cipso_v4_doi_add - Add a new DOI to the CIPSO protocol engine 372 * @doi_def: the DOI structure 373 * @audit_info: NetLabel audit information 374 * 375 * Description: 376 * The caller defines a new DOI for use by the CIPSO engine and calls this 377 * function to add it to the list of acceptable domains. The caller must 378 * ensure that the mapping table specified in @doi_def->map meets all of the 379 * requirements of the mapping type (see cipso_ipv4.h for details). Returns 380 * zero on success and non-zero on failure. 381 * 382 */ 383int cipso_v4_doi_add(struct cipso_v4_doi *doi_def, 384 struct netlbl_audit *audit_info) 385{ 386 int ret_val = -EINVAL; 387 u32 iter; 388 u32 doi; 389 u32 doi_type; 390 struct audit_buffer *audit_buf; 391 392 doi = doi_def->doi; 393 doi_type = doi_def->type; 394 395 if (doi_def->doi == CIPSO_V4_DOI_UNKNOWN) 396 goto doi_add_return; 397 for (iter = 0; iter < CIPSO_V4_TAG_MAXCNT; iter++) { 398 switch (doi_def->tags[iter]) { 399 case CIPSO_V4_TAG_RBITMAP: 400 break; 401 case CIPSO_V4_TAG_RANGE: 402 case CIPSO_V4_TAG_ENUM: 403 if (doi_def->type != CIPSO_V4_MAP_PASS) 404 goto doi_add_return; 405 break; 406 case CIPSO_V4_TAG_LOCAL: 407 if (doi_def->type != CIPSO_V4_MAP_LOCAL) 408 goto doi_add_return; 409 break; 410 case CIPSO_V4_TAG_INVALID: 411 if (iter == 0) 412 goto doi_add_return; 413 break; 414 default: 415 goto doi_add_return; 416 } 417 } 418 419 refcount_set(&doi_def->refcount, 1); 420 421 spin_lock(&cipso_v4_doi_list_lock); 422 if (cipso_v4_doi_search(doi_def->doi)) { 423 spin_unlock(&cipso_v4_doi_list_lock); 424 ret_val = -EEXIST; 425 goto doi_add_return; 426 } 427 list_add_tail_rcu(&doi_def->list, &cipso_v4_doi_list); 428 spin_unlock(&cipso_v4_doi_list_lock); 429 ret_val = 0; 430 431doi_add_return: 432 audit_buf = netlbl_audit_start(AUDIT_MAC_CIPSOV4_ADD, audit_info); 433 if (audit_buf) { 434 const char *type_str; 435 switch (doi_type) { 436 case CIPSO_V4_MAP_TRANS: 437 type_str = "trans"; 438 break; 439 case CIPSO_V4_MAP_PASS: 440 type_str = "pass"; 441 break; 442 case CIPSO_V4_MAP_LOCAL: 443 type_str = "local"; 444 break; 445 default: 446 type_str = "(unknown)"; 447 } 448 audit_log_format(audit_buf, 449 " cipso_doi=%u cipso_type=%s res=%u", 450 doi, type_str, ret_val == 0 ? 1 : 0); 451 audit_log_end(audit_buf); 452 } 453 454 return ret_val; 455} 456 457/** 458 * cipso_v4_doi_free - Frees a DOI definition 459 * @doi_def: the DOI definition 460 * 461 * Description: 462 * This function frees all of the memory associated with a DOI definition. 463 * 464 */ 465void cipso_v4_doi_free(struct cipso_v4_doi *doi_def) 466{ 467 if (!doi_def) 468 return; 469 470 switch (doi_def->type) { 471 case CIPSO_V4_MAP_TRANS: 472 kfree(doi_def->map.std->lvl.cipso); 473 kfree(doi_def->map.std->lvl.local); 474 kfree(doi_def->map.std->cat.cipso); 475 kfree(doi_def->map.std->cat.local); 476 kfree(doi_def->map.std); 477 break; 478 } 479 kfree(doi_def); 480} 481 482/** 483 * cipso_v4_doi_free_rcu - Frees a DOI definition via the RCU pointer 484 * @entry: the entry's RCU field 485 * 486 * Description: 487 * This function is designed to be used as a callback to the call_rcu() 488 * function so that the memory allocated to the DOI definition can be released 489 * safely. 490 * 491 */ 492static void cipso_v4_doi_free_rcu(struct rcu_head *entry) 493{ 494 struct cipso_v4_doi *doi_def; 495 496 doi_def = container_of(entry, struct cipso_v4_doi, rcu); 497 cipso_v4_doi_free(doi_def); 498} 499 500/** 501 * cipso_v4_doi_remove - Remove an existing DOI from the CIPSO protocol engine 502 * @doi: the DOI value 503 * @audit_info: NetLabel audit information 504 * 505 * Description: 506 * Removes a DOI definition from the CIPSO engine. The NetLabel routines will 507 * be called to release their own LSM domain mappings as well as our own 508 * domain list. Returns zero on success and negative values on failure. 509 * 510 */ 511int cipso_v4_doi_remove(u32 doi, struct netlbl_audit *audit_info) 512{ 513 int ret_val; 514 struct cipso_v4_doi *doi_def; 515 struct audit_buffer *audit_buf; 516 517 spin_lock(&cipso_v4_doi_list_lock); 518 doi_def = cipso_v4_doi_search(doi); 519 if (!doi_def) { 520 spin_unlock(&cipso_v4_doi_list_lock); 521 ret_val = -ENOENT; 522 goto doi_remove_return; 523 } 524 list_del_rcu(&doi_def->list); 525 spin_unlock(&cipso_v4_doi_list_lock); 526 527 cipso_v4_doi_putdef(doi_def); 528 ret_val = 0; 529 530doi_remove_return: 531 audit_buf = netlbl_audit_start(AUDIT_MAC_CIPSOV4_DEL, audit_info); 532 if (audit_buf) { 533 audit_log_format(audit_buf, 534 " cipso_doi=%u res=%u", 535 doi, ret_val == 0 ? 1 : 0); 536 audit_log_end(audit_buf); 537 } 538 539 return ret_val; 540} 541 542/** 543 * cipso_v4_doi_getdef - Returns a reference to a valid DOI definition 544 * @doi: the DOI value 545 * 546 * Description: 547 * Searches for a valid DOI definition and if one is found it is returned to 548 * the caller. Otherwise NULL is returned. The caller must ensure that 549 * rcu_read_lock() is held while accessing the returned definition and the DOI 550 * definition reference count is decremented when the caller is done. 551 * 552 */ 553struct cipso_v4_doi *cipso_v4_doi_getdef(u32 doi) 554{ 555 struct cipso_v4_doi *doi_def; 556 557 rcu_read_lock(); 558 doi_def = cipso_v4_doi_search(doi); 559 if (!doi_def) 560 goto doi_getdef_return; 561 if (!refcount_inc_not_zero(&doi_def->refcount)) 562 doi_def = NULL; 563 564doi_getdef_return: 565 rcu_read_unlock(); 566 return doi_def; 567} 568 569/** 570 * cipso_v4_doi_putdef - Releases a reference for the given DOI definition 571 * @doi_def: the DOI definition 572 * 573 * Description: 574 * Releases a DOI definition reference obtained from cipso_v4_doi_getdef(). 575 * 576 */ 577void cipso_v4_doi_putdef(struct cipso_v4_doi *doi_def) 578{ 579 if (!doi_def) 580 return; 581 582 if (!refcount_dec_and_test(&doi_def->refcount)) 583 return; 584 585 cipso_v4_cache_invalidate(); 586 call_rcu(&doi_def->rcu, cipso_v4_doi_free_rcu); 587} 588 589/** 590 * cipso_v4_doi_walk - Iterate through the DOI definitions 591 * @skip_cnt: skip past this number of DOI definitions, updated 592 * @callback: callback for each DOI definition 593 * @cb_arg: argument for the callback function 594 * 595 * Description: 596 * Iterate over the DOI definition list, skipping the first @skip_cnt entries. 597 * For each entry call @callback, if @callback returns a negative value stop 598 * 'walking' through the list and return. Updates the value in @skip_cnt upon 599 * return. Returns zero on success, negative values on failure. 600 * 601 */ 602int cipso_v4_doi_walk(u32 *skip_cnt, 603 int (*callback) (struct cipso_v4_doi *doi_def, void *arg), 604 void *cb_arg) 605{ 606 int ret_val = -ENOENT; 607 u32 doi_cnt = 0; 608 struct cipso_v4_doi *iter_doi; 609 610 rcu_read_lock(); 611 list_for_each_entry_rcu(iter_doi, &cipso_v4_doi_list, list) 612 if (refcount_read(&iter_doi->refcount) > 0) { 613 if (doi_cnt++ < *skip_cnt) 614 continue; 615 ret_val = callback(iter_doi, cb_arg); 616 if (ret_val < 0) { 617 doi_cnt--; 618 goto doi_walk_return; 619 } 620 } 621 622doi_walk_return: 623 rcu_read_unlock(); 624 *skip_cnt = doi_cnt; 625 return ret_val; 626} 627 628/* 629 * Label Mapping Functions 630 */ 631 632/** 633 * cipso_v4_map_lvl_valid - Checks to see if the given level is understood 634 * @doi_def: the DOI definition 635 * @level: the level to check 636 * 637 * Description: 638 * Checks the given level against the given DOI definition and returns a 639 * negative value if the level does not have a valid mapping and a zero value 640 * if the level is defined by the DOI. 641 * 642 */ 643static int cipso_v4_map_lvl_valid(const struct cipso_v4_doi *doi_def, u8 level) 644{ 645 switch (doi_def->type) { 646 case CIPSO_V4_MAP_PASS: 647 return 0; 648 case CIPSO_V4_MAP_TRANS: 649 if ((level < doi_def->map.std->lvl.cipso_size) && 650 (doi_def->map.std->lvl.cipso[level] < CIPSO_V4_INV_LVL)) 651 return 0; 652 break; 653 } 654 655 return -EFAULT; 656} 657 658/** 659 * cipso_v4_map_lvl_hton - Perform a level mapping from the host to the network 660 * @doi_def: the DOI definition 661 * @host_lvl: the host MLS level 662 * @net_lvl: the network/CIPSO MLS level 663 * 664 * Description: 665 * Perform a label mapping to translate a local MLS level to the correct 666 * CIPSO level using the given DOI definition. Returns zero on success, 667 * negative values otherwise. 668 * 669 */ 670static int cipso_v4_map_lvl_hton(const struct cipso_v4_doi *doi_def, 671 u32 host_lvl, 672 u32 *net_lvl) 673{ 674 switch (doi_def->type) { 675 case CIPSO_V4_MAP_PASS: 676 *net_lvl = host_lvl; 677 return 0; 678 case CIPSO_V4_MAP_TRANS: 679 if (host_lvl < doi_def->map.std->lvl.local_size && 680 doi_def->map.std->lvl.local[host_lvl] < CIPSO_V4_INV_LVL) { 681 *net_lvl = doi_def->map.std->lvl.local[host_lvl]; 682 return 0; 683 } 684 return -EPERM; 685 } 686 687 return -EINVAL; 688} 689 690/** 691 * cipso_v4_map_lvl_ntoh - Perform a level mapping from the network to the host 692 * @doi_def: the DOI definition 693 * @net_lvl: the network/CIPSO MLS level 694 * @host_lvl: the host MLS level 695 * 696 * Description: 697 * Perform a label mapping to translate a CIPSO level to the correct local MLS 698 * level using the given DOI definition. Returns zero on success, negative 699 * values otherwise. 700 * 701 */ 702static int cipso_v4_map_lvl_ntoh(const struct cipso_v4_doi *doi_def, 703 u32 net_lvl, 704 u32 *host_lvl) 705{ 706 struct cipso_v4_std_map_tbl *map_tbl; 707 708 switch (doi_def->type) { 709 case CIPSO_V4_MAP_PASS: 710 *host_lvl = net_lvl; 711 return 0; 712 case CIPSO_V4_MAP_TRANS: 713 map_tbl = doi_def->map.std; 714 if (net_lvl < map_tbl->lvl.cipso_size && 715 map_tbl->lvl.cipso[net_lvl] < CIPSO_V4_INV_LVL) { 716 *host_lvl = doi_def->map.std->lvl.cipso[net_lvl]; 717 return 0; 718 } 719 return -EPERM; 720 } 721 722 return -EINVAL; 723} 724 725/** 726 * cipso_v4_map_cat_rbm_valid - Checks to see if the category bitmap is valid 727 * @doi_def: the DOI definition 728 * @bitmap: category bitmap 729 * @bitmap_len: bitmap length in bytes 730 * 731 * Description: 732 * Checks the given category bitmap against the given DOI definition and 733 * returns a negative value if any of the categories in the bitmap do not have 734 * a valid mapping and a zero value if all of the categories are valid. 735 * 736 */ 737static int cipso_v4_map_cat_rbm_valid(const struct cipso_v4_doi *doi_def, 738 const unsigned char *bitmap, 739 u32 bitmap_len) 740{ 741 int cat = -1; 742 u32 bitmap_len_bits = bitmap_len * 8; 743 u32 cipso_cat_size; 744 u32 *cipso_array; 745 746 switch (doi_def->type) { 747 case CIPSO_V4_MAP_PASS: 748 return 0; 749 case CIPSO_V4_MAP_TRANS: 750 cipso_cat_size = doi_def->map.std->cat.cipso_size; 751 cipso_array = doi_def->map.std->cat.cipso; 752 for (;;) { 753 cat = netlbl_bitmap_walk(bitmap, 754 bitmap_len_bits, 755 cat + 1, 756 1); 757 if (cat < 0) 758 break; 759 if (cat >= cipso_cat_size || 760 cipso_array[cat] >= CIPSO_V4_INV_CAT) 761 return -EFAULT; 762 } 763 764 if (cat == -1) 765 return 0; 766 break; 767 } 768 769 return -EFAULT; 770} 771 772/** 773 * cipso_v4_map_cat_rbm_hton - Perform a category mapping from host to network 774 * @doi_def: the DOI definition 775 * @secattr: the security attributes 776 * @net_cat: the zero'd out category bitmap in network/CIPSO format 777 * @net_cat_len: the length of the CIPSO bitmap in bytes 778 * 779 * Description: 780 * Perform a label mapping to translate a local MLS category bitmap to the 781 * correct CIPSO bitmap using the given DOI definition. Returns the minimum 782 * size in bytes of the network bitmap on success, negative values otherwise. 783 * 784 */ 785static int cipso_v4_map_cat_rbm_hton(const struct cipso_v4_doi *doi_def, 786 const struct netlbl_lsm_secattr *secattr, 787 unsigned char *net_cat, 788 u32 net_cat_len) 789{ 790 int host_spot = -1; 791 u32 net_spot = CIPSO_V4_INV_CAT; 792 u32 net_spot_max = 0; 793 u32 net_clen_bits = net_cat_len * 8; 794 u32 host_cat_size = 0; 795 u32 *host_cat_array = NULL; 796 797 if (doi_def->type == CIPSO_V4_MAP_TRANS) { 798 host_cat_size = doi_def->map.std->cat.local_size; 799 host_cat_array = doi_def->map.std->cat.local; 800 } 801 802 for (;;) { 803 host_spot = netlbl_catmap_walk(secattr->attr.mls.cat, 804 host_spot + 1); 805 if (host_spot < 0) 806 break; 807 808 switch (doi_def->type) { 809 case CIPSO_V4_MAP_PASS: 810 net_spot = host_spot; 811 break; 812 case CIPSO_V4_MAP_TRANS: 813 if (host_spot >= host_cat_size) 814 return -EPERM; 815 net_spot = host_cat_array[host_spot]; 816 if (net_spot >= CIPSO_V4_INV_CAT) 817 return -EPERM; 818 break; 819 } 820 if (net_spot >= net_clen_bits) 821 return -ENOSPC; 822 netlbl_bitmap_setbit(net_cat, net_spot, 1); 823 824 if (net_spot > net_spot_max) 825 net_spot_max = net_spot; 826 } 827 828 if (++net_spot_max % 8) 829 return net_spot_max / 8 + 1; 830 return net_spot_max / 8; 831} 832 833/** 834 * cipso_v4_map_cat_rbm_ntoh - Perform a category mapping from network to host 835 * @doi_def: the DOI definition 836 * @net_cat: the category bitmap in network/CIPSO format 837 * @net_cat_len: the length of the CIPSO bitmap in bytes 838 * @secattr: the security attributes 839 * 840 * Description: 841 * Perform a label mapping to translate a CIPSO bitmap to the correct local 842 * MLS category bitmap using the given DOI definition. Returns zero on 843 * success, negative values on failure. 844 * 845 */ 846static int cipso_v4_map_cat_rbm_ntoh(const struct cipso_v4_doi *doi_def, 847 const unsigned char *net_cat, 848 u32 net_cat_len, 849 struct netlbl_lsm_secattr *secattr) 850{ 851 int ret_val; 852 int net_spot = -1; 853 u32 host_spot = CIPSO_V4_INV_CAT; 854 u32 net_clen_bits = net_cat_len * 8; 855 u32 net_cat_size = 0; 856 u32 *net_cat_array = NULL; 857 858 if (doi_def->type == CIPSO_V4_MAP_TRANS) { 859 net_cat_size = doi_def->map.std->cat.cipso_size; 860 net_cat_array = doi_def->map.std->cat.cipso; 861 } 862 863 for (;;) { 864 net_spot = netlbl_bitmap_walk(net_cat, 865 net_clen_bits, 866 net_spot + 1, 867 1); 868 if (net_spot < 0) { 869 if (net_spot == -2) 870 return -EFAULT; 871 return 0; 872 } 873 874 switch (doi_def->type) { 875 case CIPSO_V4_MAP_PASS: 876 host_spot = net_spot; 877 break; 878 case CIPSO_V4_MAP_TRANS: 879 if (net_spot >= net_cat_size) 880 return -EPERM; 881 host_spot = net_cat_array[net_spot]; 882 if (host_spot >= CIPSO_V4_INV_CAT) 883 return -EPERM; 884 break; 885 } 886 ret_val = netlbl_catmap_setbit(&secattr->attr.mls.cat, 887 host_spot, 888 GFP_ATOMIC); 889 if (ret_val != 0) 890 return ret_val; 891 } 892 893 return -EINVAL; 894} 895 896/** 897 * cipso_v4_map_cat_enum_valid - Checks to see if the categories are valid 898 * @doi_def: the DOI definition 899 * @enumcat: category list 900 * @enumcat_len: length of the category list in bytes 901 * 902 * Description: 903 * Checks the given categories against the given DOI definition and returns a 904 * negative value if any of the categories do not have a valid mapping and a 905 * zero value if all of the categories are valid. 906 * 907 */ 908static int cipso_v4_map_cat_enum_valid(const struct cipso_v4_doi *doi_def, 909 const unsigned char *enumcat, 910 u32 enumcat_len) 911{ 912 u16 cat; 913 int cat_prev = -1; 914 u32 iter; 915 916 if (doi_def->type != CIPSO_V4_MAP_PASS || enumcat_len & 0x01) 917 return -EFAULT; 918 919 for (iter = 0; iter < enumcat_len; iter += 2) { 920 cat = get_unaligned_be16(&enumcat[iter]); 921 if (cat <= cat_prev) 922 return -EFAULT; 923 cat_prev = cat; 924 } 925 926 return 0; 927} 928 929/** 930 * cipso_v4_map_cat_enum_hton - Perform a category mapping from host to network 931 * @doi_def: the DOI definition 932 * @secattr: the security attributes 933 * @net_cat: the zero'd out category list in network/CIPSO format 934 * @net_cat_len: the length of the CIPSO category list in bytes 935 * 936 * Description: 937 * Perform a label mapping to translate a local MLS category bitmap to the 938 * correct CIPSO category list using the given DOI definition. Returns the 939 * size in bytes of the network category bitmap on success, negative values 940 * otherwise. 941 * 942 */ 943static int cipso_v4_map_cat_enum_hton(const struct cipso_v4_doi *doi_def, 944 const struct netlbl_lsm_secattr *secattr, 945 unsigned char *net_cat, 946 u32 net_cat_len) 947{ 948 int cat = -1; 949 u32 cat_iter = 0; 950 951 for (;;) { 952 cat = netlbl_catmap_walk(secattr->attr.mls.cat, cat + 1); 953 if (cat < 0) 954 break; 955 if ((cat_iter + 2) > net_cat_len) 956 return -ENOSPC; 957 958 *((__be16 *)&net_cat[cat_iter]) = htons(cat); 959 cat_iter += 2; 960 } 961 962 return cat_iter; 963} 964 965/** 966 * cipso_v4_map_cat_enum_ntoh - Perform a category mapping from network to host 967 * @doi_def: the DOI definition 968 * @net_cat: the category list in network/CIPSO format 969 * @net_cat_len: the length of the CIPSO bitmap in bytes 970 * @secattr: the security attributes 971 * 972 * Description: 973 * Perform a label mapping to translate a CIPSO category list to the correct 974 * local MLS category bitmap using the given DOI definition. Returns zero on 975 * success, negative values on failure. 976 * 977 */ 978static int cipso_v4_map_cat_enum_ntoh(const struct cipso_v4_doi *doi_def, 979 const unsigned char *net_cat, 980 u32 net_cat_len, 981 struct netlbl_lsm_secattr *secattr) 982{ 983 int ret_val; 984 u32 iter; 985 986 for (iter = 0; iter < net_cat_len; iter += 2) { 987 ret_val = netlbl_catmap_setbit(&secattr->attr.mls.cat, 988 get_unaligned_be16(&net_cat[iter]), 989 GFP_ATOMIC); 990 if (ret_val != 0) 991 return ret_val; 992 } 993 994 return 0; 995} 996 997/** 998 * cipso_v4_map_cat_rng_valid - Checks to see if the categories are valid 999 * @doi_def: the DOI definition 1000 * @rngcat: category list 1001 * @rngcat_len: length of the category list in bytes 1002 * 1003 * Description: 1004 * Checks the given categories against the given DOI definition and returns a 1005 * negative value if any of the categories do not have a valid mapping and a 1006 * zero value if all of the categories are valid. 1007 * 1008 */ 1009static int cipso_v4_map_cat_rng_valid(const struct cipso_v4_doi *doi_def, 1010 const unsigned char *rngcat, 1011 u32 rngcat_len) 1012{ 1013 u16 cat_high; 1014 u16 cat_low; 1015 u32 cat_prev = CIPSO_V4_MAX_REM_CATS + 1; 1016 u32 iter; 1017 1018 if (doi_def->type != CIPSO_V4_MAP_PASS || rngcat_len & 0x01) 1019 return -EFAULT; 1020 1021 for (iter = 0; iter < rngcat_len; iter += 4) { 1022 cat_high = get_unaligned_be16(&rngcat[iter]); 1023 if ((iter + 4) <= rngcat_len) 1024 cat_low = get_unaligned_be16(&rngcat[iter + 2]); 1025 else 1026 cat_low = 0; 1027 1028 if (cat_high > cat_prev) 1029 return -EFAULT; 1030 1031 cat_prev = cat_low; 1032 } 1033 1034 return 0; 1035} 1036 1037/** 1038 * cipso_v4_map_cat_rng_hton - Perform a category mapping from host to network 1039 * @doi_def: the DOI definition 1040 * @secattr: the security attributes 1041 * @net_cat: the zero'd out category list in network/CIPSO format 1042 * @net_cat_len: the length of the CIPSO category list in bytes 1043 * 1044 * Description: 1045 * Perform a label mapping to translate a local MLS category bitmap to the 1046 * correct CIPSO category list using the given DOI definition. Returns the 1047 * size in bytes of the network category bitmap on success, negative values 1048 * otherwise. 1049 * 1050 */ 1051static int cipso_v4_map_cat_rng_hton(const struct cipso_v4_doi *doi_def, 1052 const struct netlbl_lsm_secattr *secattr, 1053 unsigned char *net_cat, 1054 u32 net_cat_len) 1055{ 1056 int iter = -1; 1057 u16 array[CIPSO_V4_TAG_RNG_CAT_MAX * 2]; 1058 u32 array_cnt = 0; 1059 u32 cat_size = 0; 1060 1061 /* make sure we don't overflow the 'array[]' variable */ 1062 if (net_cat_len > 1063 (CIPSO_V4_OPT_LEN_MAX - CIPSO_V4_HDR_LEN - CIPSO_V4_TAG_RNG_BLEN)) 1064 return -ENOSPC; 1065 1066 for (;;) { 1067 iter = netlbl_catmap_walk(secattr->attr.mls.cat, iter + 1); 1068 if (iter < 0) 1069 break; 1070 cat_size += (iter == 0 ? 0 : sizeof(u16)); 1071 if (cat_size > net_cat_len) 1072 return -ENOSPC; 1073 array[array_cnt++] = iter; 1074 1075 iter = netlbl_catmap_walkrng(secattr->attr.mls.cat, iter); 1076 if (iter < 0) 1077 return -EFAULT; 1078 cat_size += sizeof(u16); 1079 if (cat_size > net_cat_len) 1080 return -ENOSPC; 1081 array[array_cnt++] = iter; 1082 } 1083 1084 for (iter = 0; array_cnt > 0;) { 1085 *((__be16 *)&net_cat[iter]) = htons(array[--array_cnt]); 1086 iter += 2; 1087 array_cnt--; 1088 if (array[array_cnt] != 0) { 1089 *((__be16 *)&net_cat[iter]) = htons(array[array_cnt]); 1090 iter += 2; 1091 } 1092 } 1093 1094 return cat_size; 1095} 1096 1097/** 1098 * cipso_v4_map_cat_rng_ntoh - Perform a category mapping from network to host 1099 * @doi_def: the DOI definition 1100 * @net_cat: the category list in network/CIPSO format 1101 * @net_cat_len: the length of the CIPSO bitmap in bytes 1102 * @secattr: the security attributes 1103 * 1104 * Description: 1105 * Perform a label mapping to translate a CIPSO category list to the correct 1106 * local MLS category bitmap using the given DOI definition. Returns zero on 1107 * success, negative values on failure. 1108 * 1109 */ 1110static int cipso_v4_map_cat_rng_ntoh(const struct cipso_v4_doi *doi_def, 1111 const unsigned char *net_cat, 1112 u32 net_cat_len, 1113 struct netlbl_lsm_secattr *secattr) 1114{ 1115 int ret_val; 1116 u32 net_iter; 1117 u16 cat_low; 1118 u16 cat_high; 1119 1120 for (net_iter = 0; net_iter < net_cat_len; net_iter += 4) { 1121 cat_high = get_unaligned_be16(&net_cat[net_iter]); 1122 if ((net_iter + 4) <= net_cat_len) 1123 cat_low = get_unaligned_be16(&net_cat[net_iter + 2]); 1124 else 1125 cat_low = 0; 1126 1127 ret_val = netlbl_catmap_setrng(&secattr->attr.mls.cat, 1128 cat_low, 1129 cat_high, 1130 GFP_ATOMIC); 1131 if (ret_val != 0) 1132 return ret_val; 1133 } 1134 1135 return 0; 1136} 1137 1138/* 1139 * Protocol Handling Functions 1140 */ 1141 1142/** 1143 * cipso_v4_gentag_hdr - Generate a CIPSO option header 1144 * @doi_def: the DOI definition 1145 * @len: the total tag length in bytes, not including this header 1146 * @buf: the CIPSO option buffer 1147 * 1148 * Description: 1149 * Write a CIPSO header into the beginning of @buffer. 1150 * 1151 */ 1152static void cipso_v4_gentag_hdr(const struct cipso_v4_doi *doi_def, 1153 unsigned char *buf, 1154 u32 len) 1155{ 1156 buf[0] = IPOPT_CIPSO; 1157 buf[1] = CIPSO_V4_HDR_LEN + len; 1158 *(__be32 *)&buf[2] = htonl(doi_def->doi); 1159} 1160 1161/** 1162 * cipso_v4_gentag_rbm - Generate a CIPSO restricted bitmap tag (type #1) 1163 * @doi_def: the DOI definition 1164 * @secattr: the security attributes 1165 * @buffer: the option buffer 1166 * @buffer_len: length of buffer in bytes 1167 * 1168 * Description: 1169 * Generate a CIPSO option using the restricted bitmap tag, tag type #1. The 1170 * actual buffer length may be larger than the indicated size due to 1171 * translation between host and network category bitmaps. Returns the size of 1172 * the tag on success, negative values on failure. 1173 * 1174 */ 1175static int cipso_v4_gentag_rbm(const struct cipso_v4_doi *doi_def, 1176 const struct netlbl_lsm_secattr *secattr, 1177 unsigned char *buffer, 1178 u32 buffer_len) 1179{ 1180 int ret_val; 1181 u32 tag_len; 1182 u32 level; 1183 1184 if ((secattr->flags & NETLBL_SECATTR_MLS_LVL) == 0) 1185 return -EPERM; 1186 1187 ret_val = cipso_v4_map_lvl_hton(doi_def, 1188 secattr->attr.mls.lvl, 1189 &level); 1190 if (ret_val != 0) 1191 return ret_val; 1192 1193 if (secattr->flags & NETLBL_SECATTR_MLS_CAT) { 1194 ret_val = cipso_v4_map_cat_rbm_hton(doi_def, 1195 secattr, 1196 &buffer[4], 1197 buffer_len - 4); 1198 if (ret_val < 0) 1199 return ret_val; 1200 1201 /* This will send packets using the "optimized" format when 1202 * possible as specified in section 3.4.2.6 of the 1203 * CIPSO draft. */ 1204 if (READ_ONCE(cipso_v4_rbm_optfmt) && ret_val > 0 && 1205 ret_val <= 10) 1206 tag_len = 14; 1207 else 1208 tag_len = 4 + ret_val; 1209 } else 1210 tag_len = 4; 1211 1212 buffer[0] = CIPSO_V4_TAG_RBITMAP; 1213 buffer[1] = tag_len; 1214 buffer[3] = level; 1215 1216 return tag_len; 1217} 1218 1219/** 1220 * cipso_v4_parsetag_rbm - Parse a CIPSO restricted bitmap tag 1221 * @doi_def: the DOI definition 1222 * @tag: the CIPSO tag 1223 * @secattr: the security attributes 1224 * 1225 * Description: 1226 * Parse a CIPSO restricted bitmap tag (tag type #1) and return the security 1227 * attributes in @secattr. Return zero on success, negatives values on 1228 * failure. 1229 * 1230 */ 1231static int cipso_v4_parsetag_rbm(const struct cipso_v4_doi *doi_def, 1232 const unsigned char *tag, 1233 struct netlbl_lsm_secattr *secattr) 1234{ 1235 int ret_val; 1236 u8 tag_len = tag[1]; 1237 u32 level; 1238 1239 ret_val = cipso_v4_map_lvl_ntoh(doi_def, tag[3], &level); 1240 if (ret_val != 0) 1241 return ret_val; 1242 secattr->attr.mls.lvl = level; 1243 secattr->flags |= NETLBL_SECATTR_MLS_LVL; 1244 1245 if (tag_len > 4) { 1246 ret_val = cipso_v4_map_cat_rbm_ntoh(doi_def, 1247 &tag[4], 1248 tag_len - 4, 1249 secattr); 1250 if (ret_val != 0) { 1251 netlbl_catmap_free(secattr->attr.mls.cat); 1252 return ret_val; 1253 } 1254 1255 if (secattr->attr.mls.cat) 1256 secattr->flags |= NETLBL_SECATTR_MLS_CAT; 1257 } 1258 1259 return 0; 1260} 1261 1262/** 1263 * cipso_v4_gentag_enum - Generate a CIPSO enumerated tag (type #2) 1264 * @doi_def: the DOI definition 1265 * @secattr: the security attributes 1266 * @buffer: the option buffer 1267 * @buffer_len: length of buffer in bytes 1268 * 1269 * Description: 1270 * Generate a CIPSO option using the enumerated tag, tag type #2. Returns the 1271 * size of the tag on success, negative values on failure. 1272 * 1273 */ 1274static int cipso_v4_gentag_enum(const struct cipso_v4_doi *doi_def, 1275 const struct netlbl_lsm_secattr *secattr, 1276 unsigned char *buffer, 1277 u32 buffer_len) 1278{ 1279 int ret_val; 1280 u32 tag_len; 1281 u32 level; 1282 1283 if (!(secattr->flags & NETLBL_SECATTR_MLS_LVL)) 1284 return -EPERM; 1285 1286 ret_val = cipso_v4_map_lvl_hton(doi_def, 1287 secattr->attr.mls.lvl, 1288 &level); 1289 if (ret_val != 0) 1290 return ret_val; 1291 1292 if (secattr->flags & NETLBL_SECATTR_MLS_CAT) { 1293 ret_val = cipso_v4_map_cat_enum_hton(doi_def, 1294 secattr, 1295 &buffer[4], 1296 buffer_len - 4); 1297 if (ret_val < 0) 1298 return ret_val; 1299 1300 tag_len = 4 + ret_val; 1301 } else 1302 tag_len = 4; 1303 1304 buffer[0] = CIPSO_V4_TAG_ENUM; 1305 buffer[1] = tag_len; 1306 buffer[3] = level; 1307 1308 return tag_len; 1309} 1310 1311/** 1312 * cipso_v4_parsetag_enum - Parse a CIPSO enumerated tag 1313 * @doi_def: the DOI definition 1314 * @tag: the CIPSO tag 1315 * @secattr: the security attributes 1316 * 1317 * Description: 1318 * Parse a CIPSO enumerated tag (tag type #2) and return the security 1319 * attributes in @secattr. Return zero on success, negatives values on 1320 * failure. 1321 * 1322 */ 1323static int cipso_v4_parsetag_enum(const struct cipso_v4_doi *doi_def, 1324 const unsigned char *tag, 1325 struct netlbl_lsm_secattr *secattr) 1326{ 1327 int ret_val; 1328 u8 tag_len = tag[1]; 1329 u32 level; 1330 1331 ret_val = cipso_v4_map_lvl_ntoh(doi_def, tag[3], &level); 1332 if (ret_val != 0) 1333 return ret_val; 1334 secattr->attr.mls.lvl = level; 1335 secattr->flags |= NETLBL_SECATTR_MLS_LVL; 1336 1337 if (tag_len > 4) { 1338 ret_val = cipso_v4_map_cat_enum_ntoh(doi_def, 1339 &tag[4], 1340 tag_len - 4, 1341 secattr); 1342 if (ret_val != 0) { 1343 netlbl_catmap_free(secattr->attr.mls.cat); 1344 return ret_val; 1345 } 1346 1347 secattr->flags |= NETLBL_SECATTR_MLS_CAT; 1348 } 1349 1350 return 0; 1351} 1352 1353/** 1354 * cipso_v4_gentag_rng - Generate a CIPSO ranged tag (type #5) 1355 * @doi_def: the DOI definition 1356 * @secattr: the security attributes 1357 * @buffer: the option buffer 1358 * @buffer_len: length of buffer in bytes 1359 * 1360 * Description: 1361 * Generate a CIPSO option using the ranged tag, tag type #5. Returns the 1362 * size of the tag on success, negative values on failure. 1363 * 1364 */ 1365static int cipso_v4_gentag_rng(const struct cipso_v4_doi *doi_def, 1366 const struct netlbl_lsm_secattr *secattr, 1367 unsigned char *buffer, 1368 u32 buffer_len) 1369{ 1370 int ret_val; 1371 u32 tag_len; 1372 u32 level; 1373 1374 if (!(secattr->flags & NETLBL_SECATTR_MLS_LVL)) 1375 return -EPERM; 1376 1377 ret_val = cipso_v4_map_lvl_hton(doi_def, 1378 secattr->attr.mls.lvl, 1379 &level); 1380 if (ret_val != 0) 1381 return ret_val; 1382 1383 if (secattr->flags & NETLBL_SECATTR_MLS_CAT) { 1384 ret_val = cipso_v4_map_cat_rng_hton(doi_def, 1385 secattr, 1386 &buffer[4], 1387 buffer_len - 4); 1388 if (ret_val < 0) 1389 return ret_val; 1390 1391 tag_len = 4 + ret_val; 1392 } else 1393 tag_len = 4; 1394 1395 buffer[0] = CIPSO_V4_TAG_RANGE; 1396 buffer[1] = tag_len; 1397 buffer[3] = level; 1398 1399 return tag_len; 1400} 1401 1402/** 1403 * cipso_v4_parsetag_rng - Parse a CIPSO ranged tag 1404 * @doi_def: the DOI definition 1405 * @tag: the CIPSO tag 1406 * @secattr: the security attributes 1407 * 1408 * Description: 1409 * Parse a CIPSO ranged tag (tag type #5) and return the security attributes 1410 * in @secattr. Return zero on success, negatives values on failure. 1411 * 1412 */ 1413static int cipso_v4_parsetag_rng(const struct cipso_v4_doi *doi_def, 1414 const unsigned char *tag, 1415 struct netlbl_lsm_secattr *secattr) 1416{ 1417 int ret_val; 1418 u8 tag_len = tag[1]; 1419 u32 level; 1420 1421 ret_val = cipso_v4_map_lvl_ntoh(doi_def, tag[3], &level); 1422 if (ret_val != 0) 1423 return ret_val; 1424 secattr->attr.mls.lvl = level; 1425 secattr->flags |= NETLBL_SECATTR_MLS_LVL; 1426 1427 if (tag_len > 4) { 1428 ret_val = cipso_v4_map_cat_rng_ntoh(doi_def, 1429 &tag[4], 1430 tag_len - 4, 1431 secattr); 1432 if (ret_val != 0) { 1433 netlbl_catmap_free(secattr->attr.mls.cat); 1434 return ret_val; 1435 } 1436 1437 if (secattr->attr.mls.cat) 1438 secattr->flags |= NETLBL_SECATTR_MLS_CAT; 1439 } 1440 1441 return 0; 1442} 1443 1444/** 1445 * cipso_v4_gentag_loc - Generate a CIPSO local tag (non-standard) 1446 * @doi_def: the DOI definition 1447 * @secattr: the security attributes 1448 * @buffer: the option buffer 1449 * @buffer_len: length of buffer in bytes 1450 * 1451 * Description: 1452 * Generate a CIPSO option using the local tag. Returns the size of the tag 1453 * on success, negative values on failure. 1454 * 1455 */ 1456static int cipso_v4_gentag_loc(const struct cipso_v4_doi *doi_def, 1457 const struct netlbl_lsm_secattr *secattr, 1458 unsigned char *buffer, 1459 u32 buffer_len) 1460{ 1461 if (!(secattr->flags & NETLBL_SECATTR_SECID)) 1462 return -EPERM; 1463 1464 buffer[0] = CIPSO_V4_TAG_LOCAL; 1465 buffer[1] = CIPSO_V4_TAG_LOC_BLEN; 1466 *(u32 *)&buffer[2] = secattr->attr.secid; 1467 1468 return CIPSO_V4_TAG_LOC_BLEN; 1469} 1470 1471/** 1472 * cipso_v4_parsetag_loc - Parse a CIPSO local tag 1473 * @doi_def: the DOI definition 1474 * @tag: the CIPSO tag 1475 * @secattr: the security attributes 1476 * 1477 * Description: 1478 * Parse a CIPSO local tag and return the security attributes in @secattr. 1479 * Return zero on success, negatives values on failure. 1480 * 1481 */ 1482static int cipso_v4_parsetag_loc(const struct cipso_v4_doi *doi_def, 1483 const unsigned char *tag, 1484 struct netlbl_lsm_secattr *secattr) 1485{ 1486 secattr->attr.secid = *(u32 *)&tag[2]; 1487 secattr->flags |= NETLBL_SECATTR_SECID; 1488 1489 return 0; 1490} 1491 1492/** 1493 * cipso_v4_optptr - Find the CIPSO option in the packet 1494 * @skb: the packet 1495 * 1496 * Description: 1497 * Parse the packet's IP header looking for a CIPSO option. Returns a pointer 1498 * to the start of the CIPSO option on success, NULL if one is not found. 1499 * 1500 */ 1501unsigned char *cipso_v4_optptr(const struct sk_buff *skb) 1502{ 1503 const struct iphdr *iph = ip_hdr(skb); 1504 unsigned char *optptr = (unsigned char *)&(ip_hdr(skb)[1]); 1505 int optlen; 1506 int taglen; 1507 1508 for (optlen = iph->ihl*4 - sizeof(struct iphdr); optlen > 1; ) { 1509 switch (optptr[0]) { 1510 case IPOPT_END: 1511 return NULL; 1512 case IPOPT_NOOP: 1513 taglen = 1; 1514 break; 1515 default: 1516 taglen = optptr[1]; 1517 } 1518 if (!taglen || taglen > optlen) 1519 return NULL; 1520 if (optptr[0] == IPOPT_CIPSO) 1521 return optptr; 1522 1523 optlen -= taglen; 1524 optptr += taglen; 1525 } 1526 1527 return NULL; 1528} 1529 1530/** 1531 * cipso_v4_validate - Validate a CIPSO option 1532 * @skb: the packet 1533 * @option: the start of the option, on error it is set to point to the error 1534 * 1535 * Description: 1536 * This routine is called to validate a CIPSO option, it checks all of the 1537 * fields to ensure that they are at least valid, see the draft snippet below 1538 * for details. If the option is valid then a zero value is returned and 1539 * the value of @option is unchanged. If the option is invalid then a 1540 * non-zero value is returned and @option is adjusted to point to the 1541 * offending portion of the option. From the IETF draft ... 1542 * 1543 * "If any field within the CIPSO options, such as the DOI identifier, is not 1544 * recognized the IP datagram is discarded and an ICMP 'parameter problem' 1545 * (type 12) is generated and returned. The ICMP code field is set to 'bad 1546 * parameter' (code 0) and the pointer is set to the start of the CIPSO field 1547 * that is unrecognized." 1548 * 1549 */ 1550int cipso_v4_validate(const struct sk_buff *skb, unsigned char **option) 1551{ 1552 unsigned char *opt = *option; 1553 unsigned char *tag; 1554 unsigned char opt_iter; 1555 unsigned char err_offset = 0; 1556 u8 opt_len; 1557 u8 tag_len; 1558 struct cipso_v4_doi *doi_def = NULL; 1559 u32 tag_iter; 1560 1561 /* caller already checks for length values that are too large */ 1562 opt_len = opt[1]; 1563 if (opt_len < 8) { 1564 err_offset = 1; 1565 goto validate_return; 1566 } 1567 1568 rcu_read_lock(); 1569 doi_def = cipso_v4_doi_search(get_unaligned_be32(&opt[2])); 1570 if (!doi_def) { 1571 err_offset = 2; 1572 goto validate_return_locked; 1573 } 1574 1575 opt_iter = CIPSO_V4_HDR_LEN; 1576 tag = opt + opt_iter; 1577 while (opt_iter < opt_len) { 1578 for (tag_iter = 0; doi_def->tags[tag_iter] != tag[0];) 1579 if (doi_def->tags[tag_iter] == CIPSO_V4_TAG_INVALID || 1580 ++tag_iter == CIPSO_V4_TAG_MAXCNT) { 1581 err_offset = opt_iter; 1582 goto validate_return_locked; 1583 } 1584 1585 if (opt_iter + 1 == opt_len) { 1586 err_offset = opt_iter; 1587 goto validate_return_locked; 1588 } 1589 tag_len = tag[1]; 1590 if (tag_len > (opt_len - opt_iter)) { 1591 err_offset = opt_iter + 1; 1592 goto validate_return_locked; 1593 } 1594 1595 switch (tag[0]) { 1596 case CIPSO_V4_TAG_RBITMAP: 1597 if (tag_len < CIPSO_V4_TAG_RBM_BLEN) { 1598 err_offset = opt_iter + 1; 1599 goto validate_return_locked; 1600 } 1601 1602 /* We are already going to do all the verification 1603 * necessary at the socket layer so from our point of 1604 * view it is safe to turn these checks off (and less 1605 * work), however, the CIPSO draft says we should do 1606 * all the CIPSO validations here but it doesn't 1607 * really specify _exactly_ what we need to validate 1608 * ... so, just make it a sysctl tunable. */ 1609 if (READ_ONCE(cipso_v4_rbm_strictvalid)) { 1610 if (cipso_v4_map_lvl_valid(doi_def, 1611 tag[3]) < 0) { 1612 err_offset = opt_iter + 3; 1613 goto validate_return_locked; 1614 } 1615 if (tag_len > CIPSO_V4_TAG_RBM_BLEN && 1616 cipso_v4_map_cat_rbm_valid(doi_def, 1617 &tag[4], 1618 tag_len - 4) < 0) { 1619 err_offset = opt_iter + 4; 1620 goto validate_return_locked; 1621 } 1622 } 1623 break; 1624 case CIPSO_V4_TAG_ENUM: 1625 if (tag_len < CIPSO_V4_TAG_ENUM_BLEN) { 1626 err_offset = opt_iter + 1; 1627 goto validate_return_locked; 1628 } 1629 1630 if (cipso_v4_map_lvl_valid(doi_def, 1631 tag[3]) < 0) { 1632 err_offset = opt_iter + 3; 1633 goto validate_return_locked; 1634 } 1635 if (tag_len > CIPSO_V4_TAG_ENUM_BLEN && 1636 cipso_v4_map_cat_enum_valid(doi_def, 1637 &tag[4], 1638 tag_len - 4) < 0) { 1639 err_offset = opt_iter + 4; 1640 goto validate_return_locked; 1641 } 1642 break; 1643 case CIPSO_V4_TAG_RANGE: 1644 if (tag_len < CIPSO_V4_TAG_RNG_BLEN) { 1645 err_offset = opt_iter + 1; 1646 goto validate_return_locked; 1647 } 1648 1649 if (cipso_v4_map_lvl_valid(doi_def, 1650 tag[3]) < 0) { 1651 err_offset = opt_iter + 3; 1652 goto validate_return_locked; 1653 } 1654 if (tag_len > CIPSO_V4_TAG_RNG_BLEN && 1655 cipso_v4_map_cat_rng_valid(doi_def, 1656 &tag[4], 1657 tag_len - 4) < 0) { 1658 err_offset = opt_iter + 4; 1659 goto validate_return_locked; 1660 } 1661 break; 1662 case CIPSO_V4_TAG_LOCAL: 1663 /* This is a non-standard tag that we only allow for 1664 * local connections, so if the incoming interface is 1665 * not the loopback device drop the packet. Further, 1666 * there is no legitimate reason for setting this from 1667 * userspace so reject it if skb is NULL. */ 1668 if (!skb || !(skb->dev->flags & IFF_LOOPBACK)) { 1669 err_offset = opt_iter; 1670 goto validate_return_locked; 1671 } 1672 if (tag_len != CIPSO_V4_TAG_LOC_BLEN) { 1673 err_offset = opt_iter + 1; 1674 goto validate_return_locked; 1675 } 1676 break; 1677 default: 1678 err_offset = opt_iter; 1679 goto validate_return_locked; 1680 } 1681 1682 tag += tag_len; 1683 opt_iter += tag_len; 1684 } 1685 1686validate_return_locked: 1687 rcu_read_unlock(); 1688validate_return: 1689 *option = opt + err_offset; 1690 return err_offset; 1691} 1692 1693/** 1694 * cipso_v4_error - Send the correct response for a bad packet 1695 * @skb: the packet 1696 * @error: the error code 1697 * @gateway: CIPSO gateway flag 1698 * 1699 * Description: 1700 * Based on the error code given in @error, send an ICMP error message back to 1701 * the originating host. From the IETF draft ... 1702 * 1703 * "If the contents of the CIPSO [option] are valid but the security label is 1704 * outside of the configured host or port label range, the datagram is 1705 * discarded and an ICMP 'destination unreachable' (type 3) is generated and 1706 * returned. The code field of the ICMP is set to 'communication with 1707 * destination network administratively prohibited' (code 9) or to 1708 * 'communication with destination host administratively prohibited' 1709 * (code 10). The value of the code is dependent on whether the originator 1710 * of the ICMP message is acting as a CIPSO host or a CIPSO gateway. The 1711 * recipient of the ICMP message MUST be able to handle either value. The 1712 * same procedure is performed if a CIPSO [option] can not be added to an 1713 * IP packet because it is too large to fit in the IP options area." 1714 * 1715 * "If the error is triggered by receipt of an ICMP message, the message is 1716 * discarded and no response is permitted (consistent with general ICMP 1717 * processing rules)." 1718 * 1719 */ 1720void cipso_v4_error(struct sk_buff *skb, int error, u32 gateway) 1721{ 1722 unsigned char optbuf[sizeof(struct ip_options) + 40]; 1723 struct ip_options *opt = (struct ip_options *)optbuf; 1724 int res; 1725 1726 if (ip_hdr(skb)->protocol == IPPROTO_ICMP || error != -EACCES) 1727 return; 1728 1729 /* 1730 * We might be called above the IP layer, 1731 * so we can not use icmp_send and IPCB here. 1732 */ 1733 1734 memset(opt, 0, sizeof(struct ip_options)); 1735 opt->optlen = ip_hdr(skb)->ihl*4 - sizeof(struct iphdr); 1736 rcu_read_lock(); 1737 res = __ip_options_compile(dev_net(skb->dev), opt, skb, NULL); 1738 rcu_read_unlock(); 1739 1740 if (res) 1741 return; 1742 1743 if (gateway) 1744 __icmp_send(skb, ICMP_DEST_UNREACH, ICMP_NET_ANO, 0, opt); 1745 else 1746 __icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_ANO, 0, opt); 1747} 1748 1749/** 1750 * cipso_v4_genopt - Generate a CIPSO option 1751 * @buf: the option buffer 1752 * @buf_len: the size of opt_buf 1753 * @doi_def: the CIPSO DOI to use 1754 * @secattr: the security attributes 1755 * 1756 * Description: 1757 * Generate a CIPSO option using the DOI definition and security attributes 1758 * passed to the function. Returns the length of the option on success and 1759 * negative values on failure. 1760 * 1761 */ 1762static int cipso_v4_genopt(unsigned char *buf, u32 buf_len, 1763 const struct cipso_v4_doi *doi_def, 1764 const struct netlbl_lsm_secattr *secattr) 1765{ 1766 int ret_val; 1767 u32 iter; 1768 1769 if (buf_len <= CIPSO_V4_HDR_LEN) 1770 return -ENOSPC; 1771 1772 /* XXX - This code assumes only one tag per CIPSO option which isn't 1773 * really a good assumption to make but since we only support the MAC 1774 * tags right now it is a safe assumption. */ 1775 iter = 0; 1776 do { 1777 memset(buf, 0, buf_len); 1778 switch (doi_def->tags[iter]) { 1779 case CIPSO_V4_TAG_RBITMAP: 1780 ret_val = cipso_v4_gentag_rbm(doi_def, 1781 secattr, 1782 &buf[CIPSO_V4_HDR_LEN], 1783 buf_len - CIPSO_V4_HDR_LEN); 1784 break; 1785 case CIPSO_V4_TAG_ENUM: 1786 ret_val = cipso_v4_gentag_enum(doi_def, 1787 secattr, 1788 &buf[CIPSO_V4_HDR_LEN], 1789 buf_len - CIPSO_V4_HDR_LEN); 1790 break; 1791 case CIPSO_V4_TAG_RANGE: 1792 ret_val = cipso_v4_gentag_rng(doi_def, 1793 secattr, 1794 &buf[CIPSO_V4_HDR_LEN], 1795 buf_len - CIPSO_V4_HDR_LEN); 1796 break; 1797 case CIPSO_V4_TAG_LOCAL: 1798 ret_val = cipso_v4_gentag_loc(doi_def, 1799 secattr, 1800 &buf[CIPSO_V4_HDR_LEN], 1801 buf_len - CIPSO_V4_HDR_LEN); 1802 break; 1803 default: 1804 return -EPERM; 1805 } 1806 1807 iter++; 1808 } while (ret_val < 0 && 1809 iter < CIPSO_V4_TAG_MAXCNT && 1810 doi_def->tags[iter] != CIPSO_V4_TAG_INVALID); 1811 if (ret_val < 0) 1812 return ret_val; 1813 cipso_v4_gentag_hdr(doi_def, buf, ret_val); 1814 return CIPSO_V4_HDR_LEN + ret_val; 1815} 1816 1817/** 1818 * cipso_v4_sock_setattr - Add a CIPSO option to a socket 1819 * @sk: the socket 1820 * @doi_def: the CIPSO DOI to use 1821 * @secattr: the specific security attributes of the socket 1822 * 1823 * Description: 1824 * Set the CIPSO option on the given socket using the DOI definition and 1825 * security attributes passed to the function. This function requires 1826 * exclusive access to @sk, which means it either needs to be in the 1827 * process of being created or locked. Returns zero on success and negative 1828 * values on failure. 1829 * 1830 */ 1831int cipso_v4_sock_setattr(struct sock *sk, 1832 const struct cipso_v4_doi *doi_def, 1833 const struct netlbl_lsm_secattr *secattr) 1834{ 1835 int ret_val = -EPERM; 1836 unsigned char *buf = NULL; 1837 u32 buf_len; 1838 u32 opt_len; 1839 struct ip_options_rcu *old, *opt = NULL; 1840 struct inet_sock *sk_inet; 1841 struct inet_connection_sock *sk_conn; 1842 1843 /* In the case of sock_create_lite(), the sock->sk field is not 1844 * defined yet but it is not a problem as the only users of these 1845 * "lite" PF_INET sockets are functions which do an accept() call 1846 * afterwards so we will label the socket as part of the accept(). */ 1847 if (!sk) 1848 return 0; 1849 1850 /* We allocate the maximum CIPSO option size here so we are probably 1851 * being a little wasteful, but it makes our life _much_ easier later 1852 * on and after all we are only talking about 40 bytes. */ 1853 buf_len = CIPSO_V4_OPT_LEN_MAX; 1854 buf = kmalloc(buf_len, GFP_ATOMIC); 1855 if (!buf) { 1856 ret_val = -ENOMEM; 1857 goto socket_setattr_failure; 1858 } 1859 1860 ret_val = cipso_v4_genopt(buf, buf_len, doi_def, secattr); 1861 if (ret_val < 0) 1862 goto socket_setattr_failure; 1863 buf_len = ret_val; 1864 1865 /* We can't use ip_options_get() directly because it makes a call to 1866 * ip_options_get_alloc() which allocates memory with GFP_KERNEL and 1867 * we won't always have CAP_NET_RAW even though we _always_ want to 1868 * set the IPOPT_CIPSO option. */ 1869 opt_len = (buf_len + 3) & ~3; 1870 opt = kzalloc(sizeof(*opt) + opt_len, GFP_ATOMIC); 1871 if (!opt) { 1872 ret_val = -ENOMEM; 1873 goto socket_setattr_failure; 1874 } 1875 memcpy(opt->opt.__data, buf, buf_len); 1876 opt->opt.optlen = opt_len; 1877 opt->opt.cipso = sizeof(struct iphdr); 1878 kfree(buf); 1879 buf = NULL; 1880 1881 sk_inet = inet_sk(sk); 1882 1883 old = rcu_dereference_protected(sk_inet->inet_opt, 1884 lockdep_sock_is_held(sk)); 1885 if (sk_inet->is_icsk) { 1886 sk_conn = inet_csk(sk); 1887 if (old) 1888 sk_conn->icsk_ext_hdr_len -= old->opt.optlen; 1889 sk_conn->icsk_ext_hdr_len += opt->opt.optlen; 1890 sk_conn->icsk_sync_mss(sk, sk_conn->icsk_pmtu_cookie); 1891 } 1892 rcu_assign_pointer(sk_inet->inet_opt, opt); 1893 if (old) 1894 kfree_rcu(old, rcu); 1895 1896 return 0; 1897 1898socket_setattr_failure: 1899 kfree(buf); 1900 kfree(opt); 1901 return ret_val; 1902} 1903 1904/** 1905 * cipso_v4_req_setattr - Add a CIPSO option to a connection request socket 1906 * @req: the connection request socket 1907 * @doi_def: the CIPSO DOI to use 1908 * @secattr: the specific security attributes of the socket 1909 * 1910 * Description: 1911 * Set the CIPSO option on the given socket using the DOI definition and 1912 * security attributes passed to the function. Returns zero on success and 1913 * negative values on failure. 1914 * 1915 */ 1916int cipso_v4_req_setattr(struct request_sock *req, 1917 const struct cipso_v4_doi *doi_def, 1918 const struct netlbl_lsm_secattr *secattr) 1919{ 1920 int ret_val = -EPERM; 1921 unsigned char *buf = NULL; 1922 u32 buf_len; 1923 u32 opt_len; 1924 struct ip_options_rcu *opt = NULL; 1925 struct inet_request_sock *req_inet; 1926 1927 /* We allocate the maximum CIPSO option size here so we are probably 1928 * being a little wasteful, but it makes our life _much_ easier later 1929 * on and after all we are only talking about 40 bytes. */ 1930 buf_len = CIPSO_V4_OPT_LEN_MAX; 1931 buf = kmalloc(buf_len, GFP_ATOMIC); 1932 if (!buf) { 1933 ret_val = -ENOMEM; 1934 goto req_setattr_failure; 1935 } 1936 1937 ret_val = cipso_v4_genopt(buf, buf_len, doi_def, secattr); 1938 if (ret_val < 0) 1939 goto req_setattr_failure; 1940 buf_len = ret_val; 1941 1942 /* We can't use ip_options_get() directly because it makes a call to 1943 * ip_options_get_alloc() which allocates memory with GFP_KERNEL and 1944 * we won't always have CAP_NET_RAW even though we _always_ want to 1945 * set the IPOPT_CIPSO option. */ 1946 opt_len = (buf_len + 3) & ~3; 1947 opt = kzalloc(sizeof(*opt) + opt_len, GFP_ATOMIC); 1948 if (!opt) { 1949 ret_val = -ENOMEM; 1950 goto req_setattr_failure; 1951 } 1952 memcpy(opt->opt.__data, buf, buf_len); 1953 opt->opt.optlen = opt_len; 1954 opt->opt.cipso = sizeof(struct iphdr); 1955 kfree(buf); 1956 buf = NULL; 1957 1958 req_inet = inet_rsk(req); 1959 opt = xchg((__force struct ip_options_rcu **)&req_inet->ireq_opt, opt); 1960 if (opt) 1961 kfree_rcu(opt, rcu); 1962 1963 return 0; 1964 1965req_setattr_failure: 1966 kfree(buf); 1967 kfree(opt); 1968 return ret_val; 1969} 1970 1971/** 1972 * cipso_v4_delopt - Delete the CIPSO option from a set of IP options 1973 * @opt_ptr: IP option pointer 1974 * 1975 * Description: 1976 * Deletes the CIPSO IP option from a set of IP options and makes the necessary 1977 * adjustments to the IP option structure. Returns zero on success, negative 1978 * values on failure. 1979 * 1980 */ 1981static int cipso_v4_delopt(struct ip_options_rcu __rcu **opt_ptr) 1982{ 1983 struct ip_options_rcu *opt = rcu_dereference_protected(*opt_ptr, 1); 1984 int hdr_delta = 0; 1985 1986 if (!opt || opt->opt.cipso == 0) 1987 return 0; 1988 if (opt->opt.srr || opt->opt.rr || opt->opt.ts || opt->opt.router_alert) { 1989 u8 cipso_len; 1990 u8 cipso_off; 1991 unsigned char *cipso_ptr; 1992 int iter; 1993 int optlen_new; 1994 1995 cipso_off = opt->opt.cipso - sizeof(struct iphdr); 1996 cipso_ptr = &opt->opt.__data[cipso_off]; 1997 cipso_len = cipso_ptr[1]; 1998 1999 if (opt->opt.srr > opt->opt.cipso) 2000 opt->opt.srr -= cipso_len; 2001 if (opt->opt.rr > opt->opt.cipso) 2002 opt->opt.rr -= cipso_len; 2003 if (opt->opt.ts > opt->opt.cipso) 2004 opt->opt.ts -= cipso_len; 2005 if (opt->opt.router_alert > opt->opt.cipso) 2006 opt->opt.router_alert -= cipso_len; 2007 opt->opt.cipso = 0; 2008 2009 memmove(cipso_ptr, cipso_ptr + cipso_len, 2010 opt->opt.optlen - cipso_off - cipso_len); 2011 2012 /* determining the new total option length is tricky because of 2013 * the padding necessary, the only thing i can think to do at 2014 * this point is walk the options one-by-one, skipping the 2015 * padding at the end to determine the actual option size and 2016 * from there we can determine the new total option length */ 2017 iter = 0; 2018 optlen_new = 0; 2019 while (iter < opt->opt.optlen) 2020 if (opt->opt.__data[iter] != IPOPT_NOP) { 2021 iter += opt->opt.__data[iter + 1]; 2022 optlen_new = iter; 2023 } else 2024 iter++; 2025 hdr_delta = opt->opt.optlen; 2026 opt->opt.optlen = (optlen_new + 3) & ~3; 2027 hdr_delta -= opt->opt.optlen; 2028 } else { 2029 /* only the cipso option was present on the socket so we can 2030 * remove the entire option struct */ 2031 *opt_ptr = NULL; 2032 hdr_delta = opt->opt.optlen; 2033 kfree_rcu(opt, rcu); 2034 } 2035 2036 return hdr_delta; 2037} 2038 2039/** 2040 * cipso_v4_sock_delattr - Delete the CIPSO option from a socket 2041 * @sk: the socket 2042 * 2043 * Description: 2044 * Removes the CIPSO option from a socket, if present. 2045 * 2046 */ 2047void cipso_v4_sock_delattr(struct sock *sk) 2048{ 2049 struct inet_sock *sk_inet; 2050 int hdr_delta; 2051 2052 sk_inet = inet_sk(sk); 2053 2054 hdr_delta = cipso_v4_delopt(&sk_inet->inet_opt); 2055 if (sk_inet->is_icsk && hdr_delta > 0) { 2056 struct inet_connection_sock *sk_conn = inet_csk(sk); 2057 sk_conn->icsk_ext_hdr_len -= hdr_delta; 2058 sk_conn->icsk_sync_mss(sk, sk_conn->icsk_pmtu_cookie); 2059 } 2060} 2061 2062/** 2063 * cipso_v4_req_delattr - Delete the CIPSO option from a request socket 2064 * @req: the request socket 2065 * 2066 * Description: 2067 * Removes the CIPSO option from a request socket, if present. 2068 * 2069 */ 2070void cipso_v4_req_delattr(struct request_sock *req) 2071{ 2072 cipso_v4_delopt(&inet_rsk(req)->ireq_opt); 2073} 2074 2075/** 2076 * cipso_v4_getattr - Helper function for the cipso_v4_*_getattr functions 2077 * @cipso: the CIPSO v4 option 2078 * @secattr: the security attributes 2079 * 2080 * Description: 2081 * Inspect @cipso and return the security attributes in @secattr. Returns zero 2082 * on success and negative values on failure. 2083 * 2084 */ 2085int cipso_v4_getattr(const unsigned char *cipso, 2086 struct netlbl_lsm_secattr *secattr) 2087{ 2088 int ret_val = -ENOMSG; 2089 u32 doi; 2090 struct cipso_v4_doi *doi_def; 2091 2092 if (cipso_v4_cache_check(cipso, cipso[1], secattr) == 0) 2093 return 0; 2094 2095 doi = get_unaligned_be32(&cipso[2]); 2096 rcu_read_lock(); 2097 doi_def = cipso_v4_doi_search(doi); 2098 if (!doi_def) 2099 goto getattr_return; 2100 /* XXX - This code assumes only one tag per CIPSO option which isn't 2101 * really a good assumption to make but since we only support the MAC 2102 * tags right now it is a safe assumption. */ 2103 switch (cipso[6]) { 2104 case CIPSO_V4_TAG_RBITMAP: 2105 ret_val = cipso_v4_parsetag_rbm(doi_def, &cipso[6], secattr); 2106 break; 2107 case CIPSO_V4_TAG_ENUM: 2108 ret_val = cipso_v4_parsetag_enum(doi_def, &cipso[6], secattr); 2109 break; 2110 case CIPSO_V4_TAG_RANGE: 2111 ret_val = cipso_v4_parsetag_rng(doi_def, &cipso[6], secattr); 2112 break; 2113 case CIPSO_V4_TAG_LOCAL: 2114 ret_val = cipso_v4_parsetag_loc(doi_def, &cipso[6], secattr); 2115 break; 2116 } 2117 if (ret_val == 0) 2118 secattr->type = NETLBL_NLTYPE_CIPSOV4; 2119 2120getattr_return: 2121 rcu_read_unlock(); 2122 return ret_val; 2123} 2124 2125/** 2126 * cipso_v4_sock_getattr - Get the security attributes from a sock 2127 * @sk: the sock 2128 * @secattr: the security attributes 2129 * 2130 * Description: 2131 * Query @sk to see if there is a CIPSO option attached to the sock and if 2132 * there is return the CIPSO security attributes in @secattr. This function 2133 * requires that @sk be locked, or privately held, but it does not do any 2134 * locking itself. Returns zero on success and negative values on failure. 2135 * 2136 */ 2137int cipso_v4_sock_getattr(struct sock *sk, struct netlbl_lsm_secattr *secattr) 2138{ 2139 struct ip_options_rcu *opt; 2140 int res = -ENOMSG; 2141 2142 rcu_read_lock(); 2143 opt = rcu_dereference(inet_sk(sk)->inet_opt); 2144 if (opt && opt->opt.cipso) 2145 res = cipso_v4_getattr(opt->opt.__data + 2146 opt->opt.cipso - 2147 sizeof(struct iphdr), 2148 secattr); 2149 rcu_read_unlock(); 2150 return res; 2151} 2152 2153/** 2154 * cipso_v4_skbuff_setattr - Set the CIPSO option on a packet 2155 * @skb: the packet 2156 * @doi_def: the DOI structure 2157 * @secattr: the security attributes 2158 * 2159 * Description: 2160 * Set the CIPSO option on the given packet based on the security attributes. 2161 * Returns a pointer to the IP header on success and NULL on failure. 2162 * 2163 */ 2164int cipso_v4_skbuff_setattr(struct sk_buff *skb, 2165 const struct cipso_v4_doi *doi_def, 2166 const struct netlbl_lsm_secattr *secattr) 2167{ 2168 int ret_val; 2169 struct iphdr *iph; 2170 struct ip_options *opt = &IPCB(skb)->opt; 2171 unsigned char buf[CIPSO_V4_OPT_LEN_MAX]; 2172 u32 buf_len = CIPSO_V4_OPT_LEN_MAX; 2173 u32 opt_len; 2174 int len_delta; 2175 2176 ret_val = cipso_v4_genopt(buf, buf_len, doi_def, secattr); 2177 if (ret_val < 0) 2178 return ret_val; 2179 buf_len = ret_val; 2180 opt_len = (buf_len + 3) & ~3; 2181 2182 /* we overwrite any existing options to ensure that we have enough 2183 * room for the CIPSO option, the reason is that we _need_ to guarantee 2184 * that the security label is applied to the packet - we do the same 2185 * thing when using the socket options and it hasn't caused a problem, 2186 * if we need to we can always revisit this choice later */ 2187 2188 len_delta = opt_len - opt->optlen; 2189 /* if we don't ensure enough headroom we could panic on the skb_push() 2190 * call below so make sure we have enough, we are also "mangling" the 2191 * packet so we should probably do a copy-on-write call anyway */ 2192 ret_val = skb_cow(skb, skb_headroom(skb) + len_delta); 2193 if (ret_val < 0) 2194 return ret_val; 2195 2196 if (len_delta > 0) { 2197 /* we assume that the header + opt->optlen have already been 2198 * "pushed" in ip_options_build() or similar */ 2199 iph = ip_hdr(skb); 2200 skb_push(skb, len_delta); 2201 memmove((char *)iph - len_delta, iph, iph->ihl << 2); 2202 skb_reset_network_header(skb); 2203 iph = ip_hdr(skb); 2204 } else if (len_delta < 0) { 2205 iph = ip_hdr(skb); 2206 memset(iph + 1, IPOPT_NOP, opt->optlen); 2207 } else 2208 iph = ip_hdr(skb); 2209 2210 if (opt->optlen > 0) 2211 memset(opt, 0, sizeof(*opt)); 2212 opt->optlen = opt_len; 2213 opt->cipso = sizeof(struct iphdr); 2214 opt->is_changed = 1; 2215 2216 /* we have to do the following because we are being called from a 2217 * netfilter hook which means the packet already has had the header 2218 * fields populated and the checksum calculated - yes this means we 2219 * are doing more work than needed but we do it to keep the core 2220 * stack clean and tidy */ 2221 memcpy(iph + 1, buf, buf_len); 2222 if (opt_len > buf_len) 2223 memset((char *)(iph + 1) + buf_len, 0, opt_len - buf_len); 2224 if (len_delta != 0) { 2225 iph->ihl = 5 + (opt_len >> 2); 2226 iph->tot_len = htons(skb->len); 2227 } 2228 ip_send_check(iph); 2229 2230 return 0; 2231} 2232 2233/** 2234 * cipso_v4_skbuff_delattr - Delete any CIPSO options from a packet 2235 * @skb: the packet 2236 * 2237 * Description: 2238 * Removes any and all CIPSO options from the given packet. Returns zero on 2239 * success, negative values on failure. 2240 * 2241 */ 2242int cipso_v4_skbuff_delattr(struct sk_buff *skb) 2243{ 2244 int ret_val; 2245 struct iphdr *iph; 2246 struct ip_options *opt = &IPCB(skb)->opt; 2247 unsigned char *cipso_ptr; 2248 2249 if (opt->cipso == 0) 2250 return 0; 2251 2252 /* since we are changing the packet we should make a copy */ 2253 ret_val = skb_cow(skb, skb_headroom(skb)); 2254 if (ret_val < 0) 2255 return ret_val; 2256 2257 /* the easiest thing to do is just replace the cipso option with noop 2258 * options since we don't change the size of the packet, although we 2259 * still need to recalculate the checksum */ 2260 2261 iph = ip_hdr(skb); 2262 cipso_ptr = (unsigned char *)iph + opt->cipso; 2263 memset(cipso_ptr, IPOPT_NOOP, cipso_ptr[1]); 2264 opt->cipso = 0; 2265 opt->is_changed = 1; 2266 2267 ip_send_check(iph); 2268 2269 return 0; 2270} 2271 2272/* 2273 * Setup Functions 2274 */ 2275 2276/** 2277 * cipso_v4_init - Initialize the CIPSO module 2278 * 2279 * Description: 2280 * Initialize the CIPSO module and prepare it for use. Returns zero on success 2281 * and negative values on failure. 2282 * 2283 */ 2284static int __init cipso_v4_init(void) 2285{ 2286 int ret_val; 2287 2288 ret_val = cipso_v4_cache_init(); 2289 if (ret_val != 0) 2290 panic("Failed to initialize the CIPSO/IPv4 cache (%d)\n", 2291 ret_val); 2292 2293 return 0; 2294} 2295 2296subsys_initcall(cipso_v4_init); 2297