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.c272
1 files changed, 192 insertions, 80 deletions
diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c
index 39793a1a93aa..b32eceb3ab0d 100644
--- a/net/netlabel/netlabel_kapi.c
+++ b/net/netlabel/netlabel_kapi.c
@@ -10,7 +10,7 @@
10 */ 10 */
11 11
12/* 12/*
13 * (c) Copyright Hewlett-Packard Development Company, L.P., 2006 13 * (c) Copyright Hewlett-Packard Development Company, L.P., 2006, 2008
14 * 14 *
15 * This program is free software; you can redistribute it and/or modify 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 16 * it under the terms of the GNU General Public License as published by
@@ -82,7 +82,7 @@ int netlbl_cfg_unlbl_add_map(const char *domain,
82 82
83 entry = kzalloc(sizeof(*entry), GFP_ATOMIC); 83 entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
84 if (entry == NULL) 84 if (entry == NULL)
85 goto cfg_unlbl_add_map_failure; 85 return -ENOMEM;
86 if (domain != NULL) { 86 if (domain != NULL) {
87 entry->domain = kstrdup(domain, GFP_ATOMIC); 87 entry->domain = kstrdup(domain, GFP_ATOMIC);
88 if (entry->domain == NULL) 88 if (entry->domain == NULL)
@@ -104,49 +104,6 @@ cfg_unlbl_add_map_failure:
104} 104}
105 105
106/** 106/**
107 * netlbl_cfg_cipsov4_add - Add a new CIPSOv4 DOI definition
108 * @doi_def: the DOI definition
109 * @audit_info: NetLabel audit information
110 *
111 * Description:
112 * Add a new CIPSOv4 DOI definition to the NetLabel subsystem. Returns zero on
113 * success, negative values on failure.
114 *
115 */
116int netlbl_cfg_cipsov4_add(struct cipso_v4_doi *doi_def,
117 struct netlbl_audit *audit_info)
118{
119 int ret_val;
120 const char *type_str;
121 struct audit_buffer *audit_buf;
122
123 ret_val = cipso_v4_doi_add(doi_def);
124
125 audit_buf = netlbl_audit_start_common(AUDIT_MAC_CIPSOV4_ADD,
126 audit_info);
127 if (audit_buf != NULL) {
128 switch (doi_def->type) {
129 case CIPSO_V4_MAP_STD:
130 type_str = "std";
131 break;
132 case CIPSO_V4_MAP_PASS:
133 type_str = "pass";
134 break;
135 default:
136 type_str = "(unknown)";
137 }
138 audit_log_format(audit_buf,
139 " cipso_doi=%u cipso_type=%s res=%u",
140 doi_def->doi,
141 type_str,
142 ret_val == 0 ? 1 : 0);
143 audit_log_end(audit_buf);
144 }
145
146 return ret_val;
147}
148
149/**
150 * netlbl_cfg_cipsov4_add_map - Add a new CIPSOv4 DOI definition and mapping 107 * netlbl_cfg_cipsov4_add_map - Add a new CIPSOv4 DOI definition and mapping
151 * @doi_def: the DOI definition 108 * @doi_def: the DOI definition
152 * @domain: the domain mapping to add 109 * @domain: the domain mapping to add
@@ -164,58 +121,71 @@ int netlbl_cfg_cipsov4_add_map(struct cipso_v4_doi *doi_def,
164 struct netlbl_audit *audit_info) 121 struct netlbl_audit *audit_info)
165{ 122{
166 int ret_val = -ENOMEM; 123 int ret_val = -ENOMEM;
124 u32 doi;
125 u32 doi_type;
167 struct netlbl_dom_map *entry; 126 struct netlbl_dom_map *entry;
127 const char *type_str;
128 struct audit_buffer *audit_buf;
129
130 doi = doi_def->doi;
131 doi_type = doi_def->type;
168 132
169 entry = kzalloc(sizeof(*entry), GFP_ATOMIC); 133 entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
170 if (entry == NULL) 134 if (entry == NULL)
171 goto cfg_cipsov4_add_map_failure; 135 return -ENOMEM;
172 if (domain != NULL) { 136 if (domain != NULL) {
173 entry->domain = kstrdup(domain, GFP_ATOMIC); 137 entry->domain = kstrdup(domain, GFP_ATOMIC);
174 if (entry->domain == NULL) 138 if (entry->domain == NULL)
175 goto cfg_cipsov4_add_map_failure; 139 goto cfg_cipsov4_add_map_failure;
176 } 140 }
177 entry->type = NETLBL_NLTYPE_CIPSOV4;
178 entry->type_def.cipsov4 = doi_def;
179
180 /* Grab a RCU read lock here so nothing happens to the doi_def variable
181 * between adding it to the CIPSOv4 protocol engine and adding a
182 * domain mapping for it. */
183 141
184 rcu_read_lock(); 142 ret_val = cipso_v4_doi_add(doi_def);
185 ret_val = netlbl_cfg_cipsov4_add(doi_def, audit_info);
186 if (ret_val != 0) 143 if (ret_val != 0)
187 goto cfg_cipsov4_add_map_failure_unlock; 144 goto cfg_cipsov4_add_map_failure_remove_doi;
145 entry->type = NETLBL_NLTYPE_CIPSOV4;
146 entry->type_def.cipsov4 = cipso_v4_doi_getdef(doi);
147 if (entry->type_def.cipsov4 == NULL) {
148 ret_val = -ENOENT;
149 goto cfg_cipsov4_add_map_failure_remove_doi;
150 }
188 ret_val = netlbl_domhsh_add(entry, audit_info); 151 ret_val = netlbl_domhsh_add(entry, audit_info);
189 if (ret_val != 0) 152 if (ret_val != 0)
190 goto cfg_cipsov4_add_map_failure_remove_doi; 153 goto cfg_cipsov4_add_map_failure_release_doi;
191 rcu_read_unlock();
192 154
193 return 0; 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 }
194 177
178 return ret_val;
179
180cfg_cipsov4_add_map_failure_release_doi:
181 cipso_v4_doi_putdef(doi_def);
195cfg_cipsov4_add_map_failure_remove_doi: 182cfg_cipsov4_add_map_failure_remove_doi:
196 cipso_v4_doi_remove(doi_def->doi, audit_info, netlbl_cipsov4_doi_free); 183 cipso_v4_doi_remove(doi, audit_info);
197cfg_cipsov4_add_map_failure_unlock:
198 rcu_read_unlock();
199cfg_cipsov4_add_map_failure: 184cfg_cipsov4_add_map_failure:
200 if (entry != NULL) 185 if (entry != NULL)
201 kfree(entry->domain); 186 kfree(entry->domain);
202 kfree(entry); 187 kfree(entry);
203 return ret_val; 188 goto cfg_cipsov4_add_map_return;
204}
205
206/**
207 * netlbl_cfg_cipsov4_del - Removean existing CIPSOv4 DOI definition
208 * @doi: the CIPSO DOI value
209 * @audit_info: NetLabel audit information
210 *
211 * Description:
212 * Removes an existing CIPSOv4 DOI definition from the NetLabel subsystem.
213 * Returns zero on success, negative values on failure.
214 *
215 */
216int netlbl_cfg_cipsov4_del(u32 doi, struct netlbl_audit *audit_info)
217{
218 return cipso_v4_doi_remove(doi, audit_info, netlbl_cipsov4_doi_free);
219} 189}
220 190
221/* 191/*
@@ -452,7 +422,9 @@ int netlbl_enabled(void)
452 * Attach the correct label to the given socket using the security attributes 422 * Attach the correct label to the given socket using the security attributes
453 * specified in @secattr. This function requires exclusive access to @sk, 423 * specified in @secattr. This function requires exclusive access to @sk,
454 * which means it either needs to be in the process of being created or locked. 424 * which means it either needs to be in the process of being created or locked.
455 * Returns zero on success, negative values on failure. 425 * Returns zero on success, -EDESTADDRREQ if the domain is configured to use
426 * network address selectors (can't blindly label the socket), and negative
427 * values on all other failures.
456 * 428 *
457 */ 429 */
458int netlbl_sock_setattr(struct sock *sk, 430int netlbl_sock_setattr(struct sock *sk,
@@ -466,6 +438,9 @@ int netlbl_sock_setattr(struct sock *sk,
466 if (dom_entry == NULL) 438 if (dom_entry == NULL)
467 goto socket_setattr_return; 439 goto socket_setattr_return;
468 switch (dom_entry->type) { 440 switch (dom_entry->type) {
441 case NETLBL_NLTYPE_ADDRSELECT:
442 ret_val = -EDESTADDRREQ;
443 break;
469 case NETLBL_NLTYPE_CIPSOV4: 444 case NETLBL_NLTYPE_CIPSOV4:
470 ret_val = cipso_v4_sock_setattr(sk, 445 ret_val = cipso_v4_sock_setattr(sk,
471 dom_entry->type_def.cipsov4, 446 dom_entry->type_def.cipsov4,
@@ -484,6 +459,20 @@ socket_setattr_return:
484} 459}
485 460
486/** 461/**
462 * netlbl_sock_delattr - Delete all the NetLabel labels on a socket
463 * @sk: the socket
464 *
465 * Description:
466 * Remove all the NetLabel labeling from @sk. The caller is responsible for
467 * ensuring that @sk is locked.
468 *
469 */
470void netlbl_sock_delattr(struct sock *sk)
471{
472 cipso_v4_sock_delattr(sk);
473}
474
475/**
487 * netlbl_sock_getattr - Determine the security attributes of a sock 476 * netlbl_sock_getattr - Determine the security attributes of a sock
488 * @sk: the sock 477 * @sk: the sock
489 * @secattr: the security attributes 478 * @secattr: the security attributes
@@ -501,6 +490,128 @@ int netlbl_sock_getattr(struct sock *sk, struct netlbl_lsm_secattr *secattr)
501} 490}
502 491
503/** 492/**
493 * netlbl_conn_setattr - Label a connected socket using the correct protocol
494 * @sk: the socket to label
495 * @addr: the destination address
496 * @secattr: the security attributes
497 *
498 * Description:
499 * Attach the correct label to the given connected socket using the security
500 * attributes specified in @secattr. The caller is responsible for ensuring
501 * that @sk is locked. Returns zero on success, negative values on failure.
502 *
503 */
504int netlbl_conn_setattr(struct sock *sk,
505 struct sockaddr *addr,
506 const struct netlbl_lsm_secattr *secattr)
507{
508 int ret_val;
509 struct sockaddr_in *addr4;
510 struct netlbl_domaddr4_map *af4_entry;
511
512 rcu_read_lock();
513 switch (addr->sa_family) {
514 case AF_INET:
515 addr4 = (struct sockaddr_in *)addr;
516 af4_entry = netlbl_domhsh_getentry_af4(secattr->domain,
517 addr4->sin_addr.s_addr);
518 if (af4_entry == NULL) {
519 ret_val = -ENOENT;
520 goto conn_setattr_return;
521 }
522 switch (af4_entry->type) {
523 case NETLBL_NLTYPE_CIPSOV4:
524 ret_val = cipso_v4_sock_setattr(sk,
525 af4_entry->type_def.cipsov4,
526 secattr);
527 break;
528 case NETLBL_NLTYPE_UNLABELED:
529 /* just delete the protocols we support for right now
530 * but we could remove other protocols if needed */
531 cipso_v4_sock_delattr(sk);
532 ret_val = 0;
533 break;
534 default:
535 ret_val = -ENOENT;
536 }
537 break;
538#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
539 case AF_INET6:
540 /* since we don't support any IPv6 labeling protocols right
541 * now we can optimize everything away until we do */
542 ret_val = 0;
543 break;
544#endif /* IPv6 */
545 default:
546 ret_val = 0;
547 }
548
549conn_setattr_return:
550 rcu_read_unlock();
551 return ret_val;
552}
553
554/**
555 * netlbl_skbuff_setattr - Label a packet using the correct protocol
556 * @skb: the packet
557 * @family: protocol family
558 * @secattr: the security attributes
559 *
560 * Description:
561 * Attach the correct label to the given packet using the security attributes
562 * specified in @secattr. Returns zero on success, negative values on failure.
563 *
564 */
565int netlbl_skbuff_setattr(struct sk_buff *skb,
566 u16 family,
567 const struct netlbl_lsm_secattr *secattr)
568{
569 int ret_val;
570 struct iphdr *hdr4;
571 struct netlbl_domaddr4_map *af4_entry;
572
573 rcu_read_lock();
574 switch (family) {
575 case AF_INET:
576 hdr4 = ip_hdr(skb);
577 af4_entry = netlbl_domhsh_getentry_af4(secattr->domain,
578 hdr4->daddr);
579 if (af4_entry == NULL) {
580 ret_val = -ENOENT;
581 goto skbuff_setattr_return;
582 }
583 switch (af4_entry->type) {
584 case NETLBL_NLTYPE_CIPSOV4:
585 ret_val = cipso_v4_skbuff_setattr(skb,
586 af4_entry->type_def.cipsov4,
587 secattr);
588 break;
589 case NETLBL_NLTYPE_UNLABELED:
590 /* just delete the protocols we support for right now
591 * but we could remove other protocols if needed */
592 ret_val = cipso_v4_skbuff_delattr(skb);
593 break;
594 default:
595 ret_val = -ENOENT;
596 }
597 break;
598#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
599 case AF_INET6:
600 /* since we don't support any IPv6 labeling protocols right
601 * now we can optimize everything away until we do */
602 ret_val = 0;
603 break;
604#endif /* IPv6 */
605 default:
606 ret_val = 0;
607 }
608
609skbuff_setattr_return:
610 rcu_read_unlock();
611 return ret_val;
612}
613
614/**
504 * netlbl_skbuff_getattr - Determine the security attributes of a packet 615 * netlbl_skbuff_getattr - Determine the security attributes of a packet
505 * @skb: the packet 616 * @skb: the packet
506 * @family: protocol family 617 * @family: protocol family
@@ -528,6 +639,7 @@ int netlbl_skbuff_getattr(const struct sk_buff *skb,
528 * netlbl_skbuff_err - Handle a LSM error on a sk_buff 639 * netlbl_skbuff_err - Handle a LSM error on a sk_buff
529 * @skb: the packet 640 * @skb: the packet
530 * @error: the error code 641 * @error: the error code
642 * @gateway: true if host is acting as a gateway, false otherwise
531 * 643 *
532 * Description: 644 * Description:
533 * Deal with a LSM problem when handling the packet in @skb, typically this is 645 * Deal with a LSM problem when handling the packet in @skb, typically this is
@@ -535,10 +647,10 @@ int netlbl_skbuff_getattr(const struct sk_buff *skb,
535 * according to the packet's labeling protocol. 647 * according to the packet's labeling protocol.
536 * 648 *
537 */ 649 */
538void netlbl_skbuff_err(struct sk_buff *skb, int error) 650void netlbl_skbuff_err(struct sk_buff *skb, int error, int gateway)
539{ 651{
540 if (CIPSO_V4_OPTEXIST(skb)) 652 if (CIPSO_V4_OPTEXIST(skb))
541 cipso_v4_error(skb, error, 0); 653 cipso_v4_error(skb, error, gateway);
542} 654}
543 655
544/** 656/**