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 /* Bitmap functions 732 */ 733 734 /** 735 * netlbl_bitmap_walk - Walk a bitmap looking for a bit 736 * @bitmap: the bitmap 737 * @bitmap_len: length in bits 738 * @offset: starting offset 739 * @state: if non-zero, look for a set (1) bit else look for a cleared (0) bit 740 * 741 * Description: 742 * Starting at @offset, walk the bitmap from left to right until either the 743 * desired bit is found or we reach the end. Return the bit offset, -1 if 744 * not found, or -2 if error. 745 */ 746 int netlbl_bitmap_walk(const unsigned char *bitmap, u32 bitmap_len, 747 u32 offset, u8 state) 748 { 749 u32 bit_spot; 750 u32 byte_offset; 751 unsigned char bitmask; 752 unsigned char byte; 753 754 byte_offset = offset / 8; 755 byte = bitmap[byte_offset]; 756 bit_spot = offset; 757 bitmask = 0x80 >> (offset % 8); 758 759 while (bit_spot < bitmap_len) { 760 if ((state && (byte & bitmask) == bitmask) || 761 (state == 0 && (byte & bitmask) == 0)) 762 return bit_spot; 763 764 bit_spot++; 765 bitmask >>= 1; 766 if (bitmask == 0) { 767 byte = bitmap[++byte_offset]; 768 bitmask = 0x80; 769 } 770 } 771 772 return -1; 773 } 774 EXPORT_SYMBOL(netlbl_bitmap_walk); 775 776 /** 777 * netlbl_bitmap_setbit - Sets a single bit in a bitmap 778 * @bitmap: the bitmap 779 * @bit: the bit 780 * @state: if non-zero, set the bit (1) else clear the bit (0) 781 * 782 * Description: 783 * Set a single bit in the bitmask. Returns zero on success, negative values 784 * on error. 785 */ 786 void netlbl_bitmap_setbit(unsigned char *bitmap, u32 bit, u8 state) 787 { 788 u32 byte_spot; 789 u8 bitmask; 790 791 /* gcc always rounds to zero when doing integer division */ 792 byte_spot = bit / 8; 793 bitmask = 0x80 >> (bit % 8); 794 if (state) 795 bitmap[byte_spot] |= bitmask; 796 else 797 bitmap[byte_spot] &= ~bitmask; 798 } 799 EXPORT_SYMBOL(netlbl_bitmap_setbit); 800 801 /* 802 * LSM Functions 803 */ 804 805 /** 806 * netlbl_enabled - Determine if the NetLabel subsystem is enabled 807 * 808 * Description: 809 * The LSM can use this function to determine if it should use NetLabel 810 * security attributes in it's enforcement mechanism. Currently, NetLabel is 811 * considered to be enabled when it's configuration contains a valid setup for 812 * at least one labeled protocol (i.e. NetLabel can understand incoming 813 * labeled packets of at least one type); otherwise NetLabel is considered to 814 * be disabled. 815 * 816 */ 817 int netlbl_enabled(void) 818 { 819 /* At some point we probably want to expose this mechanism to the user 820 * as well so that admins can toggle NetLabel regardless of the 821 * configuration */ 822 return (atomic_read(&netlabel_mgmt_protocount) > 0); 823 } 824 825 /** 826 * netlbl_sock_setattr - Label a socket using the correct protocol 827 * @sk: the socket to label 828 * @family: protocol family 829 * @secattr: the security attributes 830 * 831 * Description: 832 * Attach the correct label to the given socket using the security attributes 833 * specified in @secattr. This function requires exclusive access to @sk, 834 * which means it either needs to be in the process of being created or locked. 835 * Returns zero on success, -EDESTADDRREQ if the domain is configured to use 836 * network address selectors (can't blindly label the socket), and negative 837 * values on all other failures. 838 * 839 */ 840 int netlbl_sock_setattr(struct sock *sk, 841 u16 family, 842 const struct netlbl_lsm_secattr *secattr) 843 { 844 int ret_val; 845 struct netlbl_dom_map *dom_entry; 846 847 rcu_read_lock(); 848 dom_entry = netlbl_domhsh_getentry(secattr->domain, family); 849 if (dom_entry == NULL) { 850 ret_val = -ENOENT; 851 goto socket_setattr_return; 852 } 853 switch (family) { 854 case AF_INET: 855 switch (dom_entry->def.type) { 856 case NETLBL_NLTYPE_ADDRSELECT: 857 ret_val = -EDESTADDRREQ; 858 break; 859 case NETLBL_NLTYPE_CIPSOV4: 860 ret_val = cipso_v4_sock_setattr(sk, 861 dom_entry->def.cipso, 862 secattr); 863 break; 864 case NETLBL_NLTYPE_UNLABELED: 865 ret_val = 0; 866 break; 867 default: 868 ret_val = -ENOENT; 869 } 870 break; 871 #if IS_ENABLED(CONFIG_IPV6) 872 case AF_INET6: 873 /* since we don't support any IPv6 labeling protocols right 874 * now we can optimize everything away until we do */ 875 ret_val = 0; 876 break; 877 #endif /* IPv6 */ 878 default: 879 ret_val = -EPROTONOSUPPORT; 880 } 881 882 socket_setattr_return: 883 rcu_read_unlock(); 884 return ret_val; 885 } 886 887 /** 888 * netlbl_sock_delattr - Delete all the NetLabel labels on a socket 889 * @sk: the socket 890 * 891 * Description: 892 * Remove all the NetLabel labeling from @sk. The caller is responsible for 893 * ensuring that @sk is locked. 894 * 895 */ 896 void netlbl_sock_delattr(struct sock *sk) 897 { 898 switch (sk->sk_family) { 899 case AF_INET: 900 cipso_v4_sock_delattr(sk); 901 break; 902 } 903 } 904 905 /** 906 * netlbl_sock_getattr - Determine the security attributes of a sock 907 * @sk: the sock 908 * @secattr: the security attributes 909 * 910 * Description: 911 * Examines the given sock to see if any NetLabel style labeling has been 912 * applied to the sock, if so it parses the socket label and returns the 913 * security attributes in @secattr. Returns zero on success, negative values 914 * on failure. 915 * 916 */ 917 int netlbl_sock_getattr(struct sock *sk, 918 struct netlbl_lsm_secattr *secattr) 919 { 920 int ret_val; 921 922 switch (sk->sk_family) { 923 case AF_INET: 924 ret_val = cipso_v4_sock_getattr(sk, secattr); 925 break; 926 #if IS_ENABLED(CONFIG_IPV6) 927 case AF_INET6: 928 ret_val = -ENOMSG; 929 break; 930 #endif /* IPv6 */ 931 default: 932 ret_val = -EPROTONOSUPPORT; 933 } 934 935 return ret_val; 936 } 937 938 /** 939 * netlbl_conn_setattr - Label a connected socket using the correct protocol 940 * @sk: the socket to label 941 * @addr: the destination address 942 * @secattr: the security attributes 943 * 944 * Description: 945 * Attach the correct label to the given connected socket using the security 946 * attributes specified in @secattr. The caller is responsible for ensuring 947 * that @sk is locked. Returns zero on success, negative values on failure. 948 * 949 */ 950 int netlbl_conn_setattr(struct sock *sk, 951 struct sockaddr *addr, 952 const struct netlbl_lsm_secattr *secattr) 953 { 954 int ret_val; 955 struct sockaddr_in *addr4; 956 struct netlbl_dommap_def *entry; 957 958 rcu_read_lock(); 959 switch (addr->sa_family) { 960 case AF_INET: 961 addr4 = (struct sockaddr_in *)addr; 962 entry = netlbl_domhsh_getentry_af4(secattr->domain, 963 addr4->sin_addr.s_addr); 964 if (entry == NULL) { 965 ret_val = -ENOENT; 966 goto conn_setattr_return; 967 } 968 switch (entry->type) { 969 case NETLBL_NLTYPE_CIPSOV4: 970 ret_val = cipso_v4_sock_setattr(sk, 971 entry->cipso, secattr); 972 break; 973 case NETLBL_NLTYPE_UNLABELED: 974 /* just delete the protocols we support for right now 975 * but we could remove other protocols if needed */ 976 cipso_v4_sock_delattr(sk); 977 ret_val = 0; 978 break; 979 default: 980 ret_val = -ENOENT; 981 } 982 break; 983 #if IS_ENABLED(CONFIG_IPV6) 984 case AF_INET6: 985 /* since we don't support any IPv6 labeling protocols right 986 * now we can optimize everything away until we do */ 987 ret_val = 0; 988 break; 989 #endif /* IPv6 */ 990 default: 991 ret_val = -EPROTONOSUPPORT; 992 } 993 994 conn_setattr_return: 995 rcu_read_unlock(); 996 return ret_val; 997 } 998 999 /** 1000 * netlbl_req_setattr - Label a request socket using the correct protocol 1001 * @req: the request socket to label 1002 * @secattr: the security attributes 1003 * 1004 * Description: 1005 * Attach the correct label to the given socket using the security attributes 1006 * specified in @secattr. Returns zero on success, negative values on failure. 1007 * 1008 */ 1009 int netlbl_req_setattr(struct request_sock *req, 1010 const struct netlbl_lsm_secattr *secattr) 1011 { 1012 int ret_val; 1013 struct netlbl_dommap_def *entry; 1014 1015 rcu_read_lock(); 1016 switch (req->rsk_ops->family) { 1017 case AF_INET: 1018 entry = netlbl_domhsh_getentry_af4(secattr->domain, 1019 inet_rsk(req)->ir_rmt_addr); 1020 if (entry == NULL) { 1021 ret_val = -ENOENT; 1022 goto req_setattr_return; 1023 } 1024 switch (entry->type) { 1025 case NETLBL_NLTYPE_CIPSOV4: 1026 ret_val = cipso_v4_req_setattr(req, 1027 entry->cipso, secattr); 1028 break; 1029 case NETLBL_NLTYPE_UNLABELED: 1030 /* just delete the protocols we support for right now 1031 * but we could remove other protocols if needed */ 1032 cipso_v4_req_delattr(req); 1033 ret_val = 0; 1034 break; 1035 default: 1036 ret_val = -ENOENT; 1037 } 1038 break; 1039 #if IS_ENABLED(CONFIG_IPV6) 1040 case AF_INET6: 1041 /* since we don't support any IPv6 labeling protocols right 1042 * now we can optimize everything away until we do */ 1043 ret_val = 0; 1044 break; 1045 #endif /* IPv6 */ 1046 default: 1047 ret_val = -EPROTONOSUPPORT; 1048 } 1049 1050 req_setattr_return: 1051 rcu_read_unlock(); 1052 return ret_val; 1053 } 1054 1055 /** 1056 * netlbl_req_delattr - Delete all the NetLabel labels on a socket 1057 * @req: the socket 1058 * 1059 * Description: 1060 * Remove all the NetLabel labeling from @req. 1061 * 1062 */ 1063 void netlbl_req_delattr(struct request_sock *req) 1064 { 1065 switch (req->rsk_ops->family) { 1066 case AF_INET: 1067 cipso_v4_req_delattr(req); 1068 break; 1069 } 1070 } 1071 1072 /** 1073 * netlbl_skbuff_setattr - Label a packet using the correct protocol 1074 * @skb: the packet 1075 * @family: protocol family 1076 * @secattr: the security attributes 1077 * 1078 * Description: 1079 * Attach the correct label to the given packet using the security attributes 1080 * specified in @secattr. Returns zero on success, negative values on failure. 1081 * 1082 */ 1083 int netlbl_skbuff_setattr(struct sk_buff *skb, 1084 u16 family, 1085 const struct netlbl_lsm_secattr *secattr) 1086 { 1087 int ret_val; 1088 struct iphdr *hdr4; 1089 struct netlbl_dommap_def *entry; 1090 1091 rcu_read_lock(); 1092 switch (family) { 1093 case AF_INET: 1094 hdr4 = ip_hdr(skb); 1095 entry = netlbl_domhsh_getentry_af4(secattr->domain,hdr4->daddr); 1096 if (entry == NULL) { 1097 ret_val = -ENOENT; 1098 goto skbuff_setattr_return; 1099 } 1100 switch (entry->type) { 1101 case NETLBL_NLTYPE_CIPSOV4: 1102 ret_val = cipso_v4_skbuff_setattr(skb, entry->cipso, 1103 secattr); 1104 break; 1105 case NETLBL_NLTYPE_UNLABELED: 1106 /* just delete the protocols we support for right now 1107 * but we could remove other protocols if needed */ 1108 ret_val = cipso_v4_skbuff_delattr(skb); 1109 break; 1110 default: 1111 ret_val = -ENOENT; 1112 } 1113 break; 1114 #if IS_ENABLED(CONFIG_IPV6) 1115 case AF_INET6: 1116 /* since we don't support any IPv6 labeling protocols right 1117 * now we can optimize everything away until we do */ 1118 ret_val = 0; 1119 break; 1120 #endif /* IPv6 */ 1121 default: 1122 ret_val = -EPROTONOSUPPORT; 1123 } 1124 1125 skbuff_setattr_return: 1126 rcu_read_unlock(); 1127 return ret_val; 1128 } 1129 1130 /** 1131 * netlbl_skbuff_getattr - Determine the security attributes of a packet 1132 * @skb: the packet 1133 * @family: protocol family 1134 * @secattr: the security attributes 1135 * 1136 * Description: 1137 * Examines the given packet to see if a recognized form of packet labeling 1138 * is present, if so it parses the packet label and returns the security 1139 * attributes in @secattr. Returns zero on success, negative values on 1140 * failure. 1141 * 1142 */ 1143 int netlbl_skbuff_getattr(const struct sk_buff *skb, 1144 u16 family, 1145 struct netlbl_lsm_secattr *secattr) 1146 { 1147 unsigned char *ptr; 1148 1149 switch (family) { 1150 case AF_INET: 1151 ptr = cipso_v4_optptr(skb); 1152 if (ptr && cipso_v4_getattr(ptr, secattr) == 0) 1153 return 0; 1154 break; 1155 #if IS_ENABLED(CONFIG_IPV6) 1156 case AF_INET6: 1157 break; 1158 #endif /* IPv6 */ 1159 } 1160 1161 return netlbl_unlabel_getattr(skb, family, secattr); 1162 } 1163 1164 /** 1165 * netlbl_skbuff_err - Handle a LSM error on a sk_buff 1166 * @skb: the packet 1167 * @error: the error code 1168 * @gateway: true if host is acting as a gateway, false otherwise 1169 * 1170 * Description: 1171 * Deal with a LSM problem when handling the packet in @skb, typically this is 1172 * a permission denied problem (-EACCES). The correct action is determined 1173 * according to the packet's labeling protocol. 1174 * 1175 */ 1176 void netlbl_skbuff_err(struct sk_buff *skb, int error, int gateway) 1177 { 1178 if (cipso_v4_optptr(skb)) 1179 cipso_v4_error(skb, error, gateway); 1180 } 1181 1182 /** 1183 * netlbl_cache_invalidate - Invalidate all of the NetLabel protocol caches 1184 * 1185 * Description: 1186 * For all of the NetLabel protocols that support some form of label mapping 1187 * cache, invalidate the cache. Returns zero on success, negative values on 1188 * error. 1189 * 1190 */ 1191 void netlbl_cache_invalidate(void) 1192 { 1193 cipso_v4_cache_invalidate(); 1194 } 1195 1196 /** 1197 * netlbl_cache_add - Add an entry to a NetLabel protocol cache 1198 * @skb: the packet 1199 * @secattr: the packet's security attributes 1200 * 1201 * Description: 1202 * Add the LSM security attributes for the given packet to the underlying 1203 * NetLabel protocol's label mapping cache. Returns zero on success, negative 1204 * values on error. 1205 * 1206 */ 1207 int netlbl_cache_add(const struct sk_buff *skb, 1208 const struct netlbl_lsm_secattr *secattr) 1209 { 1210 unsigned char *ptr; 1211 1212 if ((secattr->flags & NETLBL_SECATTR_CACHE) == 0) 1213 return -ENOMSG; 1214 1215 ptr = cipso_v4_optptr(skb); 1216 if (ptr) 1217 return cipso_v4_cache_add(ptr, secattr); 1218 1219 return -ENOMSG; 1220 } 1221 1222 /* 1223 * Protocol Engine Functions 1224 */ 1225 1226 /** 1227 * netlbl_audit_start - Start an audit message 1228 * @type: audit message type 1229 * @audit_info: NetLabel audit information 1230 * 1231 * Description: 1232 * Start an audit message using the type specified in @type and fill the audit 1233 * message with some fields common to all NetLabel audit messages. This 1234 * function should only be used by protocol engines, not LSMs. Returns a 1235 * pointer to the audit buffer on success, NULL on failure. 1236 * 1237 */ 1238 struct audit_buffer *netlbl_audit_start(int type, 1239 struct netlbl_audit *audit_info) 1240 { 1241 return netlbl_audit_start_common(type, audit_info); 1242 } 1243 EXPORT_SYMBOL(netlbl_audit_start); 1244 1245 /* 1246 * Setup Functions 1247 */ 1248 1249 /** 1250 * netlbl_init - Initialize NetLabel 1251 * 1252 * Description: 1253 * Perform the required NetLabel initialization before first use. 1254 * 1255 */ 1256 static int __init netlbl_init(void) 1257 { 1258 int ret_val; 1259 1260 printk(KERN_INFO "NetLabel: Initializing\n"); 1261 printk(KERN_INFO "NetLabel: domain hash size = %u\n", 1262 (1 << NETLBL_DOMHSH_BITSIZE)); 1263 printk(KERN_INFO "NetLabel: protocols =" 1264 " UNLABELED" 1265 " CIPSOv4" 1266 "\n"); 1267 1268 ret_val = netlbl_domhsh_init(NETLBL_DOMHSH_BITSIZE); 1269 if (ret_val != 0) 1270 goto init_failure; 1271 1272 ret_val = netlbl_unlabel_init(NETLBL_UNLHSH_BITSIZE); 1273 if (ret_val != 0) 1274 goto init_failure; 1275 1276 ret_val = netlbl_netlink_init(); 1277 if (ret_val != 0) 1278 goto init_failure; 1279 1280 ret_val = netlbl_unlabel_defconf(); 1281 if (ret_val != 0) 1282 goto init_failure; 1283 printk(KERN_INFO "NetLabel: unlabeled traffic allowed by default\n"); 1284 1285 return 0; 1286 1287 init_failure: 1288 panic("NetLabel: failed to initialize properly (%d)\n", ret_val); 1289 } 1290 1291 subsys_initcall(netlbl_init); 1292