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 static 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 int ret_val = 0; 566 struct netlbl_af4list *list_entry; 567 struct netlbl_unlhsh_addr4 *entry; 568 struct audit_buffer *audit_buf; 569 struct net_device *dev; 570 char *secctx; 571 u32 secctx_len; 572 573 spin_lock(&netlbl_unlhsh_lock); 574 list_entry = netlbl_af4list_remove(addr->s_addr, mask->s_addr, 575 &iface->addr4_list); 576 spin_unlock(&netlbl_unlhsh_lock); 577 if (list_entry == NULL) 578 ret_val = -ENOENT; 579 entry = netlbl_unlhsh_addr4_entry(list_entry); 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 && security_secid_to_secctx(entry->secid, 591 &secctx, 592 &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", ret_val == 0 ? 1 : 0); 597 audit_log_end(audit_buf); 598 } 599 600 if (ret_val == 0) 601 call_rcu(&entry->rcu, netlbl_unlhsh_free_addr4); 602 return ret_val; 603 } 604 605 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 606 /** 607 * netlbl_unlhsh_remove_addr6 - Remove an IPv6 address entry 608 * @net: network namespace 609 * @iface: interface entry 610 * @addr: IP address 611 * @mask: IP address mask 612 * @audit_info: NetLabel audit information 613 * 614 * Description: 615 * Remove an IP address entry from the unlabeled connection hash table. 616 * Returns zero on success, negative values on failure. The caller is 617 * responsible for calling the rcu_read_[un]lock() functions. 618 * 619 */ 620 static int netlbl_unlhsh_remove_addr6(struct net *net, 621 struct netlbl_unlhsh_iface *iface, 622 const struct in6_addr *addr, 623 const struct in6_addr *mask, 624 struct netlbl_audit *audit_info) 625 { 626 int ret_val = 0; 627 struct netlbl_af6list *list_entry; 628 struct netlbl_unlhsh_addr6 *entry; 629 struct audit_buffer *audit_buf; 630 struct net_device *dev; 631 char *secctx; 632 u32 secctx_len; 633 634 spin_lock(&netlbl_unlhsh_lock); 635 list_entry = netlbl_af6list_remove(addr, mask, &iface->addr6_list); 636 spin_unlock(&netlbl_unlhsh_lock); 637 if (list_entry == NULL) 638 ret_val = -ENOENT; 639 entry = netlbl_unlhsh_addr6_entry(list_entry); 640 641 audit_buf = netlbl_audit_start_common(AUDIT_MAC_UNLBL_STCDEL, 642 audit_info); 643 if (audit_buf != NULL) { 644 dev = dev_get_by_index(net, iface->ifindex); 645 netlbl_af6list_audit_addr(audit_buf, 1, 646 (dev != NULL ? dev->name : NULL), 647 addr, mask); 648 if (dev != NULL) 649 dev_put(dev); 650 if (entry && security_secid_to_secctx(entry->secid, 651 &secctx, 652 &secctx_len) == 0) { 653 audit_log_format(audit_buf, " sec_obj=%s", secctx); 654 security_release_secctx(secctx, secctx_len); 655 } 656 audit_log_format(audit_buf, " res=%u", ret_val == 0 ? 1 : 0); 657 audit_log_end(audit_buf); 658 } 659 660 if (ret_val == 0) 661 call_rcu(&entry->rcu, netlbl_unlhsh_free_addr6); 662 return ret_val; 663 } 664 #endif /* IPv6 */ 665 666 /** 667 * netlbl_unlhsh_condremove_iface - Remove an interface entry 668 * @iface: the interface entry 669 * 670 * Description: 671 * Remove an interface entry from the unlabeled connection hash table if it is 672 * empty. An interface entry is considered to be empty if there are no 673 * address entries assigned to it. 674 * 675 */ 676 static void netlbl_unlhsh_condremove_iface(struct netlbl_unlhsh_iface *iface) 677 { 678 struct netlbl_af4list *iter4; 679 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 680 struct netlbl_af6list *iter6; 681 #endif /* IPv6 */ 682 683 spin_lock(&netlbl_unlhsh_lock); 684 netlbl_af4list_foreach_rcu(iter4, &iface->addr4_list) 685 goto unlhsh_condremove_failure; 686 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 687 netlbl_af6list_foreach_rcu(iter6, &iface->addr6_list) 688 goto unlhsh_condremove_failure; 689 #endif /* IPv6 */ 690 iface->valid = 0; 691 if (iface->ifindex > 0) 692 list_del_rcu(&iface->list); 693 else 694 rcu_assign_pointer(netlbl_unlhsh_def, NULL); 695 spin_unlock(&netlbl_unlhsh_lock); 696 697 call_rcu(&iface->rcu, netlbl_unlhsh_free_iface); 698 return; 699 700 unlhsh_condremove_failure: 701 spin_unlock(&netlbl_unlhsh_lock); 702 return; 703 } 704 705 /** 706 * netlbl_unlhsh_remove - Remove an entry from the unlabeled hash table 707 * @net: network namespace 708 * @dev_name: interface name 709 * @addr: IP address in network byte order 710 * @mask: address mask in network byte order 711 * @addr_len: length of address/mask (4 for IPv4, 16 for IPv6) 712 * @audit_info: NetLabel audit information 713 * 714 * Description: 715 * Removes and existing entry from the unlabeled connection hash table. 716 * Returns zero on success, negative values on failure. 717 * 718 */ 719 static int netlbl_unlhsh_remove(struct net *net, 720 const char *dev_name, 721 const void *addr, 722 const void *mask, 723 u32 addr_len, 724 struct netlbl_audit *audit_info) 725 { 726 int ret_val; 727 struct net_device *dev; 728 struct netlbl_unlhsh_iface *iface; 729 730 if (addr_len != sizeof(struct in_addr) && 731 addr_len != sizeof(struct in6_addr)) 732 return -EINVAL; 733 734 rcu_read_lock(); 735 if (dev_name != NULL) { 736 dev = dev_get_by_name(net, dev_name); 737 if (dev == NULL) { 738 ret_val = -ENODEV; 739 goto unlhsh_remove_return; 740 } 741 iface = netlbl_unlhsh_search_iface(dev->ifindex); 742 dev_put(dev); 743 } else 744 iface = rcu_dereference(netlbl_unlhsh_def); 745 if (iface == NULL) { 746 ret_val = -ENOENT; 747 goto unlhsh_remove_return; 748 } 749 switch (addr_len) { 750 case sizeof(struct in_addr): 751 ret_val = netlbl_unlhsh_remove_addr4(net, 752 iface, addr, mask, 753 audit_info); 754 break; 755 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 756 case sizeof(struct in6_addr): 757 ret_val = netlbl_unlhsh_remove_addr6(net, 758 iface, addr, mask, 759 audit_info); 760 break; 761 #endif /* IPv6 */ 762 default: 763 ret_val = -EINVAL; 764 } 765 if (ret_val == 0) { 766 netlbl_unlhsh_condremove_iface(iface); 767 atomic_dec(&netlabel_mgmt_protocount); 768 } 769 770 unlhsh_remove_return: 771 rcu_read_unlock(); 772 return ret_val; 773 } 774 775 /* 776 * General Helper Functions 777 */ 778 779 /** 780 * netlbl_unlhsh_netdev_handler - Network device notification handler 781 * @this: notifier block 782 * @event: the event 783 * @ptr: the network device (cast to void) 784 * 785 * Description: 786 * Handle network device events, although at present all we care about is a 787 * network device going away. In the case of a device going away we clear any 788 * related entries from the unlabeled connection hash table. 789 * 790 */ 791 static int netlbl_unlhsh_netdev_handler(struct notifier_block *this, 792 unsigned long event, 793 void *ptr) 794 { 795 struct net_device *dev = ptr; 796 struct netlbl_unlhsh_iface *iface = NULL; 797 798 if (!net_eq(dev_net(dev), &init_net)) 799 return NOTIFY_DONE; 800 801 /* XXX - should this be a check for NETDEV_DOWN or _UNREGISTER? */ 802 if (event == NETDEV_DOWN) { 803 spin_lock(&netlbl_unlhsh_lock); 804 iface = netlbl_unlhsh_search_iface(dev->ifindex); 805 if (iface != NULL && iface->valid) { 806 iface->valid = 0; 807 list_del_rcu(&iface->list); 808 } else 809 iface = NULL; 810 spin_unlock(&netlbl_unlhsh_lock); 811 } 812 813 if (iface != NULL) 814 call_rcu(&iface->rcu, netlbl_unlhsh_free_iface); 815 816 return NOTIFY_DONE; 817 } 818 819 /** 820 * netlbl_unlabel_acceptflg_set - Set the unlabeled accept flag 821 * @value: desired value 822 * @audit_info: NetLabel audit information 823 * 824 * Description: 825 * Set the value of the unlabeled accept flag to @value. 826 * 827 */ 828 static void netlbl_unlabel_acceptflg_set(u8 value, 829 struct netlbl_audit *audit_info) 830 { 831 struct audit_buffer *audit_buf; 832 u8 old_val; 833 834 old_val = netlabel_unlabel_acceptflg; 835 netlabel_unlabel_acceptflg = value; 836 audit_buf = netlbl_audit_start_common(AUDIT_MAC_UNLBL_ALLOW, 837 audit_info); 838 if (audit_buf != NULL) { 839 audit_log_format(audit_buf, 840 " unlbl_accept=%u old=%u", value, old_val); 841 audit_log_end(audit_buf); 842 } 843 } 844 845 /** 846 * netlbl_unlabel_addrinfo_get - Get the IPv4/6 address information 847 * @info: the Generic NETLINK info block 848 * @addr: the IP address 849 * @mask: the IP address mask 850 * @len: the address length 851 * 852 * Description: 853 * Examine the Generic NETLINK message and extract the IP address information. 854 * Returns zero on success, negative values on failure. 855 * 856 */ 857 static int netlbl_unlabel_addrinfo_get(struct genl_info *info, 858 void **addr, 859 void **mask, 860 u32 *len) 861 { 862 u32 addr_len; 863 864 if (info->attrs[NLBL_UNLABEL_A_IPV4ADDR]) { 865 addr_len = nla_len(info->attrs[NLBL_UNLABEL_A_IPV4ADDR]); 866 if (addr_len != sizeof(struct in_addr) && 867 addr_len != nla_len(info->attrs[NLBL_UNLABEL_A_IPV4MASK])) 868 return -EINVAL; 869 *len = addr_len; 870 *addr = nla_data(info->attrs[NLBL_UNLABEL_A_IPV4ADDR]); 871 *mask = nla_data(info->attrs[NLBL_UNLABEL_A_IPV4MASK]); 872 return 0; 873 } else if (info->attrs[NLBL_UNLABEL_A_IPV6ADDR]) { 874 addr_len = nla_len(info->attrs[NLBL_UNLABEL_A_IPV6ADDR]); 875 if (addr_len != sizeof(struct in6_addr) && 876 addr_len != nla_len(info->attrs[NLBL_UNLABEL_A_IPV6MASK])) 877 return -EINVAL; 878 *len = addr_len; 879 *addr = nla_data(info->attrs[NLBL_UNLABEL_A_IPV6ADDR]); 880 *mask = nla_data(info->attrs[NLBL_UNLABEL_A_IPV6MASK]); 881 return 0; 882 } 883 884 return -EINVAL; 885 } 886 887 /* 888 * NetLabel Command Handlers 889 */ 890 891 /** 892 * netlbl_unlabel_accept - Handle an ACCEPT message 893 * @skb: the NETLINK buffer 894 * @info: the Generic NETLINK info block 895 * 896 * Description: 897 * Process a user generated ACCEPT message and set the accept flag accordingly. 898 * Returns zero on success, negative values on failure. 899 * 900 */ 901 static int netlbl_unlabel_accept(struct sk_buff *skb, struct genl_info *info) 902 { 903 u8 value; 904 struct netlbl_audit audit_info; 905 906 if (info->attrs[NLBL_UNLABEL_A_ACPTFLG]) { 907 value = nla_get_u8(info->attrs[NLBL_UNLABEL_A_ACPTFLG]); 908 if (value == 1 || value == 0) { 909 netlbl_netlink_auditinfo(skb, &audit_info); 910 netlbl_unlabel_acceptflg_set(value, &audit_info); 911 return 0; 912 } 913 } 914 915 return -EINVAL; 916 } 917 918 /** 919 * netlbl_unlabel_list - Handle a LIST message 920 * @skb: the NETLINK buffer 921 * @info: the Generic NETLINK info block 922 * 923 * Description: 924 * Process a user generated LIST message and respond with the current status. 925 * Returns zero on success, negative values on failure. 926 * 927 */ 928 static int netlbl_unlabel_list(struct sk_buff *skb, struct genl_info *info) 929 { 930 int ret_val = -EINVAL; 931 struct sk_buff *ans_skb; 932 void *data; 933 934 ans_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 935 if (ans_skb == NULL) 936 goto list_failure; 937 data = genlmsg_put_reply(ans_skb, info, &netlbl_unlabel_gnl_family, 938 0, NLBL_UNLABEL_C_LIST); 939 if (data == NULL) { 940 ret_val = -ENOMEM; 941 goto list_failure; 942 } 943 944 ret_val = nla_put_u8(ans_skb, 945 NLBL_UNLABEL_A_ACPTFLG, 946 netlabel_unlabel_acceptflg); 947 if (ret_val != 0) 948 goto list_failure; 949 950 genlmsg_end(ans_skb, data); 951 return genlmsg_reply(ans_skb, info); 952 953 list_failure: 954 kfree_skb(ans_skb); 955 return ret_val; 956 } 957 958 /** 959 * netlbl_unlabel_staticadd - Handle a STATICADD message 960 * @skb: the NETLINK buffer 961 * @info: the Generic NETLINK info block 962 * 963 * Description: 964 * Process a user generated STATICADD message and add a new unlabeled 965 * connection entry to the hash table. Returns zero on success, negative 966 * values on failure. 967 * 968 */ 969 static int netlbl_unlabel_staticadd(struct sk_buff *skb, 970 struct genl_info *info) 971 { 972 int ret_val; 973 char *dev_name; 974 void *addr; 975 void *mask; 976 u32 addr_len; 977 u32 secid; 978 struct netlbl_audit audit_info; 979 980 /* Don't allow users to add both IPv4 and IPv6 addresses for a 981 * single entry. However, allow users to create two entries, one each 982 * for IPv4 and IPv4, with the same LSM security context which should 983 * achieve the same result. */ 984 if (!info->attrs[NLBL_UNLABEL_A_SECCTX] || 985 !info->attrs[NLBL_UNLABEL_A_IFACE] || 986 !((!info->attrs[NLBL_UNLABEL_A_IPV4ADDR] || 987 !info->attrs[NLBL_UNLABEL_A_IPV4MASK]) ^ 988 (!info->attrs[NLBL_UNLABEL_A_IPV6ADDR] || 989 !info->attrs[NLBL_UNLABEL_A_IPV6MASK]))) 990 return -EINVAL; 991 992 netlbl_netlink_auditinfo(skb, &audit_info); 993 994 ret_val = netlbl_unlabel_addrinfo_get(info, &addr, &mask, &addr_len); 995 if (ret_val != 0) 996 return ret_val; 997 dev_name = nla_data(info->attrs[NLBL_UNLABEL_A_IFACE]); 998 ret_val = security_secctx_to_secid( 999 nla_data(info->attrs[NLBL_UNLABEL_A_SECCTX]), 1000 nla_len(info->attrs[NLBL_UNLABEL_A_SECCTX]), 1001 &secid); 1002 if (ret_val != 0) 1003 return ret_val; 1004 1005 return netlbl_unlhsh_add(&init_net, 1006 dev_name, addr, mask, addr_len, secid, 1007 &audit_info); 1008 } 1009 1010 /** 1011 * netlbl_unlabel_staticadddef - Handle a STATICADDDEF message 1012 * @skb: the NETLINK buffer 1013 * @info: the Generic NETLINK info block 1014 * 1015 * Description: 1016 * Process a user generated STATICADDDEF message and add a new default 1017 * unlabeled connection entry. Returns zero on success, negative values on 1018 * failure. 1019 * 1020 */ 1021 static int netlbl_unlabel_staticadddef(struct sk_buff *skb, 1022 struct genl_info *info) 1023 { 1024 int ret_val; 1025 void *addr; 1026 void *mask; 1027 u32 addr_len; 1028 u32 secid; 1029 struct netlbl_audit audit_info; 1030 1031 /* Don't allow users to add both IPv4 and IPv6 addresses for a 1032 * single entry. However, allow users to create two entries, one each 1033 * for IPv4 and IPv6, with the same LSM security context which should 1034 * achieve the same result. */ 1035 if (!info->attrs[NLBL_UNLABEL_A_SECCTX] || 1036 !((!info->attrs[NLBL_UNLABEL_A_IPV4ADDR] || 1037 !info->attrs[NLBL_UNLABEL_A_IPV4MASK]) ^ 1038 (!info->attrs[NLBL_UNLABEL_A_IPV6ADDR] || 1039 !info->attrs[NLBL_UNLABEL_A_IPV6MASK]))) 1040 return -EINVAL; 1041 1042 netlbl_netlink_auditinfo(skb, &audit_info); 1043 1044 ret_val = netlbl_unlabel_addrinfo_get(info, &addr, &mask, &addr_len); 1045 if (ret_val != 0) 1046 return ret_val; 1047 ret_val = security_secctx_to_secid( 1048 nla_data(info->attrs[NLBL_UNLABEL_A_SECCTX]), 1049 nla_len(info->attrs[NLBL_UNLABEL_A_SECCTX]), 1050 &secid); 1051 if (ret_val != 0) 1052 return ret_val; 1053 1054 return netlbl_unlhsh_add(&init_net, 1055 NULL, addr, mask, addr_len, secid, 1056 &audit_info); 1057 } 1058 1059 /** 1060 * netlbl_unlabel_staticremove - Handle a STATICREMOVE message 1061 * @skb: the NETLINK buffer 1062 * @info: the Generic NETLINK info block 1063 * 1064 * Description: 1065 * Process a user generated STATICREMOVE message and remove the specified 1066 * unlabeled connection entry. Returns zero on success, negative values on 1067 * failure. 1068 * 1069 */ 1070 static int netlbl_unlabel_staticremove(struct sk_buff *skb, 1071 struct genl_info *info) 1072 { 1073 int ret_val; 1074 char *dev_name; 1075 void *addr; 1076 void *mask; 1077 u32 addr_len; 1078 struct netlbl_audit audit_info; 1079 1080 /* See the note in netlbl_unlabel_staticadd() about not allowing both 1081 * IPv4 and IPv6 in the same entry. */ 1082 if (!info->attrs[NLBL_UNLABEL_A_IFACE] || 1083 !((!info->attrs[NLBL_UNLABEL_A_IPV4ADDR] || 1084 !info->attrs[NLBL_UNLABEL_A_IPV4MASK]) ^ 1085 (!info->attrs[NLBL_UNLABEL_A_IPV6ADDR] || 1086 !info->attrs[NLBL_UNLABEL_A_IPV6MASK]))) 1087 return -EINVAL; 1088 1089 netlbl_netlink_auditinfo(skb, &audit_info); 1090 1091 ret_val = netlbl_unlabel_addrinfo_get(info, &addr, &mask, &addr_len); 1092 if (ret_val != 0) 1093 return ret_val; 1094 dev_name = nla_data(info->attrs[NLBL_UNLABEL_A_IFACE]); 1095 1096 return netlbl_unlhsh_remove(&init_net, 1097 dev_name, addr, mask, addr_len, 1098 &audit_info); 1099 } 1100 1101 /** 1102 * netlbl_unlabel_staticremovedef - Handle a STATICREMOVEDEF message 1103 * @skb: the NETLINK buffer 1104 * @info: the Generic NETLINK info block 1105 * 1106 * Description: 1107 * Process a user generated STATICREMOVEDEF message and remove the default 1108 * unlabeled connection entry. Returns zero on success, negative values on 1109 * failure. 1110 * 1111 */ 1112 static int netlbl_unlabel_staticremovedef(struct sk_buff *skb, 1113 struct genl_info *info) 1114 { 1115 int ret_val; 1116 void *addr; 1117 void *mask; 1118 u32 addr_len; 1119 struct netlbl_audit audit_info; 1120 1121 /* See the note in netlbl_unlabel_staticadd() about not allowing both 1122 * IPv4 and IPv6 in the same entry. */ 1123 if (!((!info->attrs[NLBL_UNLABEL_A_IPV4ADDR] || 1124 !info->attrs[NLBL_UNLABEL_A_IPV4MASK]) ^ 1125 (!info->attrs[NLBL_UNLABEL_A_IPV6ADDR] || 1126 !info->attrs[NLBL_UNLABEL_A_IPV6MASK]))) 1127 return -EINVAL; 1128 1129 netlbl_netlink_auditinfo(skb, &audit_info); 1130 1131 ret_val = netlbl_unlabel_addrinfo_get(info, &addr, &mask, &addr_len); 1132 if (ret_val != 0) 1133 return ret_val; 1134 1135 return netlbl_unlhsh_remove(&init_net, 1136 NULL, addr, mask, addr_len, 1137 &audit_info); 1138 } 1139 1140 1141 /** 1142 * netlbl_unlabel_staticlist_gen - Generate messages for STATICLIST[DEF] 1143 * @cmd: command/message 1144 * @iface: the interface entry 1145 * @addr4: the IPv4 address entry 1146 * @addr6: the IPv6 address entry 1147 * @arg: the netlbl_unlhsh_walk_arg structure 1148 * 1149 * Description: 1150 * This function is designed to be used to generate a response for a 1151 * STATICLIST or STATICLISTDEF message. When called either @addr4 or @addr6 1152 * can be specified, not both, the other unspecified entry should be set to 1153 * NULL by the caller. Returns the size of the message on success, negative 1154 * values on failure. 1155 * 1156 */ 1157 static int netlbl_unlabel_staticlist_gen(u32 cmd, 1158 const struct netlbl_unlhsh_iface *iface, 1159 const struct netlbl_unlhsh_addr4 *addr4, 1160 const struct netlbl_unlhsh_addr6 *addr6, 1161 void *arg) 1162 { 1163 int ret_val = -ENOMEM; 1164 struct netlbl_unlhsh_walk_arg *cb_arg = arg; 1165 struct net_device *dev; 1166 void *data; 1167 u32 secid; 1168 char *secctx; 1169 u32 secctx_len; 1170 1171 data = genlmsg_put(cb_arg->skb, NETLINK_CB(cb_arg->nl_cb->skb).pid, 1172 cb_arg->seq, &netlbl_unlabel_gnl_family, 1173 NLM_F_MULTI, cmd); 1174 if (data == NULL) 1175 goto list_cb_failure; 1176 1177 if (iface->ifindex > 0) { 1178 dev = dev_get_by_index(&init_net, iface->ifindex); 1179 if (!dev) { 1180 ret_val = -ENODEV; 1181 goto list_cb_failure; 1182 } 1183 ret_val = nla_put_string(cb_arg->skb, 1184 NLBL_UNLABEL_A_IFACE, dev->name); 1185 dev_put(dev); 1186 if (ret_val != 0) 1187 goto list_cb_failure; 1188 } 1189 1190 if (addr4) { 1191 struct in_addr addr_struct; 1192 1193 addr_struct.s_addr = addr4->list.addr; 1194 ret_val = nla_put(cb_arg->skb, 1195 NLBL_UNLABEL_A_IPV4ADDR, 1196 sizeof(struct in_addr), 1197 &addr_struct); 1198 if (ret_val != 0) 1199 goto list_cb_failure; 1200 1201 addr_struct.s_addr = addr4->list.mask; 1202 ret_val = nla_put(cb_arg->skb, 1203 NLBL_UNLABEL_A_IPV4MASK, 1204 sizeof(struct in_addr), 1205 &addr_struct); 1206 if (ret_val != 0) 1207 goto list_cb_failure; 1208 1209 secid = addr4->secid; 1210 } else { 1211 ret_val = nla_put(cb_arg->skb, 1212 NLBL_UNLABEL_A_IPV6ADDR, 1213 sizeof(struct in6_addr), 1214 &addr6->list.addr); 1215 if (ret_val != 0) 1216 goto list_cb_failure; 1217 1218 ret_val = nla_put(cb_arg->skb, 1219 NLBL_UNLABEL_A_IPV6MASK, 1220 sizeof(struct in6_addr), 1221 &addr6->list.mask); 1222 if (ret_val != 0) 1223 goto list_cb_failure; 1224 1225 secid = addr6->secid; 1226 } 1227 1228 ret_val = security_secid_to_secctx(secid, &secctx, &secctx_len); 1229 if (ret_val != 0) 1230 goto list_cb_failure; 1231 ret_val = nla_put(cb_arg->skb, 1232 NLBL_UNLABEL_A_SECCTX, 1233 secctx_len, 1234 secctx); 1235 security_release_secctx(secctx, secctx_len); 1236 if (ret_val != 0) 1237 goto list_cb_failure; 1238 1239 cb_arg->seq++; 1240 return genlmsg_end(cb_arg->skb, data); 1241 1242 list_cb_failure: 1243 genlmsg_cancel(cb_arg->skb, data); 1244 return ret_val; 1245 } 1246 1247 /** 1248 * netlbl_unlabel_staticlist - Handle a STATICLIST message 1249 * @skb: the NETLINK buffer 1250 * @cb: the NETLINK callback 1251 * 1252 * Description: 1253 * Process a user generated STATICLIST message and dump the unlabeled 1254 * connection hash table in a form suitable for use in a kernel generated 1255 * STATICLIST message. Returns the length of @skb. 1256 * 1257 */ 1258 static int netlbl_unlabel_staticlist(struct sk_buff *skb, 1259 struct netlink_callback *cb) 1260 { 1261 struct netlbl_unlhsh_walk_arg cb_arg; 1262 u32 skip_bkt = cb->args[0]; 1263 u32 skip_chain = cb->args[1]; 1264 u32 skip_addr4 = cb->args[2]; 1265 u32 skip_addr6 = cb->args[3]; 1266 u32 iter_bkt; 1267 u32 iter_chain = 0, iter_addr4 = 0, iter_addr6 = 0; 1268 struct netlbl_unlhsh_iface *iface; 1269 struct list_head *iter_list; 1270 struct netlbl_af4list *addr4; 1271 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 1272 struct netlbl_af6list *addr6; 1273 #endif 1274 1275 cb_arg.nl_cb = cb; 1276 cb_arg.skb = skb; 1277 cb_arg.seq = cb->nlh->nlmsg_seq; 1278 1279 rcu_read_lock(); 1280 for (iter_bkt = skip_bkt; 1281 iter_bkt < rcu_dereference(netlbl_unlhsh)->size; 1282 iter_bkt++, iter_chain = 0, iter_addr4 = 0, iter_addr6 = 0) { 1283 iter_list = &rcu_dereference(netlbl_unlhsh)->tbl[iter_bkt]; 1284 list_for_each_entry_rcu(iface, iter_list, list) { 1285 if (!iface->valid || 1286 iter_chain++ < skip_chain) 1287 continue; 1288 netlbl_af4list_foreach_rcu(addr4, 1289 &iface->addr4_list) { 1290 if (iter_addr4++ < skip_addr4) 1291 continue; 1292 if (netlbl_unlabel_staticlist_gen( 1293 NLBL_UNLABEL_C_STATICLIST, 1294 iface, 1295 netlbl_unlhsh_addr4_entry(addr4), 1296 NULL, 1297 &cb_arg) < 0) { 1298 iter_addr4--; 1299 iter_chain--; 1300 goto unlabel_staticlist_return; 1301 } 1302 } 1303 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 1304 netlbl_af6list_foreach_rcu(addr6, 1305 &iface->addr6_list) { 1306 if (iter_addr6++ < skip_addr6) 1307 continue; 1308 if (netlbl_unlabel_staticlist_gen( 1309 NLBL_UNLABEL_C_STATICLIST, 1310 iface, 1311 NULL, 1312 netlbl_unlhsh_addr6_entry(addr6), 1313 &cb_arg) < 0) { 1314 iter_addr6--; 1315 iter_chain--; 1316 goto unlabel_staticlist_return; 1317 } 1318 } 1319 #endif /* IPv6 */ 1320 } 1321 } 1322 1323 unlabel_staticlist_return: 1324 rcu_read_unlock(); 1325 cb->args[0] = skip_bkt; 1326 cb->args[1] = skip_chain; 1327 cb->args[2] = skip_addr4; 1328 cb->args[3] = skip_addr6; 1329 return skb->len; 1330 } 1331 1332 /** 1333 * netlbl_unlabel_staticlistdef - Handle a STATICLISTDEF message 1334 * @skb: the NETLINK buffer 1335 * @cb: the NETLINK callback 1336 * 1337 * Description: 1338 * Process a user generated STATICLISTDEF message and dump the default 1339 * unlabeled connection entry in a form suitable for use in a kernel generated 1340 * STATICLISTDEF message. Returns the length of @skb. 1341 * 1342 */ 1343 static int netlbl_unlabel_staticlistdef(struct sk_buff *skb, 1344 struct netlink_callback *cb) 1345 { 1346 struct netlbl_unlhsh_walk_arg cb_arg; 1347 struct netlbl_unlhsh_iface *iface; 1348 u32 skip_addr4 = cb->args[0]; 1349 u32 skip_addr6 = cb->args[1]; 1350 u32 iter_addr4 = 0; 1351 struct netlbl_af4list *addr4; 1352 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 1353 u32 iter_addr6 = 0; 1354 struct netlbl_af6list *addr6; 1355 #endif 1356 1357 cb_arg.nl_cb = cb; 1358 cb_arg.skb = skb; 1359 cb_arg.seq = cb->nlh->nlmsg_seq; 1360 1361 rcu_read_lock(); 1362 iface = rcu_dereference(netlbl_unlhsh_def); 1363 if (iface == NULL || !iface->valid) 1364 goto unlabel_staticlistdef_return; 1365 1366 netlbl_af4list_foreach_rcu(addr4, &iface->addr4_list) { 1367 if (iter_addr4++ < skip_addr4) 1368 continue; 1369 if (netlbl_unlabel_staticlist_gen(NLBL_UNLABEL_C_STATICLISTDEF, 1370 iface, 1371 netlbl_unlhsh_addr4_entry(addr4), 1372 NULL, 1373 &cb_arg) < 0) { 1374 iter_addr4--; 1375 goto unlabel_staticlistdef_return; 1376 } 1377 } 1378 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 1379 netlbl_af6list_foreach_rcu(addr6, &iface->addr6_list) { 1380 if (iter_addr6++ < skip_addr6) 1381 continue; 1382 if (netlbl_unlabel_staticlist_gen(NLBL_UNLABEL_C_STATICLISTDEF, 1383 iface, 1384 NULL, 1385 netlbl_unlhsh_addr6_entry(addr6), 1386 &cb_arg) < 0) { 1387 iter_addr6--; 1388 goto unlabel_staticlistdef_return; 1389 } 1390 } 1391 #endif /* IPv6 */ 1392 1393 unlabel_staticlistdef_return: 1394 rcu_read_unlock(); 1395 cb->args[0] = skip_addr4; 1396 cb->args[1] = skip_addr6; 1397 return skb->len; 1398 } 1399 1400 /* 1401 * NetLabel Generic NETLINK Command Definitions 1402 */ 1403 1404 static struct genl_ops netlbl_unlabel_genl_ops[] = { 1405 { 1406 .cmd = NLBL_UNLABEL_C_STATICADD, 1407 .flags = GENL_ADMIN_PERM, 1408 .policy = netlbl_unlabel_genl_policy, 1409 .doit = netlbl_unlabel_staticadd, 1410 .dumpit = NULL, 1411 }, 1412 { 1413 .cmd = NLBL_UNLABEL_C_STATICREMOVE, 1414 .flags = GENL_ADMIN_PERM, 1415 .policy = netlbl_unlabel_genl_policy, 1416 .doit = netlbl_unlabel_staticremove, 1417 .dumpit = NULL, 1418 }, 1419 { 1420 .cmd = NLBL_UNLABEL_C_STATICLIST, 1421 .flags = 0, 1422 .policy = netlbl_unlabel_genl_policy, 1423 .doit = NULL, 1424 .dumpit = netlbl_unlabel_staticlist, 1425 }, 1426 { 1427 .cmd = NLBL_UNLABEL_C_STATICADDDEF, 1428 .flags = GENL_ADMIN_PERM, 1429 .policy = netlbl_unlabel_genl_policy, 1430 .doit = netlbl_unlabel_staticadddef, 1431 .dumpit = NULL, 1432 }, 1433 { 1434 .cmd = NLBL_UNLABEL_C_STATICREMOVEDEF, 1435 .flags = GENL_ADMIN_PERM, 1436 .policy = netlbl_unlabel_genl_policy, 1437 .doit = netlbl_unlabel_staticremovedef, 1438 .dumpit = NULL, 1439 }, 1440 { 1441 .cmd = NLBL_UNLABEL_C_STATICLISTDEF, 1442 .flags = 0, 1443 .policy = netlbl_unlabel_genl_policy, 1444 .doit = NULL, 1445 .dumpit = netlbl_unlabel_staticlistdef, 1446 }, 1447 { 1448 .cmd = NLBL_UNLABEL_C_ACCEPT, 1449 .flags = GENL_ADMIN_PERM, 1450 .policy = netlbl_unlabel_genl_policy, 1451 .doit = netlbl_unlabel_accept, 1452 .dumpit = NULL, 1453 }, 1454 { 1455 .cmd = NLBL_UNLABEL_C_LIST, 1456 .flags = 0, 1457 .policy = netlbl_unlabel_genl_policy, 1458 .doit = netlbl_unlabel_list, 1459 .dumpit = NULL, 1460 }, 1461 }; 1462 1463 /* 1464 * NetLabel Generic NETLINK Protocol Functions 1465 */ 1466 1467 /** 1468 * netlbl_unlabel_genl_init - Register the Unlabeled NetLabel component 1469 * 1470 * Description: 1471 * Register the unlabeled packet NetLabel component with the Generic NETLINK 1472 * mechanism. Returns zero on success, negative values on failure. 1473 * 1474 */ 1475 int __init netlbl_unlabel_genl_init(void) 1476 { 1477 int ret_val, i; 1478 1479 ret_val = genl_register_family(&netlbl_unlabel_gnl_family); 1480 if (ret_val != 0) 1481 return ret_val; 1482 1483 for (i = 0; i < ARRAY_SIZE(netlbl_unlabel_genl_ops); i++) { 1484 ret_val = genl_register_ops(&netlbl_unlabel_gnl_family, 1485 &netlbl_unlabel_genl_ops[i]); 1486 if (ret_val != 0) 1487 return ret_val; 1488 } 1489 1490 return 0; 1491 } 1492 1493 /* 1494 * NetLabel KAPI Hooks 1495 */ 1496 1497 static struct notifier_block netlbl_unlhsh_netdev_notifier = { 1498 .notifier_call = netlbl_unlhsh_netdev_handler, 1499 }; 1500 1501 /** 1502 * netlbl_unlabel_init - Initialize the unlabeled connection hash table 1503 * @size: the number of bits to use for the hash buckets 1504 * 1505 * Description: 1506 * Initializes the unlabeled connection hash table and registers a network 1507 * device notification handler. This function should only be called by the 1508 * NetLabel subsystem itself during initialization. Returns zero on success, 1509 * non-zero values on error. 1510 * 1511 */ 1512 int __init netlbl_unlabel_init(u32 size) 1513 { 1514 u32 iter; 1515 struct netlbl_unlhsh_tbl *hsh_tbl; 1516 1517 if (size == 0) 1518 return -EINVAL; 1519 1520 hsh_tbl = kmalloc(sizeof(*hsh_tbl), GFP_KERNEL); 1521 if (hsh_tbl == NULL) 1522 return -ENOMEM; 1523 hsh_tbl->size = 1 << size; 1524 hsh_tbl->tbl = kcalloc(hsh_tbl->size, 1525 sizeof(struct list_head), 1526 GFP_KERNEL); 1527 if (hsh_tbl->tbl == NULL) { 1528 kfree(hsh_tbl); 1529 return -ENOMEM; 1530 } 1531 for (iter = 0; iter < hsh_tbl->size; iter++) 1532 INIT_LIST_HEAD(&hsh_tbl->tbl[iter]); 1533 1534 rcu_read_lock(); 1535 spin_lock(&netlbl_unlhsh_lock); 1536 rcu_assign_pointer(netlbl_unlhsh, hsh_tbl); 1537 spin_unlock(&netlbl_unlhsh_lock); 1538 rcu_read_unlock(); 1539 1540 register_netdevice_notifier(&netlbl_unlhsh_netdev_notifier); 1541 1542 return 0; 1543 } 1544 1545 /** 1546 * netlbl_unlabel_getattr - Get the security attributes for an unlabled packet 1547 * @skb: the packet 1548 * @family: protocol family 1549 * @secattr: the security attributes 1550 * 1551 * Description: 1552 * Determine the security attributes, if any, for an unlabled packet and return 1553 * them in @secattr. Returns zero on success and negative values on failure. 1554 * 1555 */ 1556 int netlbl_unlabel_getattr(const struct sk_buff *skb, 1557 u16 family, 1558 struct netlbl_lsm_secattr *secattr) 1559 { 1560 struct netlbl_unlhsh_iface *iface; 1561 1562 rcu_read_lock(); 1563 iface = netlbl_unlhsh_search_iface_def(skb->iif); 1564 if (iface == NULL) 1565 goto unlabel_getattr_nolabel; 1566 switch (family) { 1567 case PF_INET: { 1568 struct iphdr *hdr4; 1569 struct netlbl_af4list *addr4; 1570 1571 hdr4 = ip_hdr(skb); 1572 addr4 = netlbl_af4list_search(hdr4->saddr, 1573 &iface->addr4_list); 1574 if (addr4 == NULL) 1575 goto unlabel_getattr_nolabel; 1576 secattr->attr.secid = netlbl_unlhsh_addr4_entry(addr4)->secid; 1577 break; 1578 } 1579 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 1580 case PF_INET6: { 1581 struct ipv6hdr *hdr6; 1582 struct netlbl_af6list *addr6; 1583 1584 hdr6 = ipv6_hdr(skb); 1585 addr6 = netlbl_af6list_search(&hdr6->saddr, 1586 &iface->addr6_list); 1587 if (addr6 == NULL) 1588 goto unlabel_getattr_nolabel; 1589 secattr->attr.secid = netlbl_unlhsh_addr6_entry(addr6)->secid; 1590 break; 1591 } 1592 #endif /* IPv6 */ 1593 default: 1594 goto unlabel_getattr_nolabel; 1595 } 1596 rcu_read_unlock(); 1597 1598 secattr->flags |= NETLBL_SECATTR_SECID; 1599 secattr->type = NETLBL_NLTYPE_UNLABELED; 1600 return 0; 1601 1602 unlabel_getattr_nolabel: 1603 rcu_read_unlock(); 1604 if (netlabel_unlabel_acceptflg == 0) 1605 return -ENOMSG; 1606 secattr->type = NETLBL_NLTYPE_UNLABELED; 1607 return 0; 1608 } 1609 1610 /** 1611 * netlbl_unlabel_defconf - Set the default config to allow unlabeled packets 1612 * 1613 * Description: 1614 * Set the default NetLabel configuration to allow incoming unlabeled packets 1615 * and to send unlabeled network traffic by default. 1616 * 1617 */ 1618 int __init netlbl_unlabel_defconf(void) 1619 { 1620 int ret_val; 1621 struct netlbl_dom_map *entry; 1622 struct netlbl_audit audit_info; 1623 1624 /* Only the kernel is allowed to call this function and the only time 1625 * it is called is at bootup before the audit subsystem is reporting 1626 * messages so don't worry to much about these values. */ 1627 security_task_getsecid(current, &audit_info.secid); 1628 audit_info.loginuid = 0; 1629 audit_info.sessionid = 0; 1630 1631 entry = kzalloc(sizeof(*entry), GFP_KERNEL); 1632 if (entry == NULL) 1633 return -ENOMEM; 1634 entry->type = NETLBL_NLTYPE_UNLABELED; 1635 ret_val = netlbl_domhsh_add_default(entry, &audit_info); 1636 if (ret_val != 0) 1637 return ret_val; 1638 1639 netlbl_unlabel_acceptflg_set(1, &audit_info); 1640 1641 return 0; 1642 } 1643