Skip to content

Commit cb72d38

Browse files
hdmdaviespcmoore
authored andcommitted
netlabel: Initial support for the CALIPSO netlink protocol.
CALIPSO is a packet labelling protocol for IPv6 which is very similar to CIPSO. It is specified in RFC 5570. Much of the code is based on the current CIPSO code. This adds support for adding passthrough-type CALIPSO DOIs through the NLBL_CALIPSO_C_ADD command. It requires attributes: NLBL_CALIPSO_A_TYPE which must be CALIPSO_MAP_PASS. NLBL_CALIPSO_A_DOI. In passthrough mode the CALIPSO engine will map MLS secattr levels and categories directly to the packet label. At this stage, the major difference between this and the CIPSO code is that IPv6 may be compiled as a module. To allow for this the CALIPSO functions are registered at module init time. Signed-off-by: Huw Davies <huw@codeweavers.com> Signed-off-by: Paul Moore <paul@paul-moore.com>
1 parent 8f18e67 commit cb72d38

File tree

12 files changed

+604
-2
lines changed

12 files changed

+604
-2
lines changed

include/net/calipso.h

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/*
2+
* CALIPSO - Common Architecture Label IPv6 Security Option
3+
*
4+
* This is an implementation of the CALIPSO protocol as specified in
5+
* RFC 5570.
6+
*
7+
* Authors: Paul Moore <paul@paul-moore.com>
8+
* Huw Davies <huw@codeweavers.com>
9+
*
10+
*/
11+
12+
/*
13+
* (c) Copyright Hewlett-Packard Development Company, L.P., 2006
14+
* (c) Copyright Huw Davies <huw@codeweavers.com>, 2015
15+
*
16+
* This program is free software; you can redistribute it and/or modify
17+
* it under the terms of the GNU General Public License as published by
18+
* the Free Software Foundation; either version 2 of the License, or
19+
* (at your option) any later version.
20+
*
21+
* This program is distributed in the hope that it will be useful,
22+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
23+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
24+
* the GNU General Public License for more details.
25+
*
26+
* You should have received a copy of the GNU General Public License
27+
* along with this program; if not, see <http://www.gnu.org/licenses/>.
28+
*
29+
*/
30+
31+
#ifndef _CALIPSO_H
32+
#define _CALIPSO_H
33+
34+
#include <linux/types.h>
35+
#include <linux/rcupdate.h>
36+
#include <linux/list.h>
37+
#include <linux/net.h>
38+
#include <linux/skbuff.h>
39+
#include <net/netlabel.h>
40+
#include <net/request_sock.h>
41+
#include <linux/atomic.h>
42+
#include <asm/unaligned.h>
43+
44+
/* known doi values */
45+
#define CALIPSO_DOI_UNKNOWN 0x00000000
46+
47+
/* doi mapping types */
48+
#define CALIPSO_MAP_UNKNOWN 0
49+
#define CALIPSO_MAP_PASS 2
50+
51+
/*
52+
* CALIPSO DOI definitions
53+
*/
54+
55+
/* DOI definition struct */
56+
struct calipso_doi {
57+
u32 doi;
58+
u32 type;
59+
60+
atomic_t refcount;
61+
struct list_head list;
62+
struct rcu_head rcu;
63+
};
64+
65+
#ifdef CONFIG_NETLABEL
66+
int __init calipso_init(void);
67+
void calipso_exit(void);
68+
#else
69+
static inline int __init calipso_init(void)
70+
{
71+
return 0;
72+
}
73+
74+
static inline void calipso_exit(void)
75+
{
76+
}
77+
#endif /* CONFIG_NETLABEL */
78+
79+
#endif /* _CALIPSO_H */

include/net/netlabel.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include <linux/atomic.h>
4141

4242
struct cipso_v4_doi;
43+
struct calipso_doi;
4344

