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