1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * NetLabel Kernel API 4 * 5 * This file defines the kernel API for the NetLabel system. The NetLabel 6 * system manages static and dynamic label mappings for network protocols such 7 * as CIPSO and RIPSO. 8 * 9 * Author: Paul Moore <paul@paul-moore.com> 10 */ 11 12 /* 13 * (c) Copyright Hewlett-Packard Development Company, L.P., 2006, 2008 14 */ 15 16 #include <linux/init.h> 17 #include <linux/types.h> 18 #include <linux/slab.h> 19 #include <linux/audit.h> 20 #include <linux/in.h> 21 #include <linux/in6.h> 22 #include <net/ip.h> 23 #include <net/ipv6.h> 24 #include <net/netlabel.h> 25 #include <net/cipso_ipv4.h> 26 #include <net/calipso.h> 27 #include <asm/bug.h> 28 #include <linux/atomic.h> 29 30 #include "netlabel_domainhash.h" 31 #include "netlabel_unlabeled.h" 32 #include "netlabel_cipso_v4.h" 33 #include "netlabel_calipso.h" 34 #include "netlabel_user.h" 35 #include "netlabel_mgmt.h" 36 #include "netlabel_addrlist.h" 37 38 /* 39 * Configuration Functions 40 */ 41 42 /** 43 * netlbl_cfg_map_del - Remove a NetLabel/LSM domain mapping 44 * @domain: the domain mapping to remove 45 * @family: address family 46 * @addr: IP address 47 * @mask: IP address mask 48 * @audit_info: NetLabel audit information 49 * 50 * Description: 51 * Removes a NetLabel/LSM domain mapping. A @domain value of NULL causes the 52 * default domain mapping to be removed. Returns zero on success, negative 53 * values on failure. 54 * 55 */ 56 int netlbl_cfg_map_del(const char *domain, 57 u16 family, 58 const void *addr, 59 const void *mask, 60 struct netlbl_audit *audit_info) 61 { 62 if (addr == NULL && mask == NULL) { 63 return netlbl_domhsh_remove(domain, family, audit_info); 64 } else if (addr != NULL && mask != NULL) { 65 switch (family) { 66 case AF_INET: 67 return netlbl_domhsh_remove_af4(domain, addr, mask, 68 audit_info); 69 #if IS_ENABLED(CONFIG_IPV6) 70 case AF_INET6: 71 return netlbl_domhsh_remove_af6(domain, addr, mask, 72 audit_info); 73 #endif /* IPv6 */ 74 default: 75 return -EPFNOSUPPORT; 76 } 77 } else 78 return -EINVAL; 79 } 80 81 /** 82 * netlbl_cfg_unlbl_map_add - Add a new unlabeled mapping 83 * @domain: the domain mapping to add 84 * @family: address family 85 * @addr: IP address 86 * @mask: IP address mask 87 * @audit_info: NetLabel audit information 88 * 89 * Description: 90 * Adds a new unlabeled NetLabel/LSM domain mapping. A @domain value of NULL 91 * causes a new default domain mapping to be added. Returns zero on success, 92 * negative values on failure. 93 * 94 */ 95 int netlbl_cfg_unlbl_map_add(const char *domain, 96 u16 family, 97 const void *addr, 98 const void *mask, 99 struct netlbl_audit *audit_info) 100 { 101 int ret_val = -ENOMEM; 102 struct netlbl_dom_map *entry; 103 struct netlbl_domaddr_map *addrmap = NULL; 104 struct netlbl_domaddr4_map *map4 = NULL; 105 struct netlbl_domaddr6_map *map6 = NULL; 106 107 entry = kzalloc(sizeof(*entry), GFP_ATOMIC); 108 if (entry == NULL) 109 return -ENOMEM; 110 if (domain != NULL) { 111 entry->domain = kstrdup(domain, GFP_ATOMIC); 112 if (entry->domain == NULL) 113 goto cfg_unlbl_map_add_failure; 114 } 115 entry->family = family; 116 117 if (addr == NULL && mask == NULL) 118 entry->def.type = NETLBL_NLTYPE_UNLABELED; 119 else if (addr != NULL && mask != NULL) { 120 addrmap = kzalloc(sizeof(*addrmap), GFP_ATOMIC); 121 if (addrmap == NULL) 122 goto cfg_unlbl_map_add_failure; 123 INIT_LIST_HEAD(&addrmap->list4); 124 INIT_LIST_HEAD(&addrmap->list6); 125 126 switch (family) { 127 case AF_INET: { 128 const struct in_addr *addr4 = addr; 129 const struct in_addr *mask4 = mask; 130 map4 = kzalloc(sizeof(*map4), GFP_ATOMIC); 131 if (map4 == NULL) 132 goto cfg_unlbl_map_add_failure; 133 map4->def.type = NETLBL_NLTYPE_UNLABELED; 134 map4->list.addr = addr4->s_addr & mask4->s_addr; 135 map4->list.mask = mask4->s_addr; 136 map4->list.valid = 1; 137 ret_val = netlbl_af4list_add(&map4->list, 138 &addrmap->list4); 139 if (ret_val != 0) 140 goto cfg_unlbl_map_add_failure; 141 break; 142 } 143 #if IS_ENABLED(CONFIG_IPV6) 144 case AF_INET6: { 145 const struct in6_addr *addr6 = addr; 146 const struct in6_addr *mask6 = mask; 147 map6 = kzalloc(sizeof(*map6), GFP_ATOMIC); 148 if (map6 == NULL) 149 goto cfg_unlbl_map_add_failure; 150 map6->def.type = NETLBL_NLTYPE_UNLABELED; 151 map6->list.addr = *addr6; 152 map6->list.addr.s6_addr32[0] &= mask6->s6_addr32[0]; 153 map6->list.addr.s6_addr32[1] &= mask6->s6_addr32[1]; 154 map6->list.addr.s6_addr32[2] &= mask6->s6_addr32[2]; 155 map6->list.addr.s6_addr32[3] &= mask6->s6_addr32[3]; 156 map6->list.mask = *mask6; 157 map6->list.valid = 1; 158 ret_val = netlbl_af6list_add(&map6->list, 159 &addrmap->list6); 160 if (ret_val != 0) 161 goto cfg_unlbl_map_add_failure; 162 break; 163 } 164 #endif /* IPv6 */ 165 default: 166 goto cfg_unlbl_map_add_failure; 167 } 168 169 entry->def.addrsel = addrmap; 170 entry->def.type = NETLBL_NLTYPE_ADDRSELECT; 171 } else { 172 ret_val = -EINVAL; 173 goto cfg_unlbl_map_add_failure; 174 } 175 176 ret_val = netlbl_domhsh_add(entry, audit_info); 177 if (ret_val != 0) 178 goto cfg_unlbl_map_add_failure; 179 180 return 0; 181 182 cfg_unlbl_map_add_failure: 183 kfree(entry->domain); 184 kfree(entry); 185 kfree(addrmap); 186 kfree(map4); 187 kfree(map6); 188 return ret_val; 189 } 190 191 192 /** 193 * netlbl_cfg_unlbl_static_add - Adds a new static label 194 * @net: network namespace 195 * @dev_name: interface name 196 * @addr: IP address in network byte order (struct in[6]_addr) 197 * @mask: address mask in network byte order (struct in[6]_addr) 198 * @family: address family 199 * @secid: LSM secid value for the entry 200 * @audit_info: NetLabel audit information 201 * 202 * Description: 203 * Adds a new NetLabel static label to be used when protocol provided labels 204 * are not present on incoming traffic. If @dev_name is NULL then the default 205 * interface will be used. Returns zero on success, negative values on failure. 206 * 207 */ 208 int netlbl_cfg_unlbl_static_add(struct net *net, 209 const char *dev_name, 210 const void *addr, 211 const void *mask, 212 u16 family, 213 u32 secid, 214 struct netlbl_audit *audit_info) 215 { 216 u32 addr_len; 217 218 switch (family) { 219 case AF_INET: 220 addr_len = sizeof(struct in_addr); 221 break; 222 #if IS_ENABLED(CONFIG_IPV6) 223 case AF_INET6: 224 addr_len = sizeof(struct in6_addr); 225 break; 226 #endif /* IPv6 */ 227 default: 228 return -EPFNOSUPPORT; 229 } 230 231 return netlbl_unlhsh_add(net, 232 dev_name, addr, mask, addr_len, 233 secid, audit_info); 234 } 235 236 /** 237 * netlbl_cfg_unlbl_static_del - Removes an existing static label 238 * @net: network namespace 239 * @dev_name: interface name 240 * @addr: IP address in network byte order (struct in[6]_addr) 241 * @mask: address mask in network byte order (struct in[6]_addr) 242 * @family: address family 243 * @audit_info: NetLabel audit information 244 * 245 * Description: 246 * Removes an existing NetLabel static label used when protocol provided labels 247 * are not present on incoming traffic. If @dev_name is NULL then the default 248 * interface will be used. Returns zero on success, negative values on failure. 249 * 250 */ 251 int netlbl_cfg_unlbl_static_del(struct net *net, 252 const char *dev_name, 253 const void *addr, 254 const void *mask, 255 u16 family, 256 struct netlbl_audit *audit_info) 257 { 258 u32 addr_len; 259 260 switch (family) { 261 case AF_INET: 262 addr_len = sizeof(struct in_addr); 263 break; 264 #if IS_ENABLED(CONFIG_IPV6) 265 case AF_INET6: 266 addr_len = sizeof(struct in6_addr); 267 break; 268 #endif /* IPv6 */ 269 default: 270 return -EPFNOSUPPORT; 271 } 272 273 return netlbl_unlhsh_remove(net, 274 dev_name, addr, mask, addr_len, 275 audit_info); 276 } 277 278 /** 279 * netlbl_cfg_cipsov4_add - Add a new CIPSOv4 DOI definition 280 * @doi_def: CIPSO DOI definition 281 * @audit_info: NetLabel audit information 282 * 283 * Description: 284 * Add a new CIPSO DOI definition as defined by @doi_def. Returns zero on 285 * success and negative values on failure. 286 * 287 */ 288 int netlbl_cfg_cipsov4_add(struct cipso_v4_doi *doi_def, 289 struct netlbl_audit *audit_info) 290 { 291 return cipso_v4_doi_add(doi_def, audit_info); 292 } 293 294 /** 295 * netlbl_cfg_cipsov4_del - Remove an existing CIPSOv4 DOI definition 296 * @doi: CIPSO DOI 297 * @audit_info: NetLabel audit information 298 * 299 * Description: 300 * Remove an existing CIPSO DOI definition matching @doi. Returns zero on 301 * success and negative values on failure. 302 * 303 */ 304 void netlbl_cfg_cipsov4_del(u32 doi, struct netlbl_audit *audit_info) 305 { 306 cipso_v4_doi_remove(doi, audit_info); 307 } 308 309 /** 310 * netlbl_cfg_cipsov4_map_add - Add a new CIPSOv4 DOI mapping 311 * @doi: the CIPSO DOI 312 * @domain: the domain mapping to add 313 * @addr: IP address 314 * @mask: IP address mask 315 * @audit_info: NetLabel audit information 316 * 317 * Description: 318 * Add a new NetLabel/LSM domain mapping for the given CIPSO DOI to the NetLabel 319 * subsystem. A @domain value of NULL adds a new default domain mapping. 320 * Returns zero on success, negative values on failure. 321 * 322 */ 323 int netlbl_cfg_cipsov4_map_add(u32 doi, 324 const char *domain, 325 const struct in_addr *addr, 326 const struct in_addr *mask, 327 struct netlbl_audit *audit_info) 328 { 329 int ret_val = -ENOMEM; 330 struct cipso_v4_doi *doi_def; 331 struct netlbl_dom_map *entry; 332 struct netlbl_domaddr_map *addrmap = NULL; 333 struct netlbl_domaddr4_map *addrinfo = NULL; 334 335 doi_def = cipso_v4_doi_getdef(doi); 336 if (doi_def == NULL) 337 return -ENOENT; 338 339 entry = kzalloc(sizeof(*entry), GFP_ATOMIC); 340 if (entry == NULL) 341 goto out_entry; 342 entry->family = AF_INET; 343 if (domain != NULL) { 344 entry->domain = kstrdup(domain, GFP_ATOMIC); 345 if (entry->domain == NULL) 346 goto out_domain; 347 } 348 349 if (addr == NULL && mask == NULL) { 350 entry->def.cipso = doi_def; 351 entry->def.type = NETLBL_NLTYPE_CIPSOV4; 352 } else if (addr != NULL && mask != NULL) { 353 addrmap = kzalloc(sizeof(*addrmap), GFP_ATOMIC); 354 if (addrmap == NULL) 355 goto out_addrmap; 356 INIT_LIST_HEAD(&addrmap->list4); 357 INIT_LIST_HEAD(&addrmap->list6); 358 359 addrinfo = kzalloc(sizeof(*addrinfo), GFP_ATOMIC); 360 if (addrinfo == NULL) 361 goto out_addrinfo; 362 addrinfo->def.cipso = doi_def; 363 addrinfo->def.type = NETLBL_NLTYPE_CIPSOV4; 364 addrinfo->list.addr = addr->s_addr & mask->s_addr; 365 addrinfo->list.mask = mask->s_addr; 366 addrinfo->list.valid = 1; 367 ret_val = netlbl_af4list_add(&addrinfo->list, &addrmap->list4); 368 if (ret_val != 0) 369 goto cfg_cipsov4_map_add_failure; 370 371 entry->def.addrsel = addrmap; 372 entry->def.type = NETLBL_NLTYPE_ADDRSELECT; 373 } else { 374 ret_val = -EINVAL; 375 goto out_addrmap; 376 } 377 378 ret_val = netlbl_domhsh_add(entry, audit_info); 379 if (ret_val != 0) 380 goto cfg_cipsov4_map_add_failure; 381 382 return 0; 383 384 cfg_cipsov4_map_add_failure: 385 kfree(addrinfo); 386 out_addrinfo: 387 kfree(addrmap); 388 out_addrmap: 389 kfree(entry->domain); 390 out_domain: 391 kfree(entry); 392 out_entry: 393 cipso_v4_doi_putdef(doi_def); 394 return ret_val; 395 } 396 397 /** 398 * netlbl_cfg_calipso_add - Add a new CALIPSO DOI definition 399 * @doi_def: CALIPSO DOI definition 400 * @audit_info: NetLabel audit information 401 * 402 * Description: 403 * Add a new CALIPSO DOI definition as defined by @doi_def. Returns zero on 404 * success and negative values on failure. 405 * 406 */ 407 int netlbl_cfg_calipso_add(struct calipso_doi *doi_def, 408 struct netlbl_audit *audit_info) 409 { 410 #if IS_ENABLED(CONFIG_IPV6) 411 return calipso_doi_add(doi_def, audit_info); 412 #else /* IPv6 */ 413 return -ENOSYS; 414 #endif /* IPv6 */ 415 } 416 417 /** 418 * netlbl_cfg_calipso_del - Remove an existing CALIPSO DOI definition 419 * @doi: CALIPSO DOI 420 * @audit_info: NetLabel audit information 421 * 422 * Description: 423 * Remove an existing CALIPSO DOI definition matching @doi. Returns zero on 424 * success and negative values on failure. 425 * 426 */ 427 void netlbl_cfg_calipso_del(u32 doi, struct netlbl_audit *audit_info) 428 { 429 #if IS_ENABLED(CONFIG_IPV6) 430 calipso_doi_remove(doi, audit_info); 431 #endif /* IPv6 */ 432 } 433 434 /** 435 * netlbl_cfg_calipso_map_add - Add a new CALIPSO DOI mapping 436 * @doi: the CALIPSO DOI 437 * @domain: the domain mapping to add 438 * @addr: IP address 439 * @mask: IP address mask 440 * @audit_info: NetLabel audit information 441 * 442 * Description: 443 * Add a new NetLabel/LSM domain mapping for the given CALIPSO DOI to the 444 * NetLabel subsystem. A @domain value of NULL adds a new default domain 445 * mapping. Returns zero on success, negative values on failure. 446 * 447 */ 448 int netlbl_cfg_calipso_map_add(u32 doi, 449 const char *domain, 450 const struct in6_addr *addr, 451 const struct in6_addr *mask, 452 struct netlbl_audit *audit_info) 453 { 454 #if IS_ENABLED(CONFIG_IPV6) 455 int ret_val = -ENOMEM; 456 struct calipso_doi *doi_def; 457 struct netlbl_dom_map *entry; 458 struct netlbl_domaddr_map *addrmap = NULL; 459 struct netlbl_domaddr6_map *addrinfo = NULL; 460 461 doi_def = calipso_doi_getdef(doi); 462 if (doi_def == NULL) 463 return -ENOENT; 464 465 entry = kzalloc(sizeof(*entry), GFP_ATOMIC); 466 if (entry == NULL) 467 goto out_entry; 468 entry->family = AF_INET6; 469 if (domain != NULL) { 470 entry->domain = kstrdup(domain, GFP_ATOMIC); 471 if (entry->domain == NULL) 472 goto out_domain; 473 } 474 475 if (addr == NULL && mask == NULL) { 476 entry->def.calipso = doi_def; 477 entry->def.type = NETLBL_NLTYPE_CALIPSO; 478 } else if (addr != NULL && mask != NULL) { 479 addrmap = kzalloc(sizeof(*addrmap), GFP_ATOMIC); 480 if (addrmap == NULL) 481 goto out_addrmap; 482 INIT_LIST_HEAD(&addrmap->list4); 483 INIT_LIST_HEAD(&addrmap->list6); 484 485 addrinfo = kzalloc(sizeof(*addrinfo), GFP_ATOMIC); 486 if (addrinfo == NULL) 487 goto out_addrinfo; 488 addrinfo->def.calipso = doi_def; 489 addrinfo->def.type = NETLBL_NLTYPE_CALIPSO; 490 addrinfo->list.addr = *addr; 491 addrinfo->list.addr.s6_addr32[0] &= mask->s6_addr32[0]; 492 addrinfo->list.addr.s6_addr32[1] &= mask->s6_addr32[1]; 493 addrinfo->list.addr.s6_addr32[2] &= mask->s6_addr32[2]; 494 addrinfo->list.addr.s6_addr32[3] &= mask->s6_addr32[3]; 495 addrinfo->list.mask = *mask; 496 addrinfo->list.valid = 1; 497 ret_val = netlbl_af6list_add(&addrinfo->list, &addrmap->list6); 498 if (ret_val != 0) 499 goto cfg_calipso_map_add_failure; 500 501 entry->def.addrsel = addrmap; 502 entry->def.type = NETLBL_NLTYPE_ADDRSELECT; 503 } else { 504 ret_val = -EINVAL; 505 goto out_addrmap; 506 } 507 508 ret_val = netlbl_domhsh_add(entry, audit_info); 509 if (ret_val != 0) 510 goto cfg_calipso_map_add_failure; 511 512 return 0; 513 514 cfg_calipso_map_add_failure: 515 kfree(addrinfo); 516 out_addrinfo: 517 kfree(addrmap); 518 out_addrmap: 519 kfree(entry->domain); 520 out_domain: 521 kfree(entry); 522 out_entry: 523 calipso_doi_putdef(doi_def); 524 return ret_val; 525 #else /* IPv6 */ 526 return -ENOSYS; 527 #endif /* IPv6 */ 528 } 529 530 /* 531 * Security Attribute Functions 532 */ 533 534 #define _CM_F_NONE 0x00000000 535 #define _CM_F_ALLOC 0x00000001 536 #define _CM_F_WALK 0x00000002 537 538 /** 539 * _netlbl_catmap_getnode - Get a individual node from a catmap 540 * @catmap: pointer to the category bitmap 541 * @offset: the requested offset 542 * @cm_flags: catmap flags, see _CM_F_* 543 * @gfp_flags: memory allocation flags 544 * 545 * Description: 546 * Iterate through the catmap looking for the node associated with @offset. 547 * If the _CM_F_ALLOC flag is set in @cm_flags and there is no associated node, 548 * one will be created and inserted into the catmap. If the _CM_F_WALK flag is 549 * set in @cm_flags and there is no associated node, the next highest node will 550 * be returned. Returns a pointer to the node on success, NULL on failure. 551 * 552 */ 553 static struct netlbl_lsm_catmap *_netlbl_catmap_getnode( 554 struct netlbl_lsm_catmap **catmap, 555 u32 offset, 556 unsigned int cm_flags, 557 gfp_t gfp_flags) 558 { 559 struct netlbl_lsm_catmap *iter = *catmap; 560 struct netlbl_lsm_catmap *prev = NULL; 561 562 if (iter == NULL) 563 goto catmap_getnode_alloc; 564 if (offset < iter->startbit) 565 goto catmap_getnode_walk; 566 while (iter && offset >= (iter->startbit + NETLBL_CATMAP_SIZE)) { 567 prev = iter; 568 iter = iter->next; 569 } 570 if (iter == NULL || offset < iter->startbit) 571 goto catmap_getnode_walk; 572 573 return iter; 574 575 catmap_getnode_walk: 576 if (cm_flags & _CM_F_WALK) 577 return iter; 578 catmap_getnode_alloc: 579 if (!(cm_flags & _CM_F_ALLOC)) 580 return NULL; 581 582 iter = netlbl_catmap_alloc(gfp_flags); 583 if (iter == NULL) 584 return NULL; 585 iter->startbit = offset & ~(NETLBL_CATMAP_SIZE - 1); 586 587 if (prev == NULL) { 588 iter->next = *catmap; 589 *catmap = iter; 590 } else { 591 iter->next = prev->next; 592 prev->next = iter; 593 } 594 595 return iter; 596 } 597 598 /** 599 * netlbl_catmap_walk - Walk a LSM secattr catmap looking for a bit 600 * @catmap: the category bitmap 601 * @offset: the offset to start searching at, in bits 602 * 603 * Description: 604 * This function walks a LSM secattr category bitmap starting at @offset and 605 * returns the spot of the first set bit or -ENOENT if no bits are set. 606 * 607 */ 608 int netlbl_catmap_walk(struct netlbl_lsm_catmap *catmap, u32 offset) 609 { 610 struct netlbl_lsm_catmap *iter; 611 u32 idx; 612 u32 bit; 613 u64 bitmap; 614 615 iter = _netlbl_catmap_getnode(&catmap, offset, _CM_F_WALK, 0); 616 if (iter == NULL) 617 return -ENOENT; 618 if (offset > iter->startbit) { 619 offset -= iter->startbit; 620 idx = offset / NETLBL_CATMAP_MAPSIZE; 621 bit = offset % NETLBL_CATMAP_MAPSIZE; 622 } else { 623 idx = 0; 624 bit = 0; 625 } 626 bitmap = iter->bitmap[idx] >> bit; 627 628 for (;;) { 629 if (bitmap != 0) { 630 while ((bitmap & NETLBL_CATMAP_BIT) == 0) { 631 bitmap >>= 1; 632 bit++; 633 } 634 return iter->startbit + 635 (NETLBL_CATMAP_MAPSIZE * idx) + bit; 636 } 637 if (++idx >= NETLBL_CATMAP_MAPCNT) { 638 if (iter->next != NULL) { 639 iter = iter->next; 640 idx = 0; 641 } else 642 return -ENOENT; 643 } 644 bitmap = iter->bitmap[idx]; 645 bit = 0; 646 } 647 648 return -ENOENT; 649 } 650 EXPORT_SYMBOL(netlbl_catmap_walk); 651 652 /** 653 * netlbl_catmap_walkrng - Find the end of a string of set bits 654 * @catmap: the category bitmap 655 * @offset: the offset to start searching at, in bits 656 * 657 * Description: 658 * This function walks a LSM secattr category bitmap starting at @offset and 659 * returns the spot of the first cleared bit or -ENOENT if the offset is past 660 * the end of the bitmap. 661 * 662 */ 663 int netlbl_catmap_walkrng(struct netlbl_lsm_catmap *catmap, u32 offset) 664 { 665 struct netlbl_lsm_catmap *iter; 666 struct netlbl_lsm_catmap *prev = NULL; 667 u32 idx; 668 u32 bit; 669 u64 bitmask; 670 u64 bitmap; 671 672 iter = _netlbl_catmap_getnode(&catmap, offset, _CM_F_WALK, 0); 673 if (iter == NULL) 674 return -ENOENT; 675 if (offset > iter->startbit) { 676 offset -= iter->startbit; 677 idx = offset / NETLBL_CATMAP_MAPSIZE; 678 bit = offset % NETLBL_CATMAP_MAPSIZE; 679 } else { 680 idx = 0; 681 bit = 0; 682 } 683 bitmask = NETLBL_CATMAP_BIT << bit; 684 685 for (;;) { 686 bitmap = iter->bitmap[idx]; 687 while (bitmask != 0 && (bitmap & bitmask) != 0) { 688 bitmask <<= 1; 689 bit++; 690 } 691 692 if (prev && idx == 0 && bit == 0) 693 return prev->startbit + NETLBL_CATMAP_SIZE - 1; 694 else if (bitmask != 0) 695 return iter->startbit + 696 (NETLBL_CATMAP_MAPSIZE * idx) + bit - 1; 697 else if (++idx >= NETLBL_CATMAP_MAPCNT) { 698 if (iter->next == NULL) 699 return iter->startbit + NETLBL_CATMAP_SIZE - 1; 700 prev = iter; 701 iter = iter->next; 702 idx = 0; 703 } 704 bitmask = NETLBL_CATMAP_BIT; 705 bit = 0; 706 } 707 708 return -ENOENT; 709 } 710 711 /** 712 * netlbl_catmap_getlong - Export an unsigned long bitmap 713 * @catmap: pointer to the category bitmap 714 * @offset: pointer to the requested offset 715 * @bitmap: the exported bitmap 716 * 717 * Description: 718 * Export a bitmap with an offset greater than or equal to @offset and return 719 * it in @bitmap. The @offset must be aligned to an unsigned long and will be 720 * updated on return if different from what was requested; if the catmap is 721 * empty at the requested offset and beyond, the @offset is set to (u32)-1. 722 * Returns zero on success, negative values on failure. 723 * 724 */ 725 int netlbl_catmap_getlong(struct netlbl_lsm_catmap *catmap, 726 u32 *offset, 727 unsigned long *bitmap) 728 { 729 struct netlbl_lsm_catmap *iter; 730 u32 off = *offset; 731 u32 idx; 732 733 /* only allow aligned offsets */ 734 if ((off & (BITS_PER_LONG - 1)) != 0) 735 return -EINVAL; 736 737 /* a null catmap is equivalent to an empty one */ 738 if (!catmap) { 739 *offset = (u32)-1; 740 return 0; 741 } 742 743 if (off < catmap->startbit) { 744 off = catmap->startbit; 745 *offset = off; 746 } 747 iter = _netlbl_catmap_getnode(&catmap, off, _CM_F_WALK, 0); 748 if (iter == NULL) { 749 *offset = (u32)-1; 750 return 0; 751 } 752 753 if (off < iter->startbit) { 754 *offset = iter->startbit; 755 off = 0; 756 } else 757 off -= iter->startbit; 758 idx = off / NETLBL_CATMAP_MAPSIZE; 759 *bitmap = iter->bitmap[idx] >> (off % NETLBL_CATMAP_MAPSIZE); 760 761 return 0; 762 } 763 764 /** 765 * netlbl_catmap_setbit - Set a bit in a LSM secattr catmap 766 * @catmap: pointer to the category bitmap 767 * @bit: the bit to set 768 * @flags: memory allocation flags 769 * 770 * Description: 771 * Set the bit specified by @bit in @catmap. Returns zero on success, 772 * negative values on failure. 773 * 774 */ 775 int netlbl_catmap_setbit(struct netlbl_lsm_catmap **catmap, 776 u32 bit, 777 gfp_t flags) 778 { 779 struct netlbl_lsm_catmap *iter; 780 u32 idx; 781 782 iter = _netlbl_catmap_getnode(catmap, bit, _CM_F_ALLOC, flags); 783 if (iter == NULL) 784 return -ENOMEM; 785 786 bit -= iter->startbit; 787 idx = bit / NETLBL_CATMAP_MAPSIZE; 788 iter->bitmap[idx] |= NETLBL_CATMAP_BIT << (bit % NETLBL_CATMAP_MAPSIZE); 789 790 return 0; 791 } 792 EXPORT_SYMBOL(netlbl_catmap_setbit); 793 794 /** 795 * netlbl_catmap_setrng - Set a range of bits in a LSM secattr catmap 796 * @catmap: pointer to the category bitmap 797 * @start: the starting bit 798 * @end: the last bit in the string 799 * @flags: memory allocation flags 800 * 801 * Description: 802 * Set a range of bits, starting at @start and ending with @end. Returns zero 803 * on success, negative values on failure. 804 * 805 */ 806 int netlbl_catmap_setrng(struct netlbl_lsm_catmap **catmap, 807 u32 start, 808 u32 end, 809 gfp_t flags) 810 { 811 int rc = 0; 812 u32 spot = start; 813 814 while (rc == 0 && spot <= end) { 815 if (((spot & (BITS_PER_LONG - 1)) == 0) && 816 ((end - spot) > BITS_PER_LONG)) { 817 rc = netlbl_catmap_setlong(catmap, 818 spot, 819 (unsigned long)-1, 820 flags); 821 spot += BITS_PER_LONG; 822 } else 823 rc = netlbl_catmap_setbit(catmap, spot++, flags); 824 } 825 826 return rc; 827 } 828 829 /** 830 * netlbl_catmap_setlong - Import an unsigned long bitmap 831 * @catmap: pointer to the category bitmap 832 * @offset: offset to the start of the imported bitmap 833 * @bitmap: the bitmap to import 834 * @flags: memory allocation flags 835 * 836 * Description: 837 * Import the bitmap specified in @bitmap into @catmap, using the offset 838 * in @offset. The offset must be aligned to an unsigned long. Returns zero 839 * on success, negative values on failure. 840 * 841 */ 842 int netlbl_catmap_setlong(struct netlbl_lsm_catmap **catmap, 843 u32 offset, 844 unsigned long bitmap, 845 gfp_t flags) 846 { 847 struct netlbl_lsm_catmap *iter; 848 u32 idx; 849 850 /* only allow aligned offsets */ 851 if ((offset & (BITS_PER_LONG - 1)) != 0) 852 return -EINVAL; 853 854 iter = _netlbl_catmap_getnode(catmap, offset, _CM_F_ALLOC, flags); 855 if (iter == NULL) 856 return -ENOMEM; 857 858 offset -= iter->startbit; 859 idx = offset / NETLBL_CATMAP_MAPSIZE; 860 iter->bitmap[idx] |= (u64)bitmap 861 << (offset % NETLBL_CATMAP_MAPSIZE); 862 863 return 0; 864 } 865 866 /* Bitmap functions 867 */ 868 869 /** 870 * netlbl_bitmap_walk - Walk a bitmap looking for a bit 871 * @bitmap: the bitmap 872 * @bitmap_len: length in bits 873 * @offset: starting offset 874 * @state: if non-zero, look for a set (1) bit else look for a cleared (0) bit 875 * 876 * Description: 877 * Starting at @offset, walk the bitmap from left to right until either the 878 * desired bit is found or we reach the end. Return the bit offset, -1 if 879 * not found. 880 */ 881 int netlbl_bitmap_walk(const unsigned char *bitmap, u32 bitmap_len, 882 u32 offset, u8 state) 883 { 884 u32 bit_spot; 885 u32 byte_offset; 886 unsigned char bitmask; 887 unsigned char byte; 888 889 if (offset >= bitmap_len) 890 return -1; 891 byte_offset = offset / 8; 892 byte = bitmap[byte_offset]; 893 bit_spot = offset; 894 bitmask = 0x80 >> (offset % 8); 895 896 while (bit_spot < bitmap_len) { 897 if ((state && (byte & bitmask) == bitmask) || 898 (state == 0 && (byte & bitmask) == 0)) 899 return bit_spot; 900 901 if (++bit_spot >= bitmap_len) 902 return -1; 903 bitmask >>= 1; 904 if (bitmask == 0) { 905 byte = bitmap[++byte_offset]; 906 bitmask = 0x80; 907 } 908 } 909 910 return -1; 911 } 912 EXPORT_SYMBOL(netlbl_bitmap_walk); 913 914 /** 915 * netlbl_bitmap_setbit - Sets a single bit in a bitmap 916 * @bitmap: the bitmap 917 * @bit: the bit 918 * @state: if non-zero, set the bit (1) else clear the bit (0) 919 * 920 * Description: 921 * Set a single bit in the bitmask. Returns zero on success, negative values 922 * on error. 923 */ 924 void netlbl_bitmap_setbit(unsigned char *bitmap, u32 bit, u8 state) 925 { 926 u32 byte_spot; 927 u8 bitmask; 928 929 /* gcc always rounds to zero when doing integer division */ 930 byte_spot = bit / 8; 931 bitmask = 0x80 >> (bit % 8); 932 if (state) 933 bitmap[byte_spot] |= bitmask; 934 else 935 bitmap[byte_spot] &= ~bitmask; 936 } 937 EXPORT_SYMBOL(netlbl_bitmap_setbit); 938 939 /* 940 * LSM Functions 941 */ 942 943 /** 944 * netlbl_enabled - Determine if the NetLabel subsystem is enabled 945 * 946 * Description: 947 * The LSM can use this function to determine if it should use NetLabel 948 * security attributes in it's enforcement mechanism. Currently, NetLabel is 949 * considered to be enabled when it's configuration contains a valid setup for 950 * at least one labeled protocol (i.e. NetLabel can understand incoming 951 * labeled packets of at least one type); otherwise NetLabel is considered to 952 * be disabled. 953 * 954 */ 955 int netlbl_enabled(void) 956 { 957 /* At some point we probably want to expose this mechanism to the user 958 * as well so that admins can toggle NetLabel regardless of the 959 * configuration */ 960 return (atomic_read(&netlabel_mgmt_protocount) > 0); 961 } 962 963 /** 964 * netlbl_sock_setattr - Label a socket using the correct protocol 965 * @sk: the socket to label 966 * @family: protocol family 967 * @secattr: the security attributes 968 * @sk_locked: true if caller holds the socket lock 969 * 970 * Description: 971 * Attach the correct label to the given socket using the security attributes 972 * specified in @secattr. This function requires exclusive access to @sk, 973 * which means it either needs to be in the process of being created or locked. 974 * Returns zero on success, -EDESTADDRREQ if the domain is configured to use 975 * network address selectors (can't blindly label the socket), and negative 976 * values on all other failures. 977 * 978 */ 979 int netlbl_sock_setattr(struct sock *sk, 980 u16 family, 981 const struct netlbl_lsm_secattr *secattr, 982 bool sk_locked) 983 { 984 int ret_val; 985 struct netlbl_dom_map *dom_entry; 986 987 rcu_read_lock(); 988 dom_entry = netlbl_domhsh_getentry(secattr->domain, family); 989 if (dom_entry == NULL) { 990 ret_val = -ENOENT; 991 goto socket_setattr_return; 992 } 993 switch (family) { 994 case AF_INET: 995 switch (dom_entry->def.type) { 996 case NETLBL_NLTYPE_ADDRSELECT: 997 ret_val = -EDESTADDRREQ; 998 break; 999 case NETLBL_NLTYPE_CIPSOV4: 1000 ret_val = cipso_v4_sock_setattr(sk, 1001 dom_entry->def.cipso, 1002 secattr, sk_locked); 1003 break; 1004 case NETLBL_NLTYPE_UNLABELED: 1005 ret_val = 0; 1006 break; 1007 default: 1008 ret_val = -ENOENT; 1009 } 1010 break; 1011 #if IS_ENABLED(CONFIG_IPV6) 1012 case AF_INET6: 1013 switch (dom_entry->def.type) { 1014 case NETLBL_NLTYPE_ADDRSELECT: 1015 ret_val = -EDESTADDRREQ; 1016 break; 1017 case NETLBL_NLTYPE_CALIPSO: 1018 ret_val = calipso_sock_setattr(sk, 1019 dom_entry->def.calipso, 1020 secattr); 1021 break; 1022 case NETLBL_NLTYPE_UNLABELED: 1023 ret_val = 0; 1024 break; 1025 default: 1026 ret_val = -ENOENT; 1027 } 1028 break; 1029 #endif /* IPv6 */ 1030 default: 1031 ret_val = -EPROTONOSUPPORT; 1032 } 1033 1034 socket_setattr_return: 1035 rcu_read_unlock(); 1036 return ret_val; 1037 } 1038 1039 /** 1040 * netlbl_sock_delattr - Delete all the NetLabel labels on a socket 1041 * @sk: the socket 1042 * 1043 * Description: 1044 * Remove all the NetLabel labeling from @sk. The caller is responsible for 1045 * ensuring that @sk is locked. 1046 * 1047 */ 1048 void netlbl_sock_delattr(struct sock *sk) 1049 { 1050 switch (sk->sk_family) { 1051 case AF_INET: 1052 cipso_v4_sock_delattr(sk); 1053 break; 1054 #if IS_ENABLED(CONFIG_IPV6) 1055 case AF_INET6: 1056 calipso_sock_delattr(sk); 1057 break; 1058 #endif /* IPv6 */ 1059 } 1060 } 1061 1062 /** 1063 * netlbl_sock_getattr - Determine the security attributes of a sock 1064 * @sk: the sock 1065 * @secattr: the security attributes 1066 * 1067 * Description: 1068 * Examines the given sock to see if any NetLabel style labeling has been 1069 * applied to the sock, if so it parses the socket label and returns the 1070 * security attributes in @secattr. Returns zero on success, negative values 1071 * on failure. 1072 * 1073 */ 1074 int netlbl_sock_getattr(struct sock *sk, 1075 struct netlbl_lsm_secattr *secattr) 1076 { 1077 int ret_val; 1078 1079 switch (sk->sk_family) { 1080 case AF_INET: 1081 ret_val = cipso_v4_sock_getattr(sk, secattr); 1082 break; 1083 #if IS_ENABLED(CONFIG_IPV6) 1084 case AF_INET6: 1085 ret_val = calipso_sock_getattr(sk, secattr); 1086 break; 1087 #endif /* IPv6 */ 1088 default: 1089 ret_val = -EPROTONOSUPPORT; 1090 } 1091 1092 return ret_val; 1093 } 1094 1095 /** 1096 * netlbl_sk_lock_check - Check if the socket lock has been acquired. 1097 * @sk: the socket to be checked 1098 * 1099 * Return: true if socket @sk is locked or if lock debugging is disabled at 1100 * runtime or compile-time; false otherwise 1101 * 1102 */ 1103 #ifdef CONFIG_LOCKDEP 1104 bool netlbl_sk_lock_check(struct sock *sk) 1105 { 1106 if (debug_locks) 1107 return lockdep_sock_is_held(sk); 1108 return true; 1109 } 1110 #else 1111 bool netlbl_sk_lock_check(struct sock *sk) 1112 { 1113 return true; 1114 } 1115 #endif 1116 1117 /** 1118 * netlbl_conn_setattr - Label a connected socket using the correct protocol 1119 * @sk: the socket to label 1120 * @addr: the destination address 1121 * @secattr: the security attributes 1122 * 1123 * Description: 1124 * Attach the correct label to the given connected socket using the security 1125 * attributes specified in @secattr. The caller is responsible for ensuring 1126 * that @sk is locked. Returns zero on success, negative values on failure. 1127 * 1128 */ 1129 int netlbl_conn_setattr(struct sock *sk, 1130 struct sockaddr *addr, 1131 const struct netlbl_lsm_secattr *secattr) 1132 { 1133 int ret_val; 1134 struct sockaddr_in *addr4; 1135 #if IS_ENABLED(CONFIG_IPV6) 1136 struct sockaddr_in6 *addr6; 1137 #endif 1138 struct netlbl_dommap_def *entry; 1139 1140 rcu_read_lock(); 1141 switch (addr->sa_family) { 1142 case AF_INET: 1143 addr4 = (struct sockaddr_in *)addr; 1144 entry = netlbl_domhsh_getentry_af4(secattr->domain, 1145 addr4->sin_addr.s_addr); 1146 if (entry == NULL) { 1147 ret_val = -ENOENT; 1148 goto conn_setattr_return; 1149 } 1150 switch (entry->type) { 1151 case NETLBL_NLTYPE_CIPSOV4: 1152 ret_val = cipso_v4_sock_setattr(sk, 1153 entry->cipso, secattr, 1154 netlbl_sk_lock_check(sk)); 1155 break; 1156 case NETLBL_NLTYPE_UNLABELED: 1157 /* just delete the protocols we support for right now 1158 * but we could remove other protocols if needed */ 1159 netlbl_sock_delattr(sk); 1160 ret_val = 0; 1161 break; 1162 default: 1163 ret_val = -ENOENT; 1164 } 1165 break; 1166 #if IS_ENABLED(CONFIG_IPV6) 1167 case AF_INET6: 1168 addr6 = (struct sockaddr_in6 *)addr; 1169 entry = netlbl_domhsh_getentry_af6(secattr->domain, 1170 &addr6->sin6_addr); 1171 if (entry == NULL) { 1172 ret_val = -ENOENT; 1173 goto conn_setattr_return; 1174 } 1175 switch (entry->type) { 1176 case NETLBL_NLTYPE_CALIPSO: 1177 ret_val = calipso_sock_setattr(sk, 1178 entry->calipso, secattr); 1179 break; 1180 case NETLBL_NLTYPE_UNLABELED: 1181 /* just delete the protocols we support for right now 1182 * but we could remove other protocols if needed */ 1183 netlbl_sock_delattr(sk); 1184 ret_val = 0; 1185 break; 1186 default: 1187 ret_val = -ENOENT; 1188 } 1189 break; 1190 #endif /* IPv6 */ 1191 default: 1192 ret_val = -EPROTONOSUPPORT; 1193 } 1194 1195 conn_setattr_return: 1196 rcu_read_unlock(); 1197 return ret_val; 1198 } 1199 1200 /** 1201 * netlbl_req_setattr - Label a request socket using the correct protocol 1202 * @req: the request socket to label 1203 * @secattr: the security attributes 1204 * 1205 * Description: 1206 * Attach the correct label to the given socket using the security attributes 1207 * specified in @secattr. Returns zero on success, negative values on failure. 1208 * 1209 */ 1210 int netlbl_req_setattr(struct request_sock *req, 1211 const struct netlbl_lsm_secattr *secattr) 1212 { 1213 int ret_val; 1214 struct netlbl_dommap_def *entry; 1215 struct inet_request_sock *ireq = inet_rsk(req); 1216 1217 rcu_read_lock(); 1218 switch (req->rsk_ops->family) { 1219 case AF_INET: 1220 entry = netlbl_domhsh_getentry_af4(secattr->domain, 1221 ireq->ir_rmt_addr); 1222 if (entry == NULL) { 1223 ret_val = -ENOENT; 1224 goto req_setattr_return; 1225 } 1226 switch (entry->type) { 1227 case NETLBL_NLTYPE_CIPSOV4: 1228 ret_val = cipso_v4_req_setattr(req, 1229 entry->cipso, secattr); 1230 break; 1231 case NETLBL_NLTYPE_UNLABELED: 1232 netlbl_req_delattr(req); 1233 ret_val = 0; 1234 break; 1235 default: 1236 ret_val = -ENOENT; 1237 } 1238 break; 1239 #if IS_ENABLED(CONFIG_IPV6) 1240 case AF_INET6: 1241 entry = netlbl_domhsh_getentry_af6(secattr->domain, 1242 &ireq->ir_v6_rmt_addr); 1243 if (entry == NULL) { 1244 ret_val = -ENOENT; 1245 goto req_setattr_return; 1246 } 1247 switch (entry->type) { 1248 case NETLBL_NLTYPE_CALIPSO: 1249 ret_val = calipso_req_setattr(req, 1250 entry->calipso, secattr); 1251 break; 1252 case NETLBL_NLTYPE_UNLABELED: 1253 netlbl_req_delattr(req); 1254 ret_val = 0; 1255 break; 1256 default: 1257 ret_val = -ENOENT; 1258 } 1259 break; 1260 #endif /* IPv6 */ 1261 default: 1262 ret_val = -EPROTONOSUPPORT; 1263 } 1264 1265 req_setattr_return: 1266 rcu_read_unlock(); 1267 return ret_val; 1268 } 1269 1270 /** 1271 * netlbl_req_delattr - Delete all the NetLabel labels on a socket 1272 * @req: the socket 1273 * 1274 * Description: 1275 * Remove all the NetLabel labeling from @req. 1276 * 1277 */ 1278 void netlbl_req_delattr(struct request_sock *req) 1279 { 1280 switch (req->rsk_ops->family) { 1281 case AF_INET: 1282 cipso_v4_req_delattr(req); 1283 break; 1284 #if IS_ENABLED(CONFIG_IPV6) 1285 case AF_INET6: 1286 calipso_req_delattr(req); 1287 break; 1288 #endif /* IPv6 */ 1289 } 1290 } 1291 1292 /** 1293 * netlbl_skbuff_setattr - Label a packet using the correct protocol 1294 * @skb: the packet 1295 * @family: protocol family 1296 * @secattr: the security attributes 1297 * 1298 * Description: 1299 * Attach the correct label to the given packet using the security attributes 1300 * specified in @secattr. Returns zero on success, negative values on failure. 1301 * 1302 */ 1303 int netlbl_skbuff_setattr(struct sk_buff *skb, 1304 u16 family, 1305 const struct netlbl_lsm_secattr *secattr) 1306 { 1307 int ret_val; 1308 struct iphdr *hdr4; 1309 #if IS_ENABLED(CONFIG_IPV6) 1310 struct ipv6hdr *hdr6; 1311 #endif 1312 struct netlbl_dommap_def *entry; 1313 1314 rcu_read_lock(); 1315 switch (family) { 1316 case AF_INET: 1317 hdr4 = ip_hdr(skb); 1318 entry = netlbl_domhsh_getentry_af4(secattr->domain, 1319 hdr4->daddr); 1320 if (entry == NULL) { 1321 ret_val = -ENOENT; 1322 goto skbuff_setattr_return; 1323 } 1324 switch (entry->type) { 1325 case NETLBL_NLTYPE_CIPSOV4: 1326 ret_val = cipso_v4_skbuff_setattr(skb, entry->cipso, 1327 secattr); 1328 break; 1329 case NETLBL_NLTYPE_UNLABELED: 1330 /* just delete the protocols we support for right now 1331 * but we could remove other protocols if needed */ 1332 ret_val = cipso_v4_skbuff_delattr(skb); 1333 break; 1334 default: 1335 ret_val = -ENOENT; 1336 } 1337 break; 1338 #if IS_ENABLED(CONFIG_IPV6) 1339 case AF_INET6: 1340 hdr6 = ipv6_hdr(skb); 1341 entry = netlbl_domhsh_getentry_af6(secattr->domain, 1342 &hdr6->daddr); 1343 if (entry == NULL) { 1344 ret_val = -ENOENT; 1345 goto skbuff_setattr_return; 1346 } 1347 switch (entry->type) { 1348 case NETLBL_NLTYPE_CALIPSO: 1349 ret_val = calipso_skbuff_setattr(skb, entry->calipso, 1350 secattr); 1351 break; 1352 case NETLBL_NLTYPE_UNLABELED: 1353 /* just delete the protocols we support for right now 1354 * but we could remove other protocols if needed */ 1355 ret_val = calipso_skbuff_delattr(skb); 1356 break; 1357 default: 1358 ret_val = -ENOENT; 1359 } 1360 break; 1361 #endif /* IPv6 */ 1362 default: 1363 ret_val = -EPROTONOSUPPORT; 1364 } 1365 1366 skbuff_setattr_return: 1367 rcu_read_unlock(); 1368 return ret_val; 1369 } 1370 1371 /** 1372 * netlbl_skbuff_getattr - Determine the security attributes of a packet 1373 * @skb: the packet 1374 * @family: protocol family 1375 * @secattr: the security attributes 1376 * 1377 * Description: 1378 * Examines the given packet to see if a recognized form of packet labeling 1379 * is present, if so it parses the packet label and returns the security 1380 * attributes in @secattr. Returns zero on success, negative values on 1381 * failure. 1382 * 1383 */ 1384 int netlbl_skbuff_getattr(const struct sk_buff *skb, 1385 u16 family, 1386 struct netlbl_lsm_secattr *secattr) 1387 { 1388 unsigned char *ptr; 1389 1390 switch (family) { 1391 case AF_INET: 1392 ptr = cipso_v4_optptr(skb); 1393 if (ptr && cipso_v4_getattr(ptr, secattr) == 0) 1394 return 0; 1395 break; 1396 #if IS_ENABLED(CONFIG_IPV6) 1397 case AF_INET6: 1398 ptr = calipso_optptr(skb); 1399 if (ptr && calipso_getattr(ptr, secattr) == 0) 1400 return 0; 1401 break; 1402 #endif /* IPv6 */ 1403 } 1404 1405 return netlbl_unlabel_getattr(skb, family, secattr); 1406 } 1407 1408 /** 1409 * netlbl_skbuff_err - Handle a LSM error on a sk_buff 1410 * @skb: the packet 1411 * @family: the family 1412 * @error: the error code 1413 * @gateway: true if host is acting as a gateway, false otherwise 1414 * 1415 * Description: 1416 * Deal with a LSM problem when handling the packet in @skb, typically this is 1417 * a permission denied problem (-EACCES). The correct action is determined 1418 * according to the packet's labeling protocol. 1419 * 1420 */ 1421 void netlbl_skbuff_err(struct sk_buff *skb, u16 family, int error, int gateway) 1422 { 1423 switch (family) { 1424 case AF_INET: 1425 if (cipso_v4_optptr(skb)) 1426 cipso_v4_error(skb, error, gateway); 1427 break; 1428 } 1429 } 1430 1431 /** 1432 * netlbl_cache_invalidate - Invalidate all of the NetLabel protocol caches 1433 * 1434 * Description: 1435 * For all of the NetLabel protocols that support some form of label mapping 1436 * cache, invalidate the cache. Returns zero on success, negative values on 1437 * error. 1438 * 1439 */ 1440 void netlbl_cache_invalidate(void) 1441 { 1442 cipso_v4_cache_invalidate(); 1443 #if IS_ENABLED(CONFIG_IPV6) 1444 calipso_cache_invalidate(); 1445 #endif /* IPv6 */ 1446 } 1447 1448 /** 1449 * netlbl_cache_add - Add an entry to a NetLabel protocol cache 1450 * @skb: the packet 1451 * @family: the family 1452 * @secattr: the packet's security attributes 1453 * 1454 * Description: 1455 * Add the LSM security attributes for the given packet to the underlying 1456 * NetLabel protocol's label mapping cache. Returns zero on success, negative 1457 * values on error. 1458 * 1459 */ 1460 int netlbl_cache_add(const struct sk_buff *skb, u16 family, 1461 const struct netlbl_lsm_secattr *secattr) 1462 { 1463 unsigned char *ptr; 1464 1465 if ((secattr->flags & NETLBL_SECATTR_CACHE) == 0) 1466 return -ENOMSG; 1467 1468 switch (family) { 1469 case AF_INET: 1470 ptr = cipso_v4_optptr(skb); 1471 if (ptr) 1472 return cipso_v4_cache_add(ptr, secattr); 1473 break; 1474 #if IS_ENABLED(CONFIG_IPV6) 1475 case AF_INET6: 1476 ptr = calipso_optptr(skb); 1477 if (ptr) 1478 return calipso_cache_add(ptr, secattr); 1479 break; 1480 #endif /* IPv6 */ 1481 } 1482 return -ENOMSG; 1483 } 1484 1485 /* 1486 * Protocol Engine Functions 1487 */ 1488 1489 /** 1490 * netlbl_audit_start - Start an audit message 1491 * @type: audit message type 1492 * @audit_info: NetLabel audit information 1493 * 1494 * Description: 1495 * Start an audit message using the type specified in @type and fill the audit 1496 * message with some fields common to all NetLabel audit messages. This 1497 * function should only be used by protocol engines, not LSMs. Returns a 1498 * pointer to the audit buffer on success, NULL on failure. 1499 * 1500 */ 1501 struct audit_buffer *netlbl_audit_start(int type, 1502 struct netlbl_audit *audit_info) 1503 { 1504 return netlbl_audit_start_common(type, audit_info); 1505 } 1506 EXPORT_SYMBOL(netlbl_audit_start); 1507 1508 /* 1509 * Setup Functions 1510 */ 1511 1512 /** 1513 * netlbl_init - Initialize NetLabel 1514 * 1515 * Description: 1516 * Perform the required NetLabel initialization before first use. 1517 * 1518 */ 1519 static int __init netlbl_init(void) 1520 { 1521 int ret_val; 1522 1523 printk(KERN_INFO "NetLabel: Initializing\n"); 1524 printk(KERN_INFO "NetLabel: domain hash size = %u\n", 1525 (1 << NETLBL_DOMHSH_BITSIZE)); 1526 printk(KERN_INFO "NetLabel: protocols = UNLABELED CIPSOv4 CALIPSO\n"); 1527 1528 ret_val = netlbl_domhsh_init(NETLBL_DOMHSH_BITSIZE); 1529 if (ret_val != 0) 1530 goto init_failure; 1531 1532 ret_val = netlbl_unlabel_init(NETLBL_UNLHSH_BITSIZE); 1533 if (ret_val != 0) 1534 goto init_failure; 1535 1536 ret_val = netlbl_netlink_init(); 1537 if (ret_val != 0) 1538 goto init_failure; 1539 1540 ret_val = netlbl_unlabel_defconf(); 1541 if (ret_val != 0) 1542 goto init_failure; 1543 printk(KERN_INFO "NetLabel: unlabeled traffic allowed by default\n"); 1544 1545 return 0; 1546 1547 init_failure: 1548 panic("NetLabel: failed to initialize properly (%d)\n", ret_val); 1549 } 1550 1551 subsys_initcall(netlbl_init); 1552