4445
/*
4546
* NetLabel - A management interface for maintaining network packet label
@@ -94,6 +95,8 @@ struct cipso_v4_doi;
9495
#define NETLBL_NLTYPE_UNLABELED_NAME "NLBL_UNLBL"
9596
#define NETLBL_NLTYPE_ADDRSELECT 6
9697
#define NETLBL_NLTYPE_ADDRSELECT_NAME "NLBL_ADRSEL"
98+
#define NETLBL_NLTYPE_CALIPSO 7
99+
#define NETLBL_NLTYPE_CALIPSO_NAME "NLBL_CALIPSO"
97100

98101
/*
99102
* NetLabel - Kernel API for accessing the network packet label mappings.
@@ -216,6 +219,23 @@ struct netlbl_lsm_secattr {
216219
} attr;
217220
};
218221

222+
/**
223+
* struct netlbl_calipso_ops - NetLabel CALIPSO operations
224+
* @doi_add: add a CALIPSO DOI
225+
* @doi_free: free a CALIPSO DOI
226+
*
227+
* Description:
228+
* This structure is filled out by the CALIPSO engine and passed
229+
* to the NetLabel core via a call to netlbl_calipso_ops_register().
230+
* It enables the CALIPSO engine (and hence IPv6) to be compiled
231+
* as a module.
232+
*/
233+
struct netlbl_calipso_ops {
234+
int (*doi_add)(struct calipso_doi *doi_def,
235+
struct netlbl_audit *audit_info);
236+
void (*doi_free)(struct calipso_doi *doi_def);
237+
};
238+
219239
/*
220240
* LSM security attribute operations (inline)
221241
*/
@@ -598,4 +618,7 @@ static inline struct audit_buffer *netlbl_audit_start(int type,
598618
}
599619
#endif /* CONFIG_NETLABEL */
600620

621+
const struct netlbl_calipso_ops *
622+
netlbl_calipso_ops_register(const struct netlbl_calipso_ops *ops);
623+
601624
#endif /* _NETLABEL_H */

include/uapi/linux/audit.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@
130130
#define AUDIT_MAC_IPSEC_EVENT 1415 /* Audit an IPSec event */
131131
#define AUDIT_MAC_UNLBL_STCADD 1416 /* NetLabel: add a static label */
132132
#define AUDIT_MAC_UNLBL_STCDEL 1417 /* NetLabel: del a static label */
133+
#define AUDIT_MAC_CALIPSO_ADD 1418 /* NetLabel: add CALIPSO DOI entry */
134+
#define AUDIT_MAC_CALIPSO_DEL 1419 /* NetLabel: del CALIPSO DOI entry */
133135

134136
#define AUDIT_FIRST_KERN_ANOM_MSG 1700
135137
#define AUDIT_LAST_KERN_ANOM_MSG 1799

net/ipv6/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ ipv6-$(CONFIG_NETFILTER) += netfilter.o
2121
ipv6-$(CONFIG_IPV6_MULTIPLE_TABLES) += fib6_rules.o
2222
ipv6-$(CONFIG_PROC_FS) += proc.o
2323
ipv6-$(CONFIG_SYN_COOKIES) += syncookies.o
24+
ipv6-$(CONFIG_NETLABEL) += calipso.o
2425

2526
ipv6-objs += $(ipv6-y)
2627

net/ipv6/af_inet6.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
#ifdef CONFIG_IPV6_TUNNEL
6161
#include <net/ip6_tunnel.h>
6262
#endif
63+
#include <net/calipso.h>
6364

6465
#include <asm/uaccess.h>
6566
#include <linux/mroute6.h>
@@ -970,6 +971,10 @@ static int __init inet6_init(void)
970971
if (err)
971972
goto pingv6_fail;
972973

974+
err = calipso_init();
975+
if (err)
976+
goto calipso_fail;
977+
973978
#ifdef CONFIG_SYSCTL
974979
err = ipv6_sysctl_register();
975980
if (err)
@@ -980,8 +985,10 @@ static int __init inet6_init(void)
980985

981986
#ifdef CONFIG_SYSCTL
982987
sysctl_fail:
983-
pingv6_exit();
988+
calipso_exit();
984989
#endif
990+
calipso_fail:
991+
pingv6_exit();
985992
pingv6_fail:
986993
ipv6_packet_cleanup();
987994
ipv6_packet_fail:

