1 /* 2 * NetLabel Kernel API 3 * 4 * This file defines the kernel API for the NetLabel system. The NetLabel 5 * system manages static and dynamic label mappings for network protocols such 6 * as CIPSO and RIPSO. 7 * 8 * Author: Paul Moore <paul@paul-moore.com> 9 * 10 */ 11 12 /* 13 * (c) Copyright Hewlett-Packard Development Company, L.P., 2006, 2008 14 * 15 * This program is free software; you can redistribute it and/or modify 16 * it under the terms of the GNU General Public License as published by 17 * the Free Software Foundation; either version 2 of the License, or 18 * (at your option) any later version. 19 * 20 * This program is distributed in the hope that it will be useful, 21 * but WITHOUT ANY WARRANTY; without even the implied warranty of 22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 23 * the GNU General Public License for more details. 24 * 25 * You should have received a copy of the GNU General Public License 26 * along with this program; if not, see <http://www.gnu.org/licenses/>. 27 * 28 */ 29 30 #include <linux/init.h> 31 #include <linux/types.h> 32 #include <linux/slab.h> 33 #include <linux/audit.h> 34 #include <linux/in.h> 35 #include <linux/in6.h> 36 #include <net/ip.h> 37 #include <net/ipv6.h> 38 #include <net/netlabel.h> 39 #include <net/cipso_ipv4.h> 40 #include <asm/bug.h> 41 #include <linux/atomic.h> 42 43 #include "netlabel_domainhash.h" 44 #include "netlabel_unlabeled.h" 45 #include "netlabel_cipso_v4.h" 46 #include "netlabel_user.h" 47 #include "netlabel_mgmt.h" 48 #include "netlabel_addrlist.h" 49 50 /* 51 * Configuration Functions 52 */ 53 54 /** 55 * netlbl_cfg_map_del - Remove a NetLabel/LSM domain mapping 56 * @domain: the domain mapping to remove 57 * @family: address family 58 * @addr: IP address 59 * @mask: IP address mask 60 * @audit_info: NetLabel audit information 61 * 62 * Description: 63 * Removes a NetLabel/LSM domain mapping. A @domain value of NULL causes the 64 * default domain mapping to be removed. Returns zero on success, negative 65 * values on failure. 66 * 67 */ 68 int netlbl_cfg_map_del(const char *domain, 69 u16 family, 70 const void *addr, 71 const void *mask, 72 struct netlbl_audit *audit_info) 73 { 74 if (addr == NULL && mask == NULL) { 75 return netlbl_domhsh_remove(domain, audit_info); 76 } else if (addr != NULL && mask != NULL) { 77 switch (family) { 78 case AF_INET: 79 return netlbl_domhsh_remove_af4(domain, addr, mask, 80 audit_info); 81 default: 82 return -EPFNOSUPPORT; 83 } 84 } else 85 return -EINVAL; 86 } 87 88 /** 89 * netlbl_cfg_unlbl_map_add - Add a new unlabeled mapping 90 * @domain: the domain mapping to add 91 * @family: address family 92 * @addr: IP address 93 * @mask: IP address mask 94 * @audit_info: NetLabel audit information 95 * 96 * Description: 97 * Adds a new unlabeled NetLabel/LSM domain mapping. A @domain value of NULL 98 * causes a new default domain mapping to be added. Returns zero on success, 99 * negative values on failure. 100 * 101 */ 102 int netlbl_cfg_unlbl_map_add(const char *domain, 103 u16 family, 104 const void *addr, 105 const void *mask, 106 struct netlbl_audit *audit_info) 107 { 108 int ret_val = -ENOMEM; 109 struct netlbl_dom_map *entry; 110 struct netlbl_domaddr_map *addrmap = NULL; 111 struct netlbl_domaddr4_map *map4 = NULL; 112 struct netlbl_domaddr6_map *map6 = NULL; 113 114 entry = kzalloc(sizeof(*entry), GFP_ATOMIC); 115 if (entry == NULL) 116 return -ENOMEM; 117 if (domain != NULL) { 118 entry->domain = kstrdup(domain, GFP_ATOMIC); 119 if (entry->domain == NULL) 120 goto cfg_unlbl_map_add_failure; 121 } 122 123 if (addr == NULL && mask == NULL) 124 entry->def.type = NETLBL_NLTYPE_UNLABELED; 125 else if (addr != NULL && mask != NULL) { 126 addrmap = kzalloc(sizeof(*addrmap), GFP_ATOMIC); 127 if (addrmap == NULL) 128 goto cfg_unlbl_map_add_failure; 129 INIT_LIST_HEAD(&addrmap->list4); 130 INIT_LIST_HEAD(&addrmap->list6); 131 132 switch (family) { 133 case AF_INET: { 134 const struct in_addr *addr4 = addr; 135 const struct in_addr *mask4 = mask; 136 map4 = kzalloc(sizeof(*map4), GFP_ATOMIC); 137 if (map4 == NULL) 138 goto cfg_unlbl_map_add_failure; 139 map4->def.type = NETLBL_NLTYPE_UNLABELED; 140 map4->list.addr = addr4->s_addr & mask4->s_addr; 141 map4->list.mask = mask4->s_addr; 142 map4->list.valid = 1; 143 ret_val = netlbl_af4list_add(&map4->list, 144 &addrmap->list4); 145 if (ret_val != 0) 146 goto cfg_unlbl_map_add_failure; 147 break; 148 } 149 #if IS_ENABLED(CONFIG_IPV6) 150 case AF_INET6: { 151 const struct in6_addr *addr6 = addr; 152 const struct in6_addr *mask6 = mask; 153 map6 = kzalloc(sizeof(*map6), GFP_ATOMIC); 154 if (map6 == NULL) 155 goto cfg_unlbl_map_add_failure; 156 map6->def.type = NETLBL_NLTYPE_UNLABELED; 157 map6->list.addr = *addr6; 158 map6->list.addr.s6_addr32[0] &= mask6->s6_addr32[0]; 159 map6->list.addr.s6_addr32[1] &= mask6->s6_addr32[1]; 160 map6->list.addr.s6_addr32[2] &= mask6->s6_addr32[2]; 161 map6->list.addr.s6_addr32[3] &= mask6->s6_addr32[3]; 162 map6->list.mask = *mask6; 163 map6->list.valid = 1; 164 ret_val = netlbl_af6list_add(&map6->list, 165 &addrmap->list6); 166 if (ret_val != 0) 167 goto cfg_unlbl_map_add_failure; 168 break; 169 } 170 #endif /* IPv6 */ 171 default: 172 goto cfg_unlbl_map_add_failure; 173 } 174 175 entry->def.addrsel = addrmap; 176 entry->def.type = NETLBL_NLTYPE_ADDRSELECT; 177 } else { 178 ret_val = -EINVAL; 179 goto cfg_unlbl_map_add_failure; 180 } 181 182 ret_val = netlbl_domhsh_add(entry, audit_info); 183 if (ret_val != 0) 184 goto cfg_unlbl_map_add_failure; 185 186 return 0; 187 188 cfg_unlbl_map_add_failure: 189 kfree(entry->domain); 190 kfree(entry); 191 kfree(addrmap); 192 kfree(map4); 193 kfree(map6); 194 return ret_val; 195 } 196 197 198 /** 199 * netlbl_cfg_unlbl_static_add - Adds a new static label 200 * @net: network namespace 201 * @dev_name: interface name 202 * @addr: IP address in network byte order (struct in[6]_addr) 203 * @mask: address mask in network byte order (struct in[6]_addr) 204 * @family: address family 205 * @secid: LSM secid value for the entry 206 * @audit_info: NetLabel audit information 207 * 208 * Description: 209 * Adds a new NetLabel static label to be used when protocol provided labels 210 * are not present on incoming traffic. If @dev_name is NULL then the default 211 * interface will be used. Returns zero on success, negative values on failure. 212 * 213 */ 214 int netlbl_cfg_unlbl_static_add(struct net *net, 215 const char *dev_name, 216 const void *addr, 217 const void *mask, 218 u16 family, 219 u32 secid, 220 struct netlbl_audit *audit_info) 221 { 222 u32 addr_len; 223 224 switch (family) { 225 case AF_INET: 226 addr_len = sizeof(struct in_addr); 227 break; 228 #if IS_ENABLED(CONFIG_IPV6) 229 case AF_INET6: 230 addr_len = sizeof(struct in6_addr); 231 break; 232 #endif /* IPv6 */ 233 default: 234 return -EPFNOSUPPORT; 235 } 236 237 return netlbl_unlhsh_add(net, 238 dev_name, addr, mask, addr_len, 239 secid, audit_info); 240 } 241 242 /** 243 * netlbl_cfg_unlbl_static_del - Removes an existing static label 244 * @net: network namespace 245 * @dev_name: interface name 246 * @addr: IP address in network byte order (struct in[6]_addr) 247 * @mask: address mask in network byte order (struct in[6]_addr) 248 * @family: address family 249 * @audit_info: NetLabel audit information 250 * 251 * Description: 252 * Removes an existing NetLabel static label used when protocol provided labels 253 * are not present on incoming traffic. If @dev_name is NULL then the default 254 * interface will be used. Returns zero on success, negative values on failure. 255 * 256 */ 257 int netlbl_cfg_unlbl_static_del(struct net *net, 258 const char *dev_name, 259 const void *addr, 260 const void *mask, 261 u16 family, 262 struct netlbl_audit *audit_info) 263 { 264 u32 addr_len; 265 266 switch (family) { 267 case AF_INET: 268 addr_len = sizeof(struct in_addr); 269 break; 270 #if IS_ENABLED(CONFIG_IPV6) 271 case AF_INET6: 272 addr_len = sizeof(struct in6_addr); 273 break; 274 #endif /* IPv6 */ 275 default: 276 return -EPFNOSUPPORT; 277 } 278 279 return netlbl_unlhsh_remove(net, 280 dev_name, addr, mask, addr_len, 281 audit_info); 282 } 283 284 /** 285 * netlbl_cfg_cipsov4_add - Add a new CIPSOv4 DOI definition 286 * @doi_def: CIPSO DOI definition 287 * @audit_info: NetLabel audit information 288 * 289 * Description: 290 * Add a new CIPSO DOI definition as defined by @doi_def. Returns zero on 291 * success and negative values on failure. 292 * 293 */ 294 int netlbl_cfg_cipsov4_add(struct cipso_v4_doi *doi_def, 295 struct netlbl_audit *audit_info) 296 { 297 return cipso_v4_doi_add(doi_def, audit_info); 298 } 299 300 /** 301 * netlbl_cfg_cipsov4_del - Remove an existing CIPSOv4 DOI definition 302 * @doi: CIPSO DOI 303 * @audit_info: NetLabel audit information 304 * 305 * Description: 306 * Remove an existing CIPSO DOI definition matching @doi. Returns zero on 307 * success and negative values on failure. 308 * 309 */ 310 void netlbl_cfg_cipsov4_del(u32 doi, struct netlbl_audit *audit_info) 311 { 312 cipso_v4_doi_remove(doi, audit_info); 313 } 314 315 /** 316 * netlbl_cfg_cipsov4_map_add - Add a new CIPSOv4 DOI mapping 317 * @doi: the CIPSO DOI 318 * @domain: the domain mapping to add 319 * @addr: IP address 320 * @mask: IP address mask 321 * @audit_info: NetLabel audit information 322 * 323 * Description: 324 * Add a new NetLabel/LSM domain mapping for the given CIPSO DOI to the NetLabel 325 * subsystem. A @domain value of NULL adds a new default domain mapping. 326 * Returns zero on success, negative values on failure. 327 * 328 */ 329 int netlbl_cfg_cipsov4_map_add(u32 doi, 330 const char *domain, 331 const struct in_addr *addr, 332 const struct in_addr *mask, 333 struct netlbl_audit *audit_info) 334 { 335 int ret_val = -ENOMEM; 336 struct cipso_v4_doi *doi_def; 337 struct netlbl_dom_map *entry; 338 struct netlbl_domaddr_map *addrmap = NULL; 339 struct netlbl_domaddr4_map *addrinfo = NULL; 340 341 doi_def = cipso_v4_doi_getdef(doi); 342 if (doi_def == NULL) 343 return -ENOENT; 344 345 entry = kzalloc(sizeof(*entry), GFP_ATOMIC); 346 if (entry == NULL) 347 goto out_entry; 348 if (domain != NULL) { 349 entry->domain = kstrdup(domain, GFP_ATOMIC); 350 if (entry->domain == NULL) 351 goto out_domain; 352 } 353 354 if (addr == NULL && mask == NULL) { 355 entry->def.cipso = doi_def; 356 entry->def.type = NETLBL_NLTYPE_CIPSOV4; 357 } else if (addr != NULL && mask != NULL) { 358 addrmap = kzalloc(sizeof(*addrmap), GFP_ATOMIC); 359 if (addrmap == NULL) 360 goto out_addrmap; 361 INIT_LIST_HEAD(&addrmap->list4); 362 INIT_LIST_HEAD(&addrmap->list6); 363 364 addrinfo = kzalloc(sizeof(*addrinfo), GFP_ATOMIC); 365 if (addrinfo == NULL) 366 goto out_addrinfo; 367 addrinfo->def.cipso = doi_def; 368 addrinfo->def.type = NETLBL_NLTYPE_CIPSOV4; 369 addrinfo->list.addr = addr->s_addr & mask->s_addr; 370 addrinfo->list.mask = mask->s_addr; 371 addrinfo->list.valid = 1; 372 ret_val = netlbl_af4list_add(&addrinfo->list, &addrmap->list4); 373 if (ret_val != 0) 374 goto cfg_cipsov4_map_add_failure; 375 376 entry->def.addrsel = addrmap; 377 entry->def.type = NETLBL_NLTYPE_ADDRSELECT; 378 } else { 379 ret_val = -EINVAL; 380 goto out_addrmap; 381 } 382 383 ret_val = netlbl_domhsh_add(entry, audit_info); 384 if (ret_val != 0) 385 goto cfg_cipsov4_map_add_failure; 386 387 return 0; 388 389 cfg_cipsov4_map_add_failure: 390 kfree(addrinfo); 391 out_addrinfo: 392 kfree(addrmap); 393 out_addrmap: 394 kfree(entry->domain); 395 out_domain: 396 kfree(entry); 397 out_entry: 398 cipso_v4_doi_putdef(doi_def); 399 return ret_val; 400 } 401 402 /* 403 * Security Attribute Functions 404 */ 405 406 #define _CM_F_NONE 0x00000000 407 #define _CM_F_ALLOC 0x00000001 408 #define _CM_F_WALK 0x00000002 409 410 /** 411 * _netlbl_catmap_getnode - Get a individual node from a catmap 412 * @catmap: pointer to the category bitmap 413 * @offset: the requested offset 414 * @cm_flags: catmap flags, see _CM_F_* 415 * @gfp_flags: memory allocation flags 416 * 417 * Description: 418 * Iterate through the catmap looking for the node associated with @offset. 419 * If the _CM_F_ALLOC flag is set in @cm_flags and there is no associated node, 420 * one will be created and inserted into the catmap. If the _CM_F_WALK flag is 421 * set in @cm_flags and there is no associated node, the next highest node will 422 * be returned. Returns a pointer to the node on success, NULL on failure. 423 * 424 */ 425 static struct netlbl_lsm_catmap *_netlbl_catmap_getnode( 426 struct netlbl_lsm_catmap **catmap, 427 u32 offset, 428 unsigned int cm_flags, 429 gfp_t gfp_flags) 430 { 431 struct netlbl_lsm_catmap *iter = *catmap; 432 struct netlbl_lsm_catmap *prev = NULL; 433 434 if (iter == NULL) 435 goto catmap_getnode_alloc; 436 if (offset < iter->startbit) 437 goto catmap_getnode_walk; 438 while (iter && offset >= (iter->startbit + NETLBL_CATMAP_SIZE)) { 439 prev = iter; 440 iter = iter->next; 441 } 442 if (iter == NULL || offset < iter->startbit) 443 goto catmap_getnode_walk; 444 445 return iter; 446 447 catmap_getnode_walk: 448 if (cm_flags & _CM_F_WALK) 449 return iter; 450 catmap_getnode_alloc: 451 if (!(cm_flags & _CM_F_ALLOC)) 452 return NULL; 453 454 iter = netlbl_catmap_alloc(gfp_flags); 455 if (iter == NULL) 456 return NULL; 457 iter->startbit = offset & ~(NETLBL_CATMAP_SIZE - 1); 458 459 if (prev == NULL) { 460 iter->next = *catmap; 461 *catmap = iter; 462 } else { 463 iter->next = prev->next; 464 prev->next = iter; 465 } 466 467 return iter; 468 } 469 470 /** 471 * netlbl_catmap_walk - Walk a LSM secattr catmap looking for a bit 472 * @catmap: the category bitmap 473 * @offset: the offset to start searching at, in bits 474 * 475 * Description: 476 * This function walks a LSM secattr category bitmap starting at @offset and 477 * returns the spot of the first set bit or -ENOENT if no bits are set. 478 * 479 */ 480 int netlbl_catmap_walk(struct netlbl_lsm_catmap *catmap, u32 offset) 481 { 482 struct netlbl_lsm_catmap *iter = catmap; 483 u32 idx; 484 u32 bit; 485 NETLBL_CATMAP_MAPTYPE bitmap; 486 487 iter = _netlbl_catmap_getnode(&catmap, offset, _CM_F_WALK, 0); 488 if (iter == NULL) 489 return -ENOENT; 490 if (offset > iter->startbit) { 491 offset -= iter->startbit; 492 idx = offset / NETLBL_CATMAP_MAPSIZE; 493 bit = offset % NETLBL_CATMAP_MAPSIZE; 494 } else { 495 idx = 0; 496 bit = 0; 497 } 498 bitmap = iter->bitmap[idx] >> bit; 499 500 for (;;) { 501 if (bitmap != 0) { 502 while ((bitmap & NETLBL_CATMAP_BIT) == 0) { 503 bitmap >>= 1; 504 bit++; 505 } 506 return iter->startbit + 507 (NETLBL_CATMAP_MAPSIZE * idx) + bit; 508 } 509 if (++idx >= NETLBL_CATMAP_MAPCNT) { 510 if (iter->next != NULL) { 511 iter = iter->next; 512 idx = 0; 513 } else 514 return -ENOENT; 515 } 516 bitmap = iter->bitmap[idx]; 517 bit = 0; 518 } 519 520 return -ENOENT; 521 } 522 523 /** 524 * netlbl_catmap_walkrng - Find the end of a string of set bits 525 * @catmap: the category bitmap 526 * @offset: the offset to start searching at, in bits 527 * 528 * Description: 529 * This function walks a LSM secattr category bitmap starting at @offset and 530 * returns the spot of the first cleared bit or -ENOENT if the offset is past 531 * the end of the bitmap. 532 * 533 */ 534 int netlbl_catmap_walkrng(struct netlbl_lsm_catmap *catmap, u32 offset) 535 { 536 struct netlbl_lsm_catmap *iter; 537 struct netlbl_lsm_catmap *prev = NULL; 538 u32 idx; 539 u32 bit; 540 NETLBL_CATMAP_MAPTYPE bitmask; 541 NETLBL_CATMAP_MAPTYPE bitmap; 542 543 iter = _netlbl_catmap_getnode(&catmap, offset, _CM_F_WALK, 0); 544 if (iter == NULL) 545 return -ENOENT; 546 if (offset > iter->startbit) { 547 offset -= iter->startbit; 548 idx = offset / NETLBL_CATMAP_MAPSIZE; 549 bit = offset % NETLBL_CATMAP_MAPSIZE; 550 } else { 551 idx = 0; 552 bit = 0; 553 } 554 bitmask = NETLBL_CATMAP_BIT << bit; 555 556 for (;;) { 557 bitmap = iter->bitmap[idx]; 558 while (bitmask != 0 && (bitmap & bitmask) != 0) { 559 bitmask <<= 1; 560 bit++; 561 } 562 563 if (prev && idx == 0 && bit == 0) 564 return prev->startbit + NETLBL_CATMAP_SIZE - 1; 565 else if (bitmask != 0) 566 return iter->startbit + 567 (NETLBL_CATMAP_MAPSIZE * idx) + bit - 1; 568 else if (++idx >= NETLBL_CATMAP_MAPCNT) { 569 if (iter->next == NULL) 570 return iter->startbit + NETLBL_CATMAP_SIZE - 1; 571 prev = iter; 572 iter = iter->next; 573 idx = 0; 574 } 575 bitmask = NETLBL_CATMAP_BIT; 576 bit = 0; 577 } 578 579 return -ENOENT; 580 } 581 582 /** 583 * netlbl_catmap_getlong - Export an unsigned long bitmap 584 * @catmap: pointer to the category bitmap 585 * @offset: pointer to the requested offset 586 * @bitmap: the exported bitmap 587 * 588 * Description: 589 * Export a bitmap with an offset greater than or equal to @offset and return 590 * it in @bitmap. The @offset must be aligned to an unsigned long and will be 591 * updated on return if different from what was requested; if the catmap is 592 * empty at the requested offset and beyond, the @offset is set to (u32)-1. 593 * Returns zero on sucess, negative values on failure. 594 * 595 */ 596 int netlbl_catmap_getlong(struct netlbl_lsm_catmap *catmap, 597 u32 *offset, 598 unsigned long *bitmap) 599 { 600 struct netlbl_lsm_catmap *iter; 601 u32 off = *offset; 602 u32 idx; 603 604 /* only allow aligned offsets */ 605 if ((off & (BITS_PER_LONG - 1)) != 0) 606 return -EINVAL; 607 608 if (off < catmap->startbit) { 609 off = catmap->startbit; 610 *offset = off; 611 } 612 iter = _netlbl_catmap_getnode(&catmap, off, _CM_F_NONE, 0); 613 if (iter == NULL) { 614 *offset = (u32)-1; 615 return 0; 616 } 617 618 if (off < iter->startbit) { 619 off = iter->startbit; 620 *offset = off; 621 } else 622 off -= iter->startbit; 623 624 idx = off / NETLBL_CATMAP_MAPSIZE; 625 *bitmap = iter->bitmap[idx] >> (off % NETLBL_CATMAP_SIZE); 626 627 return 0; 628 } 629 630 /** 631 * netlbl_catmap_setbit - Set a bit in a LSM secattr catmap 632 * @catmap: pointer to the category bitmap 633 * @bit: the bit to set 634 * @flags: memory allocation flags 635 * 636 * Description: 637 * Set the bit specified by @bit in @catmap. Returns zero on success, 638 * negative values on failure. 639 * 640 */ 641 int netlbl_catmap_setbit(struct netlbl_lsm_catmap **catmap, 642 u32 bit, 643 gfp_t flags) 644 { 645 struct netlbl_lsm_catmap *iter; 646 u32 idx; 647 648 iter = _netlbl_catmap_getnode(catmap, bit, _CM_F_ALLOC, flags); 649 if (iter == NULL) 650 return -ENOMEM; 651 652 bit -= iter->startbit; 653 idx = bit / NETLBL_CATMAP_MAPSIZE; 654 iter->bitmap[idx] |= NETLBL_CATMAP_BIT << (bit % NETLBL_CATMAP_MAPSIZE); 655 656 return 0; 657 } 658 659 /** 660 * netlbl_catmap_setrng - Set a range of bits in a LSM secattr catmap 661 * @catmap: pointer to the category bitmap 662 * @start: the starting bit 663 * @end: the last bit in the string 664 * @flags: memory allocation flags 665 * 666 * Description: 667 * Set a range of bits, starting at @start and ending with @end. Returns zero 668 * on success, negative values on failure. 669 * 670 */ 671 int netlbl_catmap_setrng(struct netlbl_lsm_catmap **catmap, 672 u32 start, 673 u32 end, 674 gfp_t flags) 675 { 676 int rc = 0; 677 u32 spot = start; 678 679 while (rc == 0 && spot <= end) { 680 if (((spot & (BITS_PER_LONG - 1)) != 0) && 681 ((end - spot) > BITS_PER_LONG)) { 682 rc = netlbl_catmap_setlong(catmap, 683 spot, 684 (unsigned long)-1, 685 flags); 686 spot += BITS_PER_LONG; 687 } else 688 rc = netlbl_catmap_setbit(catmap, spot++, flags); 689 } 690 691 return rc; 692 } 693 694 /** 695 * netlbl_catmap_setlong - Import an unsigned long bitmap 696 * @catmap: pointer to the category bitmap 697 * @offset: offset to the start of the imported bitmap 698 * @bitmap: the bitmap to import 699 * @flags: memory allocation flags 700 * 701 * Description: 702 * Import the bitmap specified in @bitmap into @catmap, using the offset 703 * in @offset. The offset must be aligned to an unsigned long. Returns zero 704 * on success, negative values on failure. 705 * 706 */ 707 int netlbl_catmap_setlong(struct netlbl_lsm_catmap **catmap, 708 u32 offset, 709 unsigned long bitmap, 710 gfp_t flags) 711 { 712 struct netlbl_lsm_catmap *iter; 713 u32 idx; 714 715 /* only allow aligned offsets */ 716 if ((offset & (BITS_PER_LONG - 1)) != 0) 717 return -EINVAL; 718 719 iter = _netlbl_catmap_getnode(catmap, offset, _CM_F_ALLOC, flags); 720 if (iter == NULL) 721 return -ENOMEM; 722 723 offset -= iter->startbit; 724 idx = offset / NETLBL_CATMAP_MAPSIZE; 725 iter->bitmap[idx] |= bitmap << (offset % NETLBL_CATMAP_MAPSIZE); 726 727 return 0; 728 } 729 730 /* 731 * LSM Functions 732 */ 733 734 /** 735 * netlbl_enabled - Determine if the NetLabel subsystem is enabled 736 * 737 * Description: 738 * The LSM can use this function to determine if it should use NetLabel 739 * security attributes in it's enforcement mechanism. Currently, NetLabel is 740 * considered to be enabled when it's configuration contains a valid setup for 741 * at least one labeled protocol (i.e. NetLabel can understand incoming 742 * labeled packets of at least one type); otherwise NetLabel is considered to 743 * be disabled. 744 * 745 */ 746 int netlbl_enabled(void) 747 { 748 /* At some point we probably want to expose this mechanism to the user 749 * as well so that admins can toggle NetLabel regardless of the 750 * configuration */ 751 return (atomic_read(&netlabel_mgmt_protocount) > 0); 752 } 753 754 /** 755 * netlbl_sock_setattr - Label a socket using the correct protocol 756 * @sk: the socket to label 757 * @family: protocol family 758 * @secattr: the security attributes 759 * 760 * Description: 761 * Attach the correct label to the given socket using the security attributes 762 * specified in @secattr. This function requires exclusive access to @sk, 763 * which means it either needs to be in the process of being created or locked. 764 * Returns zero on success, -EDESTADDRREQ if the domain is configured to use 765 * network address selectors (can't blindly label the socket), and negative 766 * values on all other failures. 767 * 768 */ 769 int netlbl_sock_setattr(struct sock *sk, 770 u16 family, 771 const struct netlbl_lsm_secattr *secattr) 772 { 773 int ret_val; 774 struct netlbl_dom_map *dom_entry; 775 776 rcu_read_lock(); 777 dom_entry = netlbl_domhsh_getentry(secattr->domain); 778 if (dom_entry == NULL) { 779 ret_val = -ENOENT; 780 goto socket_setattr_return; 781 } 782 switch (family) { 783 case AF_INET: 784 switch (dom_entry->def.type) { 785 case NETLBL_NLTYPE_ADDRSELECT: 786 ret_val = -EDESTADDRREQ; 787 break; 788 case NETLBL_NLTYPE_CIPSOV4: 789 ret_val = cipso_v4_sock_setattr(sk, 790 dom_entry->def.cipso, 791 secattr); 792 break; 793 case NETLBL_NLTYPE_UNLABELED: 794 ret_val = 0; 795 break; 796 default: 797 ret_val = -ENOENT; 798 } 799 break; 800 #if IS_ENABLED(CONFIG_IPV6) 801 case AF_INET6: 802 /* since we don't support any IPv6 labeling protocols right 803 * now we can optimize everything away until we do */ 804 ret_val = 0; 805 break; 806 #endif /* IPv6 */ 807 default: 808 ret_val = -EPROTONOSUPPORT; 809 } 810 811 socket_setattr_return: 812 rcu_read_unlock(); 813 return ret_val; 814 } 815 816 /** 817 * netlbl_sock_delattr - Delete all the NetLabel labels on a socket 818 * @sk: the socket 819 * 820 * Description: 821 * Remove all the NetLabel labeling from @sk. The caller is responsible for 822 * ensuring that @sk is locked. 823 * 824 */ 825 void netlbl_sock_delattr(struct sock *sk) 826 { 827 cipso_v4_sock_delattr(sk); 828 } 829 830 /** 831 * netlbl_sock_getattr - Determine the security attributes of a sock 832 * @sk: the sock 833 * @secattr: the security attributes 834 * 835 * Description: 836 * Examines the given sock to see if any NetLabel style labeling has been 837 * applied to the sock, if so it parses the socket label and returns the 838 * security attributes in @secattr. Returns zero on success, negative values 839 * on failure. 840 * 841 */ 842 int netlbl_sock_getattr(struct sock *sk, 843 struct netlbl_lsm_secattr *secattr) 844 { 845 int ret_val; 846 847 switch (sk->sk_family) { 848 case AF_INET: 849 ret_val = cipso_v4_sock_getattr(sk, secattr); 850 break; 851 #if IS_ENABLED(CONFIG_IPV6) 852 case AF_INET6: 853 ret_val = -ENOMSG; 854 break; 855 #endif /* IPv6 */ 856 default: 857 ret_val = -EPROTONOSUPPORT; 858 } 859 860 return ret_val; 861 } 862 863 /** 864 * netlbl_conn_setattr - Label a connected socket using the correct protocol 865 * @sk: the socket to label 866 * @addr: the destination address 867 * @secattr: the security attributes 868 * 869 * Description: 870 * Attach the correct label to the given connected socket using the security 871 * attributes specified in @secattr. The caller is responsible for ensuring 872 * that @sk is locked. Returns zero on success, negative values on failure. 873 * 874 */ 875 int netlbl_conn_setattr(struct sock *sk, 876 struct sockaddr *addr, 877 const struct netlbl_lsm_secattr *secattr) 878 { 879 int ret_val; 880 struct sockaddr_in *addr4; 881 struct netlbl_dommap_def *entry; 882 883 rcu_read_lock(); 884 switch (addr->sa_family) { 885 case AF_INET: 886 addr4 = (struct sockaddr_in *)addr; 887 entry = netlbl_domhsh_getentry_af4(secattr->domain, 888 addr4->sin_addr.s_addr); 889 if (entry == NULL) { 890 ret_val = -ENOENT; 891 goto conn_setattr_return; 892 } 893 switch (entry->type) { 894 case NETLBL_NLTYPE_CIPSOV4: 895 ret_val = cipso_v4_sock_setattr(sk, 896 entry->cipso, secattr); 897 break; 898 case NETLBL_NLTYPE_UNLABELED: 899 /* just delete the protocols we support for right now 900 * but we could remove other protocols if needed */ 901 cipso_v4_sock_delattr(sk); 902 ret_val = 0; 903 break; 904 default: 905 ret_val = -ENOENT; 906 } 907 break; 908 #if IS_ENABLED(CONFIG_IPV6) 909 case AF_INET6: 910 /* since we don't support any IPv6 labeling protocols right 911 * now we can optimize everything away until we do */ 912 ret_val = 0; 913 break; 914 #endif /* IPv6 */ 915 default: 916 ret_val = -EPROTONOSUPPORT; 917 } 918 919 conn_setattr_return: 920 rcu_read_unlock(); 921 return ret_val; 922 } 923 924 /** 925 * netlbl_req_setattr - Label a request socket using the correct protocol 926 * @req: the request socket to label 927 * @secattr: the security attributes 928 * 929 * Description: 930 * Attach the correct label to the given socket using the security attributes 931 * specified in @secattr. Returns zero on success, negative values on failure. 932 * 933 */ 934 int netlbl_req_setattr(struct request_sock *req, 935 const struct netlbl_lsm_secattr *secattr) 936 { 937 int ret_val; 938 struct netlbl_dommap_def *entry; 939 940 rcu_read_lock(); 941 switch (req->rsk_ops->family) { 942 case AF_INET: 943 entry = netlbl_domhsh_getentry_af4(secattr->domain, 944 inet_rsk(req)->ir_rmt_addr); 945 if (entry == NULL) { 946 ret_val = -ENOENT; 947 goto req_setattr_return; 948 } 949 switch (entry->type) { 950 case NETLBL_NLTYPE_CIPSOV4: 951 ret_val = cipso_v4_req_setattr(req, 952 entry->cipso, secattr); 953 break; 954 case NETLBL_NLTYPE_UNLABELED: 955 /* just delete the protocols we support for right now 956 * but we could remove other protocols if needed */ 957 cipso_v4_req_delattr(req); 958 ret_val = 0; 959 break; 960 default: 961 ret_val = -ENOENT; 962 } 963 break; 964 #if IS_ENABLED(CONFIG_IPV6) 965 case AF_INET6: 966 /* since we don't support any IPv6 labeling protocols right 967 * now we can optimize everything away until we do */ 968 ret_val = 0; 969 break; 970 #endif /* IPv6 */ 971 default: 972 ret_val = -EPROTONOSUPPORT; 973 } 974 975 req_setattr_return: 976 rcu_read_unlock(); 977 return ret_val; 978 } 979 980 /** 981 * netlbl_req_delattr - Delete all the NetLabel labels on a socket 982 * @req: the socket 983 * 984 * Description: 985 * Remove all the NetLabel labeling from @req. 986 * 987 */ 988 void netlbl_req_delattr(struct request_sock *req) 989 { 990 cipso_v4_req_delattr(req); 991 } 992 993 /** 994 * netlbl_skbuff_setattr - Label a packet using the correct protocol 995 * @skb: the packet 996 * @family: protocol family 997 * @secattr: the security attributes 998 * 999 * Description: 1000 * Attach the correct label to the given packet using the security attributes 1001 * specified in @secattr. Returns zero on success, negative values on failure. 1002 * 1003 */ 1004 int netlbl_skbuff_setattr(struct sk_buff *skb, 1005 u16 family, 1006 const struct netlbl_lsm_secattr *secattr) 1007 { 1008 int ret_val; 1009 struct iphdr *hdr4; 1010 struct netlbl_dommap_def *entry; 1011 1012 rcu_read_lock(); 1013 switch (family) { 1014 case AF_INET: 1015 hdr4 = ip_hdr(skb); 1016 entry = netlbl_domhsh_getentry_af4(secattr->domain,hdr4->daddr); 1017 if (entry == NULL) { 1018 ret_val = -ENOENT; 1019 goto skbuff_setattr_return; 1020 } 1021 switch (entry->type) { 1022 case NETLBL_NLTYPE_CIPSOV4: 1023 ret_val = cipso_v4_skbuff_setattr(skb, entry->cipso, 1024 secattr); 1025 break; 1026 case NETLBL_NLTYPE_UNLABELED: 1027 /* just delete the protocols we support for right now 1028 * but we could remove other protocols if needed */ 1029 ret_val = cipso_v4_skbuff_delattr(skb); 1030 break; 1031 default: 1032 ret_val = -ENOENT; 1033 } 1034 break; 1035 #if IS_ENABLED(CONFIG_IPV6) 1036 case AF_INET6: 1037 /* since we don't support any IPv6 labeling protocols right 1038 * now we can optimize everything away until we do */ 1039 ret_val = 0; 1040 break; 1041 #endif /* IPv6 */ 1042 default: 1043 ret_val = -EPROTONOSUPPORT; 1044 } 1045 1046 skbuff_setattr_return: 1047 rcu_read_unlock(); 1048 return ret_val; 1049 } 1050 1051 /** 1052 * netlbl_skbuff_getattr - Determine the security attributes of a packet 1053 * @skb: the packet 1054 * @family: protocol family 1055 * @secattr: the security attributes 1056 * 1057 * Description: 1058 * Examines the given packet to see if a recognized form of packet labeling 1059 * is present, if so it parses the packet label and returns the security 1060 * attributes in @secattr. Returns zero on success, negative values on 1061 * failure. 1062 * 1063 */ 1064 int netlbl_skbuff_getattr(const struct sk_buff *skb, 1065 u16 family, 1066 struct netlbl_lsm_secattr *secattr) 1067 { 1068 unsigned char *ptr; 1069 1070 switch (family) { 1071 case AF_INET: 1072 ptr = cipso_v4_optptr(skb); 1073 if (ptr && cipso_v4_getattr(ptr, secattr) == 0) 1074 return 0; 1075 break; 1076 #if IS_ENABLED(CONFIG_IPV6) 1077 case AF_INET6: 1078 break; 1079 #endif /* IPv6 */ 1080 } 1081 1082 return netlbl_unlabel_getattr(skb, family, secattr); 1083 } 1084 1085 /** 1086 * netlbl_skbuff_err - Handle a LSM error on a sk_buff 1087 * @skb: the packet 1088 * @error: the error code 1089 * @gateway: true if host is acting as a gateway, false otherwise 1090 * 1091 * Description: 1092 * Deal with a LSM problem when handling the packet in @skb, typically this is 1093 * a permission denied problem (-EACCES). The correct action is determined 1094 * according to the packet's labeling protocol. 1095 * 1096 */ 1097 void netlbl_skbuff_err(struct sk_buff *skb, int error, int gateway) 1098 { 1099 if (cipso_v4_optptr(skb)) 1100 cipso_v4_error(skb, error, gateway); 1101 } 1102 1103 /** 1104 * netlbl_cache_invalidate - Invalidate all of the NetLabel protocol caches 1105 * 1106 * Description: 1107 * For all of the NetLabel protocols that support some form of label mapping 1108 * cache, invalidate the cache. Returns zero on success, negative values on 1109 * error. 1110 * 1111 */ 1112 void netlbl_cache_invalidate(void) 1113 { 1114 cipso_v4_cache_invalidate(); 1115 } 1116 1117 /** 1118 * netlbl_cache_add - Add an entry to a NetLabel protocol cache 1119 * @skb: the packet 1120 * @secattr: the packet's security attributes 1121 * 1122 * Description: 1123 * Add the LSM security attributes for the given packet to the underlying 1124 * NetLabel protocol's label mapping cache. Returns zero on success, negative 1125 * values on error. 1126 * 1127 */ 1128 int netlbl_cache_add(const struct sk_buff *skb, 1129 const struct netlbl_lsm_secattr *secattr) 1130 { 1131 unsigned char *ptr; 1132 1133 if ((secattr->flags & NETLBL_SECATTR_CACHE) == 0) 1134 return -ENOMSG; 1135 1136 ptr = cipso_v4_optptr(skb); 1137 if (ptr) 1138 return cipso_v4_cache_add(ptr, secattr); 1139 1140 return -ENOMSG; 1141 } 1142 1143 /* 1144 * Protocol Engine Functions 1145 */ 1146 1147 /** 1148 * netlbl_audit_start - Start an audit message 1149 * @type: audit message type 1150 * @audit_info: NetLabel audit information 1151 * 1152 * Description: 1153 * Start an audit message using the type specified in @type and fill the audit 1154 * message with some fields common to all NetLabel audit messages. This 1155 * function should only be used by protocol engines, not LSMs. Returns a 1156 * pointer to the audit buffer on success, NULL on failure. 1157 * 1158 */ 1159 struct audit_buffer *netlbl_audit_start(int type, 1160 struct netlbl_audit *audit_info) 1161 { 1162 return netlbl_audit_start_common(type, audit_info); 1163 } 1164 1165 /* 1166 * Setup Functions 1167 */ 1168 1169 /** 1170 * netlbl_init - Initialize NetLabel 1171 * 1172 * Description: 1173 * Perform the required NetLabel initialization before first use. 1174 * 1175 */ 1176 static int __init netlbl_init(void) 1177 { 1178 int ret_val; 1179 1180 printk(KERN_INFO "NetLabel: Initializing\n"); 1181 printk(KERN_INFO "NetLabel: domain hash size = %u\n", 1182 (1 << NETLBL_DOMHSH_BITSIZE)); 1183 printk(KERN_INFO "NetLabel: protocols =" 1184 " UNLABELED" 1185 " CIPSOv4" 1186 "\n"); 1187 1188 ret_val = netlbl_domhsh_init(NETLBL_DOMHSH_BITSIZE); 1189 if (ret_val != 0) 1190 goto init_failure; 1191 1192 ret_val = netlbl_unlabel_init(NETLBL_UNLHSH_BITSIZE); 1193 if (ret_val != 0) 1194 goto init_failure; 1195 1196 ret_val = netlbl_netlink_init(); 1197 if (ret_val != 0) 1198 goto init_failure; 1199 1200 ret_val = netlbl_unlabel_defconf(); 1201 if (ret_val != 0) 1202 goto init_failure; 1203 printk(KERN_INFO "NetLabel: unlabeled traffic allowed by default\n"); 1204 1205 return 0; 1206 1207 init_failure: 1208 panic("NetLabel: failed to initialize properly (%d)\n", ret_val); 1209 } 1210 1211 subsys_initcall(netlbl_init); 1212