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