aboutsummaryrefslogtreecommitdiffstats
path: root/net/netlabel/netlabel_kapi.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/netlabel/netlabel_kapi.c')
-rw-r--r--net/netlabel/netlabel_kapi.c347
1 files changed, 287 insertions, 60 deletions
diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c
index b32eceb3ab0d..fd9229db075c 100644
--- a/net/netlabel/netlabel_kapi.c
+++ b/net/netlabel/netlabel_kapi.c
@@ -31,7 +31,10 @@
31#include <linux/init.h> 31#include <linux/init.h>
32#include <linux/types.h> 32#include <linux/types.h>
33#include <linux/audit.h> 33#include <linux/audit.h>
34#include <linux/in.h>
35#include <linux/in6.h>
34#include <net/ip.h> 36#include <net/ip.h>
37#include <net/ipv6.h>
35#include <net/netlabel.h> 38#include <net/netlabel.h>
36#include <net/cipso_ipv4.h> 39#include <net/cipso_ipv4.h>
37#include <asm/bug.h> 40#include <asm/bug.h>
@@ -42,6 +45,7 @@
42#include "netlabel_cipso_v4.h" 45#include "netlabel_cipso_v4.h"
43#include "netlabel_user.h" 46#include "netlabel_user.h"
44#include "netlabel_mgmt.h" 47#include "netlabel_mgmt.h"
48#include "netlabel_addrlist.h"
45 49
46/* 50/*
47 * Configuration Functions 51 * Configuration Functions
@@ -50,6 +54,9 @@
50/** 54/**
51 * netlbl_cfg_map_del - Remove a NetLabel/LSM domain mapping 55 * netlbl_cfg_map_del - Remove a NetLabel/LSM domain mapping
52 * @domain: the domain mapping to remove 56 * @domain: the domain mapping to remove
57 * @family: address family
58 * @addr: IP address
59 * @mask: IP address mask
53 * @audit_info: NetLabel audit information 60 * @audit_info: NetLabel audit information
54 * 61 *
55 * Description: 62 * Description:
@@ -58,14 +65,32 @@
58 * values on failure. 65 * values on failure.
59 * 66 *
60 */ 67 */
61int netlbl_cfg_map_del(const char *domain, struct netlbl_audit *audit_info) 68int netlbl_cfg_map_del(const char *domain,
69 u16 family,
70 const void *addr,
71 const void *mask,
72 struct netlbl_audit *audit_info)
62{ 73{
63 return netlbl_domhsh_remove(domain, audit_info); 74 if (addr == NULL && mask == NULL) {
75 return netlbl_domhsh_remove(domain, audit_info);
76 } else if (addr != NULL && mask != NULL) {
77 switch (family) {
78 case AF_INET:
79 return netlbl_domhsh_remove_af4(domain, addr, mask,
80 audit_info);
81 default:
82 return -EPFNOSUPPORT;
83 }
84 } else
85 return -EINVAL;
64} 86}
65 87
66/** 88/**
67 * netlbl_cfg_unlbl_add_map - Add an unlabeled NetLabel/LSM domain mapping 89 * netlbl_cfg_unlbl_map_add - Add a new unlabeled mapping
68 * @domain: the domain mapping to add 90 * @domain: the domain mapping to add
91 * @family: address family
92 * @addr: IP address
93 * @mask: IP address mask
69 * @audit_info: NetLabel audit information 94 * @audit_info: NetLabel audit information
70 * 95 *
71 * Description: 96 * Description:
@@ -74,11 +99,19 @@ int netlbl_cfg_map_del(const char *domain, struct netlbl_audit *audit_info)
74 * negative values on failure. 99 * negative values on failure.
75 * 100 *
76 */ 101 */
77int netlbl_cfg_unlbl_add_map(const char *domain, 102int netlbl_cfg_unlbl_map_add(const char *domain,
103 u16 family,
104 const void *addr,
105 const void *mask,
78 struct netlbl_audit *audit_info) 106 struct netlbl_audit *audit_info)
79{ 107{
80 int ret_val = -ENOMEM; 108 int ret_val = -ENOMEM;
81 struct netlbl_dom_map *entry; 109 struct netlbl_dom_map *entry;
110 struct netlbl_domaddr_map *addrmap = NULL;
111 struct netlbl_domaddr4_map *map4 = NULL;
112 struct netlbl_domaddr6_map *map6 = NULL;
113 const struct in_addr *addr4, *mask4;
114 const struct in6_addr *addr6, *mask6;
82 115
83 entry = kzalloc(sizeof(*entry), GFP_ATOMIC); 116 entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
84 if (entry == NULL) 117 if (entry == NULL)
@@ -86,49 +119,225 @@ int netlbl_cfg_unlbl_add_map(const char *domain,
86 if (domain != NULL) { 119 if (domain != NULL) {
87 entry->domain = kstrdup(domain, GFP_ATOMIC); 120 entry->domain = kstrdup(domain, GFP_ATOMIC);
88 if (entry->domain == NULL) 121 if (entry->domain == NULL)
89 goto cfg_unlbl_add_map_failure; 122 goto cfg_unlbl_map_add_failure;
123 }
124
125 if (addr == NULL && mask == NULL)
126 entry->type = NETLBL_NLTYPE_UNLABELED;
127 else if (addr != NULL && mask != NULL) {
128 addrmap = kzalloc(sizeof(*addrmap), GFP_ATOMIC);
129 if (addrmap == NULL)
130 goto cfg_unlbl_map_add_failure;
131 INIT_LIST_HEAD(&addrmap->list4);
132 INIT_LIST_HEAD(&addrmap->list6);
133
134 switch (family) {
135 case AF_INET:
136 addr4 = addr;
137 mask4 = mask;
138 map4 = kzalloc(sizeof(*map4), GFP_ATOMIC);
139 if (map4 == NULL)
140 goto cfg_unlbl_map_add_failure;
141 map4->type = NETLBL_NLTYPE_UNLABELED;
142 map4->list.addr = addr4->s_addr & mask4->s_addr;
143 map4->list.mask = mask4->s_addr;
144 map4->list.valid = 1;
145 ret_val = netlbl_af4list_add(&map4->list,
146 &addrmap->list4);
147 if (ret_val != 0)
148 goto cfg_unlbl_map_add_failure;
149 break;
150 case AF_INET6:
151 addr6 = addr;
152 mask6 = mask;
153 map6 = kzalloc(sizeof(*map6), GFP_ATOMIC);
154 if (map4 == NULL)
155 goto cfg_unlbl_map_add_failure;
156 map6->type = NETLBL_NLTYPE_UNLABELED;
157 ipv6_addr_copy(&map6->list.addr, addr6);
158 map6->list.addr.s6_addr32[0] &= mask6->s6_addr32[0];
159 map6->list.addr.s6_addr32[1] &= mask6->s6_addr32[1];
160 map6->list.addr.s6_addr32[2] &= mask6->s6_addr32[2];
161 map6->list.addr.s6_addr32[3] &= mask6->s6_addr32[3];
162 ipv6_addr_copy(&map6->list.mask, mask6);
163 map6->list.valid = 1;
164 ret_val = netlbl_af4list_add(&map4->list,
165 &addrmap->list4);
166 if (ret_val != 0)
167 goto cfg_unlbl_map_add_failure;
168 break;
169 default:
170 goto cfg_unlbl_map_add_failure;
171 break;
172 }
173
174 entry->type_def.addrsel = addrmap;
175 entry->type = NETLBL_NLTYPE_ADDRSELECT;
176 } else {
177 ret_val = -EINVAL;
178 goto cfg_unlbl_map_add_failure;
90 } 179 }
91 entry->type = NETLBL_NLTYPE_UNLABELED;
92 180
93 ret_val = netlbl_domhsh_add(entry, audit_info); 181 ret_val = netlbl_domhsh_add(entry, audit_info);
94 if (ret_val != 0) 182 if (ret_val != 0)
95 goto cfg_unlbl_add_map_failure; 183 goto cfg_unlbl_map_add_failure;
96 184
97 return 0; 185 return 0;
98 186
99cfg_unlbl_add_map_failure: 187cfg_unlbl_map_add_failure:
100 if (entry != NULL) 188 if (entry != NULL)
101 kfree(entry->domain); 189 kfree(entry->domain);
102 kfree(entry); 190 kfree(entry);
191 kfree(addrmap);
192 kfree(map4);
193 kfree(map6);
103 return ret_val; 194 return ret_val;
104} 195}
105 196
197
198/**
199 * netlbl_cfg_unlbl_static_add - Adds a new static label
200 * @net: network namespace
201 * @dev_name: interface name
202 * @addr: IP address in network byte order (struct in[6]_addr)
203 * @mask: address mask in network byte order (struct in[6]_addr)
204 * @family: address family
205 * @secid: LSM secid value for the entry
206 * @audit_info: NetLabel audit information
207 *
208 * Description:
209 * Adds a new NetLabel static label to be used when protocol provided labels
210 * are not present on incoming traffic. If @dev_name is NULL then the default
211 * interface will be used. Returns zero on success, negative values on failure.
212 *
213 */
214int netlbl_cfg_unlbl_static_add(struct net *net,
215 const char *dev_name,
216 const void *addr,
217 const void *mask,
218 u16 family,
219 u32 secid,
220 struct netlbl_audit *audit_info)
221{
222 u32 addr_len;
223
224 switch (family) {
225 case AF_INET:
226 addr_len = sizeof(struct in_addr);
227 break;
228 case AF_INET6:
229 addr_len = sizeof(struct in6_addr);
230 break;
231 default:
232 return -EPFNOSUPPORT;
233 }
234
235 return netlbl_unlhsh_add(net,
236 dev_name, addr, mask, addr_len,
237 secid, audit_info);
238}
239
240/**
241 * netlbl_cfg_unlbl_static_del - Removes an existing static label
242 * @net: network namespace
243 * @dev_name: interface name
244 * @addr: IP address in network byte order (struct in[6]_addr)
245 * @mask: address mask in network byte order (struct in[6]_addr)
246 * @family: address family
247 * @secid: LSM secid value for the entry
248 * @audit_info: NetLabel audit information
249 *
250 * Description:
251 * Removes an existing NetLabel static label used when protocol provided labels
252 * are not present on incoming traffic. If @dev_name is NULL then the default
253 * interface will be used. Returns zero on success, negative values on failure.
254 *
255 */
256int netlbl_cfg_unlbl_static_del(struct net *net,
257 const char *dev_name,
258 const void *addr,
259 const void *mask,
260 u16 family,
261 struct netlbl_audit *audit_info)
262{
263 u32 addr_len;
264
265 switch (family) {
266 case AF_INET:
267 addr_len = sizeof(struct in_addr);
268 break;
269 case AF_INET6:
270 addr_len = sizeof(struct in6_addr);
271 break;
272 default:
273 return -EPFNOSUPPORT;
274 }
275
276 return netlbl_unlhsh_remove(net,
277 dev_name, addr, mask, addr_len,
278 audit_info);
279}
280
281/**
282 * netlbl_cfg_cipsov4_add - Add a new CIPSOv4 DOI definition
283 * @doi_def: CIPSO DOI definition
284 * @audit_info: NetLabel audit information
285 *
286 * Description:
287 * Add a new CIPSO DOI definition as defined by @doi_def. Returns zero on
288 * success and negative values on failure.
289 *
290 */
291int netlbl_cfg_cipsov4_add(struct cipso_v4_doi *doi_def,
292 struct netlbl_audit *audit_info)
293{
294 return cipso_v4_doi_add(doi_def, audit_info);
295}
296
297/**
298 * netlbl_cfg_cipsov4_del - Remove an existing CIPSOv4 DOI definition
299 * @doi: CIPSO DOI
300 * @audit_info: NetLabel audit information
301 *
302 * Description:
303 * Remove an existing CIPSO DOI definition matching @doi. Returns zero on
304 * success and negative values on failure.
305 *
306 */
307void netlbl_cfg_cipsov4_del(u32 doi, struct netlbl_audit *audit_info)
308{
309 cipso_v4_doi_remove(doi, audit_info);
310}
311
106/** 312/**
107 * netlbl_cfg_cipsov4_add_map - Add a new CIPSOv4 DOI definition and mapping 313 * netlbl_cfg_cipsov4_map_add - Add a new CIPSOv4 DOI mapping
108 * @doi_def: the DOI definition 314 * @doi: the CIPSO DOI
109 * @domain: the domain mapping to add 315 * @domain: the domain mapping to add
316 * @addr: IP address
317 * @mask: IP address mask
110 * @audit_info: NetLabel audit information 318 * @audit_info: NetLabel audit information
111 * 319 *
112 * Description: 320 * Description:
113 * Add a new CIPSOv4 DOI definition and NetLabel/LSM domain mapping for this 321 * Add a new NetLabel/LSM domain mapping for the given CIPSO DOI to the NetLabel
114 * new DOI definition to the NetLabel subsystem. A @domain value of NULL adds 322 * subsystem. A @domain value of NULL adds a new default domain mapping.
115 * a new default domain mapping. Returns zero on success, negative values on 323 * Returns zero on success, negative values on failure.
116 * failure.
117 * 324 *
118 */ 325 */
119int netlbl_cfg_cipsov4_add_map(struct cipso_v4_doi *doi_def, 326int netlbl_cfg_cipsov4_map_add(u32 doi,
120 const char *domain, 327 const char *domain,
328 const struct in_addr *addr,
329 const struct in_addr *mask,
121 struct netlbl_audit *audit_info) 330 struct netlbl_audit *audit_info)
122{ 331{
123 int ret_val = -ENOMEM; 332 int ret_val = -ENOMEM;
124 u32 doi; 333 struct cipso_v4_doi *doi_def;
125 u32 doi_type;
126 struct netlbl_dom_map *entry; 334 struct netlbl_dom_map *entry;
127 const char *type_str; 335 struct netlbl_domaddr_map *addrmap = NULL;
128 struct audit_buffer *audit_buf; 336 struct netlbl_domaddr4_map *addrinfo = NULL;
129 337
130 doi = doi_def->doi; 338 doi_def = cipso_v4_doi_getdef(doi);
131 doi_type = doi_def->type; 339 if (doi_def == NULL)
340 return -ENOENT;
132 341
133 entry = kzalloc(sizeof(*entry), GFP_ATOMIC); 342 entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
134 if (entry == NULL) 343 if (entry == NULL)
@@ -136,56 +345,52 @@ int netlbl_cfg_cipsov4_add_map(struct cipso_v4_doi *doi_def,
136 if (domain != NULL) { 345 if (domain != NULL) {
137 entry->domain = kstrdup(domain, GFP_ATOMIC); 346 entry->domain = kstrdup(domain, GFP_ATOMIC);
138 if (entry->domain == NULL) 347 if (entry->domain == NULL)
139 goto cfg_cipsov4_add_map_failure; 348 goto cfg_cipsov4_map_add_failure;
140 } 349 }
141 350
142 ret_val = cipso_v4_doi_add(doi_def); 351 if (addr == NULL && mask == NULL) {
143 if (ret_val != 0) 352 entry->type_def.cipsov4 = doi_def;
144 goto cfg_cipsov4_add_map_failure_remove_doi; 353 entry->type = NETLBL_NLTYPE_CIPSOV4;
145 entry->type = NETLBL_NLTYPE_CIPSOV4; 354 } else if (addr != NULL && mask != NULL) {
146 entry->type_def.cipsov4 = cipso_v4_doi_getdef(doi); 355 addrmap = kzalloc(sizeof(*addrmap), GFP_ATOMIC);
147 if (entry->type_def.cipsov4 == NULL) { 356 if (addrmap == NULL)
148 ret_val = -ENOENT; 357 goto cfg_cipsov4_map_add_failure;
149 goto cfg_cipsov4_add_map_failure_remove_doi; 358 INIT_LIST_HEAD(&addrmap->list4);
359 INIT_LIST_HEAD(&addrmap->list6);
360
361 addrinfo = kzalloc(sizeof(*addrinfo), GFP_ATOMIC);
362 if (addrinfo == NULL)
363 goto cfg_cipsov4_map_add_failure;
364 addrinfo->type_def.cipsov4 = doi_def;
365 addrinfo->type = NETLBL_NLTYPE_CIPSOV4;
366 addrinfo->list.addr = addr->s_addr & mask->s_addr;
367 addrinfo->list.mask = mask->s_addr;
368 addrinfo->list.valid = 1;
369 ret_val = netlbl_af4list_add(&addrinfo->list, &addrmap->list4);
370 if (ret_val != 0)
371 goto cfg_cipsov4_map_add_failure;
372
373 entry->type_def.addrsel = addrmap;
374 entry->type = NETLBL_NLTYPE_ADDRSELECT;
375 } else {
376 ret_val = -EINVAL;
377 goto cfg_cipsov4_map_add_failure;
150 } 378 }
379
151 ret_val = netlbl_domhsh_add(entry, audit_info); 380 ret_val = netlbl_domhsh_add(entry, audit_info);
152 if (ret_val != 0) 381 if (ret_val != 0)
153 goto cfg_cipsov4_add_map_failure_release_doi; 382 goto cfg_cipsov4_map_add_failure;
154
155cfg_cipsov4_add_map_return:
156 audit_buf = netlbl_audit_start_common(AUDIT_MAC_CIPSOV4_ADD,
157 audit_info);
158 if (audit_buf != NULL) {
159 switch (doi_type) {
160 case CIPSO_V4_MAP_TRANS:
161 type_str = "trans";
162 break;
163 case CIPSO_V4_MAP_PASS:
164 type_str = "pass";
165 break;
166 case CIPSO_V4_MAP_LOCAL:
167 type_str = "local";
168 break;
169 default:
170 type_str = "(unknown)";
171 }
172 audit_log_format(audit_buf,
173 " cipso_doi=%u cipso_type=%s res=%u",
174 doi, type_str, ret_val == 0 ? 1 : 0);
175 audit_log_end(audit_buf);
176 }
177 383
178 return ret_val; 384 return 0;
179 385
180cfg_cipsov4_add_map_failure_release_doi: 386cfg_cipsov4_map_add_failure:
181 cipso_v4_doi_putdef(doi_def); 387 cipso_v4_doi_putdef(doi_def);
182cfg_cipsov4_add_map_failure_remove_doi:
183 cipso_v4_doi_remove(doi, audit_info);
184cfg_cipsov4_add_map_failure:
185 if (entry != NULL) 388 if (entry != NULL)
186 kfree(entry->domain); 389 kfree(entry->domain);
187 kfree(entry); 390 kfree(entry);
188 goto cfg_cipsov4_add_map_return; 391 kfree(addrmap);
392 kfree(addrinfo);
393 return ret_val;
189} 394}
190 395
191/* 396/*
@@ -691,6 +896,28 @@ int netlbl_cache_add(const struct sk_buff *skb,
691} 896}
692 897
693/* 898/*
899 * Protocol Engine Functions
900 */
901
902/**
903 * netlbl_audit_start - Start an audit message
904 * @type: audit message type
905 * @audit_info: NetLabel audit information
906 *
907 * Description:
908 * Start an audit message using the type specified in @type and fill the audit
909 * message with some fields common to all NetLabel audit messages. This
910 * function should only be used by protocol engines, not LSMs. Returns a
911 * pointer to the audit buffer on success, NULL on failure.
912 *
913 */
914struct audit_buffer *netlbl_audit_start(int type,
915 struct netlbl_audit *audit_info)
916{
917 return netlbl_audit_start_common(type, audit_info);
918}
919
920/*
694 * Setup Functions 921 * Setup Functions
695 */ 922 */
696 923