net/ipv6/calipso.c

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
/*
2+
* CALIPSO - Common Architecture Label IPv6 Security Option
3+
*
4+
* This is an implementation of the CALIPSO protocol as specified in
5+
* RFC 5570.
6+
*
7+
* Authors: Paul Moore <paul.moore@hp.com>
8+
* Huw Davies <huw@codeweavers.com>
9+
*
10+
*/
11+
12+
/* (c) Copyright Hewlett-Packard Development Company, L.P., 2006, 2008
13+
* (c) Copyright Huw Davies <huw@codeweavers.com>, 2015
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, see <http://www.gnu.org/licenses/>.
27+
*
28+
*/
29+
30+
#include <linux/init.h>
31+
#include <linux/types.h>
32+
#include <linux/rcupdate.h>
33+
#include <linux/list.h>
34+
#include <linux/spinlock.h>
35+
#include <linux/string.h>
36+
#include <linux/jhash.h>
37+
#include <linux/audit.h>
38+
#include <linux/slab.h>
39+
#include <net/ip.h>
40+
#include <net/icmp.h>
41+
#include <net/tcp.h>
42+
#include <net/netlabel.h>
43+
#include <net/calipso.h>
44+
#include <linux/atomic.h>
45+
#include <linux/bug.h>
46+
#include <asm/unaligned.h>
47+
48+
/* List of available DOI definitions */
49+
static DEFINE_SPINLOCK(calipso_doi_list_lock);
50+
static LIST_HEAD(calipso_doi_list);
51+
52+
/* DOI List Functions
53+
*/
54+
55+
/**
56+
* calipso_doi_search - Searches for a DOI definition
57+
* @doi: the DOI to search for
58+
*
59+
* Description:
60+
* Search the DOI definition list for a DOI definition with a DOI value that
61+
* matches @doi. The caller is responsible for calling rcu_read_[un]lock().
62+
* Returns a pointer to the DOI definition on success and NULL on failure.
63+
*/
64+
static struct calipso_doi *calipso_doi_search(u32 doi)
65+
{
66+
struct calipso_doi *iter;
67+
68+
list_for_each_entry_rcu(iter, &calipso_doi_list, list)
69+
if (iter->doi == doi && atomic_read(&iter->refcount))
70+
return iter;
71+
return NULL;
72+
}
73+
74+
/**
75+
* calipso_doi_add - Add a new DOI to the CALIPSO protocol engine
76+
* @doi_def: the DOI structure
77+
* @audit_info: NetLabel audit information
78+
*
79+
* Description:
80+
* The caller defines a new DOI for use by the CALIPSO engine and calls this
81+
* function to add it to the list of acceptable domains. The caller must
82+
* ensure that the mapping table specified in @doi_def->map meets all of the
83+
* requirements of the mapping type (see calipso.h for details). Returns
84+
* zero on success and non-zero on failure.
85+
*
86+
*/
87+
static int calipso_doi_add(struct calipso_doi *doi_def,
88+
struct netlbl_audit *audit_info)
89+
{
90+
int ret_val = -EINVAL;
91+
u32 doi;
92+
u32 doi_type;
93+
struct audit_buffer *audit_buf;
94+
95+
doi = doi_def->doi;
96+
doi_type = doi_def->type;
97+
98+
if (doi_def->doi == CALIPSO_DOI_UNKNOWN)
99+
goto doi_add_return;
100+
101+
atomic_set(&doi_def->refcount, 1);
102+
103+
spin_lock(&calipso_doi_list_lock);
104+
if (calipso_doi_search(doi_def->doi)) {
105+
spin_unlock(&calipso_doi_list_lock);
106+
ret_val = -EEXIST;
107+
goto doi_add_return;
108+
}
109+
list_add_tail_rcu(&doi_def->list, &calipso_doi_list);
110+
spin_unlock(&calipso_doi_list_lock);
111+
ret_val = 0;
112+
113+
doi_add_return:
114+
audit_buf = netlbl_audit_start(AUDIT_MAC_CALIPSO_ADD, audit_info);
115+
if (audit_buf) {
116+
const char *type_str;
117+
118+
switch (doi_type) {
119+
case CALIPSO_MAP_PASS:
120+
type_str = "pass";
121+
break;
122+
default:
123+
type_str = "(unknown)";
124+
}
125+
audit_log_format(audit_buf,
126+
" calipso_doi=%u calipso_type=%s res=%u",
127+
doi, type_str, ret_val == 0 ? 1 : 0);
128+
audit_log_end(audit_buf);
129+
}
130+
131+
return ret_val;
132+
}
133+
134+
/**
135+
* calipso_doi_free - Frees a DOI definition
136+
* @doi_def: the DOI definition
137+
*
138+
* Description:
139+
* This function frees all of the memory associated with a DOI definition.
140+
*
141+
*/
142+
static void calipso_doi_free(struct calipso_doi *doi_def)
143+
{
144+
kfree(doi_def);
145+
}
146+
147+
static const struct netlbl_calipso_ops ops = {
148+
.doi_add = calipso_doi_add,
149+
.doi_free = calipso_doi_free,
150+
};
151+
152+
/**
153+
* calipso_init - Initialize the CALIPSO module
154+
*
155+
* Description:
156+
* Initialize the CALIPSO module and prepare it for use. Returns zero on
157+
* success and negative values on failure.
158+
*
159+
*/
160+
int __init calipso_init(void)
161+
{
162+
netlbl_calipso_ops_register(&ops);
163+
return 0;
164+
}
165+
166+
void calipso_exit(void)
167+
{
168+
netlbl_calipso_ops_register(NULL);
169+
}

net/netlabel/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,4 @@ obj-y += netlabel_mgmt.o
1212
# protocol modules
1313
obj-y += netlabel_unlabeled.o
1414
obj-y += netlabel_cipso_v4.o
15-
15+
obj-$(subst m,y,$(CONFIG_IPV6)) += netlabel_calipso.o

0 commit comments

Comments
 (0)