1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * NetLabel Unlabeled Support 4 * 5 * This file defines functions for dealing with unlabeled packets for the 6 * NetLabel system. The NetLabel system manages static and dynamic label 7 * mappings for network protocols such as CIPSO and RIPSO. 8 * 9 * Author: Paul Moore <paul@paul-moore.com> 10 */ 11 12 /* 13 * (c) Copyright Hewlett-Packard Development Company, L.P., 2006 - 2008 14 */ 15 16 #include <linux/types.h> 17 #include <linux/rcupdate.h> 18 #include <linux/list.h> 19 #include <linux/spinlock.h> 20 #include <linux/socket.h> 21 #include <linux/string.h> 22 #include <linux/skbuff.h> 23 #include <linux/audit.h> 24 #include <linux/in.h> 25 #include <linux/in6.h> 26 #include <linux/ip.h> 27 #include <linux/ipv6.h> 28 #include <linux/notifier.h> 29 #include <linux/netdevice.h> 30 #include <linux/security.h> 31 #include <linux/slab.h> 32 #include <net/sock.h> 33 #include <net/netlink.h> 34 #include <net/genetlink.h> 35 #include <net/ip.h> 36 #include <net/ipv6.h> 37 #include <net/net_namespace.h> 38 #include <net/netlabel.h> 39 #include <asm/bug.h> 40 #include <linux/atomic.h> 41 42 #include "netlabel_user.h" 43 #include "netlabel_addrlist.h" 44 #include "netlabel_domainhash.h" 45 #include "netlabel_unlabeled.h" 46 #include "netlabel_mgmt.h" 47 48 /* NOTE: at present we always use init's network namespace since we don't 49 * presently support different namespaces even though the majority of 50 * the functions in this file are "namespace safe" */ 51 52 /* The unlabeled connection hash table which we use to map network interfaces 53 * and addresses of unlabeled packets to a user specified secid value for the 54 * LSM. The hash table is used to lookup the network interface entry 55 * (struct netlbl_unlhsh_iface) and then the interface entry is used to 56 * lookup an IP address match from an ordered list. If a network interface 57 * match can not be found in the hash table then the default entry 58 * (netlbl_unlhsh_def) is used. The IP address entry list 59 * (struct netlbl_unlhsh_addr) is ordered such that the entries with a 60 * larger netmask come first. 61 */ 62 struct netlbl_unlhsh_tbl { 63 struct list_head *tbl; 64 u32 size; 65 }; 66 #define netlbl_unlhsh_addr4_entry(iter) \ 67 container_of(iter, struct netlbl_unlhsh_addr4, list) 68 struct netlbl_unlhsh_addr4 { 69 u32 secid; 70 71 struct netlbl_af4list list; 72 struct rcu_head rcu; 73 }; 74 #define netlbl_unlhsh_addr6_entry(iter) \ 75 container_of(iter, struct netlbl_unlhsh_addr6, list) 76 struct netlbl_unlhsh_addr6 { 77 u32 secid; 78 79 struct netlbl_af6list list; 80 struct rcu_head rcu; 81 }; 82 struct netlbl_unlhsh_iface { 83 int ifindex; 84 struct list_head addr4_list; 85 struct list_head addr6_list; 86 87 u32 valid; 88 struct list_head list; 89 struct rcu_head rcu; 90 }; 91 92 /* Argument struct for netlbl_unlhsh_walk() */ 93 struct netlbl_unlhsh_walk_arg { 94 struct netlink_callback *nl_cb; 95 struct sk_buff *skb; 96 u32 seq; 97 }; 98 99 /* Unlabeled connection hash table */ 100 /* updates should be so rare that having one spinlock for the entire 101 * hash table should be okay */ 102 static DEFINE_SPINLOCK(netlbl_unlhsh_lock); 103 #define netlbl_unlhsh_rcu_deref(p) \ 104 rcu_dereference_check(p, lockdep_is_held(&netlbl_unlhsh_lock)) 105 static struct netlbl_unlhsh_tbl __rcu *netlbl_unlhsh; 106 static struct netlbl_unlhsh_iface __rcu *netlbl_unlhsh_def; 107 108 /* Accept unlabeled packets flag */ 109 static u8 netlabel_unlabel_acceptflg; 110 111 /* NetLabel Generic NETLINK unlabeled family */ 112 static struct genl_family netlbl_unlabel_gnl_family; 113 114 /* NetLabel Netlink attribute policy */ 115 static const struct nla_policy netlbl_unlabel_genl_policy[NLBL_UNLABEL_A_MAX + 1] = { 116 [NLBL_UNLABEL_A_ACPTFLG] = { .type = NLA_U8 }, 117 [NLBL_UNLABEL_A_IPV6ADDR] = { .type = NLA_BINARY, 118 .len = sizeof(struct in6_addr) }, 119 [NLBL_UNLABEL_A_IPV6MASK] = { .type = NLA_BINARY, 120 .len = sizeof(struct in6_addr) }, 121 [NLBL_UNLABEL_A_IPV4ADDR] = { .type = NLA_BINARY, 122 .len = sizeof(struct in_addr) }, 123 [NLBL_UNLABEL_A_IPV4MASK] = { .type = NLA_BINARY, 124 .len = sizeof(struct in_addr) }, 125 [NLBL_UNLABEL_A_IFACE] = { .type = NLA_NUL_STRING, 126 .len = IFNAMSIZ - 1 }, 127 [NLBL_UNLABEL_A_SECCTX] = { .type = NLA_BINARY } 128 }; 129 130 /* 131 * Unlabeled Connection Hash Table Functions 132 */ 133 134 /** 135 * netlbl_unlhsh_free_iface - Frees an interface entry from the hash table 136 * @entry: the entry's RCU field 137 * 138 * Description: 139 * This function is designed to be used as a callback to the call_rcu() 140 * function so that memory allocated to a hash table interface entry can be 141 * released safely. It is important to note that this function does not free 142 * the IPv4 and IPv6 address lists contained as part of an interface entry. It 143 * is up to the rest of the code to make sure an interface entry is only freed 144 * once it's address lists are empty. 145 * 146 */ 147 static void netlbl_unlhsh_free_iface(struct rcu_head *entry) 148 { 149 struct netlbl_unlhsh_iface *iface; 150 struct netlbl_af4list *iter4; 151 struct netlbl_af4list *tmp4; 152 #if IS_ENABLED(CONFIG_IPV6) 153 struct netlbl_af6list *iter6; 154 struct netlbl_af6list *tmp6; 155 #endif /* IPv6 */ 156 157 iface = container_of(entry, struct netlbl_unlhsh_iface, rcu); 158 159 /* no need for locks here since we are the only one with access to this 160 * structure */ 161 162 netlbl_af4list_foreach_safe(iter4, tmp4, &iface->addr4_list) { 163 netlbl_af4list_remove_entry(iter4); 164 kfree(netlbl_unlhsh_addr4_entry(iter4)); 165 } 166 #if IS_ENABLED(CONFIG_IPV6) 167 netlbl_af6list_foreach_safe(iter6, tmp6, &iface->addr6_list) { 168 netlbl_af6list_remove_entry(iter6); 169 kfree(netlbl_unlhsh_addr6_entry(iter6)); 170 } 171 #endif /* IPv6 */ 172 kfree(iface); 173 } 174 175 /** 176 * netlbl_unlhsh_hash - Hashing function for the hash table 177 * @ifindex: the network interface/device to hash 178 * 179 * Description: 180 * This is the hashing function for the unlabeled hash table, it returns the 181 * bucket number for the given device/interface. The caller is responsible for 182 * ensuring that the hash table is protected with either a RCU read lock or 183 * the hash table lock. 184 * 185 */ 186 static u32 netlbl_unlhsh_hash(int ifindex) 187 { 188 return ifindex & (netlbl_unlhsh_rcu_deref(netlbl_unlhsh)->size - 1); 189 } 190 191 /** 192 * netlbl_unlhsh_search_iface - Search for a matching interface entry 193 * @ifindex: the network interface 194 * 195 * Description: 196 * Searches the unlabeled connection hash table and returns a pointer to the 197 * interface entry which matches @ifindex, otherwise NULL is returned. The 198 * caller is responsible for ensuring that the hash table is protected with 199 * either a RCU read lock or the hash table lock. 200 * 201 */ 202 static struct netlbl_unlhsh_iface *netlbl_unlhsh_search_iface(int ifindex) 203 { 204 u32 bkt; 205 struct list_head *bkt_list; 206 struct netlbl_unlhsh_iface *iter; 207 208 bkt = netlbl_unlhsh_hash(ifindex); 209 bkt_list = &netlbl_unlhsh_rcu_deref(netlbl_unlhsh)->tbl[bkt]; 210 list_for_each_entry_rcu(iter, bkt_list, list) 211 if (iter->valid && iter->ifindex == ifindex) 212 return iter; 213 214 return NULL; 215 } 216 217 /** 218 * netlbl_unlhsh_add_addr4 - Add a new IPv4 address entry to the hash table 219 * @iface: the associated interface entry 220 * @addr: IPv4 address in network byte order 221 * @mask: IPv4 address mask in network byte order 222 * @secid: LSM secid value for entry 223 * 224 * Description: 225 * Add a new address entry into the unlabeled connection hash table using the 226 * interface entry specified by @iface. On success zero is returned, otherwise 227 * a negative value is returned. 228 * 229 */ 230 static int netlbl_unlhsh_add_addr4(struct netlbl_unlhsh_iface *iface, 231 const struct in_addr *addr, 232 const struct in_addr *mask, 233 u32 secid) 234 { 235 int ret_val; 236 struct netlbl_unlhsh_addr4 *entry; 237 238 entry = kzalloc(sizeof(*entry), GFP_ATOMIC); 239 if (entry == NULL) 240 return -ENOMEM; 241 242 entry->list.addr = addr->s_addr & mask->s_addr; 243 entry->list.mask = mask->s_addr; 244 entry->list.valid = 1; 245 entry->secid = secid; 246 247 spin_lock(&netlbl_unlhsh_lock); 248 ret_val = netlbl_af4list_add(&entry->list, &iface->addr4_list); 249 spin_unlock(&netlbl_unlhsh_lock); 250 251 if (ret_val != 0) 252 kfree(entry); 253 return ret_val; 254 } 255 256 #if IS_ENABLED(CONFIG_IPV6) 257 /** 258 * netlbl_unlhsh_add_addr6 - Add a new IPv6 address entry to the hash table 259 * @iface: the associated interface entry 260 * @addr: IPv6 address in network byte order 261 * @mask: IPv6 address mask in network byte order 262 * @secid: LSM secid value for entry 263 * 264 * Description: 265 * Add a new address entry into the unlabeled connection hash table using the 266 * interface entry specified by @iface. On success zero is returned, otherwise 267 * a negative value is returned. 268 * 269 */ 270 static int netlbl_unlhsh_add_addr6(struct netlbl_unlhsh_iface *iface, 271 const struct in6_addr *addr, 272 const struct in6_addr *mask, 273 u32 secid) 274 { 275 int ret_val; 276 struct netlbl_unlhsh_addr6 *entry; 277 278 entry = kzalloc(sizeof(*entry), GFP_ATOMIC); 279 if (entry == NULL) 280 return -ENOMEM; 281 282 entry->list.addr = *addr; 283 entry->list.addr.s6_addr32[0] &= mask->s6_addr32[0]; 284 entry->list.addr.s6_addr32[1] &= mask->s6_addr32[1]; 285 entry->list.addr.s6_addr32[2] &= mask->s6_addr32[2]; 286 entry->list.addr.s6_addr32[3] &= mask->s6_addr32[3]; 287 entry->list.mask = *mask; 288 entry->list.valid = 1; 289 entry->secid = secid; 290 291 spin_lock(&netlbl_unlhsh_lock); 292 ret_val = netlbl_af6list_add(&entry->list, &iface->addr6_list); 293 spin_unlock(&netlbl_unlhsh_lock); 294 295 if (ret_val != 0) 296 kfree(entry); 297 return 0; 298 } 299 #endif /* IPv6 */ 300 301 /** 302 * netlbl_unlhsh_add_iface - Adds a new interface entry to the hash table 303 * @ifindex: network interface 304 * 305 * Description: 306 * Add a new, empty, interface entry into the unlabeled connection hash table. 307 * On success a pointer to the new interface entry is returned, on failure NULL 308 * is returned. 309 * 310 */ 311 static struct netlbl_unlhsh_iface *netlbl_unlhsh_add_iface(int ifindex) 312 { 313 u32 bkt; 314 struct netlbl_unlhsh_iface *iface; 315 316 iface = kzalloc(sizeof(*iface), GFP_ATOMIC); 317 if (iface == NULL) 318 return NULL; 319 320 iface->ifindex = ifindex; 321 INIT_LIST_HEAD(&iface->addr4_list); 322 INIT_LIST_HEAD(&iface->addr6_list); 323 iface->valid = 1; 324 325 spin_lock(&netlbl_unlhsh_lock); 326 if (ifindex > 0) { 327 bkt = netlbl_unlhsh_hash(ifindex); 328 if (netlbl_unlhsh_search_iface(ifindex) != NULL) 329 goto add_iface_failure; 330 list_add_tail_rcu(&iface->list, 331 &netlbl_unlhsh_rcu_deref(netlbl_unlhsh)->tbl[bkt]); 332 } else { 333 INIT_LIST_HEAD(&iface->list); 334 if (netlbl_unlhsh_rcu_deref(netlbl_unlhsh_def) != NULL) 335 goto add_iface_failure; 336 rcu_assign_pointer(netlbl_unlhsh_def, iface); 337 } 338 spin_unlock(&netlbl_unlhsh_lock); 339 340 return iface; 341 342 add_iface_failure: 343 spin_unlock(&netlbl_unlhsh_lock); 344 kfree(iface); 345 return NULL; 346 } 347 348 /** 349 * netlbl_unlhsh_add - Adds a new entry to the unlabeled connection hash table 350 * @net: network namespace 351 * @dev_name: interface name 352 * @addr: IP address in network byte order 353 * @mask: address mask in network byte order 354 * @addr_len: length of address/mask (4 for IPv4, 16 for IPv6) 355 * @secid: LSM secid value for the entry 356 * @audit_info: NetLabel audit information 357 * 358 * Description: 359 * Adds a new entry to the unlabeled connection hash table. Returns zero on 360 * success, negative values on failure. 361 * 362 */ 363 int netlbl_unlhsh_add(struct net *net, 364 const char *dev_name, 365 const void *addr, 366 const void *mask, 367 u32 addr_len, 368 u32 secid, 369 struct netlbl_audit *audit_info) 370 { 371 int ret_val; 372 int ifindex; 373 struct net_device *dev; 374 struct netlbl_unlhsh_iface *iface; 375 struct audit_buffer *audit_buf = NULL; 376 char *secctx = NULL; 377 u32 secctx_len; 378 379 if (addr_len != sizeof(struct in_addr) && 380 addr_len != sizeof(struct in6_addr)) 381 return -EINVAL; 382 383 rcu_read_lock(); 384 if (dev_name != NULL) { 385 dev = dev_get_by_name_rcu(net, dev_name); 386 if (dev == NULL) { 387 ret_val = -ENODEV; 388 goto unlhsh_add_return; 389 } 390 ifindex = dev->ifindex; 391 iface = netlbl_unlhsh_search_iface(ifindex); 392 } else { 393 ifindex = 0; 394 iface = rcu_dereference(netlbl_unlhsh_def); 395 } 396 if (iface == NULL) { 397 iface = netlbl_unlhsh_add_iface(ifindex); 398 if (iface == NULL) { 399 ret_val = -ENOMEM; 400 goto unlhsh_add_return; 401 } 402 } 403 audit_buf = netlbl_audit_start_common(AUDIT_MAC_UNLBL_STCADD, 404 audit_info); 405 switch (addr_len) { 406 case sizeof(struct in_addr): { 407 const struct in_addr *addr4 = addr; 408 const struct in_addr *mask4 = mask; 409 410 ret_val = netlbl_unlhsh_add_addr4(iface, addr4, mask4, secid); 411 if (audit_buf != NULL) 412 netlbl_af4list_audit_addr(audit_buf, 1, 413 dev_name, 414 addr4->s_addr, 415 mask4->s_addr); 416 break; 417 } 418 #if IS_ENABLED(CONFIG_IPV6) 419 case sizeof(struct in6_addr): { 420 const struct in6_addr *addr6 = addr; 421 const struct in6_addr *mask6 = mask; 422 423 ret_val = netlbl_unlhsh_add_addr6(iface, addr6, mask6, secid); 424 if (audit_buf != NULL) 425 netlbl_af6list_audit_addr(audit_buf, 1, 426 dev_name, 427 addr6, mask6); 428 break; 429 } 430 #endif /* IPv6 */ 431 default: 432 ret_val = -EINVAL; 433 } 434 if (ret_val == 0) 435 atomic_inc(&netlabel_mgmt_protocount); 436 437 unlhsh_add_return: 438 rcu_read_unlock(); 439 if (audit_buf != NULL) { 440 if (security_secid_to_secctx(secid, 441 &secctx, 442 &secctx_len) == 0) { 443 audit_log_format(audit_buf, " sec_obj=%s", secctx); 444 security_release_secctx(secctx, secctx_len); 445 } 446 audit_log_format(audit_buf, " res=%u", ret_val == 0 ? 1 : 0); 447 audit_log_end(audit_buf); 448 } 449 return ret_val; 450 } 451 452 /** 453 * netlbl_unlhsh_remove_addr4 - Remove an IPv4 address entry 454 * @net: network namespace 455 * @iface: interface entry 456 * @addr: IP address 457 * @mask: IP address mask 458 * @audit_info: NetLabel audit information 459 * 460 * Description: 461 * Remove an IP address entry from the unlabeled connection hash table. 462 * Returns zero on success, negative values on failure. 463 * 464 */ 465 static int netlbl_unlhsh_remove_addr4(struct net *net, 466 struct netlbl_unlhsh_iface *iface, 467 const struct in_addr *addr, 468 const struct in_addr *mask, 469 struct netlbl_audit *audit_info) 470 { 471 struct netlbl_af4list *list_entry; 472 struct netlbl_unlhsh_addr4 *entry; 473 struct audit_buffer *audit_buf; 474 struct net_device *dev; 475 char *secctx; 476 u32 secctx_len; 477 478 spin_lock(&netlbl_unlhsh_lock); 479 list_entry = netlbl_af4list_remove(addr->s_addr, mask->s_addr, 480 &iface->addr4_list); 481 spin_unlock(&netlbl_unlhsh_lock); 482 if (list_entry != NULL) 483 entry = netlbl_unlhsh_addr4_entry(list_entry); 484 else 485 entry = NULL; 486 487 audit_buf = netlbl_audit_start_common(AUDIT_MAC_UNLBL_STCDEL, 488 audit_info); 489 if (audit_buf != NULL) { 490 dev = dev_get_by_index(net, iface->ifindex); 491 netlbl_af4list_audit_addr(audit_buf, 1, 492 (dev != NULL ? dev->name : NULL), 493 addr->s_addr, mask->s_addr); 494 if (dev != NULL) 495 dev_put(dev); 496 if (entry != NULL && 497 security_secid_to_secctx(entry->secid, 498 &secctx, &secctx_len) == 0) { 499 audit_log_format(audit_buf, " sec_obj=%s", secctx); 500 security_release_secctx(secctx, secctx_len); 501 } 502 audit_log_format(audit_buf, " res=%u", entry != NULL ? 1 : 0); 503 audit_log_end(audit_buf); 504 } 505 506 if (entry == NULL) 507 return -ENOENT; 508 509 kfree_rcu(entry, rcu); 510 return 0; 511 } 512 513 #if IS_ENABLED(CONFIG_IPV6) 514 /** 515 * netlbl_unlhsh_remove_addr6 - Remove an IPv6 address entry 516 * @net: network namespace 517 * @iface: interface entry 518 * @addr: IP address 519 * @mask: IP address mask 520 * @audit_info: NetLabel audit information 521 * 522 * Description: 523 * Remove an IP address entry from the unlabeled connection hash table. 524 * Returns zero on success, negative values on failure. 525 * 526 */ 527 static int netlbl_unlhsh_remove_addr6(struct net *net, 528 struct netlbl_unlhsh_iface *iface, 529 const struct in6_addr *addr, 530 const struct in6_addr *mask, 531 struct netlbl_audit *audit_info) 532 { 533 struct netlbl_af6list *list_entry; 534 struct netlbl_unlhsh_addr6 *entry; 535 struct audit_buffer *audit_buf; 536 struct net_device *dev; 537 char *secctx; 538 u32 secctx_len; 539 540 spin_lock(&netlbl_unlhsh_lock); 541 list_entry = netlbl_af6list_remove(addr, mask, &iface->addr6_list); 542 spin_unlock(&netlbl_unlhsh_lock); 543 if (list_entry != NULL) 544 entry = netlbl_unlhsh_addr6_entry(list_entry); 545 else 546 entry = NULL; 547 548 audit_buf = netlbl_audit_start_common(AUDIT_MAC_UNLBL_STCDEL, 549 audit_info); 550 if (audit_buf != NULL) { 551 dev = dev_get_by_index(net, iface->ifindex); 552 netlbl_af6list_audit_addr(audit_buf, 1, 553 (dev != NULL ? dev->name : NULL), 554 addr, mask); 555 if (dev != NULL) 556 dev_put(dev); 557 if (entry != NULL && 558 security_secid_to_secctx(entry->secid, 559 &secctx, &secctx_len) == 0) { 560 audit_log_format(audit_buf, " sec_obj=%s", secctx); 561 security_release_secctx(secctx, secctx_len); 562 } 563 audit_log_format(audit_buf, " res=%u", entry != NULL ? 1 : 0); 564 audit_log_end(audit_buf); 565 } 566 567 if (entry == NULL) 568 return -ENOENT; 569 570 kfree_rcu(entry, rcu); 571 return 0; 572 } 573 #endif /* IPv6 */ 574 575 /** 576 * netlbl_unlhsh_condremove_iface - Remove an interface entry 577 * @iface: the interface entry 578 * 579 * Description: 580 * Remove an interface entry from the unlabeled connection hash table if it is 581 * empty. An interface entry is considered to be empty if there are no 582 * address entries assigned to it. 583 * 584 */ 585 static void netlbl_unlhsh_condremove_iface(struct netlbl_unlhsh_iface *iface) 586 { 587 struct netlbl_af4list *iter4; 588 #if IS_ENABLED(CONFIG_IPV6) 589 struct netlbl_af6list *iter6; 590 #endif /* IPv6 */ 591 592 spin_lock(&netlbl_unlhsh_lock); 593 netlbl_af4list_foreach_rcu(iter4, &iface->addr4_list) 594 goto unlhsh_condremove_failure; 595 #if IS_ENABLED(CONFIG_IPV6) 596 netlbl_af6list_foreach_rcu(iter6, &iface->addr6_list) 597 goto unlhsh_condremove_failure; 598 #endif /* IPv6 */ 599 iface->valid = 0; 600 if (iface->ifindex > 0) 601 list_del_rcu(&iface->list); 602 else 603 RCU_INIT_POINTER(netlbl_unlhsh_def, NULL); 604 spin_unlock(&netlbl_unlhsh_lock); 605 606 call_rcu(&iface->rcu, netlbl_unlhsh_free_iface); 607 return; 608 609 unlhsh_condremove_failure: 610 spin_unlock(&netlbl_unlhsh_lock); 611 } 612 613 /** 614 * netlbl_unlhsh_remove - Remove an entry from the unlabeled hash table 615 * @net: network namespace 616 * @dev_name: interface name 617 * @addr: IP address in network byte order 618 * @mask: address mask in network byte order 619 * @addr_len: length of address/mask (4 for IPv4, 16 for IPv6) 620 * @audit_info: NetLabel audit information 621 * 622 * Description: 623 * Removes and existing entry from the unlabeled connection hash table. 624 * Returns zero on success, negative values on failure. 625 * 626 */ 627 int netlbl_unlhsh_remove(struct net *net, 628 const char *dev_name, 629 const void *addr, 630 const void *mask, 631 u32 addr_len, 632 struct netlbl_audit *audit_info) 633 { 634 int ret_val; 635 struct net_device *dev; 636 struct netlbl_unlhsh_iface *iface; 637 638 if (addr_len != sizeof(struct in_addr) && 639 addr_len != sizeof(struct in6_addr)) 640 return -EINVAL; 641 642 rcu_read_lock(); 643 if (dev_name != NULL) { 644 dev = dev_get_by_name_rcu(net, dev_name); 645 if (dev == NULL) { 646 ret_val = -ENODEV; 647 goto unlhsh_remove_return; 648 } 649 iface = netlbl_unlhsh_search_iface(dev->ifindex); 650 } else 651 iface = rcu_dereference(netlbl_unlhsh_def); 652 if (iface == NULL) { 653 ret_val = -ENOENT; 654 goto unlhsh_remove_return; 655 } 656 switch (addr_len) { 657 case sizeof(struct in_addr): 658 ret_val = netlbl_unlhsh_remove_addr4(net, 659 iface, addr, mask, 660 audit_info); 661 break; 662 #if IS_ENABLED(CONFIG_IPV6) 663 case sizeof(struct in6_addr): 664 ret_val = netlbl_unlhsh_remove_addr6(net, 665 iface, addr, mask, 666 audit_info); 667 break; 668 #endif /* IPv6 */ 669 default: 670 ret_val = -EINVAL; 671 } 672 if (ret_val == 0) { 673 netlbl_unlhsh_condremove_iface(iface); 674 atomic_dec(&netlabel_mgmt_protocount); 675 } 676 677 unlhsh_remove_return: 678 rcu_read_unlock(); 679 return ret_val; 680 } 681 682 /* 683 * General Helper Functions 684 */ 685 686 /** 687 * netlbl_unlhsh_netdev_handler - Network device notification handler 688 * @this: notifier block 689 * @event: the event 690 * @ptr: the netdevice notifier info (cast to void) 691 * 692 * Description: 693 * Handle network device events, although at present all we care about is a 694 * network device going away. In the case of a device going away we clear any 695 * related entries from the unlabeled connection hash table. 696 * 697 */ 698 static int netlbl_unlhsh_netdev_handler(struct notifier_block *this, 699 unsigned long event, void *ptr) 700 { 701 struct net_device *dev = netdev_notifier_info_to_dev(ptr); 702 struct netlbl_unlhsh_iface *iface = NULL; 703 704 if (!net_eq(dev_net(dev), &init_net)) 705 return NOTIFY_DONE; 706 707 /* XXX - should this be a check for NETDEV_DOWN or _UNREGISTER? */ 708 if (event == NETDEV_DOWN) { 709 spin_lock(&netlbl_unlhsh_lock); 710 iface = netlbl_unlhsh_search_iface(dev->ifindex); 711 if (iface != NULL && iface->valid) { 712 iface->valid = 0; 713 list_del_rcu(&iface->list); 714 } else 715 iface = NULL; 716 spin_unlock(&netlbl_unlhsh_lock); 717 } 718 719 if (iface != NULL) 720 call_rcu(&iface->rcu, netlbl_unlhsh_free_iface); 721 722 return NOTIFY_DONE; 723 } 724 725 /** 726 * netlbl_unlabel_acceptflg_set - Set the unlabeled accept flag 727 * @value: desired value 728 * @audit_info: NetLabel audit information 729 * 730 * Description: 731 * Set the value of the unlabeled accept flag to @value. 732 * 733 */ 734 static void netlbl_unlabel_acceptflg_set(u8 value, 735 struct netlbl_audit *audit_info) 736 { 737 struct audit_buffer *audit_buf; 738 u8 old_val; 739 740 old_val = netlabel_unlabel_acceptflg; 741 netlabel_unlabel_acceptflg = value; 742 audit_buf = netlbl_audit_start_common(AUDIT_MAC_UNLBL_ALLOW, 743 audit_info); 744 if (audit_buf != NULL) { 745 audit_log_format(audit_buf, 746 " unlbl_accept=%u old=%u", value, old_val); 747 audit_log_end(audit_buf); 748 } 749 } 750 751 /** 752 * netlbl_unlabel_addrinfo_get - Get the IPv4/6 address information 753 * @info: the Generic NETLINK info block 754 * @addr: the IP address 755 * @mask: the IP address mask 756 * @len: the address length 757 * 758 * Description: 759 * Examine the Generic NETLINK message and extract the IP address information. 760 * Returns zero on success, negative values on failure. 761 * 762 */ 763 static int netlbl_unlabel_addrinfo_get(struct genl_info *info, 764 void **addr, 765 void **mask, 766 u32 *len) 767 { 768 u32 addr_len; 769 770 if (info->attrs[NLBL_UNLABEL_A_IPV4ADDR] && 771 info->attrs[NLBL_UNLABEL_A_IPV4MASK]) { 772 addr_len = nla_len(info->attrs[NLBL_UNLABEL_A_IPV4ADDR]); 773 if (addr_len != sizeof(struct in_addr) && 774 addr_len != nla_len(info->attrs[NLBL_UNLABEL_A_IPV4MASK])) 775 return -EINVAL; 776 *len = addr_len; 777 *addr = nla_data(info->attrs[NLBL_UNLABEL_A_IPV4ADDR]); 778 *mask = nla_data(info->attrs[NLBL_UNLABEL_A_IPV4MASK]); 779 return 0; 780 } else if (info->attrs[NLBL_UNLABEL_A_IPV6ADDR]) { 781 addr_len = nla_len(info->attrs[NLBL_UNLABEL_A_IPV6ADDR]); 782 if (addr_len != sizeof(struct in6_addr) && 783 addr_len != nla_len(info->attrs[NLBL_UNLABEL_A_IPV6MASK])) 784 return -EINVAL; 785 *len = addr_len; 786 *addr = nla_data(info->attrs[NLBL_UNLABEL_A_IPV6ADDR]); 787 *mask = nla_data(info->attrs[NLBL_UNLABEL_A_IPV6MASK]); 788 return 0; 789 } 790 791 return -EINVAL; 792 } 793 794 /* 795 * NetLabel Command Handlers 796 */ 797 798 /** 799 * netlbl_unlabel_accept - Handle an ACCEPT message 800 * @skb: the NETLINK buffer 801 * @info: the Generic NETLINK info block 802 * 803 * Description: 804 * Process a user generated ACCEPT message and set the accept flag accordingly. 805 * Returns zero on success, negative values on failure. 806 * 807 */ 808 static int netlbl_unlabel_accept(struct sk_buff *skb, struct genl_info *info) 809 { 810 u8 value; 811 struct netlbl_audit audit_info; 812 813 if (info->attrs[NLBL_UNLABEL_A_ACPTFLG]) { 814 value = nla_get_u8(info->attrs[NLBL_UNLABEL_A_ACPTFLG]); 815 if (value == 1 || value == 0) { 816 netlbl_netlink_auditinfo(skb, &audit_info); 817 netlbl_unlabel_acceptflg_set(value, &audit_info); 818 return 0; 819 } 820 } 821 822 return -EINVAL; 823 } 824 825 /** 826 * netlbl_unlabel_list - Handle a LIST message 827 * @skb: the NETLINK buffer 828 * @info: the Generic NETLINK info block 829 * 830 * Description: 831 * Process a user generated LIST message and respond with the current status. 832 * Returns zero on success, negative values on failure. 833 * 834 */ 835 static int netlbl_unlabel_list(struct sk_buff *skb, struct genl_info *info) 836 { 837 int ret_val = -EINVAL; 838 struct sk_buff *ans_skb; 839 void *data; 840 841 ans_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 842 if (ans_skb == NULL) 843 goto list_failure; 844 data = genlmsg_put_reply(ans_skb, info, &netlbl_unlabel_gnl_family, 845 0, NLBL_UNLABEL_C_LIST); 846 if (data == NULL) { 847 ret_val = -ENOMEM; 848 goto list_failure; 849 } 850 851 ret_val = nla_put_u8(ans_skb, 852 NLBL_UNLABEL_A_ACPTFLG, 853 netlabel_unlabel_acceptflg); 854 if (ret_val != 0) 855 goto list_failure; 856 857 genlmsg_end(ans_skb, data); 858 return genlmsg_reply(ans_skb, info); 859 860 list_failure: 861 kfree_skb(ans_skb); 862 return ret_val; 863 } 864 865 /** 866 * netlbl_unlabel_staticadd - Handle a STATICADD message 867 * @skb: the NETLINK buffer 868 * @info: the Generic NETLINK info block 869 * 870 * Description: 871 * Process a user generated STATICADD message and add a new unlabeled 872 * connection entry to the hash table. Returns zero on success, negative 873 * values on failure. 874 * 875 */ 876 static int netlbl_unlabel_staticadd(struct sk_buff *skb, 877 struct genl_info *info) 878 { 879 int ret_val; 880 char *dev_name; 881 void *addr; 882 void *mask; 883 u32 addr_len; 884 u32 secid; 885 struct netlbl_audit audit_info; 886 887 /* Don't allow users to add both IPv4 and IPv6 addresses for a 888 * single entry. However, allow users to create two entries, one each 889 * for IPv4 and IPv4, with the same LSM security context which should 890 * achieve the same result. */ 891 if (!info->attrs[NLBL_UNLABEL_A_SECCTX] || 892 !info->attrs[NLBL_UNLABEL_A_IFACE] || 893 !((!info->attrs[NLBL_UNLABEL_A_IPV4ADDR] || 894 !info->attrs[NLBL_UNLABEL_A_IPV4MASK]) ^ 895 (!info->attrs[NLBL_UNLABEL_A_IPV6ADDR] || 896 !info->attrs[NLBL_UNLABEL_A_IPV6MASK]))) 897 return -EINVAL; 898 899 netlbl_netlink_auditinfo(skb, &audit_info); 900 901 ret_val = netlbl_unlabel_addrinfo_get(info, &addr, &mask, &addr_len); 902 if (ret_val != 0) 903 return ret_val; 904 dev_name = nla_data(info->attrs[NLBL_UNLABEL_A_IFACE]); 905 ret_val = security_secctx_to_secid( 906 nla_data(info->attrs[NLBL_UNLABEL_A_SECCTX]), 907 nla_len(info->attrs[NLBL_UNLABEL_A_SECCTX]), 908 &secid); 909 if (ret_val != 0) 910 return ret_val; 911 912 return netlbl_unlhsh_add(&init_net, 913 dev_name, addr, mask, addr_len, secid, 914 &audit_info); 915 } 916 917 /** 918 * netlbl_unlabel_staticadddef - Handle a STATICADDDEF message 919 * @skb: the NETLINK buffer 920 * @info: the Generic NETLINK info block 921 * 922 * Description: 923 * Process a user generated STATICADDDEF message and add a new default 924 * unlabeled connection entry. Returns zero on success, negative values on 925 * failure. 926 * 927 */ 928 static int netlbl_unlabel_staticadddef(struct sk_buff *skb, 929 struct genl_info *info) 930 { 931 int ret_val; 932 void *addr; 933 void *mask; 934 u32 addr_len; 935 u32 secid; 936 struct netlbl_audit audit_info; 937 938 /* Don't allow users to add both IPv4 and IPv6 addresses for a 939 * single entry. However, allow users to create two entries, one each 940 * for IPv4 and IPv6, with the same LSM security context which should 941 * achieve the same result. */ 942 if (!info->attrs[NLBL_UNLABEL_A_SECCTX] || 943 !((!info->attrs[NLBL_UNLABEL_A_IPV4ADDR] || 944 !info->attrs[NLBL_UNLABEL_A_IPV4MASK]) ^ 945 (!info->attrs[NLBL_UNLABEL_A_IPV6ADDR] || 946 !info->attrs[NLBL_UNLABEL_A_IPV6MASK]))) 947 return -EINVAL; 948 949 netlbl_netlink_auditinfo(skb, &audit_info); 950 951 ret_val = netlbl_unlabel_addrinfo_get(info, &addr, &mask, &addr_len); 952 if (ret_val != 0) 953 return ret_val; 954 ret_val = security_secctx_to_secid( 955 nla_data(info->attrs[NLBL_UNLABEL_A_SECCTX]), 956 nla_len(info->attrs[NLBL_UNLABEL_A_SECCTX]), 957 &secid); 958 if (ret_val != 0) 959 return ret_val; 960 961 return netlbl_unlhsh_add(&init_net, 962 NULL, addr, mask, addr_len, secid, 963 &audit_info); 964 } 965 966 /** 967 * netlbl_unlabel_staticremove - Handle a STATICREMOVE message 968 * @skb: the NETLINK buffer 969 * @info: the Generic NETLINK info block 970 * 971 * Description: 972 * Process a user generated STATICREMOVE message and remove the specified 973 * unlabeled connection entry. Returns zero on success, negative values on 974 * failure. 975 * 976 */ 977 static int netlbl_unlabel_staticremove(struct sk_buff *skb, 978 struct genl_info *info) 979 { 980 int ret_val; 981 char *dev_name; 982 void *addr; 983 void *mask; 984 u32 addr_len; 985 struct netlbl_audit audit_info; 986 987 /* See the note in netlbl_unlabel_staticadd() about not allowing both 988 * IPv4 and IPv6 in the same entry. */ 989 if (!info->attrs[NLBL_UNLABEL_A_IFACE] || 990 !((!info->attrs[NLBL_UNLABEL_A_IPV4ADDR] || 991 !info->attrs[NLBL_UNLABEL_A_IPV4MASK]) ^ 992 (!info->attrs[NLBL_UNLABEL_A_IPV6ADDR] || 993 !info->attrs[NLBL_UNLABEL_A_IPV6MASK]))) 994 return -EINVAL; 995 996 netlbl_netlink_auditinfo(skb, &audit_info); 997 998 ret_val = netlbl_unlabel_addrinfo_get(info, &addr, &mask, &addr_len); 999 if (ret_val != 0) 1000 return ret_val; 1001 dev_name = nla_data(info->attrs[NLBL_UNLABEL_A_IFACE]); 1002 1003 return netlbl_unlhsh_remove(&init_net, 1004 dev_name, addr, mask, addr_len, 1005 &audit_info); 1006 } 1007 1008 /** 1009 * netlbl_unlabel_staticremovedef - Handle a STATICREMOVEDEF message 1010 * @skb: the NETLINK buffer 1011 * @info: the Generic NETLINK info block 1012 * 1013 * Description: 1014 * Process a user generated STATICREMOVEDEF message and remove the default 1015 * unlabeled connection entry. Returns zero on success, negative values on 1016 * failure. 1017 * 1018 */ 1019 static int netlbl_unlabel_staticremovedef(struct sk_buff *skb, 1020 struct genl_info *info) 1021 { 1022 int ret_val; 1023 void *addr; 1024 void *mask; 1025 u32 addr_len; 1026 struct netlbl_audit audit_info; 1027 1028 /* See the note in netlbl_unlabel_staticadd() about not allowing both 1029 * IPv4 and IPv6 in the same entry. */ 1030 if (!((!info->attrs[NLBL_UNLABEL_A_IPV4ADDR] || 1031 !info->attrs[NLBL_UNLABEL_A_IPV4MASK]) ^ 1032 (!info->attrs[NLBL_UNLABEL_A_IPV6ADDR] || 1033 !info->attrs[NLBL_UNLABEL_A_IPV6MASK]))) 1034 return -EINVAL; 1035 1036 netlbl_netlink_auditinfo(skb, &audit_info); 1037 1038 ret_val = netlbl_unlabel_addrinfo_get(info, &addr, &mask, &addr_len); 1039 if (ret_val != 0) 1040 return ret_val; 1041 1042 return netlbl_unlhsh_remove(&init_net, 1043 NULL, addr, mask, addr_len, 1044 &audit_info); 1045 } 1046 1047 1048 /** 1049 * netlbl_unlabel_staticlist_gen - Generate messages for STATICLIST[DEF] 1050 * @cmd: command/message 1051 * @iface: the interface entry 1052 * @addr4: the IPv4 address entry 1053 * @addr6: the IPv6 address entry 1054 * @arg: the netlbl_unlhsh_walk_arg structure 1055 * 1056 * Description: 1057 * This function is designed to be used to generate a response for a 1058 * STATICLIST or STATICLISTDEF message. When called either @addr4 or @addr6 1059 * can be specified, not both, the other unspecified entry should be set to 1060 * NULL by the caller. Returns the size of the message on success, negative 1061 * values on failure. 1062 * 1063 */ 1064 static int netlbl_unlabel_staticlist_gen(u32 cmd, 1065 const struct netlbl_unlhsh_iface *iface, 1066 const struct netlbl_unlhsh_addr4 *addr4, 1067 const struct netlbl_unlhsh_addr6 *addr6, 1068 void *arg) 1069 { 1070 int ret_val = -ENOMEM; 1071 struct netlbl_unlhsh_walk_arg *cb_arg = arg; 1072 struct net_device *dev; 1073 void *data; 1074 u32 secid; 1075 char *secctx; 1076 u32 secctx_len; 1077 1078 data = genlmsg_put(cb_arg->skb, NETLINK_CB(cb_arg->nl_cb->skb).portid, 1079 cb_arg->seq, &netlbl_unlabel_gnl_family, 1080 NLM_F_MULTI, cmd); 1081 if (data == NULL) 1082 goto list_cb_failure; 1083 1084 if (iface->ifindex > 0) { 1085 dev = dev_get_by_index(&init_net, iface->ifindex); 1086 if (!dev) { 1087 ret_val = -ENODEV; 1088 goto list_cb_failure; 1089 } 1090 ret_val = nla_put_string(cb_arg->skb, 1091 NLBL_UNLABEL_A_IFACE, dev->name); 1092 dev_put(dev); 1093 if (ret_val != 0) 1094 goto list_cb_failure; 1095 } 1096 1097 if (addr4) { 1098 struct in_addr addr_struct; 1099 1100 addr_struct.s_addr = addr4->list.addr; 1101 ret_val = nla_put_in_addr(cb_arg->skb, 1102 NLBL_UNLABEL_A_IPV4ADDR, 1103 addr_struct.s_addr); 1104 if (ret_val != 0) 1105 goto list_cb_failure; 1106 1107 addr_struct.s_addr = addr4->list.mask; 1108 ret_val = nla_put_in_addr(cb_arg->skb, 1109 NLBL_UNLABEL_A_IPV4MASK, 1110 addr_struct.s_addr); 1111 if (ret_val != 0) 1112 goto list_cb_failure; 1113 1114 secid = addr4->secid; 1115 } else { 1116 ret_val = nla_put_in6_addr(cb_arg->skb, 1117 NLBL_UNLABEL_A_IPV6ADDR, 1118 &addr6->list.addr); 1119 if (ret_val != 0) 1120 goto list_cb_failure; 1121 1122 ret_val = nla_put_in6_addr(cb_arg->skb, 1123 NLBL_UNLABEL_A_IPV6MASK, 1124 &addr6->list.mask); 1125 if (ret_val != 0) 1126 goto list_cb_failure; 1127 1128 secid = addr6->secid; 1129 } 1130 1131 ret_val = security_secid_to_secctx(secid, &secctx, &secctx_len); 1132 if (ret_val != 0) 1133 goto list_cb_failure; 1134 ret_val = nla_put(cb_arg->skb, 1135 NLBL_UNLABEL_A_SECCTX, 1136 secctx_len, 1137 secctx); 1138 security_release_secctx(secctx, secctx_len); 1139 if (ret_val != 0) 1140 goto list_cb_failure; 1141 1142 cb_arg->seq++; 1143 genlmsg_end(cb_arg->skb, data); 1144 return 0; 1145 1146 list_cb_failure: 1147 genlmsg_cancel(cb_arg->skb, data); 1148 return ret_val; 1149 } 1150 1151 /** 1152 * netlbl_unlabel_staticlist - Handle a STATICLIST message 1153 * @skb: the NETLINK buffer 1154 * @cb: the NETLINK callback 1155 * 1156 * Description: 1157 * Process a user generated STATICLIST message and dump the unlabeled 1158 * connection hash table in a form suitable for use in a kernel generated 1159 * STATICLIST message. Returns the length of @skb. 1160 * 1161 */ 1162 static int netlbl_unlabel_staticlist(struct sk_buff *skb, 1163 struct netlink_callback *cb) 1164 { 1165 struct netlbl_unlhsh_walk_arg cb_arg; 1166 u32 skip_bkt = cb->args[0]; 1167 u32 skip_chain = cb->args[1]; 1168 u32 iter_bkt; 1169 u32 iter_chain = 0, iter_addr4 = 0, iter_addr6 = 0; 1170 struct netlbl_unlhsh_iface *iface; 1171 struct list_head *iter_list; 1172 struct netlbl_af4list *addr4; 1173 #if IS_ENABLED(CONFIG_IPV6) 1174 struct netlbl_af6list *addr6; 1175 #endif 1176 1177 cb_arg.nl_cb = cb; 1178 cb_arg.skb = skb; 1179 cb_arg.seq = cb->nlh->nlmsg_seq; 1180 1181 rcu_read_lock(); 1182 for (iter_bkt = skip_bkt; 1183 iter_bkt < rcu_dereference(netlbl_unlhsh)->size; 1184 iter_bkt++, iter_chain = 0, iter_addr4 = 0, iter_addr6 = 0) { 1185 iter_list = &rcu_dereference(netlbl_unlhsh)->tbl[iter_bkt]; 1186 list_for_each_entry_rcu(iface, iter_list, list) { 1187 if (!iface->valid || 1188 iter_chain++ < skip_chain) 1189 continue; 1190 netlbl_af4list_foreach_rcu(addr4, 1191 &iface->addr4_list) { 1192 if (iter_addr4++ < cb->args[2]) 1193 continue; 1194 if (netlbl_unlabel_staticlist_gen( 1195 NLBL_UNLABEL_C_STATICLIST, 1196 iface, 1197 netlbl_unlhsh_addr4_entry(addr4), 1198 NULL, 1199 &cb_arg) < 0) { 1200 iter_addr4--; 1201 iter_chain--; 1202 goto unlabel_staticlist_return; 1203 } 1204 } 1205 #if IS_ENABLED(CONFIG_IPV6) 1206 netlbl_af6list_foreach_rcu(addr6, 1207 &iface->addr6_list) { 1208 if (iter_addr6++ < cb->args[3]) 1209 continue; 1210 if (netlbl_unlabel_staticlist_gen( 1211 NLBL_UNLABEL_C_STATICLIST, 1212 iface, 1213 NULL, 1214 netlbl_unlhsh_addr6_entry(addr6), 1215 &cb_arg) < 0) { 1216 iter_addr6--; 1217 iter_chain--; 1218 goto unlabel_staticlist_return; 1219 } 1220 } 1221 #endif /* IPv6 */ 1222 } 1223 } 1224 1225 unlabel_staticlist_return: 1226 rcu_read_unlock(); 1227 cb->args[0] = iter_bkt; 1228 cb->args[1] = iter_chain; 1229 cb->args[2] = iter_addr4; 1230 cb->args[3] = iter_addr6; 1231 return skb->len; 1232 } 1233 1234 /** 1235 * netlbl_unlabel_staticlistdef - Handle a STATICLISTDEF message 1236 * @skb: the NETLINK buffer 1237 * @cb: the NETLINK callback 1238 * 1239 * Description: 1240 * Process a user generated STATICLISTDEF message and dump the default 1241 * unlabeled connection entry in a form suitable for use in a kernel generated 1242 * STATICLISTDEF message. Returns the length of @skb. 1243 * 1244 */ 1245 static int netlbl_unlabel_staticlistdef(struct sk_buff *skb, 1246 struct netlink_callback *cb) 1247 { 1248 struct netlbl_unlhsh_walk_arg cb_arg; 1249 struct netlbl_unlhsh_iface *iface; 1250 u32 iter_addr4 = 0, iter_addr6 = 0; 1251 struct netlbl_af4list *addr4; 1252 #if IS_ENABLED(CONFIG_IPV6) 1253 struct netlbl_af6list *addr6; 1254 #endif 1255 1256 cb_arg.nl_cb = cb; 1257 cb_arg.skb = skb; 1258 cb_arg.seq = cb->nlh->nlmsg_seq; 1259 1260 rcu_read_lock(); 1261 iface = rcu_dereference(netlbl_unlhsh_def); 1262 if (iface == NULL || !iface->valid) 1263 goto unlabel_staticlistdef_return; 1264 1265 netlbl_af4list_foreach_rcu(addr4, &iface->addr4_list) { 1266 if (iter_addr4++ < cb->args[0]) 1267 continue; 1268 if (netlbl_unlabel_staticlist_gen(NLBL_UNLABEL_C_STATICLISTDEF, 1269 iface, 1270 netlbl_unlhsh_addr4_entry(addr4), 1271 NULL, 1272 &cb_arg) < 0) { 1273 iter_addr4--; 1274 goto unlabel_staticlistdef_return; 1275 } 1276 } 1277 #if IS_ENABLED(CONFIG_IPV6) 1278 netlbl_af6list_foreach_rcu(addr6, &iface->addr6_list) { 1279 if (iter_addr6++ < cb->args[1]) 1280 continue; 1281 if (netlbl_unlabel_staticlist_gen(NLBL_UNLABEL_C_STATICLISTDEF, 1282 iface, 1283 NULL, 1284 netlbl_unlhsh_addr6_entry(addr6), 1285 &cb_arg) < 0) { 1286 iter_addr6--; 1287 goto unlabel_staticlistdef_return; 1288 } 1289 } 1290 #endif /* IPv6 */ 1291 1292 unlabel_staticlistdef_return: 1293 rcu_read_unlock(); 1294 cb->args[0] = iter_addr4; 1295 cb->args[1] = iter_addr6; 1296 return skb->len; 1297 } 1298 1299 /* 1300 * NetLabel Generic NETLINK Command Definitions 1301 */ 1302 1303 static const struct genl_ops netlbl_unlabel_genl_ops[] = { 1304 { 1305 .cmd = NLBL_UNLABEL_C_STATICADD, 1306 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 1307 .flags = GENL_ADMIN_PERM, 1308 .doit = netlbl_unlabel_staticadd, 1309 .dumpit = NULL, 1310 }, 1311 { 1312 .cmd = NLBL_UNLABEL_C_STATICREMOVE, 1313 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 1314 .flags = GENL_ADMIN_PERM, 1315 .doit = netlbl_unlabel_staticremove, 1316 .dumpit = NULL, 1317 }, 1318 { 1319 .cmd = NLBL_UNLABEL_C_STATICLIST, 1320 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 1321 .flags = 0, 1322 .doit = NULL, 1323 .dumpit = netlbl_unlabel_staticlist, 1324 }, 1325 { 1326 .cmd = NLBL_UNLABEL_C_STATICADDDEF, 1327 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 1328 .flags = GENL_ADMIN_PERM, 1329 .doit = netlbl_unlabel_staticadddef, 1330 .dumpit = NULL, 1331 }, 1332 { 1333 .cmd = NLBL_UNLABEL_C_STATICREMOVEDEF, 1334 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 1335 .flags = GENL_ADMIN_PERM, 1336 .doit = netlbl_unlabel_staticremovedef, 1337 .dumpit = NULL, 1338 }, 1339 { 1340 .cmd = NLBL_UNLABEL_C_STATICLISTDEF, 1341 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 1342 .flags = 0, 1343 .doit = NULL, 1344 .dumpit = netlbl_unlabel_staticlistdef, 1345 }, 1346 { 1347 .cmd = NLBL_UNLABEL_C_ACCEPT, 1348 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 1349 .flags = GENL_ADMIN_PERM, 1350 .doit = netlbl_unlabel_accept, 1351 .dumpit = NULL, 1352 }, 1353 { 1354 .cmd = NLBL_UNLABEL_C_LIST, 1355 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 1356 .flags = 0, 1357 .doit = netlbl_unlabel_list, 1358 .dumpit = NULL, 1359 }, 1360 }; 1361 1362 static struct genl_family netlbl_unlabel_gnl_family __ro_after_init = { 1363 .hdrsize = 0, 1364 .name = NETLBL_NLTYPE_UNLABELED_NAME, 1365 .version = NETLBL_PROTO_VERSION, 1366 .maxattr = NLBL_UNLABEL_A_MAX, 1367 .policy = netlbl_unlabel_genl_policy, 1368 .module = THIS_MODULE, 1369 .ops = netlbl_unlabel_genl_ops, 1370 .n_ops = ARRAY_SIZE(netlbl_unlabel_genl_ops), 1371 }; 1372 1373 /* 1374 * NetLabel Generic NETLINK Protocol Functions 1375 */ 1376 1377 /** 1378 * netlbl_unlabel_genl_init - Register the Unlabeled NetLabel component 1379 * 1380 * Description: 1381 * Register the unlabeled packet NetLabel component with the Generic NETLINK 1382 * mechanism. Returns zero on success, negative values on failure. 1383 * 1384 */ 1385 int __init netlbl_unlabel_genl_init(void) 1386 { 1387 return genl_register_family(&netlbl_unlabel_gnl_family); 1388 } 1389 1390 /* 1391 * NetLabel KAPI Hooks 1392 */ 1393 1394 static struct notifier_block netlbl_unlhsh_netdev_notifier = { 1395 .notifier_call = netlbl_unlhsh_netdev_handler, 1396 }; 1397 1398 /** 1399 * netlbl_unlabel_init - Initialize the unlabeled connection hash table 1400 * @size: the number of bits to use for the hash buckets 1401 * 1402 * Description: 1403 * Initializes the unlabeled connection hash table and registers a network 1404 * device notification handler. This function should only be called by the 1405 * NetLabel subsystem itself during initialization. Returns zero on success, 1406 * non-zero values on error. 1407 * 1408 */ 1409 int __init netlbl_unlabel_init(u32 size) 1410 { 1411 u32 iter; 1412 struct netlbl_unlhsh_tbl *hsh_tbl; 1413 1414 if (size == 0) 1415 return -EINVAL; 1416 1417 hsh_tbl = kmalloc(sizeof(*hsh_tbl), GFP_KERNEL); 1418 if (hsh_tbl == NULL) 1419 return -ENOMEM; 1420 hsh_tbl->size = 1 << size; 1421 hsh_tbl->tbl = kcalloc(hsh_tbl->size, 1422 sizeof(struct list_head), 1423 GFP_KERNEL); 1424 if (hsh_tbl->tbl == NULL) { 1425 kfree(hsh_tbl); 1426 return -ENOMEM; 1427 } 1428 for (iter = 0; iter < hsh_tbl->size; iter++) 1429 INIT_LIST_HEAD(&hsh_tbl->tbl[iter]); 1430 1431 spin_lock(&netlbl_unlhsh_lock); 1432 rcu_assign_pointer(netlbl_unlhsh, hsh_tbl); 1433 spin_unlock(&netlbl_unlhsh_lock); 1434 1435 register_netdevice_notifier(&netlbl_unlhsh_netdev_notifier); 1436 1437 return 0; 1438 } 1439 1440 /** 1441 * netlbl_unlabel_getattr - Get the security attributes for an unlabled packet 1442 * @skb: the packet 1443 * @family: protocol family 1444 * @secattr: the security attributes 1445 * 1446 * Description: 1447 * Determine the security attributes, if any, for an unlabled packet and return 1448 * them in @secattr. Returns zero on success and negative values on failure. 1449 * 1450 */ 1451 int netlbl_unlabel_getattr(const struct sk_buff *skb, 1452 u16 family, 1453 struct netlbl_lsm_secattr *secattr) 1454 { 1455 struct netlbl_unlhsh_iface *iface; 1456 1457 rcu_read_lock(); 1458 iface = netlbl_unlhsh_search_iface(skb->skb_iif); 1459 if (iface == NULL) 1460 iface = rcu_dereference(netlbl_unlhsh_def); 1461 if (iface == NULL || !iface->valid) 1462 goto unlabel_getattr_nolabel; 1463 1464 #if IS_ENABLED(CONFIG_IPV6) 1465 /* When resolving a fallback label, check the sk_buff version as 1466 * it is possible (e.g. SCTP) to have family = PF_INET6 while 1467 * receiving ip_hdr(skb)->version = 4. 1468 */ 1469 if (family == PF_INET6 && ip_hdr(skb)->version == 4) 1470 family = PF_INET; 1471 #endif /* IPv6 */ 1472 1473 switch (family) { 1474 case PF_INET: { 1475 struct iphdr *hdr4; 1476 struct netlbl_af4list *addr4; 1477 1478 hdr4 = ip_hdr(skb); 1479 addr4 = netlbl_af4list_search(hdr4->saddr, 1480 &iface->addr4_list); 1481 if (addr4 == NULL) 1482 goto unlabel_getattr_nolabel; 1483 secattr->attr.secid = netlbl_unlhsh_addr4_entry(addr4)->secid; 1484 break; 1485 } 1486 #if IS_ENABLED(CONFIG_IPV6) 1487 case PF_INET6: { 1488 struct ipv6hdr *hdr6; 1489 struct netlbl_af6list *addr6; 1490 1491 hdr6 = ipv6_hdr(skb); 1492 addr6 = netlbl_af6list_search(&hdr6->saddr, 1493 &iface->addr6_list); 1494 if (addr6 == NULL) 1495 goto unlabel_getattr_nolabel; 1496 secattr->attr.secid = netlbl_unlhsh_addr6_entry(addr6)->secid; 1497 break; 1498 } 1499 #endif /* IPv6 */ 1500 default: 1501 goto unlabel_getattr_nolabel; 1502 } 1503 rcu_read_unlock(); 1504 1505 secattr->flags |= NETLBL_SECATTR_SECID; 1506 secattr->type = NETLBL_NLTYPE_UNLABELED; 1507 return 0; 1508 1509 unlabel_getattr_nolabel: 1510 rcu_read_unlock(); 1511 if (netlabel_unlabel_acceptflg == 0) 1512 return -ENOMSG; 1513 secattr->type = NETLBL_NLTYPE_UNLABELED; 1514 return 0; 1515 } 1516 1517 /** 1518 * netlbl_unlabel_defconf - Set the default config to allow unlabeled packets 1519 * 1520 * Description: 1521 * Set the default NetLabel configuration to allow incoming unlabeled packets 1522 * and to send unlabeled network traffic by default. 1523 * 1524 */ 1525 int __init netlbl_unlabel_defconf(void) 1526 { 1527 int ret_val; 1528 struct netlbl_dom_map *entry; 1529 struct netlbl_audit audit_info; 1530 1531 /* Only the kernel is allowed to call this function and the only time 1532 * it is called is at bootup before the audit subsystem is reporting 1533 * messages so don't worry to much about these values. */ 1534 security_task_getsecid(current, &audit_info.secid); 1535 audit_info.loginuid = GLOBAL_ROOT_UID; 1536 audit_info.sessionid = 0; 1537 1538 entry = kzalloc(sizeof(*entry), GFP_KERNEL); 1539 if (entry == NULL) 1540 return -ENOMEM; 1541 entry->family = AF_UNSPEC; 1542 entry->def.type = NETLBL_NLTYPE_UNLABELED; 1543 ret_val = netlbl_domhsh_add_default(entry, &audit_info); 1544 if (ret_val != 0) 1545 return ret_val; 1546 1547 netlbl_unlabel_acceptflg_set(1, &audit_info); 1548 1549 return 0; 1550 } 1551