Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

NetLabel: introduce a new kernel configuration API for NetLabel

Add a new set of configuration functions to the NetLabel/LSM API so that
LSMs can perform their own configuration of the NetLabel subsystem without
relying on assistance from userspace.

Signed-off-by: Paul Moore <paul.moore@hp.com>
Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
Reviewed-by: James Morris <jmorris@namei.org>
Cc: Chris Wright <chrisw@sous-sol.org>
Cc: Stephen Smalley <sds@tycho.nsa.gov>
Cc: Casey Schaufler <casey@schaufler-ca.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Paul Moore and committed by
Linus Torvalds
eda61d32 97829955

+225 -9
+41 -6
include/net/netlabel.h
··· 36 36 #include <net/netlink.h> 37 37 #include <asm/atomic.h> 38 38 39 + struct cipso_v4_doi; 40 + 39 41 /* 40 42 * NetLabel - A management interface for maintaining network packet label 41 43 * mapping tables for explicit packet labling protocols. ··· 104 102 u32 secid; 105 103 uid_t loginuid; 106 104 }; 107 - 108 - /* Domain mapping definition struct */ 109 - struct netlbl_dom_map; 110 - 111 - /* Domain mapping operations */ 112 - int netlbl_domhsh_remove(const char *domain, struct netlbl_audit *audit_info); 113 105 114 106 /* 115 107 * LSM security attributes ··· 340 344 341 345 #ifdef CONFIG_NETLABEL 342 346 /* 347 + * LSM configuration operations 348 + */ 349 + int netlbl_cfg_map_del(const char *domain, struct netlbl_audit *audit_info); 350 + int netlbl_cfg_unlbl_add_map(const char *domain, 351 + struct netlbl_audit *audit_info); 352 + int netlbl_cfg_cipsov4_add(struct cipso_v4_doi *doi_def, 353 + struct netlbl_audit *audit_info); 354 + int netlbl_cfg_cipsov4_add_map(struct cipso_v4_doi *doi_def, 355 + const char *domain, 356 + struct netlbl_audit *audit_info); 357 + int netlbl_cfg_cipsov4_del(u32 doi, struct netlbl_audit *audit_info); 358 + 359 + /* 343 360 * LSM security attribute operations 344 361 */ 345 362 int netlbl_secattr_catmap_walk(struct netlbl_lsm_secattr_catmap *catmap, ··· 387 378 int netlbl_cache_add(const struct sk_buff *skb, 388 379 const struct netlbl_lsm_secattr *secattr); 389 380 #else 381 + static inline int netlbl_cfg_map_del(const char *domain, 382 + struct netlbl_audit *audit_info) 383 + { 384 + return -ENOSYS; 385 + } 386 + static inline int netlbl_cfg_unlbl_add_map(const char *domain, 387 + struct netlbl_audit *audit_info) 388 + { 389 + return -ENOSYS; 390 + } 391 + static inline int netlbl_cfg_cipsov4_add(struct cipso_v4_doi *doi_def, 392 + struct netlbl_audit *audit_info) 393 + { 394 + return -ENOSYS; 395 + } 396 + static inline int netlbl_cfg_cipsov4_add_map(struct cipso_v4_doi *doi_def, 397 + const char *domain, 398 + struct netlbl_audit *audit_info) 399 + { 400 + return -ENOSYS; 401 + } 402 + static inline int netlbl_cfg_cipsov4_del(u32 doi, 403 + struct netlbl_audit *audit_info) 404 + { 405 + return -ENOSYS; 406 + } 390 407 static inline int netlbl_secattr_catmap_walk( 391 408 struct netlbl_lsm_secattr_catmap *catmap, 392 409 u32 offset)
+2 -2
net/ipv4/cipso_ipv4.c
··· 547 547 rcu_read_lock(); 548 548 list_for_each_entry_rcu(dom_iter, &doi_def->dom_list, list) 549 549 if (dom_iter->valid) 550 - netlbl_domhsh_remove(dom_iter->domain, 551 - audit_info); 550 + netlbl_cfg_map_del(dom_iter->domain, 551 + audit_info); 552 552 rcu_read_unlock(); 553 553 cipso_v4_cache_invalidate(); 554 554 call_rcu(&doi_def->rcu, callback);
+1 -1
net/netlabel/netlabel_cipso_v4.c
··· 90 90 * safely. 91 91 * 92 92 */ 93 - static void netlbl_cipsov4_doi_free(struct rcu_head *entry) 93 + void netlbl_cipsov4_doi_free(struct rcu_head *entry) 94 94 { 95 95 struct cipso_v4_doi *ptr; 96 96
+3
net/netlabel/netlabel_cipso_v4.h
··· 163 163 /* NetLabel protocol functions */ 164 164 int netlbl_cipsov4_genl_init(void); 165 165 166 + /* Free the memory associated with a CIPSOv4 DOI definition */ 167 + void netlbl_cipsov4_doi_free(struct rcu_head *entry); 168 + 166 169 #endif
+1
net/netlabel/netlabel_domainhash.h
··· 61 61 struct netlbl_audit *audit_info); 62 62 int netlbl_domhsh_add_default(struct netlbl_dom_map *entry, 63 63 struct netlbl_audit *audit_info); 64 + int netlbl_domhsh_remove(const char *domain, struct netlbl_audit *audit_info); 64 65 int netlbl_domhsh_remove_default(struct netlbl_audit *audit_info); 65 66 struct netlbl_dom_map *netlbl_domhsh_getentry(const char *domain); 66 67 int netlbl_domhsh_walk(u32 *skip_bkt,
+177
net/netlabel/netlabel_kapi.c
··· 30 30 31 31 #include <linux/init.h> 32 32 #include <linux/types.h> 33 + #include <linux/audit.h> 33 34 #include <net/ip.h> 34 35 #include <net/netlabel.h> 35 36 #include <net/cipso_ipv4.h> ··· 39 38 40 39 #include "netlabel_domainhash.h" 41 40 #include "netlabel_unlabeled.h" 41 + #include "netlabel_cipso_v4.h" 42 42 #include "netlabel_user.h" 43 43 #include "netlabel_mgmt.h" 44 + 45 + /* 46 + * Configuration Functions 47 + */ 48 + 49 + /** 50 + * netlbl_cfg_map_del - Remove a NetLabel/LSM domain mapping 51 + * @domain: the domain mapping to remove 52 + * @audit_info: NetLabel audit information 53 + * 54 + * Description: 55 + * Removes a NetLabel/LSM domain mapping. A @domain value of NULL causes the 56 + * default domain mapping to be removed. Returns zero on success, negative 57 + * values on failure. 58 + * 59 + */ 60 + int netlbl_cfg_map_del(const char *domain, struct netlbl_audit *audit_info) 61 + { 62 + return netlbl_domhsh_remove(domain, audit_info); 63 + } 64 + 65 + /** 66 + * netlbl_cfg_unlbl_add_map - Add an unlabeled NetLabel/LSM domain mapping 67 + * @domain: the domain mapping to add 68 + * @audit_info: NetLabel audit information 69 + * 70 + * Description: 71 + * Adds a new unlabeled NetLabel/LSM domain mapping. A @domain value of NULL 72 + * causes a new default domain mapping to be added. Returns zero on success, 73 + * negative values on failure. 74 + * 75 + */ 76 + int netlbl_cfg_unlbl_add_map(const char *domain, 77 + struct netlbl_audit *audit_info) 78 + { 79 + int ret_val = -ENOMEM; 80 + struct netlbl_dom_map *entry; 81 + 82 + entry = kzalloc(sizeof(*entry), GFP_ATOMIC); 83 + if (entry == NULL) 84 + goto cfg_unlbl_add_map_failure; 85 + if (domain != NULL) { 86 + entry->domain = kstrdup(domain, GFP_ATOMIC); 87 + if (entry->domain == NULL) 88 + goto cfg_unlbl_add_map_failure; 89 + } 90 + entry->type = NETLBL_NLTYPE_UNLABELED; 91 + 92 + ret_val = netlbl_domhsh_add(entry, audit_info); 93 + if (ret_val != 0) 94 + goto cfg_unlbl_add_map_failure; 95 + 96 + return 0; 97 + 98 + cfg_unlbl_add_map_failure: 99 + if (entry != NULL) 100 + kfree(entry->domain); 101 + kfree(entry); 102 + return ret_val; 103 + } 104 + 105 + /** 106 + * netlbl_cfg_cipsov4_add - Add a new CIPSOv4 DOI definition 107 + * @doi_def: the DOI definition 108 + * @audit_info: NetLabel audit information 109 + * 110 + * Description: 111 + * Add a new CIPSOv4 DOI definition to the NetLabel subsystem. Returns zero on 112 + * success, negative values on failure. 113 + * 114 + */ 115 + int netlbl_cfg_cipsov4_add(struct cipso_v4_doi *doi_def, 116 + struct netlbl_audit *audit_info) 117 + { 118 + int ret_val; 119 + const char *type_str; 120 + struct audit_buffer *audit_buf; 121 + 122 + ret_val = cipso_v4_doi_add(doi_def); 123 + 124 + audit_buf = netlbl_audit_start_common(AUDIT_MAC_CIPSOV4_ADD, 125 + audit_info); 126 + if (audit_buf != NULL) { 127 + switch (doi_def->type) { 128 + case CIPSO_V4_MAP_STD: 129 + type_str = "std"; 130 + break; 131 + case CIPSO_V4_MAP_PASS: 132 + type_str = "pass"; 133 + break; 134 + default: 135 + type_str = "(unknown)"; 136 + } 137 + audit_log_format(audit_buf, 138 + " cipso_doi=%u cipso_type=%s res=%u", 139 + doi_def->doi, 140 + type_str, 141 + ret_val == 0 ? 1 : 0); 142 + audit_log_end(audit_buf); 143 + } 144 + 145 + return ret_val; 146 + } 147 + 148 + /** 149 + * netlbl_cfg_cipsov4_add_map - Add a new CIPSOv4 DOI definition and mapping 150 + * @doi_def: the DOI definition 151 + * @domain: the domain mapping to add 152 + * @audit_info: NetLabel audit information 153 + * 154 + * Description: 155 + * Add a new CIPSOv4 DOI definition and NetLabel/LSM domain mapping for this 156 + * new DOI definition to the NetLabel subsystem. A @domain value of NULL adds 157 + * a new default domain mapping. Returns zero on success, negative values on 158 + * failure. 159 + * 160 + */ 161 + int netlbl_cfg_cipsov4_add_map(struct cipso_v4_doi *doi_def, 162 + const char *domain, 163 + struct netlbl_audit *audit_info) 164 + { 165 + int ret_val = -ENOMEM; 166 + struct netlbl_dom_map *entry; 167 + 168 + entry = kzalloc(sizeof(*entry), GFP_ATOMIC); 169 + if (entry == NULL) 170 + goto cfg_cipsov4_add_map_failure; 171 + if (domain != NULL) { 172 + entry->domain = kstrdup(domain, GFP_ATOMIC); 173 + if (entry->domain == NULL) 174 + goto cfg_cipsov4_add_map_failure; 175 + } 176 + entry->type = NETLBL_NLTYPE_CIPSOV4; 177 + entry->type_def.cipsov4 = doi_def; 178 + 179 + /* Grab a RCU read lock here so nothing happens to the doi_def variable 180 + * between adding it to the CIPSOv4 protocol engine and adding a 181 + * domain mapping for it. */ 182 + 183 + rcu_read_lock(); 184 + ret_val = netlbl_cfg_cipsov4_add(doi_def, audit_info); 185 + if (ret_val != 0) 186 + goto cfg_cipsov4_add_map_failure_unlock; 187 + ret_val = netlbl_domhsh_add(entry, audit_info); 188 + if (ret_val != 0) 189 + goto cfg_cipsov4_add_map_failure_remove_doi; 190 + rcu_read_unlock(); 191 + 192 + return 0; 193 + 194 + cfg_cipsov4_add_map_failure_remove_doi: 195 + cipso_v4_doi_remove(doi_def->doi, audit_info, netlbl_cipsov4_doi_free); 196 + cfg_cipsov4_add_map_failure_unlock: 197 + rcu_read_unlock(); 198 + cfg_cipsov4_add_map_failure: 199 + if (entry != NULL) 200 + kfree(entry->domain); 201 + kfree(entry); 202 + return ret_val; 203 + } 204 + 205 + /** 206 + * netlbl_cfg_cipsov4_del - Removean existing CIPSOv4 DOI definition 207 + * @doi: the CIPSO DOI value 208 + * @audit_info: NetLabel audit information 209 + * 210 + * Description: 211 + * Removes an existing CIPSOv4 DOI definition from the NetLabel subsystem. 212 + * Returns zero on success, negative values on failure. 213 + * 214 + */ 215 + int netlbl_cfg_cipsov4_del(u32 doi, struct netlbl_audit *audit_info) 216 + { 217 + return cipso_v4_doi_remove(doi, audit_info, netlbl_cipsov4_doi_free); 218 + } 44 219 45 220 /* 46 221 * Security Attribute Functions