xref: /linux/net/ipv4/cipso_ipv4.c (revision b1edeb102397546438ab4624489c6ccd7b410d97)
1 /*
2  * CIPSO - Commercial IP Security Option
3  *
4  * This is an implementation of the CIPSO 2.2 protocol as specified in
5  * draft-ietf-cipso-ipsecurity-01.txt with additional tag types as found in
6  * FIPS-188, copies of both documents can be found in the Documentation
7  * directory.  While CIPSO never became a full IETF RFC standard many vendors
8  * have chosen to adopt the protocol and over the years it has become a
9  * de-facto standard for labeled networking.
10  *
11  * Author: Paul Moore <paul.moore@hp.com>
12  *
13  */
14 
15 /*
16  * (c) Copyright Hewlett-Packard Development Company, L.P., 2006
17  *
18  * This program is free software;  you can redistribute it and/or modify
19  * it under the terms of the GNU General Public License as published by
20  * the Free Software Foundation; either version 2 of the License, or
21  * (at your option) any later version.
22  *
23  * This program is distributed in the hope that it will be useful,
24  * but WITHOUT ANY WARRANTY;  without even the implied warranty of
25  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
26  * the GNU General Public License for more details.
27  *
28  * You should have received a copy of the GNU General Public License
29  * along with this program;  if not, write to the Free Software
30  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31  *
32  */
33 
34 #include <linux/init.h>
35 #include <linux/types.h>
36 #include <linux/rcupdate.h>
37 #include <linux/list.h>
38 #include <linux/spinlock.h>
39 #include <linux/string.h>
40 #include <linux/jhash.h>
41 #include <net/ip.h>
42 #include <net/icmp.h>
43 #include <net/tcp.h>
44 #include <net/netlabel.h>
45 #include <net/cipso_ipv4.h>
46 #include <asm/atomic.h>
47 #include <asm/bug.h>
48 #include <asm/unaligned.h>
49 
50 /* List of available DOI definitions */
51 /* XXX - This currently assumes a minimal number of different DOIs in use,
52  * if in practice there are a lot of different DOIs this list should
53  * probably be turned into a hash table or something similar so we
54  * can do quick lookups. */
55 static DEFINE_SPINLOCK(cipso_v4_doi_list_lock);
56 static LIST_HEAD(cipso_v4_doi_list);
57 
58 /* Label mapping cache */
59 int cipso_v4_cache_enabled = 1;
60 int cipso_v4_cache_bucketsize = 10;
61 #define CIPSO_V4_CACHE_BUCKETBITS     7
62 #define CIPSO_V4_CACHE_BUCKETS        (1 << CIPSO_V4_CACHE_BUCKETBITS)
63 #define CIPSO_V4_CACHE_REORDERLIMIT   10
64 struct cipso_v4_map_cache_bkt {
65 	spinlock_t lock;
66 	u32 size;
67 	struct list_head list;
68 };
69 struct cipso_v4_map_cache_entry {
70 	u32 hash;
71 	unsigned char *key;
72 	size_t key_len;
73 
74 	struct netlbl_lsm_cache *lsm_data;
75 
76 	u32 activity;
77 	struct list_head list;
78 };
79 static struct cipso_v4_map_cache_bkt *cipso_v4_cache = NULL;
80 
81 /* Restricted bitmap (tag #1) flags */
82 int cipso_v4_rbm_optfmt = 0;
83 int cipso_v4_rbm_strictvalid = 1;
84 
85 /*
86  * Protocol Constants
87  */
88 
89 /* Maximum size of the CIPSO IP option, derived from the fact that the maximum
90  * IPv4 header size is 60 bytes and the base IPv4 header is 20 bytes long. */
91 #define CIPSO_V4_OPT_LEN_MAX          40
92 
93 /* Length of the base CIPSO option, this includes the option type (1 byte), the
94  * option length (1 byte), and the DOI (4 bytes). */
95 #define CIPSO_V4_HDR_LEN              6
96 
97 /* Base length of the restrictive category bitmap tag (tag #1). */
98 #define CIPSO_V4_TAG_RBM_BLEN         4
99 
100 /* Base length of the enumerated category tag (tag #2). */
101 #define CIPSO_V4_TAG_ENUM_BLEN        4
102 
103 /* Base length of the ranged categories bitmap tag (tag #5). */
104 #define CIPSO_V4_TAG_RNG_BLEN         4
105 /* The maximum number of category ranges permitted in the ranged category tag
106  * (tag #5).  You may note that the IETF draft states that the maximum number
107  * of category ranges is 7, but if the low end of the last category range is
108  * zero then it is possibile to fit 8 category ranges because the zero should
109  * be omitted. */
110 #define CIPSO_V4_TAG_RNG_CAT_MAX      8
111 
112 /*
113  * Helper Functions
114  */
115 
116 /**
117  * cipso_v4_bitmap_walk - Walk a bitmap looking for a bit
118  * @bitmap: the bitmap
119  * @bitmap_len: length in bits
120  * @offset: starting offset
121  * @state: if non-zero, look for a set (1) bit else look for a cleared (0) bit
122  *
123  * Description:
124  * Starting at @offset, walk the bitmap from left to right until either the
125  * desired bit is found or we reach the end.  Return the bit offset, -1 if
126  * not found, or -2 if error.
127  */
128 static int cipso_v4_bitmap_walk(const unsigned char *bitmap,
129 				u32 bitmap_len,
130 				u32 offset,
131 				u8 state)
132 {
133 	u32 bit_spot;
134 	u32 byte_offset;
135 	unsigned char bitmask;
136 	unsigned char byte;
137 
138 	/* gcc always rounds to zero when doing integer division */
139 	byte_offset = offset / 8;
140 	byte = bitmap[byte_offset];
141 	bit_spot = offset;
142 	bitmask = 0x80 >> (offset % 8);
143 
144 	while (bit_spot < bitmap_len) {
145 		if ((state && (byte & bitmask) == bitmask) ||
146 		    (state == 0 && (byte & bitmask) == 0))
147 			return bit_spot;
148 
149 		bit_spot++;
150 		bitmask >>= 1;
151 		if (bitmask == 0) {
152 			byte = bitmap[++byte_offset];
153 			bitmask = 0x80;
154 		}
155 	}
156 
157 	return -1;
158 }
159 
160 /**
161  * cipso_v4_bitmap_setbit - Sets a single bit in a bitmap
162  * @bitmap: the bitmap
163  * @bit: the bit
164  * @state: if non-zero, set the bit (1) else clear the bit (0)
165  *
166  * Description:
167  * Set a single bit in the bitmask.  Returns zero on success, negative values
168  * on error.
169  */
170 static void cipso_v4_bitmap_setbit(unsigned char *bitmap,
171 				   u32 bit,
172 				   u8 state)
173 {
174 	u32 byte_spot;
175 	u8 bitmask;
176 
177 	/* gcc always rounds to zero when doing integer division */
178 	byte_spot = bit / 8;
179 	bitmask = 0x80 >> (bit % 8);
180 	if (state)
181 		bitmap[byte_spot] |= bitmask;
182 	else
183 		bitmap[byte_spot] &= ~bitmask;
184 }
185 
186 /**
187  * cipso_v4_cache_entry_free - Frees a cache entry
188  * @entry: the entry to free
189  *
190  * Description:
191  * This function frees the memory associated with a cache entry including the
192  * LSM cache data if there are no longer any users, i.e. reference count == 0.
193  *
194  */
195 static void cipso_v4_cache_entry_free(struct cipso_v4_map_cache_entry *entry)
196 {
197 	if (entry->lsm_data)
198 		netlbl_secattr_cache_free(entry->lsm_data);
199 	kfree(entry->key);
200 	kfree(entry);
201 }
202 
203 /**
204  * cipso_v4_map_cache_hash - Hashing function for the CIPSO cache
205  * @key: the hash key
206  * @key_len: the length of the key in bytes
207  *
208  * Description:
209  * The CIPSO tag hashing function.  Returns a 32-bit hash value.
210  *
211  */
212 static u32 cipso_v4_map_cache_hash(const unsigned char *key, u32 key_len)
213 {
214 	return jhash(key, key_len, 0);
215 }
216 
217 /*
218  * Label Mapping Cache Functions
219  */
220 
221 /**
222  * cipso_v4_cache_init - Initialize the CIPSO cache
223  *
224  * Description:
225  * Initializes the CIPSO label mapping cache, this function should be called
226  * before any of the other functions defined in this file.  Returns zero on
227  * success, negative values on error.
228  *
229  */
230 static int cipso_v4_cache_init(void)
231 {
232 	u32 iter;
233 
234 	cipso_v4_cache = kcalloc(CIPSO_V4_CACHE_BUCKETS,
235 				 sizeof(struct cipso_v4_map_cache_bkt),
236 				 GFP_KERNEL);
237 	if (cipso_v4_cache == NULL)
238 		return -ENOMEM;
239 
240 	for (iter = 0; iter < CIPSO_V4_CACHE_BUCKETS; iter++) {
241 		spin_lock_init(&cipso_v4_cache[iter].lock);
242 		cipso_v4_cache[iter].size = 0;
243 		INIT_LIST_HEAD(&cipso_v4_cache[iter].list);
244 	}
245 
246 	return 0;
247 }
248 
249 /**
250  * cipso_v4_cache_invalidate - Invalidates the current CIPSO cache
251  *
252  * Description:
253  * Invalidates and frees any entries in the CIPSO cache.  Returns zero on
254  * success and negative values on failure.
255  *
256  */
257 void cipso_v4_cache_invalidate(void)
258 {
259 	struct cipso_v4_map_cache_entry *entry, *tmp_entry;
260 	u32 iter;
261 
262 	for (iter = 0; iter < CIPSO_V4_CACHE_BUCKETS; iter++) {
263 		spin_lock_bh(&cipso_v4_cache[iter].lock);
264 		list_for_each_entry_safe(entry,
265 					 tmp_entry,
266 					 &cipso_v4_cache[iter].list, list) {
267 			list_del(&entry->list);
268 			cipso_v4_cache_entry_free(entry);
269 		}
270 		cipso_v4_cache[iter].size = 0;
271 		spin_unlock_bh(&cipso_v4_cache[iter].lock);
272 	}
273 
274 	return;
275 }
276 
277 /**
278  * cipso_v4_cache_check - Check the CIPSO cache for a label mapping
279  * @key: the buffer to check
280  * @key_len: buffer length in bytes
281  * @secattr: the security attribute struct to use
282  *
283  * Description:
284  * This function checks the cache to see if a label mapping already exists for
285  * the given key.  If there is a match then the cache is adjusted and the
286  * @secattr struct is populated with the correct LSM security attributes.  The
287  * cache is adjusted in the following manner if the entry is not already the
288  * first in the cache bucket:
289  *
290  *  1. The cache entry's activity counter is incremented
291  *  2. The previous (higher ranking) entry's activity counter is decremented
292  *  3. If the difference between the two activity counters is geater than
293  *     CIPSO_V4_CACHE_REORDERLIMIT the two entries are swapped
294  *
295  * Returns zero on success, -ENOENT for a cache miss, and other negative values
296  * on error.
297  *
298  */
299 static int cipso_v4_cache_check(const unsigned char *key,
300 				u32 key_len,
301 				struct netlbl_lsm_secattr *secattr)
302 {
303 	u32 bkt;
304 	struct cipso_v4_map_cache_entry *entry;
305 	struct cipso_v4_map_cache_entry *prev_entry = NULL;
306 	u32 hash;
307 
308 	if (!cipso_v4_cache_enabled)
309 		return -ENOENT;
310 
311 	hash = cipso_v4_map_cache_hash(key, key_len);
312 	bkt = hash & (CIPSO_V4_CACHE_BUCKETS - 1);
313 	spin_lock_bh(&cipso_v4_cache[bkt].lock);
314 	list_for_each_entry(entry, &cipso_v4_cache[bkt].list, list) {
315 		if (entry->hash == hash &&
316 		    entry->key_len == key_len &&
317 		    memcmp(entry->key, key, key_len) == 0) {
318 			entry->activity += 1;
319 			atomic_inc(&entry->lsm_data->refcount);
320 			secattr->cache = entry->lsm_data;
321 			secattr->flags |= NETLBL_SECATTR_CACHE;
322 			secattr->type = NETLBL_NLTYPE_CIPSOV4;
323 			if (prev_entry == NULL) {
324 				spin_unlock_bh(&cipso_v4_cache[bkt].lock);
325 				return 0;
326 			}
327 
328 			if (prev_entry->activity > 0)
329 				prev_entry->activity -= 1;
330 			if (entry->activity > prev_entry->activity &&
331 			    entry->activity - prev_entry->activity >
332 			    CIPSO_V4_CACHE_REORDERLIMIT) {
333 				__list_del(entry->list.prev, entry->list.next);
334 				__list_add(&entry->list,
335 					   prev_entry->list.prev,
336 					   &prev_entry->list);
337 			}
338 
339 			spin_unlock_bh(&cipso_v4_cache[bkt].lock);
340 			return 0;
341 		}
342 		prev_entry = entry;
343 	}
344 	spin_unlock_bh(&cipso_v4_cache[bkt].lock);
345 
346 	return -ENOENT;
347 }
348 
349 /**
350  * cipso_v4_cache_add - Add an entry to the CIPSO cache
351  * @skb: the packet
352  * @secattr: the packet's security attributes
353  *
354  * Description:
355  * Add a new entry into the CIPSO label mapping cache.  Add the new entry to
356  * head of the cache bucket's list, if the cache bucket is out of room remove
357  * the last entry in the list first.  It is important to note that there is
358  * currently no checking for duplicate keys.  Returns zero on success,
359  * negative values on failure.
360  *
361  */
362 int cipso_v4_cache_add(const struct sk_buff *skb,
363 		       const struct netlbl_lsm_secattr *secattr)
364 {
365 	int ret_val = -EPERM;
366 	u32 bkt;
367 	struct cipso_v4_map_cache_entry *entry = NULL;
368 	struct cipso_v4_map_cache_entry *old_entry = NULL;
369 	unsigned char *cipso_ptr;
370 	u32 cipso_ptr_len;
371 
372 	if (!cipso_v4_cache_enabled || cipso_v4_cache_bucketsize <= 0)
373 		return 0;
374 
375 	cipso_ptr = CIPSO_V4_OPTPTR(skb);
376 	cipso_ptr_len = cipso_ptr[1];
377 
378 	entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
379 	if (entry == NULL)
380 		return -ENOMEM;
381 	entry->key = kmemdup(cipso_ptr, cipso_ptr_len, GFP_ATOMIC);
382 	if (entry->key == NULL) {
383 		ret_val = -ENOMEM;
384 		goto cache_add_failure;
385 	}
386 	entry->key_len = cipso_ptr_len;
387 	entry->hash = cipso_v4_map_cache_hash(cipso_ptr, cipso_ptr_len);
388 	atomic_inc(&secattr->cache->refcount);
389 	entry->lsm_data = secattr->cache;
390 
391 	bkt = entry->hash & (CIPSO_V4_CACHE_BUCKETS - 1);
392 	spin_lock_bh(&cipso_v4_cache[bkt].lock);
393 	if (cipso_v4_cache[bkt].size < cipso_v4_cache_bucketsize) {
394 		list_add(&entry->list, &cipso_v4_cache[bkt].list);
395 		cipso_v4_cache[bkt].size += 1;
396 	} else {
397 		old_entry = list_entry(cipso_v4_cache[bkt].list.prev,
398 				       struct cipso_v4_map_cache_entry, list);
399 		list_del(&old_entry->list);
400 		list_add(&entry->list, &cipso_v4_cache[bkt].list);
401 		cipso_v4_cache_entry_free(old_entry);
402 	}
403 	spin_unlock_bh(&cipso_v4_cache[bkt].lock);
404 
405 	return 0;
406 
407 cache_add_failure:
408 	if (entry)
409 		cipso_v4_cache_entry_free(entry);
410 	return ret_val;
411 }
412 
413 /*
414  * DOI List Functions
415  */
416 
417 /**
418  * cipso_v4_doi_search - Searches for a DOI definition
419  * @doi: the DOI to search for
420  *
421  * Description:
422  * Search the DOI definition list for a DOI definition with a DOI value that
423  * matches @doi.  The caller is responsibile for calling rcu_read_[un]lock().
424  * Returns a pointer to the DOI definition on success and NULL on failure.
425  */
426 static struct cipso_v4_doi *cipso_v4_doi_search(u32 doi)
427 {
428 	struct cipso_v4_doi *iter;
429 
430 	list_for_each_entry_rcu(iter, &cipso_v4_doi_list, list)
431 		if (iter->doi == doi && atomic_read(&iter->refcount))
432 			return iter;
433 	return NULL;
434 }
435 
436 /**
437  * cipso_v4_doi_add - Add a new DOI to the CIPSO protocol engine
438  * @doi_def: the DOI structure
439  *
440  * Description:
441  * The caller defines a new DOI for use by the CIPSO engine and calls this
442  * function to add it to the list of acceptable domains.  The caller must
443  * ensure that the mapping table specified in @doi_def->map meets all of the
444  * requirements of the mapping type (see cipso_ipv4.h for details).  Returns
445  * zero on success and non-zero on failure.
446  *
447  */
448 int cipso_v4_doi_add(struct cipso_v4_doi *doi_def)
449 {
450 	u32 iter;
451 
452 	if (doi_def == NULL || doi_def->doi == CIPSO_V4_DOI_UNKNOWN)
453 		return -EINVAL;
454 	for (iter = 0; iter < CIPSO_V4_TAG_MAXCNT; iter++) {
455 		switch (doi_def->tags[iter]) {
456 		case CIPSO_V4_TAG_RBITMAP:
457 			break;
458 		case CIPSO_V4_TAG_RANGE:
459 			if (doi_def->type != CIPSO_V4_MAP_PASS)
460 				return -EINVAL;
461 			break;
462 		case CIPSO_V4_TAG_INVALID:
463 			if (iter == 0)
464 				return -EINVAL;
465 			break;
466 		case CIPSO_V4_TAG_ENUM:
467 			if (doi_def->type != CIPSO_V4_MAP_PASS)
468 				return -EINVAL;
469 			break;
470 		default:
471 			return -EINVAL;
472 		}
473 	}
474 
475 	atomic_set(&doi_def->refcount, 1);
476 	INIT_RCU_HEAD(&doi_def->rcu);
477 
478 	spin_lock(&cipso_v4_doi_list_lock);
479 	if (cipso_v4_doi_search(doi_def->doi) != NULL)
480 		goto doi_add_failure;
481 	list_add_tail_rcu(&doi_def->list, &cipso_v4_doi_list);
482 	spin_unlock(&cipso_v4_doi_list_lock);
483 
484 	return 0;
485 
486 doi_add_failure:
487 	spin_unlock(&cipso_v4_doi_list_lock);
488 	return -EEXIST;
489 }
490 
491 /**
492  * cipso_v4_doi_free - Frees a DOI definition
493  * @entry: the entry's RCU field
494  *
495  * Description:
496  * This function frees all of the memory associated with a DOI definition.
497  *
498  */
499 void cipso_v4_doi_free(struct cipso_v4_doi *doi_def)
500 {
501 	if (doi_def == NULL)
502 		return;
503 
504 	switch (doi_def->type) {
505 	case CIPSO_V4_MAP_STD:
506 		kfree(doi_def->map.std->lvl.cipso);
507 		kfree(doi_def->map.std->lvl.local);
508 		kfree(doi_def->map.std->cat.cipso);
509 		kfree(doi_def->map.std->cat.local);
510 		break;
511 	}
512 	kfree(doi_def);
513 }
514 
515 /**
516  * cipso_v4_doi_free_rcu - Frees a DOI definition via the RCU pointer
517  * @entry: the entry's RCU field
518  *
519  * Description:
520  * This function is designed to be used as a callback to the call_rcu()
521  * function so that the memory allocated to the DOI definition can be released
522  * safely.
523  *
524  */
525 static void cipso_v4_doi_free_rcu(struct rcu_head *entry)
526 {
527 	struct cipso_v4_doi *doi_def;
528 
529 	doi_def = container_of(entry, struct cipso_v4_doi, rcu);
530 	cipso_v4_doi_free(doi_def);
531 }
532 
533 /**
534  * cipso_v4_doi_remove - Remove an existing DOI from the CIPSO protocol engine
535  * @doi: the DOI value
536  * @audit_secid: the LSM secid to use in the audit message
537  *
538  * Description:
539  * Removes a DOI definition from the CIPSO engine.  The NetLabel routines will
540  * be called to release their own LSM domain mappings as well as our own
541  * domain list.  Returns zero on success and negative values on failure.
542  *
543  */
544 int cipso_v4_doi_remove(u32 doi, struct netlbl_audit *audit_info)
545 {
546 	struct cipso_v4_doi *doi_def;
547 
548 	spin_lock(&cipso_v4_doi_list_lock);
549 	doi_def = cipso_v4_doi_search(doi);
550 	if (doi_def == NULL) {
551 		spin_unlock(&cipso_v4_doi_list_lock);
552 		return -ENOENT;
553 	}
554 	if (!atomic_dec_and_test(&doi_def->refcount)) {
555 		spin_unlock(&cipso_v4_doi_list_lock);
556 		return -EBUSY;
557 	}
558 	list_del_rcu(&doi_def->list);
559 	spin_unlock(&cipso_v4_doi_list_lock);
560 
561 	cipso_v4_cache_invalidate();
562 	call_rcu(&doi_def->rcu, cipso_v4_doi_free_rcu);
563 
564 	return 0;
565 }
566 
567 /**
568  * cipso_v4_doi_getdef - Returns a reference to a valid DOI definition
569  * @doi: the DOI value
570  *
571  * Description:
572  * Searches for a valid DOI definition and if one is found it is returned to
573  * the caller.  Otherwise NULL is returned.  The caller must ensure that
574  * rcu_read_lock() is held while accessing the returned definition and the DOI
575  * definition reference count is decremented when the caller is done.
576  *
577  */
578 struct cipso_v4_doi *cipso_v4_doi_getdef(u32 doi)
579 {
580 	struct cipso_v4_doi *doi_def;
581 
582 	rcu_read_lock();
583 	doi_def = cipso_v4_doi_search(doi);
584 	if (doi_def == NULL)
585 		goto doi_getdef_return;
586 	if (!atomic_inc_not_zero(&doi_def->refcount))
587 		doi_def = NULL;
588 
589 doi_getdef_return:
590 	rcu_read_unlock();
591 	return doi_def;
592 }
593 
594 /**
595  * cipso_v4_doi_putdef - Releases a reference for the given DOI definition
596  * @doi_def: the DOI definition
597  *
598  * Description:
599  * Releases a DOI definition reference obtained from cipso_v4_doi_getdef().
600  *
601  */
602 void cipso_v4_doi_putdef(struct cipso_v4_doi *doi_def)
603 {
604 	if (doi_def == NULL)
605 		return;
606 
607 	if (!atomic_dec_and_test(&doi_def->refcount))
608 		return;
609 	spin_lock(&cipso_v4_doi_list_lock);
610 	list_del_rcu(&doi_def->list);
611 	spin_unlock(&cipso_v4_doi_list_lock);
612 
613 	cipso_v4_cache_invalidate();
614 	call_rcu(&doi_def->rcu, cipso_v4_doi_free_rcu);
615 }
616 
617 /**
618  * cipso_v4_doi_walk - Iterate through the DOI definitions
619  * @skip_cnt: skip past this number of DOI definitions, updated
620  * @callback: callback for each DOI definition
621  * @cb_arg: argument for the callback function
622  *
623  * Description:
624  * Iterate over the DOI definition list, skipping the first @skip_cnt entries.
625  * For each entry call @callback, if @callback returns a negative value stop
626  * 'walking' through the list and return.  Updates the value in @skip_cnt upon
627  * return.  Returns zero on success, negative values on failure.
628  *
629  */
630 int cipso_v4_doi_walk(u32 *skip_cnt,
631 		     int (*callback) (struct cipso_v4_doi *doi_def, void *arg),
632 		     void *cb_arg)
633 {
634 	int ret_val = -ENOENT;
635 	u32 doi_cnt = 0;
636 	struct cipso_v4_doi *iter_doi;
637 
638 	rcu_read_lock();
639 	list_for_each_entry_rcu(iter_doi, &cipso_v4_doi_list, list)
640 		if (atomic_read(&iter_doi->refcount) > 0) {
641 			if (doi_cnt++ < *skip_cnt)
642 				continue;
643 			ret_val = callback(iter_doi, cb_arg);
644 			if (ret_val < 0) {
645 				doi_cnt--;
646 				goto doi_walk_return;
647 			}
648 		}
649 
650 doi_walk_return:
651 	rcu_read_unlock();
652 	*skip_cnt = doi_cnt;
653 	return ret_val;
654 }
655 
656 /*
657  * Label Mapping Functions
658  */
659 
660 /**
661  * cipso_v4_map_lvl_valid - Checks to see if the given level is understood
662  * @doi_def: the DOI definition
663  * @level: the level to check
664  *
665  * Description:
666  * Checks the given level against the given DOI definition and returns a
667  * negative value if the level does not have a valid mapping and a zero value
668  * if the level is defined by the DOI.
669  *
670  */
671 static int cipso_v4_map_lvl_valid(const struct cipso_v4_doi *doi_def, u8 level)
672 {
673 	switch (doi_def->type) {
674 	case CIPSO_V4_MAP_PASS:
675 		return 0;
676 	case CIPSO_V4_MAP_STD:
677 		if (doi_def->map.std->lvl.cipso[level] < CIPSO_V4_INV_LVL)
678 			return 0;
679 		break;
680 	}
681 
682 	return -EFAULT;
683 }
684 
685 /**
686  * cipso_v4_map_lvl_hton - Perform a level mapping from the host to the network
687  * @doi_def: the DOI definition
688  * @host_lvl: the host MLS level
689  * @net_lvl: the network/CIPSO MLS level
690  *
691  * Description:
692  * Perform a label mapping to translate a local MLS level to the correct
693  * CIPSO level using the given DOI definition.  Returns zero on success,
694  * negative values otherwise.
695  *
696  */
697 static int cipso_v4_map_lvl_hton(const struct cipso_v4_doi *doi_def,
698 				 u32 host_lvl,
699 				 u32 *net_lvl)
700 {
701 	switch (doi_def->type) {
702 	case CIPSO_V4_MAP_PASS:
703 		*net_lvl = host_lvl;
704 		return 0;
705 	case CIPSO_V4_MAP_STD:
706 		if (host_lvl < doi_def->map.std->lvl.local_size &&
707 		    doi_def->map.std->lvl.local[host_lvl] < CIPSO_V4_INV_LVL) {
708 			*net_lvl = doi_def->map.std->lvl.local[host_lvl];
709 			return 0;
710 		}
711 		return -EPERM;
712 	}
713 
714 	return -EINVAL;
715 }
716 
717 /**
718  * cipso_v4_map_lvl_ntoh - Perform a level mapping from the network to the host
719  * @doi_def: the DOI definition
720  * @net_lvl: the network/CIPSO MLS level
721  * @host_lvl: the host MLS level
722  *
723  * Description:
724  * Perform a label mapping to translate a CIPSO level to the correct local MLS
725  * level using the given DOI definition.  Returns zero on success, negative
726  * values otherwise.
727  *
728  */
729 static int cipso_v4_map_lvl_ntoh(const struct cipso_v4_doi *doi_def,
730 				 u32 net_lvl,
731 				 u32 *host_lvl)
732 {
733 	struct cipso_v4_std_map_tbl *map_tbl;
734 
735 	switch (doi_def->type) {
736 	case CIPSO_V4_MAP_PASS:
737 		*host_lvl = net_lvl;
738 		return 0;
739 	case CIPSO_V4_MAP_STD:
740 		map_tbl = doi_def->map.std;
741 		if (net_lvl < map_tbl->lvl.cipso_size &&
742 		    map_tbl->lvl.cipso[net_lvl] < CIPSO_V4_INV_LVL) {
743 			*host_lvl = doi_def->map.std->lvl.cipso[net_lvl];
744 			return 0;
745 		}
746 		return -EPERM;
747 	}
748 
749 	return -EINVAL;
750 }
751 
752 /**
753  * cipso_v4_map_cat_rbm_valid - Checks to see if the category bitmap is valid
754  * @doi_def: the DOI definition
755  * @bitmap: category bitmap
756  * @bitmap_len: bitmap length in bytes
757  *
758  * Description:
759  * Checks the given category bitmap against the given DOI definition and
760  * returns a negative value if any of the categories in the bitmap do not have
761  * a valid mapping and a zero value if all of the categories are valid.
762  *
763  */
764 static int cipso_v4_map_cat_rbm_valid(const struct cipso_v4_doi *doi_def,
765 				      const unsigned char *bitmap,
766 				      u32 bitmap_len)
767 {
768 	int cat = -1;
769 	u32 bitmap_len_bits = bitmap_len * 8;
770 	u32 cipso_cat_size;
771 	u32 *cipso_array;
772 
773 	switch (doi_def->type) {
774 	case CIPSO_V4_MAP_PASS:
775 		return 0;
776 	case CIPSO_V4_MAP_STD:
777 		cipso_cat_size = doi_def->map.std->cat.cipso_size;
778 		cipso_array = doi_def->map.std->cat.cipso;
779 		for (;;) {
780 			cat = cipso_v4_bitmap_walk(bitmap,
781 						   bitmap_len_bits,
782 						   cat + 1,
783 						   1);
784 			if (cat < 0)
785 				break;
786 			if (cat >= cipso_cat_size ||
787 			    cipso_array[cat] >= CIPSO_V4_INV_CAT)
788 				return -EFAULT;
789 		}
790 
791 		if (cat == -1)
792 			return 0;
793 		break;
794 	}
795 
796 	return -EFAULT;
797 }
798 
799 /**
800  * cipso_v4_map_cat_rbm_hton - Perform a category mapping from host to network
801  * @doi_def: the DOI definition
802  * @secattr: the security attributes
803  * @net_cat: the zero'd out category bitmap in network/CIPSO format
804  * @net_cat_len: the length of the CIPSO bitmap in bytes
805  *
806  * Description:
807  * Perform a label mapping to translate a local MLS category bitmap to the
808  * correct CIPSO bitmap using the given DOI definition.  Returns the minimum
809  * size in bytes of the network bitmap on success, negative values otherwise.
810  *
811  */
812 static int cipso_v4_map_cat_rbm_hton(const struct cipso_v4_doi *doi_def,
813 				     const struct netlbl_lsm_secattr *secattr,
814 				     unsigned char *net_cat,
815 				     u32 net_cat_len)
816 {
817 	int host_spot = -1;
818 	u32 net_spot = CIPSO_V4_INV_CAT;
819 	u32 net_spot_max = 0;
820 	u32 net_clen_bits = net_cat_len * 8;
821 	u32 host_cat_size = 0;
822 	u32 *host_cat_array = NULL;
823 
824 	if (doi_def->type == CIPSO_V4_MAP_STD) {
825 		host_cat_size = doi_def->map.std->cat.local_size;
826 		host_cat_array = doi_def->map.std->cat.local;
827 	}
828 
829 	for (;;) {
830 		host_spot = netlbl_secattr_catmap_walk(secattr->attr.mls.cat,
831 						       host_spot + 1);
832 		if (host_spot < 0)
833 			break;
834 
835 		switch (doi_def->type) {
836 		case CIPSO_V4_MAP_PASS:
837 			net_spot = host_spot;
838 			break;
839 		case CIPSO_V4_MAP_STD:
840 			if (host_spot >= host_cat_size)
841 				return -EPERM;
842 			net_spot = host_cat_array[host_spot];
843 			if (net_spot >= CIPSO_V4_INV_CAT)
844 				return -EPERM;
845 			break;
846 		}
847 		if (net_spot >= net_clen_bits)
848 			return -ENOSPC;
849 		cipso_v4_bitmap_setbit(net_cat, net_spot, 1);
850 
851 		if (net_spot > net_spot_max)
852 			net_spot_max = net_spot;
853 	}
854 
855 	if (++net_spot_max % 8)
856 		return net_spot_max / 8 + 1;
857 	return net_spot_max / 8;
858 }
859 
860 /**
861  * cipso_v4_map_cat_rbm_ntoh - Perform a category mapping from network to host
862  * @doi_def: the DOI definition
863  * @net_cat: the category bitmap in network/CIPSO format
864  * @net_cat_len: the length of the CIPSO bitmap in bytes
865  * @secattr: the security attributes
866  *
867  * Description:
868  * Perform a label mapping to translate a CIPSO bitmap to the correct local
869  * MLS category bitmap using the given DOI definition.  Returns zero on
870  * success, negative values on failure.
871  *
872  */
873 static int cipso_v4_map_cat_rbm_ntoh(const struct cipso_v4_doi *doi_def,
874 				     const unsigned char *net_cat,
875 				     u32 net_cat_len,
876 				     struct netlbl_lsm_secattr *secattr)
877 {
878 	int ret_val;
879 	int net_spot = -1;
880 	u32 host_spot = CIPSO_V4_INV_CAT;
881 	u32 net_clen_bits = net_cat_len * 8;
882 	u32 net_cat_size = 0;
883 	u32 *net_cat_array = NULL;
884 
885 	if (doi_def->type == CIPSO_V4_MAP_STD) {
886 		net_cat_size = doi_def->map.std->cat.cipso_size;
887 		net_cat_array = doi_def->map.std->cat.cipso;
888 	}
889 
890 	for (;;) {
891 		net_spot = cipso_v4_bitmap_walk(net_cat,
892 						net_clen_bits,
893 						net_spot + 1,
894 						1);
895 		if (net_spot < 0) {
896 			if (net_spot == -2)
897 				return -EFAULT;
898 			return 0;
899 		}
900 
901 		switch (doi_def->type) {
902 		case CIPSO_V4_MAP_PASS:
903 			host_spot = net_spot;
904 			break;
905 		case CIPSO_V4_MAP_STD:
906 			if (net_spot >= net_cat_size)
907 				return -EPERM;
908 			host_spot = net_cat_array[net_spot];
909 			if (host_spot >= CIPSO_V4_INV_CAT)
910 				return -EPERM;
911 			break;
912 		}
913 		ret_val = netlbl_secattr_catmap_setbit(secattr->attr.mls.cat,
914 						       host_spot,
915 						       GFP_ATOMIC);
916 		if (ret_val != 0)
917 			return ret_val;
918 	}
919 
920 	return -EINVAL;
921 }
922 
923 /**
924  * cipso_v4_map_cat_enum_valid - Checks to see if the categories are valid
925  * @doi_def: the DOI definition
926  * @enumcat: category list
927  * @enumcat_len: length of the category list in bytes
928  *
929  * Description:
930  * Checks the given categories against the given DOI definition and returns a
931  * negative value if any of the categories do not have a valid mapping and a
932  * zero value if all of the categories are valid.
933  *
934  */
935 static int cipso_v4_map_cat_enum_valid(const struct cipso_v4_doi *doi_def,
936 				       const unsigned char *enumcat,
937 				       u32 enumcat_len)
938 {
939 	u16 cat;
940 	int cat_prev = -1;
941 	u32 iter;
942 
943 	if (doi_def->type != CIPSO_V4_MAP_PASS || enumcat_len & 0x01)
944 		return -EFAULT;
945 
946 	for (iter = 0; iter < enumcat_len; iter += 2) {
947 		cat = get_unaligned_be16(&enumcat[iter]);
948 		if (cat <= cat_prev)
949 			return -EFAULT;
950 		cat_prev = cat;
951 	}
952 
953 	return 0;
954 }
955 
956 /**
957  * cipso_v4_map_cat_enum_hton - Perform a category mapping from host to network
958  * @doi_def: the DOI definition
959  * @secattr: the security attributes
960  * @net_cat: the zero'd out category list in network/CIPSO format
961  * @net_cat_len: the length of the CIPSO category list in bytes
962  *
963  * Description:
964  * Perform a label mapping to translate a local MLS category bitmap to the
965  * correct CIPSO category list using the given DOI definition.   Returns the
966  * size in bytes of the network category bitmap on success, negative values
967  * otherwise.
968  *
969  */
970 static int cipso_v4_map_cat_enum_hton(const struct cipso_v4_doi *doi_def,
971 				      const struct netlbl_lsm_secattr *secattr,
972 				      unsigned char *net_cat,
973 				      u32 net_cat_len)
974 {
975 	int cat = -1;
976 	u32 cat_iter = 0;
977 
978 	for (;;) {
979 		cat = netlbl_secattr_catmap_walk(secattr->attr.mls.cat,
980 						 cat + 1);
981 		if (cat < 0)
982 			break;
983 		if ((cat_iter + 2) > net_cat_len)
984 			return -ENOSPC;
985 
986 		*((__be16 *)&net_cat[cat_iter]) = htons(cat);
987 		cat_iter += 2;
988 	}
989 
990 	return cat_iter;
991 }
992 
993 /**
994  * cipso_v4_map_cat_enum_ntoh - Perform a category mapping from network to host
995  * @doi_def: the DOI definition
996  * @net_cat: the category list in network/CIPSO format
997  * @net_cat_len: the length of the CIPSO bitmap in bytes
998  * @secattr: the security attributes
999  *
1000  * Description:
1001  * Perform a label mapping to translate a CIPSO category list to the correct
1002  * local MLS category bitmap using the given DOI definition.  Returns zero on
1003  * success, negative values on failure.
1004  *
1005  */
1006 static int cipso_v4_map_cat_enum_ntoh(const struct cipso_v4_doi *doi_def,
1007 				      const unsigned char *net_cat,
1008 				      u32 net_cat_len,
1009 				      struct netlbl_lsm_secattr *secattr)
1010 {
1011 	int ret_val;
1012 	u32 iter;
1013 
1014 	for (iter = 0; iter < net_cat_len; iter += 2) {
1015 		ret_val = netlbl_secattr_catmap_setbit(secattr->attr.mls.cat,
1016 				get_unaligned_be16(&net_cat[iter]),
1017 				GFP_ATOMIC);
1018 		if (ret_val != 0)
1019 			return ret_val;
1020 	}
1021 
1022 	return 0;
1023 }
1024 
1025 /**
1026  * cipso_v4_map_cat_rng_valid - Checks to see if the categories are valid
1027  * @doi_def: the DOI definition
1028  * @rngcat: category list
1029  * @rngcat_len: length of the category list in bytes
1030  *
1031  * Description:
1032  * Checks the given categories against the given DOI definition and returns a
1033  * negative value if any of the categories do not have a valid mapping and a
1034  * zero value if all of the categories are valid.
1035  *
1036  */
1037 static int cipso_v4_map_cat_rng_valid(const struct cipso_v4_doi *doi_def,
1038 				      const unsigned char *rngcat,
1039 				      u32 rngcat_len)
1040 {
1041 	u16 cat_high;
1042 	u16 cat_low;
1043 	u32 cat_prev = CIPSO_V4_MAX_REM_CATS + 1;
1044 	u32 iter;
1045 
1046 	if (doi_def->type != CIPSO_V4_MAP_PASS || rngcat_len & 0x01)
1047 		return -EFAULT;
1048 
1049 	for (iter = 0; iter < rngcat_len; iter += 4) {
1050 		cat_high = get_unaligned_be16(&rngcat[iter]);
1051 		if ((iter + 4) <= rngcat_len)
1052 			cat_low = get_unaligned_be16(&rngcat[iter + 2]);
1053 		else
1054 			cat_low = 0;
1055 
1056 		if (cat_high > cat_prev)
1057 			return -EFAULT;
1058 
1059 		cat_prev = cat_low;
1060 	}
1061 
1062 	return 0;
1063 }
1064 
1065 /**
1066  * cipso_v4_map_cat_rng_hton - Perform a category mapping from host to network
1067  * @doi_def: the DOI definition
1068  * @secattr: the security attributes
1069  * @net_cat: the zero'd out category list in network/CIPSO format
1070  * @net_cat_len: the length of the CIPSO category list in bytes
1071  *
1072  * Description:
1073  * Perform a label mapping to translate a local MLS category bitmap to the
1074  * correct CIPSO category list using the given DOI definition.   Returns the
1075  * size in bytes of the network category bitmap on success, negative values
1076  * otherwise.
1077  *
1078  */
1079 static int cipso_v4_map_cat_rng_hton(const struct cipso_v4_doi *doi_def,
1080 				     const struct netlbl_lsm_secattr *secattr,
1081 				     unsigned char *net_cat,
1082 				     u32 net_cat_len)
1083 {
1084 	int iter = -1;
1085 	u16 array[CIPSO_V4_TAG_RNG_CAT_MAX * 2];
1086 	u32 array_cnt = 0;
1087 	u32 cat_size = 0;
1088 
1089 	/* make sure we don't overflow the 'array[]' variable */
1090 	if (net_cat_len >
1091 	    (CIPSO_V4_OPT_LEN_MAX - CIPSO_V4_HDR_LEN - CIPSO_V4_TAG_RNG_BLEN))
1092 		return -ENOSPC;
1093 
1094 	for (;;) {
1095 		iter = netlbl_secattr_catmap_walk(secattr->attr.mls.cat,
1096 						  iter + 1);
1097 		if (iter < 0)
1098 			break;
1099 		cat_size += (iter == 0 ? 0 : sizeof(u16));
1100 		if (cat_size > net_cat_len)
1101 			return -ENOSPC;
1102 		array[array_cnt++] = iter;
1103 
1104 		iter = netlbl_secattr_catmap_walk_rng(secattr->attr.mls.cat,
1105 						      iter);
1106 		if (iter < 0)
1107 			return -EFAULT;
1108 		cat_size += sizeof(u16);
1109 		if (cat_size > net_cat_len)
1110 			return -ENOSPC;
1111 		array[array_cnt++] = iter;
1112 	}
1113 
1114 	for (iter = 0; array_cnt > 0;) {
1115 		*((__be16 *)&net_cat[iter]) = htons(array[--array_cnt]);
1116 		iter += 2;
1117 		array_cnt--;
1118 		if (array[array_cnt] != 0) {
1119 			*((__be16 *)&net_cat[iter]) = htons(array[array_cnt]);
1120 			iter += 2;
1121 		}
1122 	}
1123 
1124 	return cat_size;
1125 }
1126 
1127 /**
1128  * cipso_v4_map_cat_rng_ntoh - Perform a category mapping from network to host
1129  * @doi_def: the DOI definition
1130  * @net_cat: the category list in network/CIPSO format
1131  * @net_cat_len: the length of the CIPSO bitmap in bytes
1132  * @secattr: the security attributes
1133  *
1134  * Description:
1135  * Perform a label mapping to translate a CIPSO category list to the correct
1136  * local MLS category bitmap using the given DOI definition.  Returns zero on
1137  * success, negative values on failure.
1138  *
1139  */
1140 static int cipso_v4_map_cat_rng_ntoh(const struct cipso_v4_doi *doi_def,
1141 				     const unsigned char *net_cat,
1142 				     u32 net_cat_len,
1143 				     struct netlbl_lsm_secattr *secattr)
1144 {
1145 	int ret_val;
1146 	u32 net_iter;
1147 	u16 cat_low;
1148 	u16 cat_high;
1149 
1150 	for (net_iter = 0; net_iter < net_cat_len; net_iter += 4) {
1151 		cat_high = get_unaligned_be16(&net_cat[net_iter]);
1152 		if ((net_iter + 4) <= net_cat_len)
1153 			cat_low = get_unaligned_be16(&net_cat[net_iter + 2]);
1154 		else
1155 			cat_low = 0;
1156 
1157 		ret_val = netlbl_secattr_catmap_setrng(secattr->attr.mls.cat,
1158 						       cat_low,
1159 						       cat_high,
1160 						       GFP_ATOMIC);
1161 		if (ret_val != 0)
1162 			return ret_val;
1163 	}
1164 
1165 	return 0;
1166 }
1167 
1168 /*
1169  * Protocol Handling Functions
1170  */
1171 
1172 /**
1173  * cipso_v4_gentag_hdr - Generate a CIPSO option header
1174  * @doi_def: the DOI definition
1175  * @len: the total tag length in bytes, not including this header
1176  * @buf: the CIPSO option buffer
1177  *
1178  * Description:
1179  * Write a CIPSO header into the beginning of @buffer.
1180  *
1181  */
1182 static void cipso_v4_gentag_hdr(const struct cipso_v4_doi *doi_def,
1183 				unsigned char *buf,
1184 				u32 len)
1185 {
1186 	buf[0] = IPOPT_CIPSO;
1187 	buf[1] = CIPSO_V4_HDR_LEN + len;
1188 	*(__be32 *)&buf[2] = htonl(doi_def->doi);
1189 }
1190 
1191 /**
1192  * cipso_v4_gentag_rbm - Generate a CIPSO restricted bitmap tag (type #1)
1193  * @doi_def: the DOI definition
1194  * @secattr: the security attributes
1195  * @buffer: the option buffer
1196  * @buffer_len: length of buffer in bytes
1197  *
1198  * Description:
1199  * Generate a CIPSO option using the restricted bitmap tag, tag type #1.  The
1200  * actual buffer length may be larger than the indicated size due to
1201  * translation between host and network category bitmaps.  Returns the size of
1202  * the tag on success, negative values on failure.
1203  *
1204  */
1205 static int cipso_v4_gentag_rbm(const struct cipso_v4_doi *doi_def,
1206 			       const struct netlbl_lsm_secattr *secattr,
1207 			       unsigned char *buffer,
1208 			       u32 buffer_len)
1209 {
1210 	int ret_val;
1211 	u32 tag_len;
1212 	u32 level;
1213 
1214 	if ((secattr->flags & NETLBL_SECATTR_MLS_LVL) == 0)
1215 		return -EPERM;
1216 
1217 	ret_val = cipso_v4_map_lvl_hton(doi_def,
1218 					secattr->attr.mls.lvl,
1219 					&level);
1220 	if (ret_val != 0)
1221 		return ret_val;
1222 
1223 	if (secattr->flags & NETLBL_SECATTR_MLS_CAT) {
1224 		ret_val = cipso_v4_map_cat_rbm_hton(doi_def,
1225 						    secattr,
1226 						    &buffer[4],
1227 						    buffer_len - 4);
1228 		if (ret_val < 0)
1229 			return ret_val;
1230 
1231 		/* This will send packets using the "optimized" format when
1232 		 * possibile as specified in  section 3.4.2.6 of the
1233 		 * CIPSO draft. */
1234 		if (cipso_v4_rbm_optfmt && ret_val > 0 && ret_val <= 10)
1235 			tag_len = 14;
1236 		else
1237 			tag_len = 4 + ret_val;
1238 	} else
1239 		tag_len = 4;
1240 
1241 	buffer[0] = 0x01;
1242 	buffer[1] = tag_len;
1243 	buffer[3] = level;
1244 
1245 	return tag_len;
1246 }
1247 
1248 /**
1249  * cipso_v4_parsetag_rbm - Parse a CIPSO restricted bitmap tag
1250  * @doi_def: the DOI definition
1251  * @tag: the CIPSO tag
1252  * @secattr: the security attributes
1253  *
1254  * Description:
1255  * Parse a CIPSO restricted bitmap tag (tag type #1) and return the security
1256  * attributes in @secattr.  Return zero on success, negatives values on
1257  * failure.
1258  *
1259  */
1260 static int cipso_v4_parsetag_rbm(const struct cipso_v4_doi *doi_def,
1261 				 const unsigned char *tag,
1262 				 struct netlbl_lsm_secattr *secattr)
1263 {
1264 	int ret_val;
1265 	u8 tag_len = tag[1];
1266 	u32 level;
1267 
1268 	ret_val = cipso_v4_map_lvl_ntoh(doi_def, tag[3], &level);
1269 	if (ret_val != 0)
1270 		return ret_val;
1271 	secattr->attr.mls.lvl = level;
1272 	secattr->flags |= NETLBL_SECATTR_MLS_LVL;
1273 
1274 	if (tag_len > 4) {
1275 		secattr->attr.mls.cat =
1276 		                       netlbl_secattr_catmap_alloc(GFP_ATOMIC);
1277 		if (secattr->attr.mls.cat == NULL)
1278 			return -ENOMEM;
1279 
1280 		ret_val = cipso_v4_map_cat_rbm_ntoh(doi_def,
1281 						    &tag[4],
1282 						    tag_len - 4,
1283 						    secattr);
1284 		if (ret_val != 0) {
1285 			netlbl_secattr_catmap_free(secattr->attr.mls.cat);
1286 			return ret_val;
1287 		}
1288 
1289 		secattr->flags |= NETLBL_SECATTR_MLS_CAT;
1290 	}
1291 
1292 	return 0;
1293 }
1294 
1295 /**
1296  * cipso_v4_gentag_enum - Generate a CIPSO enumerated tag (type #2)
1297  * @doi_def: the DOI definition
1298  * @secattr: the security attributes
1299  * @buffer: the option buffer
1300  * @buffer_len: length of buffer in bytes
1301  *
1302  * Description:
1303  * Generate a CIPSO option using the enumerated tag, tag type #2.  Returns the
1304  * size of the tag on success, negative values on failure.
1305  *
1306  */
1307 static int cipso_v4_gentag_enum(const struct cipso_v4_doi *doi_def,
1308 				const struct netlbl_lsm_secattr *secattr,
1309 				unsigned char *buffer,
1310 				u32 buffer_len)
1311 {
1312 	int ret_val;
1313 	u32 tag_len;
1314 	u32 level;
1315 
1316 	if (!(secattr->flags & NETLBL_SECATTR_MLS_LVL))
1317 		return -EPERM;
1318 
1319 	ret_val = cipso_v4_map_lvl_hton(doi_def,
1320 					secattr->attr.mls.lvl,
1321 					&level);
1322 	if (ret_val != 0)
1323 		return ret_val;
1324 
1325 	if (secattr->flags & NETLBL_SECATTR_MLS_CAT) {
1326 		ret_val = cipso_v4_map_cat_enum_hton(doi_def,
1327 						     secattr,
1328 						     &buffer[4],
1329 						     buffer_len - 4);
1330 		if (ret_val < 0)
1331 			return ret_val;
1332 
1333 		tag_len = 4 + ret_val;
1334 	} else
1335 		tag_len = 4;
1336 
1337 	buffer[0] = 0x02;
1338 	buffer[1] = tag_len;
1339 	buffer[3] = level;
1340 
1341 	return tag_len;
1342 }
1343 
1344 /**
1345  * cipso_v4_parsetag_enum - Parse a CIPSO enumerated tag
1346  * @doi_def: the DOI definition
1347  * @tag: the CIPSO tag
1348  * @secattr: the security attributes
1349  *
1350  * Description:
1351  * Parse a CIPSO enumerated tag (tag type #2) and return the security
1352  * attributes in @secattr.  Return zero on success, negatives values on
1353  * failure.
1354  *
1355  */
1356 static int cipso_v4_parsetag_enum(const struct cipso_v4_doi *doi_def,
1357 				  const unsigned char *tag,
1358 				  struct netlbl_lsm_secattr *secattr)
1359 {
1360 	int ret_val;
1361 	u8 tag_len = tag[1];
1362 	u32 level;
1363 
1364 	ret_val = cipso_v4_map_lvl_ntoh(doi_def, tag[3], &level);
1365 	if (ret_val != 0)
1366 		return ret_val;
1367 	secattr->attr.mls.lvl = level;
1368 	secattr->flags |= NETLBL_SECATTR_MLS_LVL;
1369 
1370 	if (tag_len > 4) {
1371 		secattr->attr.mls.cat =
1372 			               netlbl_secattr_catmap_alloc(GFP_ATOMIC);
1373 		if (secattr->attr.mls.cat == NULL)
1374 			return -ENOMEM;
1375 
1376 		ret_val = cipso_v4_map_cat_enum_ntoh(doi_def,
1377 						     &tag[4],
1378 						     tag_len - 4,
1379 						     secattr);
1380 		if (ret_val != 0) {
1381 			netlbl_secattr_catmap_free(secattr->attr.mls.cat);
1382 			return ret_val;
1383 		}
1384 
1385 		secattr->flags |= NETLBL_SECATTR_MLS_CAT;
1386 	}
1387 
1388 	return 0;
1389 }
1390 
1391 /**
1392  * cipso_v4_gentag_rng - Generate a CIPSO ranged tag (type #5)
1393  * @doi_def: the DOI definition
1394  * @secattr: the security attributes
1395  * @buffer: the option buffer
1396  * @buffer_len: length of buffer in bytes
1397  *
1398  * Description:
1399  * Generate a CIPSO option using the ranged tag, tag type #5.  Returns the
1400  * size of the tag on success, negative values on failure.
1401  *
1402  */
1403 static int cipso_v4_gentag_rng(const struct cipso_v4_doi *doi_def,
1404 			       const struct netlbl_lsm_secattr *secattr,
1405 			       unsigned char *buffer,
1406 			       u32 buffer_len)
1407 {
1408 	int ret_val;
1409 	u32 tag_len;
1410 	u32 level;
1411 
1412 	if (!(secattr->flags & NETLBL_SECATTR_MLS_LVL))
1413 		return -EPERM;
1414 
1415 	ret_val = cipso_v4_map_lvl_hton(doi_def,
1416 					secattr->attr.mls.lvl,
1417 					&level);
1418 	if (ret_val != 0)
1419 		return ret_val;
1420 
1421 	if (secattr->flags & NETLBL_SECATTR_MLS_CAT) {
1422 		ret_val = cipso_v4_map_cat_rng_hton(doi_def,
1423 						    secattr,
1424 						    &buffer[4],
1425 						    buffer_len - 4);
1426 		if (ret_val < 0)
1427 			return ret_val;
1428 
1429 		tag_len = 4 + ret_val;
1430 	} else
1431 		tag_len = 4;
1432 
1433 	buffer[0] = 0x05;
1434 	buffer[1] = tag_len;
1435 	buffer[3] = level;
1436 
1437 	return tag_len;
1438 }
1439 
1440 /**
1441  * cipso_v4_parsetag_rng - Parse a CIPSO ranged tag
1442  * @doi_def: the DOI definition
1443  * @tag: the CIPSO tag
1444  * @secattr: the security attributes
1445  *
1446  * Description:
1447  * Parse a CIPSO ranged tag (tag type #5) and return the security attributes
1448  * in @secattr.  Return zero on success, negatives values on failure.
1449  *
1450  */
1451 static int cipso_v4_parsetag_rng(const struct cipso_v4_doi *doi_def,
1452 				 const unsigned char *tag,
1453 				 struct netlbl_lsm_secattr *secattr)
1454 {
1455 	int ret_val;
1456 	u8 tag_len = tag[1];
1457 	u32 level;
1458 
1459 	ret_val = cipso_v4_map_lvl_ntoh(doi_def, tag[3], &level);
1460 	if (ret_val != 0)
1461 		return ret_val;
1462 	secattr->attr.mls.lvl = level;
1463 	secattr->flags |= NETLBL_SECATTR_MLS_LVL;
1464 
1465 	if (tag_len > 4) {
1466 		secattr->attr.mls.cat =
1467 			               netlbl_secattr_catmap_alloc(GFP_ATOMIC);
1468 		if (secattr->attr.mls.cat == NULL)
1469 			return -ENOMEM;
1470 
1471 		ret_val = cipso_v4_map_cat_rng_ntoh(doi_def,
1472 						    &tag[4],
1473 						    tag_len - 4,
1474 						    secattr);
1475 		if (ret_val != 0) {
1476 			netlbl_secattr_catmap_free(secattr->attr.mls.cat);
1477 			return ret_val;
1478 		}
1479 
1480 		secattr->flags |= NETLBL_SECATTR_MLS_CAT;
1481 	}
1482 
1483 	return 0;
1484 }
1485 
1486 /**
1487  * cipso_v4_validate - Validate a CIPSO option
1488  * @option: the start of the option, on error it is set to point to the error
1489  *
1490  * Description:
1491  * This routine is called to validate a CIPSO option, it checks all of the
1492  * fields to ensure that they are at least valid, see the draft snippet below
1493  * for details.  If the option is valid then a zero value is returned and
1494  * the value of @option is unchanged.  If the option is invalid then a
1495  * non-zero value is returned and @option is adjusted to point to the
1496  * offending portion of the option.  From the IETF draft ...
1497  *
1498  *  "If any field within the CIPSO options, such as the DOI identifier, is not
1499  *   recognized the IP datagram is discarded and an ICMP 'parameter problem'
1500  *   (type 12) is generated and returned.  The ICMP code field is set to 'bad
1501  *   parameter' (code 0) and the pointer is set to the start of the CIPSO field
1502  *   that is unrecognized."
1503  *
1504  */
1505 int cipso_v4_validate(unsigned char **option)
1506 {
1507 	unsigned char *opt = *option;
1508 	unsigned char *tag;
1509 	unsigned char opt_iter;
1510 	unsigned char err_offset = 0;
1511 	u8 opt_len;
1512 	u8 tag_len;
1513 	struct cipso_v4_doi *doi_def = NULL;
1514 	u32 tag_iter;
1515 
1516 	/* caller already checks for length values that are too large */
1517 	opt_len = opt[1];
1518 	if (opt_len < 8) {
1519 		err_offset = 1;
1520 		goto validate_return;
1521 	}
1522 
1523 	rcu_read_lock();
1524 	doi_def = cipso_v4_doi_search(get_unaligned_be32(&opt[2]));
1525 	if (doi_def == NULL) {
1526 		err_offset = 2;
1527 		goto validate_return_locked;
1528 	}
1529 
1530 	opt_iter = 6;
1531 	tag = opt + opt_iter;
1532 	while (opt_iter < opt_len) {
1533 		for (tag_iter = 0; doi_def->tags[tag_iter] != tag[0];)
1534 			if (doi_def->tags[tag_iter] == CIPSO_V4_TAG_INVALID ||
1535 			    ++tag_iter == CIPSO_V4_TAG_MAXCNT) {
1536 				err_offset = opt_iter;
1537 				goto validate_return_locked;
1538 			}
1539 
1540 		tag_len = tag[1];
1541 		if (tag_len > (opt_len - opt_iter)) {
1542 			err_offset = opt_iter + 1;
1543 			goto validate_return_locked;
1544 		}
1545 
1546 		switch (tag[0]) {
1547 		case CIPSO_V4_TAG_RBITMAP:
1548 			if (tag_len < 4) {
1549 				err_offset = opt_iter + 1;
1550 				goto validate_return_locked;
1551 			}
1552 
1553 			/* We are already going to do all the verification
1554 			 * necessary at the socket layer so from our point of
1555 			 * view it is safe to turn these checks off (and less
1556 			 * work), however, the CIPSO draft says we should do
1557 			 * all the CIPSO validations here but it doesn't
1558 			 * really specify _exactly_ what we need to validate
1559 			 * ... so, just make it a sysctl tunable. */
1560 			if (cipso_v4_rbm_strictvalid) {
1561 				if (cipso_v4_map_lvl_valid(doi_def,
1562 							   tag[3]) < 0) {
1563 					err_offset = opt_iter + 3;
1564 					goto validate_return_locked;
1565 				}
1566 				if (tag_len > 4 &&
1567 				    cipso_v4_map_cat_rbm_valid(doi_def,
1568 							    &tag[4],
1569 							    tag_len - 4) < 0) {
1570 					err_offset = opt_iter + 4;
1571 					goto validate_return_locked;
1572 				}
1573 			}
1574 			break;
1575 		case CIPSO_V4_TAG_ENUM:
1576 			if (tag_len < 4) {
1577 				err_offset = opt_iter + 1;
1578 				goto validate_return_locked;
1579 			}
1580 
1581 			if (cipso_v4_map_lvl_valid(doi_def,
1582 						   tag[3]) < 0) {
1583 				err_offset = opt_iter + 3;
1584 				goto validate_return_locked;
1585 			}
1586 			if (tag_len > 4 &&
1587 			    cipso_v4_map_cat_enum_valid(doi_def,
1588 							&tag[4],
1589 							tag_len - 4) < 0) {
1590 				err_offset = opt_iter + 4;
1591 				goto validate_return_locked;
1592 			}
1593 			break;
1594 		case CIPSO_V4_TAG_RANGE:
1595 			if (tag_len < 4) {
1596 				err_offset = opt_iter + 1;
1597 				goto validate_return_locked;
1598 			}
1599 
1600 			if (cipso_v4_map_lvl_valid(doi_def,
1601 						   tag[3]) < 0) {
1602 				err_offset = opt_iter + 3;
1603 				goto validate_return_locked;
1604 			}
1605 			if (tag_len > 4 &&
1606 			    cipso_v4_map_cat_rng_valid(doi_def,
1607 						       &tag[4],
1608 						       tag_len - 4) < 0) {
1609 				err_offset = opt_iter + 4;
1610 				goto validate_return_locked;
1611 			}
1612 			break;
1613 		default:
1614 			err_offset = opt_iter;
1615 			goto validate_return_locked;
1616 		}
1617 
1618 		tag += tag_len;
1619 		opt_iter += tag_len;
1620 	}
1621 
1622 validate_return_locked:
1623 	rcu_read_unlock();
1624 validate_return:
1625 	*option = opt + err_offset;
1626 	return err_offset;
1627 }
1628 
1629 /**
1630  * cipso_v4_error - Send the correct reponse for a bad packet
1631  * @skb: the packet
1632  * @error: the error code
1633  * @gateway: CIPSO gateway flag
1634  *
1635  * Description:
1636  * Based on the error code given in @error, send an ICMP error message back to
1637  * the originating host.  From the IETF draft ...
1638  *
1639  *  "If the contents of the CIPSO [option] are valid but the security label is
1640  *   outside of the configured host or port label range, the datagram is
1641  *   discarded and an ICMP 'destination unreachable' (type 3) is generated and
1642  *   returned.  The code field of the ICMP is set to 'communication with
1643  *   destination network administratively prohibited' (code 9) or to
1644  *   'communication with destination host administratively prohibited'
1645  *   (code 10).  The value of the code is dependent on whether the originator
1646  *   of the ICMP message is acting as a CIPSO host or a CIPSO gateway.  The
1647  *   recipient of the ICMP message MUST be able to handle either value.  The
1648  *   same procedure is performed if a CIPSO [option] can not be added to an
1649  *   IP packet because it is too large to fit in the IP options area."
1650  *
1651  *  "If the error is triggered by receipt of an ICMP message, the message is
1652  *   discarded and no response is permitted (consistent with general ICMP
1653  *   processing rules)."
1654  *
1655  */
1656 void cipso_v4_error(struct sk_buff *skb, int error, u32 gateway)
1657 {
1658 	if (ip_hdr(skb)->protocol == IPPROTO_ICMP || error != -EACCES)
1659 		return;
1660 
1661 	if (gateway)
1662 		icmp_send(skb, ICMP_DEST_UNREACH, ICMP_NET_ANO, 0);
1663 	else
1664 		icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_ANO, 0);
1665 }
1666 
1667 /**
1668  * cipso_v4_sock_setattr - Add a CIPSO option to a socket
1669  * @sk: the socket
1670  * @doi_def: the CIPSO DOI to use
1671  * @secattr: the specific security attributes of the socket
1672  *
1673  * Description:
1674  * Set the CIPSO option on the given socket using the DOI definition and
1675  * security attributes passed to the function.  This function requires
1676  * exclusive access to @sk, which means it either needs to be in the
1677  * process of being created or locked.  Returns zero on success and negative
1678  * values on failure.
1679  *
1680  */
1681 int cipso_v4_sock_setattr(struct sock *sk,
1682 			  const struct cipso_v4_doi *doi_def,
1683 			  const struct netlbl_lsm_secattr *secattr)
1684 {
1685 	int ret_val = -EPERM;
1686 	u32 iter;
1687 	unsigned char *buf;
1688 	u32 buf_len = 0;
1689 	u32 opt_len;
1690 	struct ip_options *opt = NULL;
1691 	struct inet_sock *sk_inet;
1692 	struct inet_connection_sock *sk_conn;
1693 
1694 	/* In the case of sock_create_lite(), the sock->sk field is not
1695 	 * defined yet but it is not a problem as the only users of these
1696 	 * "lite" PF_INET sockets are functions which do an accept() call
1697 	 * afterwards so we will label the socket as part of the accept(). */
1698 	if (sk == NULL)
1699 		return 0;
1700 
1701 	/* We allocate the maximum CIPSO option size here so we are probably
1702 	 * being a little wasteful, but it makes our life _much_ easier later
1703 	 * on and after all we are only talking about 40 bytes. */
1704 	buf_len = CIPSO_V4_OPT_LEN_MAX;
1705 	buf = kmalloc(buf_len, GFP_ATOMIC);
1706 	if (buf == NULL) {
1707 		ret_val = -ENOMEM;
1708 		goto socket_setattr_failure;
1709 	}
1710 
1711 	/* XXX - This code assumes only one tag per CIPSO option which isn't
1712 	 * really a good assumption to make but since we only support the MAC
1713 	 * tags right now it is a safe assumption. */
1714 	iter = 0;
1715 	do {
1716 		memset(buf, 0, buf_len);
1717 		switch (doi_def->tags[iter]) {
1718 		case CIPSO_V4_TAG_RBITMAP:
1719 			ret_val = cipso_v4_gentag_rbm(doi_def,
1720 						   secattr,
1721 						   &buf[CIPSO_V4_HDR_LEN],
1722 						   buf_len - CIPSO_V4_HDR_LEN);
1723 			break;
1724 		case CIPSO_V4_TAG_ENUM:
1725 			ret_val = cipso_v4_gentag_enum(doi_def,
1726 						   secattr,
1727 						   &buf[CIPSO_V4_HDR_LEN],
1728 						   buf_len - CIPSO_V4_HDR_LEN);
1729 			break;
1730 		case CIPSO_V4_TAG_RANGE:
1731 			ret_val = cipso_v4_gentag_rng(doi_def,
1732 						   secattr,
1733 						   &buf[CIPSO_V4_HDR_LEN],
1734 						   buf_len - CIPSO_V4_HDR_LEN);
1735 			break;
1736 		default:
1737 			ret_val = -EPERM;
1738 			goto socket_setattr_failure;
1739 		}
1740 
1741 		iter++;
1742 	} while (ret_val < 0 &&
1743 		 iter < CIPSO_V4_TAG_MAXCNT &&
1744 		 doi_def->tags[iter] != CIPSO_V4_TAG_INVALID);
1745 	if (ret_val < 0)
1746 		goto socket_setattr_failure;
1747 	cipso_v4_gentag_hdr(doi_def, buf, ret_val);
1748 	buf_len = CIPSO_V4_HDR_LEN + ret_val;
1749 
1750 	/* We can't use ip_options_get() directly because it makes a call to
1751 	 * ip_options_get_alloc() which allocates memory with GFP_KERNEL and
1752 	 * we won't always have CAP_NET_RAW even though we _always_ want to
1753 	 * set the IPOPT_CIPSO option. */
1754 	opt_len = (buf_len + 3) & ~3;
1755 	opt = kzalloc(sizeof(*opt) + opt_len, GFP_ATOMIC);
1756 	if (opt == NULL) {
1757 		ret_val = -ENOMEM;
1758 		goto socket_setattr_failure;
1759 	}
1760 	memcpy(opt->__data, buf, buf_len);
1761 	opt->optlen = opt_len;
1762 	opt->cipso = sizeof(struct iphdr);
1763 	kfree(buf);
1764 	buf = NULL;
1765 
1766 	sk_inet = inet_sk(sk);
1767 	if (sk_inet->is_icsk) {
1768 		sk_conn = inet_csk(sk);
1769 		if (sk_inet->opt)
1770 			sk_conn->icsk_ext_hdr_len -= sk_inet->opt->optlen;
1771 		sk_conn->icsk_ext_hdr_len += opt->optlen;
1772 		sk_conn->icsk_sync_mss(sk, sk_conn->icsk_pmtu_cookie);
1773 	}
1774 	opt = xchg(&sk_inet->opt, opt);
1775 	kfree(opt);
1776 
1777 	return 0;
1778 
1779 socket_setattr_failure:
1780 	kfree(buf);
1781 	kfree(opt);
1782 	return ret_val;
1783 }
1784 
1785 /**
1786  * cipso_v4_getattr - Helper function for the cipso_v4_*_getattr functions
1787  * @cipso: the CIPSO v4 option
1788  * @secattr: the security attributes
1789  *
1790  * Description:
1791  * Inspect @cipso and return the security attributes in @secattr.  Returns zero
1792  * on success and negative values on failure.
1793  *
1794  */
1795 static int cipso_v4_getattr(const unsigned char *cipso,
1796 			    struct netlbl_lsm_secattr *secattr)
1797 {
1798 	int ret_val = -ENOMSG;
1799 	u32 doi;
1800 	struct cipso_v4_doi *doi_def;
1801 
1802 	if (cipso_v4_cache_check(cipso, cipso[1], secattr) == 0)
1803 		return 0;
1804 
1805 	doi = get_unaligned_be32(&cipso[2]);
1806 	rcu_read_lock();
1807 	doi_def = cipso_v4_doi_search(doi);
1808 	if (doi_def == NULL)
1809 		goto getattr_return;
1810 	/* XXX - This code assumes only one tag per CIPSO option which isn't
1811 	 * really a good assumption to make but since we only support the MAC
1812 	 * tags right now it is a safe assumption. */
1813 	switch (cipso[6]) {
1814 	case CIPSO_V4_TAG_RBITMAP:
1815 		ret_val = cipso_v4_parsetag_rbm(doi_def, &cipso[6], secattr);
1816 		break;
1817 	case CIPSO_V4_TAG_ENUM:
1818 		ret_val = cipso_v4_parsetag_enum(doi_def, &cipso[6], secattr);
1819 		break;
1820 	case CIPSO_V4_TAG_RANGE:
1821 		ret_val = cipso_v4_parsetag_rng(doi_def, &cipso[6], secattr);
1822 		break;
1823 	}
1824 	if (ret_val == 0)
1825 		secattr->type = NETLBL_NLTYPE_CIPSOV4;
1826 
1827 getattr_return:
1828 	rcu_read_unlock();
1829 	return ret_val;
1830 }
1831 
1832 /**
1833  * cipso_v4_sock_getattr - Get the security attributes from a sock
1834  * @sk: the sock
1835  * @secattr: the security attributes
1836  *
1837  * Description:
1838  * Query @sk to see if there is a CIPSO option attached to the sock and if
1839  * there is return the CIPSO security attributes in @secattr.  This function
1840  * requires that @sk be locked, or privately held, but it does not do any
1841  * locking itself.  Returns zero on success and negative values on failure.
1842  *
1843  */
1844 int cipso_v4_sock_getattr(struct sock *sk, struct netlbl_lsm_secattr *secattr)
1845 {
1846 	struct ip_options *opt;
1847 
1848 	opt = inet_sk(sk)->opt;
1849 	if (opt == NULL || opt->cipso == 0)
1850 		return -ENOMSG;
1851 
1852 	return cipso_v4_getattr(opt->__data + opt->cipso - sizeof(struct iphdr),
1853 				secattr);
1854 }
1855 
1856 /**
1857  * cipso_v4_skbuff_getattr - Get the security attributes from the CIPSO option
1858  * @skb: the packet
1859  * @secattr: the security attributes
1860  *
1861  * Description:
1862  * Parse the given packet's CIPSO option and return the security attributes.
1863  * Returns zero on success and negative values on failure.
1864  *
1865  */
1866 int cipso_v4_skbuff_getattr(const struct sk_buff *skb,
1867 			    struct netlbl_lsm_secattr *secattr)
1868 {
1869 	return cipso_v4_getattr(CIPSO_V4_OPTPTR(skb), secattr);
1870 }
1871 
1872 /*
1873  * Setup Functions
1874  */
1875 
1876 /**
1877  * cipso_v4_init - Initialize the CIPSO module
1878  *
1879  * Description:
1880  * Initialize the CIPSO module and prepare it for use.  Returns zero on success
1881  * and negative values on failure.
1882  *
1883  */
1884 static int __init cipso_v4_init(void)
1885 {
1886 	int ret_val;
1887 
1888 	ret_val = cipso_v4_cache_init();
1889 	if (ret_val != 0)
1890 		panic("Failed to initialize the CIPSO/IPv4 cache (%d)\n",
1891 		      ret_val);
1892 
1893 	return 0;
1894 }
1895 
1896 subsys_initcall(cipso_v4_init);
1897