^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 CIPSO/IPv4 Support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * This file defines the CIPSO/IPv4 functions for the NetLabel system. The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * NetLabel system manages static and dynamic label mappings for network
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * protocols such as CIPSO and RIPSO.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Author: Paul Moore <paul@paul-moore.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * (c) Copyright Hewlett-Packard Development Company, L.P., 2006
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/socket.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/skbuff.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/audit.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <net/sock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <net/netlink.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <net/genetlink.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <net/netlabel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <net/cipso_ipv4.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/atomic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include "netlabel_user.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include "netlabel_cipso_v4.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include "netlabel_mgmt.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include "netlabel_domainhash.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) /* Argument struct for cipso_v4_doi_walk() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) struct netlbl_cipsov4_doiwalk_arg {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) struct netlink_callback *nl_cb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) u32 seq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) /* Argument struct for netlbl_domhsh_walk() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) struct netlbl_domhsh_walk_arg {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) struct netlbl_audit *audit_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) u32 doi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) /* NetLabel Generic NETLINK CIPSOv4 family */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) static struct genl_family netlbl_cipsov4_gnl_family;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) /* NetLabel Netlink attribute policy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) static const struct nla_policy netlbl_cipsov4_genl_policy[NLBL_CIPSOV4_A_MAX + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) [NLBL_CIPSOV4_A_DOI] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) [NLBL_CIPSOV4_A_MTYPE] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) [NLBL_CIPSOV4_A_TAG] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) [NLBL_CIPSOV4_A_TAGLST] = { .type = NLA_NESTED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) [NLBL_CIPSOV4_A_MLSLVLLOC] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) [NLBL_CIPSOV4_A_MLSLVLREM] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) [NLBL_CIPSOV4_A_MLSLVL] = { .type = NLA_NESTED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) [NLBL_CIPSOV4_A_MLSLVLLST] = { .type = NLA_NESTED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) [NLBL_CIPSOV4_A_MLSCATLOC] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) [NLBL_CIPSOV4_A_MLSCATREM] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) [NLBL_CIPSOV4_A_MLSCAT] = { .type = NLA_NESTED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) [NLBL_CIPSOV4_A_MLSCATLST] = { .type = NLA_NESTED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) * Helper Functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) * netlbl_cipsov4_add_common - Parse the common sections of a ADD message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) * @info: the Generic NETLINK info block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) * @doi_def: the CIPSO V4 DOI definition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) * Parse the common sections of a ADD message and fill in the related values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) * in @doi_def. Returns zero on success, negative values on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) static int netlbl_cipsov4_add_common(struct genl_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) struct cipso_v4_doi *doi_def)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) struct nlattr *nla;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) int nla_rem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) u32 iter = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) doi_def->doi = nla_get_u32(info->attrs[NLBL_CIPSOV4_A_DOI]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) if (nla_validate_nested_deprecated(info->attrs[NLBL_CIPSOV4_A_TAGLST],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) NLBL_CIPSOV4_A_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) netlbl_cipsov4_genl_policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) NULL) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) nla_for_each_nested(nla, info->attrs[NLBL_CIPSOV4_A_TAGLST], nla_rem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) if (nla_type(nla) == NLBL_CIPSOV4_A_TAG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) if (iter >= CIPSO_V4_TAG_MAXCNT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) doi_def->tags[iter++] = nla_get_u8(nla);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) while (iter < CIPSO_V4_TAG_MAXCNT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) doi_def->tags[iter++] = CIPSO_V4_TAG_INVALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * NetLabel Command Handlers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) * netlbl_cipsov4_add_std - Adds a CIPSO V4 DOI definition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) * @info: the Generic NETLINK info block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) * @audit_info: NetLabel audit information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) * Create a new CIPSO_V4_MAP_TRANS DOI definition based on the given ADD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) * message and add it to the CIPSO V4 engine. Return zero on success and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) * non-zero on error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) static int netlbl_cipsov4_add_std(struct genl_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) struct netlbl_audit *audit_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) int ret_val = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) struct cipso_v4_doi *doi_def = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) struct nlattr *nla_a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) struct nlattr *nla_b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) int nla_a_rem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) int nla_b_rem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) u32 iter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) if (!info->attrs[NLBL_CIPSOV4_A_TAGLST] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) !info->attrs[NLBL_CIPSOV4_A_MLSLVLLST])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) if (nla_validate_nested_deprecated(info->attrs[NLBL_CIPSOV4_A_MLSLVLLST],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) NLBL_CIPSOV4_A_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) netlbl_cipsov4_genl_policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) NULL) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) doi_def = kmalloc(sizeof(*doi_def), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) if (doi_def == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) doi_def->map.std = kzalloc(sizeof(*doi_def->map.std), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) if (doi_def->map.std == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) kfree(doi_def);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) doi_def->type = CIPSO_V4_MAP_TRANS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) ret_val = netlbl_cipsov4_add_common(info, doi_def);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) if (ret_val != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) goto add_std_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) ret_val = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) nla_for_each_nested(nla_a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) info->attrs[NLBL_CIPSOV4_A_MLSLVLLST],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) nla_a_rem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) if (nla_type(nla_a) == NLBL_CIPSOV4_A_MLSLVL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) if (nla_validate_nested_deprecated(nla_a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) NLBL_CIPSOV4_A_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) netlbl_cipsov4_genl_policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) NULL) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) goto add_std_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) nla_for_each_nested(nla_b, nla_a, nla_b_rem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) switch (nla_type(nla_b)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) case NLBL_CIPSOV4_A_MLSLVLLOC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) if (nla_get_u32(nla_b) >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) CIPSO_V4_MAX_LOC_LVLS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) goto add_std_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) if (nla_get_u32(nla_b) >=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) doi_def->map.std->lvl.local_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) doi_def->map.std->lvl.local_size =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) nla_get_u32(nla_b) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) case NLBL_CIPSOV4_A_MLSLVLREM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) if (nla_get_u32(nla_b) >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) CIPSO_V4_MAX_REM_LVLS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) goto add_std_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) if (nla_get_u32(nla_b) >=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) doi_def->map.std->lvl.cipso_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) doi_def->map.std->lvl.cipso_size =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) nla_get_u32(nla_b) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) doi_def->map.std->lvl.local = kcalloc(doi_def->map.std->lvl.local_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) sizeof(u32),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) GFP_KERNEL | __GFP_NOWARN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) if (doi_def->map.std->lvl.local == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) ret_val = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) goto add_std_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) doi_def->map.std->lvl.cipso = kcalloc(doi_def->map.std->lvl.cipso_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) sizeof(u32),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) GFP_KERNEL | __GFP_NOWARN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) if (doi_def->map.std->lvl.cipso == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) ret_val = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) goto add_std_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) for (iter = 0; iter < doi_def->map.std->lvl.local_size; iter++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) doi_def->map.std->lvl.local[iter] = CIPSO_V4_INV_LVL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) for (iter = 0; iter < doi_def->map.std->lvl.cipso_size; iter++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) doi_def->map.std->lvl.cipso[iter] = CIPSO_V4_INV_LVL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) nla_for_each_nested(nla_a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) info->attrs[NLBL_CIPSOV4_A_MLSLVLLST],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) nla_a_rem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) if (nla_type(nla_a) == NLBL_CIPSOV4_A_MLSLVL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) struct nlattr *lvl_loc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) struct nlattr *lvl_rem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) lvl_loc = nla_find_nested(nla_a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) NLBL_CIPSOV4_A_MLSLVLLOC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) lvl_rem = nla_find_nested(nla_a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) NLBL_CIPSOV4_A_MLSLVLREM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) if (lvl_loc == NULL || lvl_rem == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) goto add_std_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) doi_def->map.std->lvl.local[nla_get_u32(lvl_loc)] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) nla_get_u32(lvl_rem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) doi_def->map.std->lvl.cipso[nla_get_u32(lvl_rem)] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) nla_get_u32(lvl_loc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) if (info->attrs[NLBL_CIPSOV4_A_MLSCATLST]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) if (nla_validate_nested_deprecated(info->attrs[NLBL_CIPSOV4_A_MLSCATLST],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) NLBL_CIPSOV4_A_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) netlbl_cipsov4_genl_policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) NULL) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) goto add_std_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) nla_for_each_nested(nla_a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) info->attrs[NLBL_CIPSOV4_A_MLSCATLST],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) nla_a_rem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) if (nla_type(nla_a) == NLBL_CIPSOV4_A_MLSCAT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) if (nla_validate_nested_deprecated(nla_a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) NLBL_CIPSOV4_A_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) netlbl_cipsov4_genl_policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) NULL) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) goto add_std_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) nla_for_each_nested(nla_b, nla_a, nla_b_rem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) switch (nla_type(nla_b)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) case NLBL_CIPSOV4_A_MLSCATLOC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) if (nla_get_u32(nla_b) >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) CIPSO_V4_MAX_LOC_CATS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) goto add_std_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) if (nla_get_u32(nla_b) >=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) doi_def->map.std->cat.local_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) doi_def->map.std->cat.local_size =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) nla_get_u32(nla_b) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) case NLBL_CIPSOV4_A_MLSCATREM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) if (nla_get_u32(nla_b) >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) CIPSO_V4_MAX_REM_CATS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) goto add_std_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) if (nla_get_u32(nla_b) >=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) doi_def->map.std->cat.cipso_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) doi_def->map.std->cat.cipso_size =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) nla_get_u32(nla_b) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) doi_def->map.std->cat.local = kcalloc(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) doi_def->map.std->cat.local_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) sizeof(u32),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) GFP_KERNEL | __GFP_NOWARN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) if (doi_def->map.std->cat.local == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) ret_val = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) goto add_std_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) doi_def->map.std->cat.cipso = kcalloc(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) doi_def->map.std->cat.cipso_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) sizeof(u32),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) GFP_KERNEL | __GFP_NOWARN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) if (doi_def->map.std->cat.cipso == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) ret_val = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) goto add_std_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) for (iter = 0; iter < doi_def->map.std->cat.local_size; iter++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) doi_def->map.std->cat.local[iter] = CIPSO_V4_INV_CAT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) for (iter = 0; iter < doi_def->map.std->cat.cipso_size; iter++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) doi_def->map.std->cat.cipso[iter] = CIPSO_V4_INV_CAT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) nla_for_each_nested(nla_a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) info->attrs[NLBL_CIPSOV4_A_MLSCATLST],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) nla_a_rem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) if (nla_type(nla_a) == NLBL_CIPSOV4_A_MLSCAT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) struct nlattr *cat_loc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) struct nlattr *cat_rem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) cat_loc = nla_find_nested(nla_a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) NLBL_CIPSOV4_A_MLSCATLOC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) cat_rem = nla_find_nested(nla_a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) NLBL_CIPSOV4_A_MLSCATREM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) if (cat_loc == NULL || cat_rem == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) goto add_std_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) doi_def->map.std->cat.local[
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) nla_get_u32(cat_loc)] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) nla_get_u32(cat_rem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) doi_def->map.std->cat.cipso[
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) nla_get_u32(cat_rem)] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) nla_get_u32(cat_loc);
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) ret_val = cipso_v4_doi_add(doi_def, audit_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) if (ret_val != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) goto add_std_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) add_std_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) cipso_v4_doi_free(doi_def);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) return ret_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) * netlbl_cipsov4_add_pass - Adds a CIPSO V4 DOI definition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) * @info: the Generic NETLINK info block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) * @audit_info: NetLabel audit information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) * Create a new CIPSO_V4_MAP_PASS DOI definition based on the given ADD message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) * and add it to the CIPSO V4 engine. Return zero on success and non-zero on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) * error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) static int netlbl_cipsov4_add_pass(struct genl_info *info,
^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;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) struct cipso_v4_doi *doi_def = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) if (!info->attrs[NLBL_CIPSOV4_A_TAGLST])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) doi_def = kmalloc(sizeof(*doi_def), GFP_KERNEL);
^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 -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) doi_def->type = CIPSO_V4_MAP_PASS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) ret_val = netlbl_cipsov4_add_common(info, doi_def);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) if (ret_val != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) goto add_pass_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) ret_val = cipso_v4_doi_add(doi_def, audit_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) if (ret_val != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) goto add_pass_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) add_pass_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) cipso_v4_doi_free(doi_def);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) return ret_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) * netlbl_cipsov4_add_local - Adds a CIPSO V4 DOI definition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) * @info: the Generic NETLINK info block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) * @audit_info: NetLabel audit information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) * Create a new CIPSO_V4_MAP_LOCAL DOI definition based on the given ADD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) * message and add it to the CIPSO V4 engine. Return zero on success and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) * non-zero on error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) static int netlbl_cipsov4_add_local(struct genl_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) struct netlbl_audit *audit_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) int ret_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) struct cipso_v4_doi *doi_def = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) if (!info->attrs[NLBL_CIPSOV4_A_TAGLST])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) doi_def = kmalloc(sizeof(*doi_def), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) if (doi_def == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) doi_def->type = CIPSO_V4_MAP_LOCAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) ret_val = netlbl_cipsov4_add_common(info, doi_def);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) if (ret_val != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) goto add_local_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) ret_val = cipso_v4_doi_add(doi_def, audit_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) if (ret_val != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) goto add_local_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) add_local_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) cipso_v4_doi_free(doi_def);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) return ret_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) * netlbl_cipsov4_add - Handle an ADD message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) * @skb: the NETLINK buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) * @info: the Generic NETLINK info block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) * Create a new DOI definition based on the given ADD message and add it to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) * CIPSO V4 engine. Returns zero on success, negative values on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) static int netlbl_cipsov4_add(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) int ret_val = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) struct netlbl_audit audit_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) if (!info->attrs[NLBL_CIPSOV4_A_DOI] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) !info->attrs[NLBL_CIPSOV4_A_MTYPE])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) netlbl_netlink_auditinfo(skb, &audit_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) switch (nla_get_u32(info->attrs[NLBL_CIPSOV4_A_MTYPE])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) case CIPSO_V4_MAP_TRANS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) ret_val = netlbl_cipsov4_add_std(info, &audit_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) case CIPSO_V4_MAP_PASS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) ret_val = netlbl_cipsov4_add_pass(info, &audit_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) case CIPSO_V4_MAP_LOCAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) ret_val = netlbl_cipsov4_add_local(info, &audit_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) if (ret_val == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) atomic_inc(&netlabel_mgmt_protocount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) return ret_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) * netlbl_cipsov4_list - Handle a LIST message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) * @skb: the NETLINK buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) * @info: the Generic NETLINK info block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) * Process a user generated LIST message and respond accordingly. While the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) * response message generated by the kernel is straightforward, determining
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) * before hand the size of the buffer to allocate is not (we have to generate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) * the message to know the size). In order to keep this function sane what we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) * do is allocate a buffer of NLMSG_GOODSIZE and try to fit the response in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) * that size, if we fail then we restart with a larger buffer and try again.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) * We continue in this manner until we hit a limit of failed attempts then we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) * give up and just send an error message. Returns zero on success and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) * negative values on error.
^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) static int netlbl_cipsov4_list(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) int ret_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) struct sk_buff *ans_skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) u32 nlsze_mult = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) void *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) u32 doi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) struct nlattr *nla_a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) struct nlattr *nla_b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) struct cipso_v4_doi *doi_def;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) u32 iter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) if (!info->attrs[NLBL_CIPSOV4_A_DOI]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) ret_val = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) goto list_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) list_start:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) ans_skb = nlmsg_new(NLMSG_DEFAULT_SIZE * nlsze_mult, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) if (ans_skb == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) ret_val = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) goto list_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) data = genlmsg_put_reply(ans_skb, info, &netlbl_cipsov4_gnl_family,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 0, NLBL_CIPSOV4_C_LIST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) if (data == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) ret_val = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) goto list_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) doi = nla_get_u32(info->attrs[NLBL_CIPSOV4_A_DOI]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) doi_def = cipso_v4_doi_getdef(doi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) if (doi_def == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) ret_val = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) goto list_failure_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) ret_val = nla_put_u32(ans_skb, NLBL_CIPSOV4_A_MTYPE, doi_def->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) if (ret_val != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) goto list_failure_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) nla_a = nla_nest_start_noflag(ans_skb, NLBL_CIPSOV4_A_TAGLST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) if (nla_a == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) ret_val = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) goto list_failure_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) for (iter = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) iter < CIPSO_V4_TAG_MAXCNT &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) doi_def->tags[iter] != CIPSO_V4_TAG_INVALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) iter++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) ret_val = nla_put_u8(ans_skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) NLBL_CIPSOV4_A_TAG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) doi_def->tags[iter]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) if (ret_val != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) goto list_failure_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) nla_nest_end(ans_skb, nla_a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) switch (doi_def->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) case CIPSO_V4_MAP_TRANS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) nla_a = nla_nest_start_noflag(ans_skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) NLBL_CIPSOV4_A_MLSLVLLST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) if (nla_a == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) ret_val = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) goto list_failure_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) for (iter = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) iter < doi_def->map.std->lvl.local_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) iter++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) if (doi_def->map.std->lvl.local[iter] ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) CIPSO_V4_INV_LVL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) nla_b = nla_nest_start_noflag(ans_skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) NLBL_CIPSOV4_A_MLSLVL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) if (nla_b == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) ret_val = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) goto list_retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) ret_val = nla_put_u32(ans_skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) NLBL_CIPSOV4_A_MLSLVLLOC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) iter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) if (ret_val != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) goto list_retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) ret_val = nla_put_u32(ans_skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) NLBL_CIPSOV4_A_MLSLVLREM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) doi_def->map.std->lvl.local[iter]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) if (ret_val != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) goto list_retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) nla_nest_end(ans_skb, nla_b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) nla_nest_end(ans_skb, nla_a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) nla_a = nla_nest_start_noflag(ans_skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) NLBL_CIPSOV4_A_MLSCATLST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) if (nla_a == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) ret_val = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) goto list_retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) for (iter = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) iter < doi_def->map.std->cat.local_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) iter++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) if (doi_def->map.std->cat.local[iter] ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) CIPSO_V4_INV_CAT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) nla_b = nla_nest_start_noflag(ans_skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) NLBL_CIPSOV4_A_MLSCAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) if (nla_b == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) ret_val = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) goto list_retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) ret_val = nla_put_u32(ans_skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) NLBL_CIPSOV4_A_MLSCATLOC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) iter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) if (ret_val != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) goto list_retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) ret_val = nla_put_u32(ans_skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) NLBL_CIPSOV4_A_MLSCATREM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) doi_def->map.std->cat.local[iter]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) if (ret_val != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) goto list_retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) nla_nest_end(ans_skb, nla_b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) nla_nest_end(ans_skb, nla_a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) cipso_v4_doi_putdef(doi_def);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) genlmsg_end(ans_skb, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) return genlmsg_reply(ans_skb, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) list_retry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) /* XXX - this limit is a guesstimate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) if (nlsze_mult < 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) cipso_v4_doi_putdef(doi_def);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) kfree_skb(ans_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) nlsze_mult *= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) goto list_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) list_failure_lock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) cipso_v4_doi_putdef(doi_def);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) list_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) kfree_skb(ans_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) return ret_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) * netlbl_cipsov4_listall_cb - cipso_v4_doi_walk() callback for LISTALL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) * @doi_def: the CIPSOv4 DOI definition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) * @arg: the netlbl_cipsov4_doiwalk_arg structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) * This function is designed to be used as a callback to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) * cipso_v4_doi_walk() function for use in generating a response for a LISTALL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) * message. Returns the size of the message on success, negative values on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) * failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) static int netlbl_cipsov4_listall_cb(struct cipso_v4_doi *doi_def, void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) int ret_val = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) struct netlbl_cipsov4_doiwalk_arg *cb_arg = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) void *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) data = genlmsg_put(cb_arg->skb, NETLINK_CB(cb_arg->nl_cb->skb).portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) cb_arg->seq, &netlbl_cipsov4_gnl_family,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) NLM_F_MULTI, NLBL_CIPSOV4_C_LISTALL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) if (data == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) goto listall_cb_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) ret_val = nla_put_u32(cb_arg->skb, NLBL_CIPSOV4_A_DOI, doi_def->doi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) if (ret_val != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) goto listall_cb_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) ret_val = nla_put_u32(cb_arg->skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) NLBL_CIPSOV4_A_MTYPE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) doi_def->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) if (ret_val != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) goto listall_cb_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) genlmsg_end(cb_arg->skb, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) listall_cb_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) genlmsg_cancel(cb_arg->skb, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) return ret_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) * netlbl_cipsov4_listall - Handle a LISTALL message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) * @skb: the NETLINK buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) * @cb: the NETLINK callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) * Process a user generated LISTALL message and respond accordingly. Returns
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) * zero on success and negative values on error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) static int netlbl_cipsov4_listall(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) struct netlink_callback *cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) struct netlbl_cipsov4_doiwalk_arg cb_arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) u32 doi_skip = cb->args[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) cb_arg.nl_cb = cb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) cb_arg.skb = skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) cb_arg.seq = cb->nlh->nlmsg_seq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) cipso_v4_doi_walk(&doi_skip, netlbl_cipsov4_listall_cb, &cb_arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) cb->args[0] = doi_skip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) return skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) * netlbl_cipsov4_remove_cb - netlbl_cipsov4_remove() callback for REMOVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) * @entry: LSM domain mapping entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) * @arg: the netlbl_domhsh_walk_arg structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) * This function is intended for use by netlbl_cipsov4_remove() as the callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) * for the netlbl_domhsh_walk() function; it removes LSM domain map entries
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) * which are associated with the CIPSO DOI specified in @arg. Returns zero on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) * success, negative values on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) static int netlbl_cipsov4_remove_cb(struct netlbl_dom_map *entry, void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) struct netlbl_domhsh_walk_arg *cb_arg = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) if (entry->def.type == NETLBL_NLTYPE_CIPSOV4 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) entry->def.cipso->doi == cb_arg->doi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) return netlbl_domhsh_remove_entry(entry, cb_arg->audit_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) }
^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) * netlbl_cipsov4_remove - Handle a REMOVE message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) * @skb: the NETLINK buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) * @info: the Generic NETLINK info block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) * Process a user generated REMOVE message and respond accordingly. Returns
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) * zero on success, negative values on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) static int netlbl_cipsov4_remove(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) int ret_val = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) struct netlbl_domhsh_walk_arg cb_arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) struct netlbl_audit audit_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) u32 skip_bkt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) u32 skip_chain = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) if (!info->attrs[NLBL_CIPSOV4_A_DOI])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) netlbl_netlink_auditinfo(skb, &audit_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) cb_arg.doi = nla_get_u32(info->attrs[NLBL_CIPSOV4_A_DOI]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) cb_arg.audit_info = &audit_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) ret_val = netlbl_domhsh_walk(&skip_bkt, &skip_chain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) netlbl_cipsov4_remove_cb, &cb_arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) if (ret_val == 0 || ret_val == -ENOENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) ret_val = cipso_v4_doi_remove(cb_arg.doi, &audit_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) if (ret_val == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) atomic_dec(&netlabel_mgmt_protocount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) return ret_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) * NetLabel Generic NETLINK Command Definitions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) static const struct genl_small_ops netlbl_cipsov4_ops[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) .cmd = NLBL_CIPSOV4_C_ADD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) .flags = GENL_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) .doit = netlbl_cipsov4_add,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) .dumpit = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) .cmd = NLBL_CIPSOV4_C_REMOVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) .flags = GENL_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) .doit = netlbl_cipsov4_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) .dumpit = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) .cmd = NLBL_CIPSOV4_C_LIST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) .flags = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) .doit = netlbl_cipsov4_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) .dumpit = NULL,
^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) .cmd = NLBL_CIPSOV4_C_LISTALL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) .flags = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) .doit = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) .dumpit = netlbl_cipsov4_listall,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) static struct genl_family netlbl_cipsov4_gnl_family __ro_after_init = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) .hdrsize = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) .name = NETLBL_NLTYPE_CIPSOV4_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) .version = NETLBL_PROTO_VERSION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) .maxattr = NLBL_CIPSOV4_A_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) .policy = netlbl_cipsov4_genl_policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) .module = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) .small_ops = netlbl_cipsov4_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) .n_small_ops = ARRAY_SIZE(netlbl_cipsov4_ops),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) * NetLabel Generic NETLINK Protocol Functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) * netlbl_cipsov4_genl_init - Register the CIPSOv4 NetLabel component
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) * Register the CIPSOv4 packet NetLabel component with the Generic NETLINK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) * mechanism. Returns zero on success, negative values on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) int __init netlbl_cipsov4_genl_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) return genl_register_family(&netlbl_cipsov4_gnl_family);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) }