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