^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 Kernel API
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * This file defines the kernel API for the NetLabel system. The NetLabel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * system manages static and dynamic label mappings for network protocols such
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * 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/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/audit.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/in.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/in6.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <net/ip.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <net/ipv6.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <net/netlabel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <net/cipso_ipv4.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <net/calipso.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <asm/bug.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/atomic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include "netlabel_domainhash.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include "netlabel_unlabeled.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include "netlabel_cipso_v4.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include "netlabel_calipso.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include "netlabel_user.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include "netlabel_mgmt.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include "netlabel_addrlist.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * Configuration Functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * netlbl_cfg_map_del - Remove a NetLabel/LSM domain mapping
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * @domain: the domain mapping to remove
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * @family: address family
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * @addr: IP address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * @mask: IP address mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * @audit_info: NetLabel audit information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * Removes a NetLabel/LSM domain mapping. A @domain value of NULL causes the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * default domain mapping to be removed. Returns zero on success, negative
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * values on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) int netlbl_cfg_map_del(const char *domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) u16 family,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) const void *addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) const void *mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) struct netlbl_audit *audit_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) if (addr == NULL && mask == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) return netlbl_domhsh_remove(domain, family, audit_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) } else if (addr != NULL && mask != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) switch (family) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) case AF_INET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) return netlbl_domhsh_remove_af4(domain, addr, mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) audit_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) case AF_INET6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) return netlbl_domhsh_remove_af6(domain, addr, mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) audit_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #endif /* IPv6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) return -EPFNOSUPPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) * netlbl_cfg_unlbl_map_add - Add a new unlabeled mapping
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) * @domain: the domain mapping to add
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) * @family: address family
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * @addr: IP address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) * @mask: IP address mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * @audit_info: NetLabel audit information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * Adds a new unlabeled NetLabel/LSM domain mapping. A @domain value of NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) * causes a new default domain mapping to be added. Returns zero on success,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) * negative values on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) int netlbl_cfg_unlbl_map_add(const char *domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) u16 family,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) const void *addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) const void *mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) struct netlbl_audit *audit_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) int ret_val = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) struct netlbl_dom_map *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) struct netlbl_domaddr_map *addrmap = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) struct netlbl_domaddr4_map *map4 = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) struct netlbl_domaddr6_map *map6 = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) if (entry == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) if (domain != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) entry->domain = kstrdup(domain, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) if (entry->domain == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) goto cfg_unlbl_map_add_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) entry->family = family;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) if (addr == NULL && mask == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) entry->def.type = NETLBL_NLTYPE_UNLABELED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) else if (addr != NULL && mask != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) addrmap = kzalloc(sizeof(*addrmap), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) if (addrmap == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) goto cfg_unlbl_map_add_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) INIT_LIST_HEAD(&addrmap->list4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) INIT_LIST_HEAD(&addrmap->list6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) switch (family) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) case AF_INET: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) const struct in_addr *addr4 = addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) const struct in_addr *mask4 = mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) map4 = kzalloc(sizeof(*map4), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) if (map4 == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) goto cfg_unlbl_map_add_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) map4->def.type = NETLBL_NLTYPE_UNLABELED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) map4->list.addr = addr4->s_addr & mask4->s_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) map4->list.mask = mask4->s_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) map4->list.valid = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) ret_val = netlbl_af4list_add(&map4->list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) &addrmap->list4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) if (ret_val != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) goto cfg_unlbl_map_add_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) case AF_INET6: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) const struct in6_addr *addr6 = addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) const struct in6_addr *mask6 = mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) map6 = kzalloc(sizeof(*map6), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) if (map6 == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) goto cfg_unlbl_map_add_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) map6->def.type = NETLBL_NLTYPE_UNLABELED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) map6->list.addr = *addr6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) map6->list.addr.s6_addr32[0] &= mask6->s6_addr32[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) map6->list.addr.s6_addr32[1] &= mask6->s6_addr32[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) map6->list.addr.s6_addr32[2] &= mask6->s6_addr32[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) map6->list.addr.s6_addr32[3] &= mask6->s6_addr32[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) map6->list.mask = *mask6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) map6->list.valid = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) ret_val = netlbl_af6list_add(&map6->list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) &addrmap->list6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) if (ret_val != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) goto cfg_unlbl_map_add_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) #endif /* IPv6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) goto cfg_unlbl_map_add_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) entry->def.addrsel = addrmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) entry->def.type = NETLBL_NLTYPE_ADDRSELECT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) ret_val = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) goto cfg_unlbl_map_add_failure;
^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) ret_val = netlbl_domhsh_add(entry, audit_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) if (ret_val != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) goto cfg_unlbl_map_add_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) cfg_unlbl_map_add_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) kfree(entry->domain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) kfree(entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) kfree(addrmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) kfree(map4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) kfree(map6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) return ret_val;
^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) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) * netlbl_cfg_unlbl_static_add - Adds a new static label
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) * @net: network namespace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * @dev_name: interface name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) * @addr: IP address in network byte order (struct in[6]_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) * @mask: address mask in network byte order (struct in[6]_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) * @family: address family
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) * @secid: LSM secid value for the entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) * @audit_info: NetLabel audit information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) * Adds a new NetLabel static label to be used when protocol provided labels
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) * are not present on incoming traffic. If @dev_name is NULL then the default
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) * interface will be used. Returns zero on success, negative values on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) int netlbl_cfg_unlbl_static_add(struct net *net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) const char *dev_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) const void *addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) const void *mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) u16 family,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) u32 secid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) struct netlbl_audit *audit_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) u32 addr_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) switch (family) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) case AF_INET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) addr_len = sizeof(struct in_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) case AF_INET6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) addr_len = sizeof(struct in6_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) #endif /* IPv6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) return -EPFNOSUPPORT;
^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) return netlbl_unlhsh_add(net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) dev_name, addr, mask, addr_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) secid, audit_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) * netlbl_cfg_unlbl_static_del - Removes an existing static label
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) * @net: network namespace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) * @dev_name: interface name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) * @addr: IP address in network byte order (struct in[6]_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) * @mask: address mask in network byte order (struct in[6]_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) * @family: address family
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) * @audit_info: NetLabel audit information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) * Removes an existing NetLabel static label used when protocol provided labels
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) * are not present on incoming traffic. If @dev_name is NULL then the default
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) * interface will be used. Returns zero on success, negative values on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) int netlbl_cfg_unlbl_static_del(struct net *net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) const char *dev_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) const void *addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) const void *mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) u16 family,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) struct netlbl_audit *audit_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) u32 addr_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) switch (family) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) case AF_INET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) addr_len = sizeof(struct in_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) case AF_INET6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) addr_len = sizeof(struct in6_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) #endif /* IPv6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) return -EPFNOSUPPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) return netlbl_unlhsh_remove(net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) dev_name, addr, mask, addr_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) audit_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) * netlbl_cfg_cipsov4_add - Add a new CIPSOv4 DOI definition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) * @doi_def: CIPSO DOI definition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) * @audit_info: NetLabel audit information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) * Add a new CIPSO DOI definition as defined by @doi_def. Returns zero on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) * success and negative values on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) int netlbl_cfg_cipsov4_add(struct cipso_v4_doi *doi_def,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) struct netlbl_audit *audit_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) return cipso_v4_doi_add(doi_def, audit_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) * netlbl_cfg_cipsov4_del - Remove an existing CIPSOv4 DOI definition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) * @doi: CIPSO DOI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) * @audit_info: NetLabel audit information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) * Remove an existing CIPSO DOI definition matching @doi. Returns zero on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) * success and negative values on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) void netlbl_cfg_cipsov4_del(u32 doi, struct netlbl_audit *audit_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) cipso_v4_doi_remove(doi, audit_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) * netlbl_cfg_cipsov4_map_add - Add a new CIPSOv4 DOI mapping
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) * @doi: the CIPSO DOI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) * @domain: the domain mapping to add
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) * @addr: IP address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) * @mask: IP address mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) * @audit_info: NetLabel audit information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) * Add a new NetLabel/LSM domain mapping for the given CIPSO DOI to the NetLabel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) * subsystem. A @domain value of NULL adds a new default domain mapping.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) * Returns zero on success, negative values on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) int netlbl_cfg_cipsov4_map_add(u32 doi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) const char *domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) const struct in_addr *addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) const struct in_addr *mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) struct netlbl_audit *audit_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) int ret_val = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) struct cipso_v4_doi *doi_def;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) struct netlbl_dom_map *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) struct netlbl_domaddr_map *addrmap = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) struct netlbl_domaddr4_map *addrinfo = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) doi_def = cipso_v4_doi_getdef(doi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) if (doi_def == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) if (entry == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) goto out_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) entry->family = AF_INET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) if (domain != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) entry->domain = kstrdup(domain, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) if (entry->domain == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) goto out_domain;
^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) if (addr == NULL && mask == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) entry->def.cipso = doi_def;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) entry->def.type = NETLBL_NLTYPE_CIPSOV4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) } else if (addr != NULL && mask != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) addrmap = kzalloc(sizeof(*addrmap), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) if (addrmap == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) goto out_addrmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) INIT_LIST_HEAD(&addrmap->list4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) INIT_LIST_HEAD(&addrmap->list6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) addrinfo = kzalloc(sizeof(*addrinfo), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) if (addrinfo == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) goto out_addrinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) addrinfo->def.cipso = doi_def;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) addrinfo->def.type = NETLBL_NLTYPE_CIPSOV4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) addrinfo->list.addr = addr->s_addr & mask->s_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) addrinfo->list.mask = mask->s_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) addrinfo->list.valid = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) ret_val = netlbl_af4list_add(&addrinfo->list, &addrmap->list4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) if (ret_val != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) goto cfg_cipsov4_map_add_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) entry->def.addrsel = addrmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) entry->def.type = NETLBL_NLTYPE_ADDRSELECT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) ret_val = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) goto out_addrmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) ret_val = netlbl_domhsh_add(entry, audit_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) if (ret_val != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) goto cfg_cipsov4_map_add_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) cfg_cipsov4_map_add_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) kfree(addrinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) out_addrinfo:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) kfree(addrmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) out_addrmap:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) kfree(entry->domain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) out_domain:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) kfree(entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) out_entry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) cipso_v4_doi_putdef(doi_def);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) return ret_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) * netlbl_cfg_calipso_add - Add a new CALIPSO DOI definition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) * @doi_def: CALIPSO DOI definition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) * @audit_info: NetLabel audit information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) * Add a new CALIPSO DOI definition as defined by @doi_def. Returns zero on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) * success and negative values on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) int netlbl_cfg_calipso_add(struct calipso_doi *doi_def,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) struct netlbl_audit *audit_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) return calipso_doi_add(doi_def, audit_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) #else /* IPv6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) return -ENOSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) #endif /* IPv6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) * netlbl_cfg_calipso_del - Remove an existing CALIPSO DOI definition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) * @doi: CALIPSO DOI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) * @audit_info: NetLabel audit information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) * Remove an existing CALIPSO DOI definition matching @doi. Returns zero on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) * success and negative values on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) void netlbl_cfg_calipso_del(u32 doi, struct netlbl_audit *audit_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) calipso_doi_remove(doi, audit_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) #endif /* IPv6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) * netlbl_cfg_calipso_map_add - Add a new CALIPSO DOI mapping
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) * @doi: the CALIPSO DOI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) * @domain: the domain mapping to add
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) * @addr: IP address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) * @mask: IP address mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) * @audit_info: NetLabel audit information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) * Add a new NetLabel/LSM domain mapping for the given CALIPSO DOI to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) * NetLabel subsystem. A @domain value of NULL adds a new default domain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) * mapping. Returns zero on success, negative values on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) int netlbl_cfg_calipso_map_add(u32 doi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) const char *domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) const struct in6_addr *addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) const struct in6_addr *mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) struct netlbl_audit *audit_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) int ret_val = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) struct calipso_doi *doi_def;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) struct netlbl_dom_map *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) struct netlbl_domaddr_map *addrmap = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) struct netlbl_domaddr6_map *addrinfo = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) doi_def = calipso_doi_getdef(doi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) if (doi_def == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) if (entry == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) goto out_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) entry->family = AF_INET6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) if (domain != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) entry->domain = kstrdup(domain, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) if (entry->domain == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) goto out_domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) if (addr == NULL && mask == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) entry->def.calipso = doi_def;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) entry->def.type = NETLBL_NLTYPE_CALIPSO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) } else if (addr != NULL && mask != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) addrmap = kzalloc(sizeof(*addrmap), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) if (addrmap == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) goto out_addrmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) INIT_LIST_HEAD(&addrmap->list4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) INIT_LIST_HEAD(&addrmap->list6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) addrinfo = kzalloc(sizeof(*addrinfo), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) if (addrinfo == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) goto out_addrinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) addrinfo->def.calipso = doi_def;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) addrinfo->def.type = NETLBL_NLTYPE_CALIPSO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) addrinfo->list.addr = *addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) addrinfo->list.addr.s6_addr32[0] &= mask->s6_addr32[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) addrinfo->list.addr.s6_addr32[1] &= mask->s6_addr32[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) addrinfo->list.addr.s6_addr32[2] &= mask->s6_addr32[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) addrinfo->list.addr.s6_addr32[3] &= mask->s6_addr32[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) addrinfo->list.mask = *mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) addrinfo->list.valid = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) ret_val = netlbl_af6list_add(&addrinfo->list, &addrmap->list6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) if (ret_val != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) goto cfg_calipso_map_add_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) entry->def.addrsel = addrmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) entry->def.type = NETLBL_NLTYPE_ADDRSELECT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) ret_val = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) goto out_addrmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) ret_val = netlbl_domhsh_add(entry, audit_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) if (ret_val != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) goto cfg_calipso_map_add_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) cfg_calipso_map_add_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) kfree(addrinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) out_addrinfo:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) kfree(addrmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) out_addrmap:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) kfree(entry->domain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) out_domain:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) kfree(entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) out_entry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) calipso_doi_putdef(doi_def);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) return ret_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) #else /* IPv6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) return -ENOSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) #endif /* IPv6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) * Security Attribute Functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) #define _CM_F_NONE 0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) #define _CM_F_ALLOC 0x00000001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) #define _CM_F_WALK 0x00000002
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) * _netlbl_catmap_getnode - Get a individual node from a catmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) * @catmap: pointer to the category bitmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) * @offset: the requested offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) * @cm_flags: catmap flags, see _CM_F_*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) * @gfp_flags: memory allocation flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) * Iterate through the catmap looking for the node associated with @offset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) * If the _CM_F_ALLOC flag is set in @cm_flags and there is no associated node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) * one will be created and inserted into the catmap. If the _CM_F_WALK flag is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) * set in @cm_flags and there is no associated node, the next highest node will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) * be returned. Returns a pointer to the node on success, NULL on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) static struct netlbl_lsm_catmap *_netlbl_catmap_getnode(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) struct netlbl_lsm_catmap **catmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) u32 offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) unsigned int cm_flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) gfp_t gfp_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) struct netlbl_lsm_catmap *iter = *catmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) struct netlbl_lsm_catmap *prev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) if (iter == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) goto catmap_getnode_alloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) if (offset < iter->startbit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) goto catmap_getnode_walk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) while (iter && offset >= (iter->startbit + NETLBL_CATMAP_SIZE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) prev = iter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) iter = iter->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) if (iter == NULL || offset < iter->startbit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) goto catmap_getnode_walk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) return iter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) catmap_getnode_walk:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) if (cm_flags & _CM_F_WALK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) return iter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) catmap_getnode_alloc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) if (!(cm_flags & _CM_F_ALLOC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) iter = netlbl_catmap_alloc(gfp_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) if (iter == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) iter->startbit = offset & ~(NETLBL_CATMAP_SIZE - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) if (prev == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) iter->next = *catmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) *catmap = iter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) iter->next = prev->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) prev->next = iter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) return iter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) * netlbl_catmap_walk - Walk a LSM secattr catmap looking for a bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) * @catmap: the category bitmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) * @offset: the offset to start searching at, in bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) * This function walks a LSM secattr category bitmap starting at @offset and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) * returns the spot of the first set bit or -ENOENT if no bits are set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) int netlbl_catmap_walk(struct netlbl_lsm_catmap *catmap, u32 offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) struct netlbl_lsm_catmap *iter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) u32 idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) u32 bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) NETLBL_CATMAP_MAPTYPE bitmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) iter = _netlbl_catmap_getnode(&catmap, offset, _CM_F_WALK, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) if (iter == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) if (offset > iter->startbit) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) offset -= iter->startbit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) idx = offset / NETLBL_CATMAP_MAPSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) bit = offset % NETLBL_CATMAP_MAPSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) bit = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) bitmap = iter->bitmap[idx] >> bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) if (bitmap != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) while ((bitmap & NETLBL_CATMAP_BIT) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) bitmap >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) bit++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) return iter->startbit +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) (NETLBL_CATMAP_MAPSIZE * idx) + bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) if (++idx >= NETLBL_CATMAP_MAPCNT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) if (iter->next != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) iter = iter->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) bitmap = iter->bitmap[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) bit = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) EXPORT_SYMBOL(netlbl_catmap_walk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) * netlbl_catmap_walkrng - Find the end of a string of set bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) * @catmap: the category bitmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) * @offset: the offset to start searching at, in bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) * This function walks a LSM secattr category bitmap starting at @offset and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) * returns the spot of the first cleared bit or -ENOENT if the offset is past
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) * the end of the bitmap.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) int netlbl_catmap_walkrng(struct netlbl_lsm_catmap *catmap, u32 offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) struct netlbl_lsm_catmap *iter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) struct netlbl_lsm_catmap *prev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) u32 idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) u32 bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) NETLBL_CATMAP_MAPTYPE bitmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) NETLBL_CATMAP_MAPTYPE bitmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) iter = _netlbl_catmap_getnode(&catmap, offset, _CM_F_WALK, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) if (iter == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) if (offset > iter->startbit) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) offset -= iter->startbit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) idx = offset / NETLBL_CATMAP_MAPSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) bit = offset % NETLBL_CATMAP_MAPSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) bit = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) bitmask = NETLBL_CATMAP_BIT << bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) bitmap = iter->bitmap[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) while (bitmask != 0 && (bitmap & bitmask) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) bitmask <<= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) bit++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) if (prev && idx == 0 && bit == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) return prev->startbit + NETLBL_CATMAP_SIZE - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) else if (bitmask != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) return iter->startbit +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) (NETLBL_CATMAP_MAPSIZE * idx) + bit - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) else if (++idx >= NETLBL_CATMAP_MAPCNT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) if (iter->next == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) return iter->startbit + NETLBL_CATMAP_SIZE - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) prev = iter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) iter = iter->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) bitmask = NETLBL_CATMAP_BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) bit = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) * netlbl_catmap_getlong - Export an unsigned long bitmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) * @catmap: pointer to the category bitmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) * @offset: pointer to the requested offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) * @bitmap: the exported bitmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) * Export a bitmap with an offset greater than or equal to @offset and return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) * it in @bitmap. The @offset must be aligned to an unsigned long and will be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) * updated on return if different from what was requested; if the catmap is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) * empty at the requested offset and beyond, the @offset is set to (u32)-1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) * Returns zero on sucess, negative values on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) int netlbl_catmap_getlong(struct netlbl_lsm_catmap *catmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) u32 *offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) unsigned long *bitmap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) struct netlbl_lsm_catmap *iter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) u32 off = *offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) u32 idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) /* only allow aligned offsets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) if ((off & (BITS_PER_LONG - 1)) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) /* a null catmap is equivalent to an empty one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) if (!catmap) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) *offset = (u32)-1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) if (off < catmap->startbit) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) off = catmap->startbit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) *offset = off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) iter = _netlbl_catmap_getnode(&catmap, off, _CM_F_WALK, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) if (iter == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) *offset = (u32)-1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) return 0;
^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) if (off < iter->startbit) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) *offset = iter->startbit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) off = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) off -= iter->startbit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) idx = off / NETLBL_CATMAP_MAPSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) *bitmap = iter->bitmap[idx] >> (off % NETLBL_CATMAP_MAPSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) return 0;
^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) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) * netlbl_catmap_setbit - Set a bit in a LSM secattr catmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) * @catmap: pointer to the category bitmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) * @bit: the bit to set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) * @flags: memory allocation flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) * Set the bit specified by @bit in @catmap. Returns zero on success,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) * negative values on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) int netlbl_catmap_setbit(struct netlbl_lsm_catmap **catmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) u32 bit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) gfp_t flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) struct netlbl_lsm_catmap *iter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) u32 idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) iter = _netlbl_catmap_getnode(catmap, bit, _CM_F_ALLOC, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) if (iter == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) bit -= iter->startbit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) idx = bit / NETLBL_CATMAP_MAPSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) iter->bitmap[idx] |= NETLBL_CATMAP_BIT << (bit % NETLBL_CATMAP_MAPSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) EXPORT_SYMBOL(netlbl_catmap_setbit);
^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) * netlbl_catmap_setrng - Set a range of bits in a LSM secattr catmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) * @catmap: pointer to the category bitmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) * @start: the starting bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) * @end: the last bit in the string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) * @flags: memory allocation flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) * Set a range of bits, starting at @start and ending with @end. Returns zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) * on success, negative values on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) int netlbl_catmap_setrng(struct netlbl_lsm_catmap **catmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) u32 start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) u32 end,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) gfp_t flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) u32 spot = start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) while (rc == 0 && spot <= end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) if (((spot & (BITS_PER_LONG - 1)) == 0) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) ((end - spot) > BITS_PER_LONG)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) rc = netlbl_catmap_setlong(catmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) spot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) (unsigned long)-1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) spot += BITS_PER_LONG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) rc = netlbl_catmap_setbit(catmap, spot++, flags);
^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) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) * netlbl_catmap_setlong - Import an unsigned long bitmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) * @catmap: pointer to the category bitmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) * @offset: offset to the start of the imported bitmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) * @bitmap: the bitmap to import
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) * @flags: memory allocation flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) * Import the bitmap specified in @bitmap into @catmap, using the offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) * in @offset. The offset must be aligned to an unsigned long. Returns zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) * on success, negative values on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) int netlbl_catmap_setlong(struct netlbl_lsm_catmap **catmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) u32 offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) unsigned long bitmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) gfp_t flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) struct netlbl_lsm_catmap *iter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) u32 idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) /* only allow aligned offsets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) if ((offset & (BITS_PER_LONG - 1)) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) iter = _netlbl_catmap_getnode(catmap, offset, _CM_F_ALLOC, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) if (iter == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) offset -= iter->startbit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) idx = offset / NETLBL_CATMAP_MAPSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) iter->bitmap[idx] |= bitmap << (offset % NETLBL_CATMAP_MAPSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) /* Bitmap functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) * netlbl_bitmap_walk - Walk a bitmap looking for a bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) * @bitmap: the bitmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) * @bitmap_len: length in bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) * @offset: starting offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) * @state: if non-zero, look for a set (1) bit else look for a cleared (0) bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) * Starting at @offset, walk the bitmap from left to right until either the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) * desired bit is found or we reach the end. Return the bit offset, -1 if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) * not found, or -2 if error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) int netlbl_bitmap_walk(const unsigned char *bitmap, u32 bitmap_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) u32 offset, u8 state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) u32 bit_spot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) u32 byte_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) unsigned char bitmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) unsigned char byte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) byte_offset = offset / 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) byte = bitmap[byte_offset];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) bit_spot = offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) bitmask = 0x80 >> (offset % 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) while (bit_spot < bitmap_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) if ((state && (byte & bitmask) == bitmask) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) (state == 0 && (byte & bitmask) == 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) return bit_spot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) if (++bit_spot >= bitmap_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) bitmask >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) if (bitmask == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) byte = bitmap[++byte_offset];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) bitmask = 0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) EXPORT_SYMBOL(netlbl_bitmap_walk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) * netlbl_bitmap_setbit - Sets a single bit in a bitmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) * @bitmap: the bitmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) * @bit: the bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) * @state: if non-zero, set the bit (1) else clear the bit (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) * Set a single bit in the bitmask. Returns zero on success, negative values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) * on error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) void netlbl_bitmap_setbit(unsigned char *bitmap, u32 bit, u8 state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) u32 byte_spot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) u8 bitmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) /* gcc always rounds to zero when doing integer division */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) byte_spot = bit / 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) bitmask = 0x80 >> (bit % 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) if (state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) bitmap[byte_spot] |= bitmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) bitmap[byte_spot] &= ~bitmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) EXPORT_SYMBOL(netlbl_bitmap_setbit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) * LSM Functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) * netlbl_enabled - Determine if the NetLabel subsystem is enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) * The LSM can use this function to determine if it should use NetLabel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) * security attributes in it's enforcement mechanism. Currently, NetLabel is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) * considered to be enabled when it's configuration contains a valid setup for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) * at least one labeled protocol (i.e. NetLabel can understand incoming
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) * labeled packets of at least one type); otherwise NetLabel is considered to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) * be disabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) int netlbl_enabled(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) /* At some point we probably want to expose this mechanism to the user
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) * as well so that admins can toggle NetLabel regardless of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) * configuration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) return (atomic_read(&netlabel_mgmt_protocount) > 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) * netlbl_sock_setattr - Label a socket using the correct protocol
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) * @sk: the socket to label
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) * @family: protocol family
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) * @secattr: the security attributes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) * Attach the correct label to the given socket using the security attributes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) * specified in @secattr. This function requires exclusive access to @sk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) * which means it either needs to be in the process of being created or locked.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) * Returns zero on success, -EDESTADDRREQ if the domain is configured to use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) * network address selectors (can't blindly label the socket), and negative
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) * values on all other failures.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) int netlbl_sock_setattr(struct sock *sk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) u16 family,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) const struct netlbl_lsm_secattr *secattr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) int ret_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) struct netlbl_dom_map *dom_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) dom_entry = netlbl_domhsh_getentry(secattr->domain, family);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) if (dom_entry == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) ret_val = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) goto socket_setattr_return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) switch (family) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) case AF_INET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) switch (dom_entry->def.type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) case NETLBL_NLTYPE_ADDRSELECT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) ret_val = -EDESTADDRREQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) case NETLBL_NLTYPE_CIPSOV4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) ret_val = cipso_v4_sock_setattr(sk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) dom_entry->def.cipso,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) secattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) case NETLBL_NLTYPE_UNLABELED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) ret_val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) ret_val = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) case AF_INET6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) switch (dom_entry->def.type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) case NETLBL_NLTYPE_ADDRSELECT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) ret_val = -EDESTADDRREQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) case NETLBL_NLTYPE_CALIPSO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) ret_val = calipso_sock_setattr(sk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) dom_entry->def.calipso,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) secattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) case NETLBL_NLTYPE_UNLABELED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) ret_val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) ret_val = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) #endif /* IPv6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) ret_val = -EPROTONOSUPPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) socket_setattr_return:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) return ret_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) * netlbl_sock_delattr - Delete all the NetLabel labels on a socket
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) * @sk: the socket
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) * Remove all the NetLabel labeling from @sk. The caller is responsible for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) * ensuring that @sk is locked.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) void netlbl_sock_delattr(struct sock *sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) switch (sk->sk_family) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) case AF_INET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) cipso_v4_sock_delattr(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) case AF_INET6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) calipso_sock_delattr(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) #endif /* IPv6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) * netlbl_sock_getattr - Determine the security attributes of a sock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) * @sk: the sock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) * @secattr: the security attributes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) * Examines the given sock to see if any NetLabel style labeling has been
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) * applied to the sock, if so it parses the socket label and returns the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) * security attributes in @secattr. Returns zero on success, negative values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) * on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) int netlbl_sock_getattr(struct sock *sk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) struct netlbl_lsm_secattr *secattr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) int ret_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) switch (sk->sk_family) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) case AF_INET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) ret_val = cipso_v4_sock_getattr(sk, secattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) case AF_INET6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) ret_val = calipso_sock_getattr(sk, secattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) #endif /* IPv6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) ret_val = -EPROTONOSUPPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) return ret_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) * netlbl_conn_setattr - Label a connected socket using the correct protocol
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) * @sk: the socket to label
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) * @addr: the destination address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) * @secattr: the security attributes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) * Attach the correct label to the given connected socket using the security
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) * attributes specified in @secattr. The caller is responsible for ensuring
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) * that @sk is locked. Returns zero on success, negative values on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) int netlbl_conn_setattr(struct sock *sk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) struct sockaddr *addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) const struct netlbl_lsm_secattr *secattr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) int ret_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) struct sockaddr_in *addr4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) struct sockaddr_in6 *addr6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) struct netlbl_dommap_def *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) switch (addr->sa_family) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) case AF_INET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) addr4 = (struct sockaddr_in *)addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) entry = netlbl_domhsh_getentry_af4(secattr->domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) addr4->sin_addr.s_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) if (entry == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) ret_val = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) goto conn_setattr_return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) switch (entry->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) case NETLBL_NLTYPE_CIPSOV4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) ret_val = cipso_v4_sock_setattr(sk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) entry->cipso, secattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) case NETLBL_NLTYPE_UNLABELED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) /* just delete the protocols we support for right now
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) * but we could remove other protocols if needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) netlbl_sock_delattr(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) ret_val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) ret_val = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) case AF_INET6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) addr6 = (struct sockaddr_in6 *)addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) entry = netlbl_domhsh_getentry_af6(secattr->domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) &addr6->sin6_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) if (entry == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) ret_val = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) goto conn_setattr_return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) switch (entry->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) case NETLBL_NLTYPE_CALIPSO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) ret_val = calipso_sock_setattr(sk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) entry->calipso, secattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) case NETLBL_NLTYPE_UNLABELED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) /* just delete the protocols we support for right now
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) * but we could remove other protocols if needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) netlbl_sock_delattr(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) ret_val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) ret_val = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) #endif /* IPv6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) ret_val = -EPROTONOSUPPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) conn_setattr_return:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) return ret_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) * netlbl_req_setattr - Label a request socket using the correct protocol
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) * @req: the request socket to label
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) * @secattr: the security attributes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) * Attach the correct label to the given socket using the security attributes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) * specified in @secattr. Returns zero on success, negative values on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) int netlbl_req_setattr(struct request_sock *req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) const struct netlbl_lsm_secattr *secattr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) int ret_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) struct netlbl_dommap_def *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) struct inet_request_sock *ireq = inet_rsk(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) switch (req->rsk_ops->family) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) case AF_INET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) entry = netlbl_domhsh_getentry_af4(secattr->domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) ireq->ir_rmt_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) if (entry == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) ret_val = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) goto req_setattr_return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) switch (entry->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) case NETLBL_NLTYPE_CIPSOV4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) ret_val = cipso_v4_req_setattr(req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) entry->cipso, secattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) case NETLBL_NLTYPE_UNLABELED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) netlbl_req_delattr(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) ret_val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) ret_val = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) case AF_INET6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) entry = netlbl_domhsh_getentry_af6(secattr->domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) &ireq->ir_v6_rmt_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) if (entry == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) ret_val = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) goto req_setattr_return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) switch (entry->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) case NETLBL_NLTYPE_CALIPSO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) ret_val = calipso_req_setattr(req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) entry->calipso, secattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) case NETLBL_NLTYPE_UNLABELED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) netlbl_req_delattr(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) ret_val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) ret_val = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) #endif /* IPv6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) ret_val = -EPROTONOSUPPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) req_setattr_return:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) return ret_val;
^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_req_delattr - Delete all the NetLabel labels on a socket
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) * @req: the socket
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) * Remove all the NetLabel labeling from @req.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) void netlbl_req_delattr(struct request_sock *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) switch (req->rsk_ops->family) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) case AF_INET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) cipso_v4_req_delattr(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) case AF_INET6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) calipso_req_delattr(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) #endif /* IPv6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) * netlbl_skbuff_setattr - Label a packet using the correct protocol
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) * @skb: the packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) * @family: protocol family
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) * @secattr: the security attributes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) * Attach the correct label to the given packet using the security attributes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) * specified in @secattr. Returns zero on success, negative values on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) int netlbl_skbuff_setattr(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) u16 family,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) const struct netlbl_lsm_secattr *secattr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) int ret_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) struct iphdr *hdr4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) struct ipv6hdr *hdr6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) struct netlbl_dommap_def *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) switch (family) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) case AF_INET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) hdr4 = ip_hdr(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) entry = netlbl_domhsh_getentry_af4(secattr->domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) hdr4->daddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) if (entry == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) ret_val = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) goto skbuff_setattr_return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) switch (entry->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) case NETLBL_NLTYPE_CIPSOV4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) ret_val = cipso_v4_skbuff_setattr(skb, entry->cipso,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) secattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) case NETLBL_NLTYPE_UNLABELED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) /* just delete the protocols we support for right now
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) * but we could remove other protocols if needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) ret_val = cipso_v4_skbuff_delattr(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) ret_val = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) case AF_INET6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) hdr6 = ipv6_hdr(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) entry = netlbl_domhsh_getentry_af6(secattr->domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) &hdr6->daddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) if (entry == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) ret_val = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) goto skbuff_setattr_return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) switch (entry->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) case NETLBL_NLTYPE_CALIPSO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) ret_val = calipso_skbuff_setattr(skb, entry->calipso,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) secattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) case NETLBL_NLTYPE_UNLABELED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) /* just delete the protocols we support for right now
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) * but we could remove other protocols if needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) ret_val = calipso_skbuff_delattr(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) ret_val = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) #endif /* IPv6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) ret_val = -EPROTONOSUPPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) skbuff_setattr_return:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) return ret_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) * netlbl_skbuff_getattr - Determine the security attributes of a packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) * @skb: the packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) * @family: protocol family
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) * @secattr: the security attributes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) * Examines the given packet to see if a recognized form of packet labeling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) * is present, if so it parses the packet label and returns the security
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) * attributes in @secattr. Returns zero on success, negative values on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) * failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) int netlbl_skbuff_getattr(const struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) u16 family,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) struct netlbl_lsm_secattr *secattr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) unsigned char *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) switch (family) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) case AF_INET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) ptr = cipso_v4_optptr(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) if (ptr && cipso_v4_getattr(ptr, secattr) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) case AF_INET6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) ptr = calipso_optptr(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) if (ptr && calipso_getattr(ptr, secattr) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) #endif /* IPv6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) return netlbl_unlabel_getattr(skb, family, secattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) }
^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) * netlbl_skbuff_err - Handle a LSM error on a sk_buff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) * @skb: the packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) * @family: the family
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) * @error: the error code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) * @gateway: true if host is acting as a gateway, false otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) * Deal with a LSM problem when handling the packet in @skb, typically this is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) * a permission denied problem (-EACCES). The correct action is determined
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) * according to the packet's labeling protocol.
^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) void netlbl_skbuff_err(struct sk_buff *skb, u16 family, int error, int gateway)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) switch (family) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) case AF_INET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) if (cipso_v4_optptr(skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) cipso_v4_error(skb, error, gateway);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) break;
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) * netlbl_cache_invalidate - Invalidate all of the NetLabel protocol caches
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) * For all of the NetLabel protocols that support some form of label mapping
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) * cache, invalidate the cache. Returns zero on success, negative values on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) * error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) void netlbl_cache_invalidate(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) cipso_v4_cache_invalidate();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) calipso_cache_invalidate();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) #endif /* IPv6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) * netlbl_cache_add - Add an entry to a NetLabel protocol cache
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) * @skb: the packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) * @family: the family
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) * @secattr: the packet's security attributes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) * Add the LSM security attributes for the given packet to the underlying
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) * NetLabel protocol's label mapping cache. Returns zero on success, negative
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) * values on error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) int netlbl_cache_add(const struct sk_buff *skb, u16 family,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) const struct netlbl_lsm_secattr *secattr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) unsigned char *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) if ((secattr->flags & NETLBL_SECATTR_CACHE) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) return -ENOMSG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) switch (family) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) case AF_INET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) ptr = cipso_v4_optptr(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) if (ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) return cipso_v4_cache_add(ptr, secattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) case AF_INET6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) ptr = calipso_optptr(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) if (ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) return calipso_cache_add(ptr, secattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) #endif /* IPv6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) return -ENOMSG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) * Protocol Engine Functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) * netlbl_audit_start - Start an audit message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) * @type: audit message type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) * @audit_info: NetLabel audit information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) * Start an audit message using the type specified in @type and fill the audit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) * message with some fields common to all NetLabel audit messages. This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) * function should only be used by protocol engines, not LSMs. Returns a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) * pointer to the audit buffer on success, NULL on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) struct audit_buffer *netlbl_audit_start(int type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) struct netlbl_audit *audit_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) return netlbl_audit_start_common(type, audit_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) EXPORT_SYMBOL(netlbl_audit_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) * Setup Functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) * netlbl_init - Initialize NetLabel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) * Perform the required NetLabel initialization before first use.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) static int __init netlbl_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) int ret_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) printk(KERN_INFO "NetLabel: Initializing\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) printk(KERN_INFO "NetLabel: domain hash size = %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) (1 << NETLBL_DOMHSH_BITSIZE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) printk(KERN_INFO "NetLabel: protocols = UNLABELED CIPSOv4 CALIPSO\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) ret_val = netlbl_domhsh_init(NETLBL_DOMHSH_BITSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) if (ret_val != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) goto init_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) ret_val = netlbl_unlabel_init(NETLBL_UNLHSH_BITSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) if (ret_val != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) goto init_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) ret_val = netlbl_netlink_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) if (ret_val != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) goto init_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) ret_val = netlbl_unlabel_defconf();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) if (ret_val != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) goto init_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) printk(KERN_INFO "NetLabel: unlabeled traffic allowed by default\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) init_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) panic("NetLabel: failed to initialize properly (%d)\n", ret_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) subsys_initcall(netlbl_init);