xref: /openbmc/linux/net/netlabel/netlabel_kapi.c (revision 05e00cbf5036929355020dab4837b637203a0742)
1 /*
2  * NetLabel Kernel API
3  *
4  * This file defines the kernel API for the NetLabel system.  The NetLabel
5  * system manages static and dynamic label mappings for network protocols such
6  * 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/init.h>
32 #include <linux/types.h>
33 #include <net/ip.h>
34 #include <net/netlabel.h>
35 #include <net/cipso_ipv4.h>
36 #include <asm/bug.h>
37 
38 #include "netlabel_domainhash.h"
39 #include "netlabel_unlabeled.h"
40 #include "netlabel_user.h"
41 
42 /*
43  * LSM Functions
44  */
45 
46 /**
47  * netlbl_socket_setattr - Label a socket using the correct protocol
48  * @sock: the socket to label
49  * @secattr: the security attributes
50  *
51  * Description:
52  * Attach the correct label to the given socket using the security attributes
53  * specified in @secattr.  This function requires exclusive access to
54  * @sock->sk, which means it either needs to be in the process of being
55  * created or locked via lock_sock(sock->sk).  Returns zero on success,
56  * negative values on failure.
57  *
58  */
59 int netlbl_socket_setattr(const struct socket *sock,
60 			  const struct netlbl_lsm_secattr *secattr)
61 {
62 	int ret_val = -ENOENT;
63 	struct netlbl_dom_map *dom_entry;
64 
65 	if ((secattr->flags & NETLBL_SECATTR_DOMAIN) == 0)
66 		return -ENOENT;
67 
68 	rcu_read_lock();
69 	dom_entry = netlbl_domhsh_getentry(secattr->domain);
70 	if (dom_entry == NULL)
71 		goto socket_setattr_return;
72 	switch (dom_entry->type) {
73 	case NETLBL_NLTYPE_CIPSOV4:
74 		ret_val = cipso_v4_socket_setattr(sock,
75 						  dom_entry->type_def.cipsov4,
76 						  secattr);
77 		break;
78 	case NETLBL_NLTYPE_UNLABELED:
79 		ret_val = 0;
80 		break;
81 	default:
82 		ret_val = -ENOENT;
83 	}
84 
85 socket_setattr_return:
86 	rcu_read_unlock();
87 	return ret_val;
88 }
89 
90 /**
91  * netlbl_sock_getattr - Determine the security attributes of a sock
92  * @sk: the sock
93  * @secattr: the security attributes
94  *
95  * Description:
96  * Examines the given sock to see any NetLabel style labeling has been
97  * applied to the sock, if so it parses the socket label and returns the
98  * security attributes in @secattr.  Returns zero on success, negative values
99  * on failure.
100  *
101  */
102 int netlbl_sock_getattr(struct sock *sk, struct netlbl_lsm_secattr *secattr)
103 {
104 	int ret_val;
105 
106 	ret_val = cipso_v4_sock_getattr(sk, secattr);
107 	if (ret_val == 0)
108 		return 0;
109 
110 	return netlbl_unlabel_getattr(secattr);
111 }
112 
113 /**
114  * netlbl_socket_getattr - Determine the security attributes of a socket
115  * @sock: the socket
116  * @secattr: the security attributes
117  *
118  * Description:
119  * Examines the given socket to see any NetLabel style labeling has been
120  * applied to the socket, if so it parses the socket label and returns the
121  * security attributes in @secattr.  Returns zero on success, negative values
122  * on failure.
123  *
124  */
125 int netlbl_socket_getattr(const struct socket *sock,
126 			  struct netlbl_lsm_secattr *secattr)
127 {
128 	int ret_val;
129 
130 	ret_val = cipso_v4_socket_getattr(sock, secattr);
131 	if (ret_val == 0)
132 		return 0;
133 
134 	return netlbl_unlabel_getattr(secattr);
135 }
136 
137 /**
138  * netlbl_skbuff_getattr - Determine the security attributes of a packet
139  * @skb: the packet
140  * @secattr: the security attributes
141  *
142  * Description:
143  * Examines the given packet to see if a recognized form of packet labeling
144  * is present, if so it parses the packet label and returns the security
145  * attributes in @secattr.  Returns zero on success, negative values on
146  * failure.
147  *
148  */
149 int netlbl_skbuff_getattr(const struct sk_buff *skb,
150 			  struct netlbl_lsm_secattr *secattr)
151 {
152 	if (CIPSO_V4_OPTEXIST(skb) &&
153 	    cipso_v4_skbuff_getattr(skb, secattr) == 0)
154 		return 0;
155 
156 	return netlbl_unlabel_getattr(secattr);
157 }
158 
159 /**
160  * netlbl_skbuff_err - Handle a LSM error on a sk_buff
161  * @skb: the packet
162  * @error: the error code
163  *
164  * Description:
165  * Deal with a LSM problem when handling the packet in @skb, typically this is
166  * a permission denied problem (-EACCES).  The correct action is determined
167  * according to the packet's labeling protocol.
168  *
169  */
170 void netlbl_skbuff_err(struct sk_buff *skb, int error)
171 {
172 	if (CIPSO_V4_OPTEXIST(skb))
173 		cipso_v4_error(skb, error, 0);
174 }
175 
176 /**
177  * netlbl_cache_invalidate - Invalidate all of the NetLabel protocol caches
178  *
179  * Description:
180  * For all of the NetLabel protocols that support some form of label mapping
181  * cache, invalidate the cache.  Returns zero on success, negative values on
182  * error.
183  *
184  */
185 void netlbl_cache_invalidate(void)
186 {
187 	cipso_v4_cache_invalidate();
188 }
189 
190 /**
191  * netlbl_cache_add - Add an entry to a NetLabel protocol cache
192  * @skb: the packet
193  * @secattr: the packet's security attributes
194  *
195  * Description:
196  * Add the LSM security attributes for the given packet to the underlying
197  * NetLabel protocol's label mapping cache.  Returns zero on success, negative
198  * values on error.
199  *
200  */
201 int netlbl_cache_add(const struct sk_buff *skb,
202 		     const struct netlbl_lsm_secattr *secattr)
203 {
204 	if ((secattr->flags & NETLBL_SECATTR_CACHE) == 0)
205 		return -ENOMSG;
206 
207 	if (CIPSO_V4_OPTEXIST(skb))
208 		return cipso_v4_cache_add(skb, secattr);
209 
210 	return -ENOMSG;
211 }
212 
213 /*
214  * Setup Functions
215  */
216 
217 /**
218  * netlbl_init - Initialize NetLabel
219  *
220  * Description:
221  * Perform the required NetLabel initialization before first use.
222  *
223  */
224 static int __init netlbl_init(void)
225 {
226 	int ret_val;
227 
228 	printk(KERN_INFO "NetLabel: Initializing\n");
229 	printk(KERN_INFO "NetLabel:  domain hash size = %u\n",
230 	       (1 << NETLBL_DOMHSH_BITSIZE));
231 	printk(KERN_INFO "NetLabel:  protocols ="
232 	       " UNLABELED"
233 	       " CIPSOv4"
234 	       "\n");
235 
236 	ret_val = netlbl_domhsh_init(NETLBL_DOMHSH_BITSIZE);
237 	if (ret_val != 0)
238 		goto init_failure;
239 
240 	ret_val = netlbl_netlink_init();
241 	if (ret_val != 0)
242 		goto init_failure;
243 
244 	ret_val = netlbl_unlabel_defconf();
245 	if (ret_val != 0)
246 		goto init_failure;
247 	printk(KERN_INFO "NetLabel:  unlabeled traffic allowed by default\n");
248 
249 	return 0;
250 
251 init_failure:
252 	panic("NetLabel: failed to initialize properly (%d)\n", ret_val);
253 }
254 
255 subsys_initcall(netlbl_init);
256