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