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