1 /* 2 * NetLabel Unlabeled Support 3 * 4 * This file defines functions for dealing with unlabeled packets for the 5 * NetLabel system. The NetLabel system manages static and dynamic label 6 * mappings for network protocols such as CIPSO and RIPSO. 7 * 8 * Author: Paul Moore <paul.moore@hp.com> 9 * 10 */ 11 12 /* 13 * (c) Copyright Hewlett-Packard Development Company, L.P., 2006 14 * 15 * This program is free software; you can redistribute it and/or modify 16 * it under the terms of the GNU General Public License as published by 17 * the Free Software Foundation; either version 2 of the License, or 18 * (at your option) any later version. 19 * 20 * This program is distributed in the hope that it will be useful, 21 * but WITHOUT ANY WARRANTY; without even the implied warranty of 22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 23 * the GNU General Public License for more details. 24 * 25 * You should have received a copy of the GNU General Public License 26 * along with this program; if not, write to the Free Software 27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 28 * 29 */ 30 31 #include <linux/types.h> 32 #include <linux/rcupdate.h> 33 #include <linux/list.h> 34 #include <linux/spinlock.h> 35 #include <linux/socket.h> 36 #include <linux/string.h> 37 #include <linux/skbuff.h> 38 #include <net/sock.h> 39 #include <net/netlink.h> 40 #include <net/genetlink.h> 41 42 #include <net/netlabel.h> 43 #include <asm/bug.h> 44 45 #include "netlabel_user.h" 46 #include "netlabel_domainhash.h" 47 #include "netlabel_unlabeled.h" 48 49 /* Accept unlabeled packets flag */ 50 static atomic_t netlabel_unlabel_accept_flg = ATOMIC_INIT(0); 51 52 /* NetLabel Generic NETLINK CIPSOv4 family */ 53 static struct genl_family netlbl_unlabel_gnl_family = { 54 .id = GENL_ID_GENERATE, 55 .hdrsize = 0, 56 .name = NETLBL_NLTYPE_UNLABELED_NAME, 57 .version = NETLBL_PROTO_VERSION, 58 .maxattr = NLBL_UNLABEL_A_MAX, 59 }; 60 61 /* NetLabel Netlink attribute policy */ 62 static struct nla_policy netlbl_unlabel_genl_policy[NLBL_UNLABEL_A_MAX + 1] = { 63 [NLBL_UNLABEL_A_ACPTFLG] = { .type = NLA_U8 }, 64 }; 65 66 /* 67 * Helper Functions 68 */ 69 70 /** 71 * netlbl_unlabel_acceptflg_set - Set the unlabeled accept flag 72 * @value: desired value 73 * @audit_secid: the LSM secid to use in the audit message 74 * 75 * Description: 76 * Set the value of the unlabeled accept flag to @value. 77 * 78 */ 79 static void netlbl_unlabel_acceptflg_set(u8 value, u32 audit_secid) 80 { 81 atomic_set(&netlabel_unlabel_accept_flg, value); 82 netlbl_audit_nomsg((value ? 83 AUDIT_MAC_UNLBL_ACCEPT : AUDIT_MAC_UNLBL_DENY), 84 audit_secid); 85 } 86 87 /* 88 * NetLabel Command Handlers 89 */ 90 91 /** 92 * netlbl_unlabel_accept - Handle an ACCEPT message 93 * @skb: the NETLINK buffer 94 * @info: the Generic NETLINK info block 95 * 96 * Description: 97 * Process a user generated ACCEPT message and set the accept flag accordingly. 98 * Returns zero on success, negative values on failure. 99 * 100 */ 101 static int netlbl_unlabel_accept(struct sk_buff *skb, struct genl_info *info) 102 { 103 u8 value; 104 105 if (info->attrs[NLBL_UNLABEL_A_ACPTFLG]) { 106 value = nla_get_u8(info->attrs[NLBL_UNLABEL_A_ACPTFLG]); 107 if (value == 1 || value == 0) { 108 netlbl_unlabel_acceptflg_set(value, 109 NETLINK_CB(skb).sid); 110 return 0; 111 } 112 } 113 114 return -EINVAL; 115 } 116 117 /** 118 * netlbl_unlabel_list - Handle a LIST message 119 * @skb: the NETLINK buffer 120 * @info: the Generic NETLINK info block 121 * 122 * Description: 123 * Process a user generated LIST message and respond with the current status. 124 * Returns zero on success, negative values on failure. 125 * 126 */ 127 static int netlbl_unlabel_list(struct sk_buff *skb, struct genl_info *info) 128 { 129 int ret_val = -EINVAL; 130 struct sk_buff *ans_skb; 131 void *data; 132 133 ans_skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); 134 if (ans_skb == NULL) 135 goto list_failure; 136 data = netlbl_netlink_hdr_put(ans_skb, 137 info->snd_pid, 138 info->snd_seq, 139 netlbl_unlabel_gnl_family.id, 140 0, 141 NLBL_UNLABEL_C_LIST); 142 if (data == NULL) { 143 ret_val = -ENOMEM; 144 goto list_failure; 145 } 146 147 ret_val = nla_put_u8(ans_skb, 148 NLBL_UNLABEL_A_ACPTFLG, 149 atomic_read(&netlabel_unlabel_accept_flg)); 150 if (ret_val != 0) 151 goto list_failure; 152 153 genlmsg_end(ans_skb, data); 154 155 ret_val = genlmsg_unicast(ans_skb, info->snd_pid); 156 if (ret_val != 0) 157 goto list_failure; 158 return 0; 159 160 list_failure: 161 kfree(ans_skb); 162 return ret_val; 163 } 164 165 166 /* 167 * NetLabel Generic NETLINK Command Definitions 168 */ 169 170 static struct genl_ops netlbl_unlabel_genl_c_accept = { 171 .cmd = NLBL_UNLABEL_C_ACCEPT, 172 .flags = GENL_ADMIN_PERM, 173 .policy = netlbl_unlabel_genl_policy, 174 .doit = netlbl_unlabel_accept, 175 .dumpit = NULL, 176 }; 177 178 static struct genl_ops netlbl_unlabel_genl_c_list = { 179 .cmd = NLBL_UNLABEL_C_LIST, 180 .flags = 0, 181 .policy = netlbl_unlabel_genl_policy, 182 .doit = netlbl_unlabel_list, 183 .dumpit = NULL, 184 }; 185 186 187 /* 188 * NetLabel Generic NETLINK Protocol Functions 189 */ 190 191 /** 192 * netlbl_unlabel_genl_init - Register the Unlabeled NetLabel component 193 * 194 * Description: 195 * Register the unlabeled packet NetLabel component with the Generic NETLINK 196 * mechanism. Returns zero on success, negative values on failure. 197 * 198 */ 199 int netlbl_unlabel_genl_init(void) 200 { 201 int ret_val; 202 203 ret_val = genl_register_family(&netlbl_unlabel_gnl_family); 204 if (ret_val != 0) 205 return ret_val; 206 207 ret_val = genl_register_ops(&netlbl_unlabel_gnl_family, 208 &netlbl_unlabel_genl_c_accept); 209 if (ret_val != 0) 210 return ret_val; 211 212 ret_val = genl_register_ops(&netlbl_unlabel_gnl_family, 213 &netlbl_unlabel_genl_c_list); 214 if (ret_val != 0) 215 return ret_val; 216 217 return 0; 218 } 219 220 /* 221 * NetLabel KAPI Hooks 222 */ 223 224 /** 225 * netlbl_unlabel_getattr - Get the security attributes for an unlabled packet 226 * @secattr: the security attributes 227 * 228 * Description: 229 * Determine the security attributes, if any, for an unlabled packet and return 230 * them in @secattr. Returns zero on success and negative values on failure. 231 * 232 */ 233 int netlbl_unlabel_getattr(struct netlbl_lsm_secattr *secattr) 234 { 235 if (atomic_read(&netlabel_unlabel_accept_flg) == 1) 236 return netlbl_secattr_init(secattr); 237 238 return -ENOMSG; 239 } 240 241 /** 242 * netlbl_unlabel_defconf - Set the default config to allow unlabeled packets 243 * 244 * Description: 245 * Set the default NetLabel configuration to allow incoming unlabeled packets 246 * and to send unlabeled network traffic by default. 247 * 248 */ 249 int netlbl_unlabel_defconf(void) 250 { 251 int ret_val; 252 struct netlbl_dom_map *entry; 253 u32 secid; 254 255 security_task_getsecid(current, &secid); 256 257 entry = kzalloc(sizeof(*entry), GFP_KERNEL); 258 if (entry == NULL) 259 return -ENOMEM; 260 entry->type = NETLBL_NLTYPE_UNLABELED; 261 ret_val = netlbl_domhsh_add_default(entry, secid); 262 if (ret_val != 0) 263 return ret_val; 264 265 netlbl_unlabel_acceptflg_set(1, secid); 266 267 return 0; 268 } 269