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