Branch data Line data Source code
1 : : /* SPDX-License-Identifier: GPL-2.0-or-later */
2 : : /*
3 : : * CIPSO - Commercial IP Security Option
4 : : *
5 : : * This is an implementation of the CIPSO 2.2 protocol as specified in
6 : : * draft-ietf-cipso-ipsecurity-01.txt with additional tag types as found in
7 : : * FIPS-188, copies of both documents can be found in the Documentation
8 : : * directory. While CIPSO never became a full IETF RFC standard many vendors
9 : : * have chosen to adopt the protocol and over the years it has become a
10 : : * de-facto standard for labeled networking.
11 : : *
12 : : * Author: Paul Moore <paul@paul-moore.com>
13 : : */
14 : :
15 : : /*
16 : : * (c) Copyright Hewlett-Packard Development Company, L.P., 2006
17 : : */
18 : :
19 : : #ifndef _CIPSO_IPV4_H
20 : : #define _CIPSO_IPV4_H
21 : :
22 : : #include <linux/types.h>
23 : : #include <linux/rcupdate.h>
24 : : #include <linux/list.h>
25 : : #include <linux/net.h>
26 : : #include <linux/skbuff.h>
27 : : #include <net/netlabel.h>
28 : : #include <net/request_sock.h>
29 : : #include <linux/atomic.h>
30 : : #include <linux/refcount.h>
31 : : #include <asm/unaligned.h>
32 : :
33 : : /* known doi values */
34 : : #define CIPSO_V4_DOI_UNKNOWN 0x00000000
35 : :
36 : : /* standard tag types */
37 : : #define CIPSO_V4_TAG_INVALID 0
38 : : #define CIPSO_V4_TAG_RBITMAP 1
39 : : #define CIPSO_V4_TAG_ENUM 2
40 : : #define CIPSO_V4_TAG_RANGE 5
41 : : #define CIPSO_V4_TAG_PBITMAP 6
42 : : #define CIPSO_V4_TAG_FREEFORM 7
43 : :
44 : : /* non-standard tag types (tags > 127) */
45 : : #define CIPSO_V4_TAG_LOCAL 128
46 : :
47 : : /* doi mapping types */
48 : : #define CIPSO_V4_MAP_UNKNOWN 0
49 : : #define CIPSO_V4_MAP_TRANS 1
50 : : #define CIPSO_V4_MAP_PASS 2
51 : : #define CIPSO_V4_MAP_LOCAL 3
52 : :
53 : : /* limits */
54 : : #define CIPSO_V4_MAX_REM_LVLS 255
55 : : #define CIPSO_V4_INV_LVL 0x80000000
56 : : #define CIPSO_V4_MAX_LOC_LVLS (CIPSO_V4_INV_LVL - 1)
57 : : #define CIPSO_V4_MAX_REM_CATS 65534
58 : : #define CIPSO_V4_INV_CAT 0x80000000
59 : : #define CIPSO_V4_MAX_LOC_CATS (CIPSO_V4_INV_CAT - 1)
60 : :
61 : : /*
62 : : * CIPSO DOI definitions
63 : : */
64 : :
65 : : /* DOI definition struct */
66 : : #define CIPSO_V4_TAG_MAXCNT 5
67 : : struct cipso_v4_doi {
68 : : u32 doi;
69 : : u32 type;
70 : : union {
71 : : struct cipso_v4_std_map_tbl *std;
72 : : } map;
73 : : u8 tags[CIPSO_V4_TAG_MAXCNT];
74 : :
75 : : refcount_t refcount;
76 : : struct list_head list;
77 : : struct rcu_head rcu;
78 : : };
79 : :
80 : : /* Standard CIPSO mapping table */
81 : : /* NOTE: the highest order bit (i.e. 0x80000000) is an 'invalid' flag, if the
82 : : * bit is set then consider that value as unspecified, meaning the
83 : : * mapping for that particular level/category is invalid */
84 : : struct cipso_v4_std_map_tbl {
85 : : struct {
86 : : u32 *cipso;
87 : : u32 *local;
88 : : u32 cipso_size;
89 : : u32 local_size;
90 : : } lvl;
91 : : struct {
92 : : u32 *cipso;
93 : : u32 *local;
94 : : u32 cipso_size;
95 : : u32 local_size;
96 : : } cat;
97 : : };
98 : :
99 : : /*
100 : : * Sysctl Variables
101 : : */
102 : :
103 : : #ifdef CONFIG_NETLABEL
104 : : extern int cipso_v4_cache_enabled;
105 : : extern int cipso_v4_cache_bucketsize;
106 : : extern int cipso_v4_rbm_optfmt;
107 : : extern int cipso_v4_rbm_strictvalid;
108 : : #endif
109 : :
110 : : /*
111 : : * DOI List Functions
112 : : */
113 : :
114 : : #ifdef CONFIG_NETLABEL
115 : : int cipso_v4_doi_add(struct cipso_v4_doi *doi_def,
116 : : struct netlbl_audit *audit_info);
117 : : void cipso_v4_doi_free(struct cipso_v4_doi *doi_def);
118 : : int cipso_v4_doi_remove(u32 doi, struct netlbl_audit *audit_info);
119 : : struct cipso_v4_doi *cipso_v4_doi_getdef(u32 doi);
120 : : void cipso_v4_doi_putdef(struct cipso_v4_doi *doi_def);
121 : : int cipso_v4_doi_walk(u32 *skip_cnt,
122 : : int (*callback) (struct cipso_v4_doi *doi_def, void *arg),
123 : : void *cb_arg);
124 : : #else
125 : : static inline int cipso_v4_doi_add(struct cipso_v4_doi *doi_def,
126 : : struct netlbl_audit *audit_info)
127 : : {
128 : : return -ENOSYS;
129 : : }
130 : :
131 : : static inline void cipso_v4_doi_free(struct cipso_v4_doi *doi_def)
132 : : {
133 : : return;
134 : : }
135 : :
136 : : static inline int cipso_v4_doi_remove(u32 doi,
137 : : struct netlbl_audit *audit_info)
138 : : {
139 : : return 0;
140 : : }
141 : :
142 : : static inline struct cipso_v4_doi *cipso_v4_doi_getdef(u32 doi)
143 : : {
144 : : return NULL;
145 : : }
146 : :
147 : : static inline int cipso_v4_doi_walk(u32 *skip_cnt,
148 : : int (*callback) (struct cipso_v4_doi *doi_def, void *arg),
149 : : void *cb_arg)
150 : : {
151 : : return 0;
152 : : }
153 : :
154 : : static inline int cipso_v4_doi_domhsh_add(struct cipso_v4_doi *doi_def,
155 : : const char *domain)
156 : : {
157 : : return -ENOSYS;
158 : : }
159 : :
160 : : static inline int cipso_v4_doi_domhsh_remove(struct cipso_v4_doi *doi_def,
161 : : const char *domain)
162 : : {
163 : : return 0;
164 : : }
165 : : #endif /* CONFIG_NETLABEL */
166 : :
167 : : /*
168 : : * Label Mapping Cache Functions
169 : : */
170 : :
171 : : #ifdef CONFIG_NETLABEL
172 : : void cipso_v4_cache_invalidate(void);
173 : : int cipso_v4_cache_add(const unsigned char *cipso_ptr,
174 : : const struct netlbl_lsm_secattr *secattr);
175 : : #else
176 : : static inline void cipso_v4_cache_invalidate(void)
177 : : {
178 : : return;
179 : : }
180 : :
181 : : static inline int cipso_v4_cache_add(const unsigned char *cipso_ptr,
182 : : const struct netlbl_lsm_secattr *secattr)
183 : : {
184 : : return 0;
185 : : }
186 : : #endif /* CONFIG_NETLABEL */
187 : :
188 : : /*
189 : : * Protocol Handling Functions
190 : : */
191 : :
192 : : #ifdef CONFIG_NETLABEL
193 : : void cipso_v4_error(struct sk_buff *skb, int error, u32 gateway);
194 : : int cipso_v4_getattr(const unsigned char *cipso,
195 : : struct netlbl_lsm_secattr *secattr);
196 : : int cipso_v4_sock_setattr(struct sock *sk,
197 : : const struct cipso_v4_doi *doi_def,
198 : : const struct netlbl_lsm_secattr *secattr);
199 : : void cipso_v4_sock_delattr(struct sock *sk);
200 : : int cipso_v4_sock_getattr(struct sock *sk, struct netlbl_lsm_secattr *secattr);
201 : : int cipso_v4_req_setattr(struct request_sock *req,
202 : : const struct cipso_v4_doi *doi_def,
203 : : const struct netlbl_lsm_secattr *secattr);
204 : : void cipso_v4_req_delattr(struct request_sock *req);
205 : : int cipso_v4_skbuff_setattr(struct sk_buff *skb,
206 : : const struct cipso_v4_doi *doi_def,
207 : : const struct netlbl_lsm_secattr *secattr);
208 : : int cipso_v4_skbuff_delattr(struct sk_buff *skb);
209 : : int cipso_v4_skbuff_getattr(const struct sk_buff *skb,
210 : : struct netlbl_lsm_secattr *secattr);
211 : : unsigned char *cipso_v4_optptr(const struct sk_buff *skb);
212 : : int cipso_v4_validate(const struct sk_buff *skb, unsigned char **option);
213 : : #else
214 : : static inline void cipso_v4_error(struct sk_buff *skb,
215 : : int error,
216 : : u32 gateway)
217 : : {
218 : : return;
219 : : }
220 : :
221 : : static inline int cipso_v4_getattr(const unsigned char *cipso,
222 : : struct netlbl_lsm_secattr *secattr)
223 : : {
224 : : return -ENOSYS;
225 : : }
226 : :
227 : : static inline int cipso_v4_sock_setattr(struct sock *sk,
228 : : const struct cipso_v4_doi *doi_def,
229 : : const struct netlbl_lsm_secattr *secattr)
230 : : {
231 : : return -ENOSYS;
232 : : }
233 : :
234 : : static inline void cipso_v4_sock_delattr(struct sock *sk)
235 : : {
236 : : }
237 : :
238 : : static inline int cipso_v4_sock_getattr(struct sock *sk,
239 : : struct netlbl_lsm_secattr *secattr)
240 : : {
241 : : return -ENOSYS;
242 : : }
243 : :
244 : : static inline int cipso_v4_req_setattr(struct request_sock *req,
245 : : const struct cipso_v4_doi *doi_def,
246 : : const struct netlbl_lsm_secattr *secattr)
247 : : {
248 : : return -ENOSYS;
249 : : }
250 : :
251 : : static inline void cipso_v4_req_delattr(struct request_sock *req)
252 : : {
253 : : return;
254 : : }
255 : :
256 : : static inline int cipso_v4_skbuff_setattr(struct sk_buff *skb,
257 : : const struct cipso_v4_doi *doi_def,
258 : : const struct netlbl_lsm_secattr *secattr)
259 : : {
260 : : return -ENOSYS;
261 : : }
262 : :
263 : : static inline int cipso_v4_skbuff_delattr(struct sk_buff *skb)
264 : : {
265 : : return -ENOSYS;
266 : : }
267 : :
268 : : static inline int cipso_v4_skbuff_getattr(const struct sk_buff *skb,
269 : : struct netlbl_lsm_secattr *secattr)
270 : : {
271 : : return -ENOSYS;
272 : : }
273 : :
274 : : static inline unsigned char *cipso_v4_optptr(const struct sk_buff *skb)
275 : : {
276 : : return NULL;
277 : : }
278 : :
279 : 0 : static inline int cipso_v4_validate(const struct sk_buff *skb,
280 : : unsigned char **option)
281 : : {
282 : 0 : unsigned char *opt = *option;
283 : : unsigned char err_offset = 0;
284 : 0 : u8 opt_len = opt[1];
285 : : u8 opt_iter;
286 : : u8 tag_len;
287 : :
288 [ # # ]: 0 : if (opt_len < 8) {
289 : : err_offset = 1;
290 : : goto out;
291 : : }
292 : :
293 [ # # ]: 0 : if (get_unaligned_be32(&opt[2]) == 0) {
294 : : err_offset = 2;
295 : : goto out;
296 : : }
297 : :
298 [ # # ]: 0 : for (opt_iter = 6; opt_iter < opt_len;) {
299 [ # # ]: 0 : if (opt_iter + 1 == opt_len) {
300 : 0 : err_offset = opt_iter;
301 : 0 : goto out;
302 : : }
303 : 0 : tag_len = opt[opt_iter + 1];
304 [ # # # # ]: 0 : if ((tag_len == 0) || (tag_len > (opt_len - opt_iter))) {
305 : 0 : err_offset = opt_iter + 1;
306 : 0 : goto out;
307 : : }
308 : 0 : opt_iter += tag_len;
309 : : }
310 : :
311 : : out:
312 : 0 : *option = opt + err_offset;
313 : 0 : return err_offset;
314 : :
315 : : }
316 : : #endif /* CONFIG_NETLABEL */
317 : :
318 : : #endif /* _CIPSO_IPV4_H */
|