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 <linux/audit.h> 39 #include <net/sock.h> 40 #include <net/netlink.h> 41 #include <net/genetlink.h> 42 43 #include <net/netlabel.h> 44 #include <asm/bug.h> 45 46 #include "netlabel_user.h" 47 #include "netlabel_domainhash.h" 48 #include "netlabel_unlabeled.h" 49 50 /* Accept unlabeled packets flag */ 51 static DEFINE_SPINLOCK(netlabel_unlabel_acceptflg_lock); 52 static u8 netlabel_unlabel_acceptflg = 0; 53 54 /* NetLabel Generic NETLINK CIPSOv4 family */ 55 static struct genl_family netlbl_unlabel_gnl_family = { 56 .id = GENL_ID_GENERATE, 57 .hdrsize = 0, 58 .name = NETLBL_NLTYPE_UNLABELED_NAME, 59 .version = NETLBL_PROTO_VERSION, 60 .maxattr = NLBL_UNLABEL_A_MAX, 61 }; 62 63 /* NetLabel Netlink attribute policy */ 64 static struct nla_policy netlbl_unlabel_genl_policy[NLBL_UNLABEL_A_MAX + 1] = { 65 [NLBL_UNLABEL_A_ACPTFLG] = { .type = NLA_U8 }, 66 }; 67 68 /* 69 * Helper Functions 70 */ 71 72 /** 73 * netlbl_unlabel_acceptflg_set - Set the unlabeled accept flag 74 * @value: desired value 75 * @audit_info: NetLabel audit information 76 * 77 * Description: 78 * Set the value of the unlabeled accept flag to @value. 79 * 80 */ 81 static void netlbl_unlabel_acceptflg_set(u8 value, 82 struct netlbl_audit *audit_info) 83 { 84 struct audit_buffer *audit_buf; 85 u8 old_val; 86 87 rcu_read_lock(); 88 old_val = netlabel_unlabel_acceptflg; 89 spin_lock(&netlabel_unlabel_acceptflg_lock); 90 netlabel_unlabel_acceptflg = value; 91 spin_unlock(&netlabel_unlabel_acceptflg_lock); 92 rcu_read_unlock(); 93 94 audit_buf = netlbl_audit_start_common(AUDIT_MAC_UNLBL_ALLOW, 95 audit_info); 96 if (audit_buf != NULL) { 97 audit_log_format(audit_buf, 98 " unlbl_accept=%u old=%u", value, old_val); 99 audit_log_end(audit_buf); 100 } 101 } 102 103 /* 104 * NetLabel Command Handlers 105 */ 106 107 /** 108 * netlbl_unlabel_accept - Handle an ACCEPT message 109 * @skb: the NETLINK buffer 110 * @info: the Generic NETLINK info block 111 * 112 * Description: 113 * Process a user generated ACCEPT message and set the accept flag accordingly. 114 * Returns zero on success, negative values on failure. 115 * 116 */ 117 static int netlbl_unlabel_accept(struct sk_buff *skb, struct genl_info *info) 118 { 119 u8 value; 120 struct netlbl_audit audit_info; 121 122 if (info->attrs[NLBL_UNLABEL_A_ACPTFLG]) { 123 value = nla_get_u8(info->attrs[NLBL_UNLABEL_A_ACPTFLG]); 124 if (value == 1 || value == 0) { 125 netlbl_netlink_auditinfo(skb, &audit_info); 126 netlbl_unlabel_acceptflg_set(value, &audit_info); 127 return 0; 128 } 129 } 130 131 return -EINVAL; 132 } 133 134 /** 135 * netlbl_unlabel_list - Handle a LIST message 136 * @skb: the NETLINK buffer 137 * @info: the Generic NETLINK info block 138 * 139 * Description: 140 * Process a user generated LIST message and respond with the current status. 141 * Returns zero on success, negative values on failure. 142 * 143 */ 144 static int netlbl_unlabel_list(struct sk_buff *skb, struct genl_info *info) 145 { 146 int ret_val = -EINVAL; 147 struct sk_buff *ans_skb; 148 void *data; 149 150 ans_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 151 if (ans_skb == NULL) 152 goto list_failure; 153 data = genlmsg_put_reply(ans_skb, info, &netlbl_unlabel_gnl_family, 154 0, NLBL_UNLABEL_C_LIST); 155 if (data == NULL) { 156 ret_val = -ENOMEM; 157 goto list_failure; 158 } 159 160 rcu_read_lock(); 161 ret_val = nla_put_u8(ans_skb, 162 NLBL_UNLABEL_A_ACPTFLG, 163 netlabel_unlabel_acceptflg); 164 rcu_read_unlock(); 165 if (ret_val != 0) 166 goto list_failure; 167 168 genlmsg_end(ans_skb, data); 169 170 ret_val = genlmsg_reply(ans_skb, info); 171 if (ret_val != 0) 172 goto list_failure; 173 return 0; 174 175 list_failure: 176 kfree(ans_skb); 177 return ret_val; 178 } 179 180 181 /* 182 * NetLabel Generic NETLINK Command Definitions 183 */ 184 185 static struct genl_ops netlbl_unlabel_genl_c_accept = { 186 .cmd = NLBL_UNLABEL_C_ACCEPT, 187 .flags = GENL_ADMIN_PERM, 188 .policy = netlbl_unlabel_genl_policy, 189 .doit = netlbl_unlabel_accept, 190 .dumpit = NULL, 191 }; 192 193 static struct genl_ops netlbl_unlabel_genl_c_list = { 194 .cmd = NLBL_UNLABEL_C_LIST, 195 .flags = 0, 196 .policy = netlbl_unlabel_genl_policy, 197 .doit = netlbl_unlabel_list, 198 .dumpit = NULL, 199 }; 200 201 202 /* 203 * NetLabel Generic NETLINK Protocol Functions 204 */ 205 206 /** 207 * netlbl_unlabel_genl_init - Register the Unlabeled NetLabel component 208 * 209 * Description: 210 * Register the unlabeled packet NetLabel component with the Generic NETLINK 211 * mechanism. Returns zero on success, negative values on failure. 212 * 213 */ 214 int netlbl_unlabel_genl_init(void) 215 { 216 int ret_val; 217 218 ret_val = genl_register_family(&netlbl_unlabel_gnl_family); 219 if (ret_val != 0) 220 return ret_val; 221 222 ret_val = genl_register_ops(&netlbl_unlabel_gnl_family, 223 &netlbl_unlabel_genl_c_accept); 224 if (ret_val != 0) 225 return ret_val; 226 227 ret_val = genl_register_ops(&netlbl_unlabel_gnl_family, 228 &netlbl_unlabel_genl_c_list); 229 if (ret_val != 0) 230 return ret_val; 231 232 return 0; 233 } 234 235 /* 236 * NetLabel KAPI Hooks 237 */ 238 239 /** 240 * netlbl_unlabel_getattr - Get the security attributes for an unlabled packet 241 * @secattr: the security attributes 242 * 243 * Description: 244 * Determine the security attributes, if any, for an unlabled packet and return 245 * them in @secattr. Returns zero on success and negative values on failure. 246 * 247 */ 248 int netlbl_unlabel_getattr(struct netlbl_lsm_secattr *secattr) 249 { 250 int ret_val; 251 252 rcu_read_lock(); 253 if (netlabel_unlabel_acceptflg == 1) { 254 netlbl_secattr_init(secattr); 255 ret_val = 0; 256 } else 257 ret_val = -ENOMSG; 258 rcu_read_unlock(); 259 260 return ret_val; 261 } 262 263 /** 264 * netlbl_unlabel_defconf - Set the default config to allow unlabeled packets 265 * 266 * Description: 267 * Set the default NetLabel configuration to allow incoming unlabeled packets 268 * and to send unlabeled network traffic by default. 269 * 270 */ 271 int netlbl_unlabel_defconf(void) 272 { 273 int ret_val; 274 struct netlbl_dom_map *entry; 275 struct netlbl_audit audit_info; 276 277 /* Only the kernel is allowed to call this function and the only time 278 * it is called is at bootup before the audit subsystem is reporting 279 * messages so don't worry to much about these values. */ 280 security_task_getsecid(current, &audit_info.secid); 281 audit_info.loginuid = 0; 282 283 entry = kzalloc(sizeof(*entry), GFP_KERNEL); 284 if (entry == NULL) 285 return -ENOMEM; 286 entry->type = NETLBL_NLTYPE_UNLABELED; 287 ret_val = netlbl_domhsh_add_default(entry, &audit_info); 288 if (ret_val != 0) 289 return ret_val; 290 291 netlbl_unlabel_acceptflg_set(1, &audit_info); 292 293 return 0; 294 } 295