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