GNU Linux-libre 4.4.296-gnu1
[releases.git] / net / ipv4 / cipso_ipv4.c
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.  While CIPSO never became a full IETF RFC standard many vendors
7  * have chosen to adopt the protocol and over the years it has become a
8  * de-facto standard for labeled networking.
9  *
10  * The CIPSO draft specification can be found in the kernel's Documentation
11  * directory as well as the following URL:
12  *   http://tools.ietf.org/id/draft-ietf-cipso-ipsecurity-01.txt
13  * The FIPS-188 specification can be found at the following URL:
14  *   http://www.itl.nist.gov/fipspubs/fip188.htm
15  *
16  * Author: Paul Moore <paul.moore@hp.com>
17  *
18  */
19
20 /*
21  * (c) Copyright Hewlett-Packard Development Company, L.P., 2006, 2008
22  *
23  * This program is free software;  you can redistribute it and/or modify
24  * it under the terms of the GNU General Public License as published by
25  * the Free Software Foundation; either version 2 of the License, or
26  * (at your option) any later version.
27  *
28  * This program is distributed in the hope that it will be useful,
29  * but WITHOUT ANY WARRANTY;  without even the implied warranty of
30  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
31  * the GNU General Public License for more details.
32  *
33  * You should have received a copy of the GNU General Public License
34  * along with this program;  if not, see <http://www.gnu.org/licenses/>.
35  *
36  */
37
38 #include <linux/init.h>
39 #include <linux/types.h>
40 #include <linux/rcupdate.h>
41 #include <linux/list.h>
42 #include <linux/spinlock.h>
43 #include <linux/string.h>
44 #include <linux/jhash.h>
45 #include <linux/audit.h>
46 #include <linux/slab.h>
47 #include <net/ip.h>
48 #include <net/icmp.h>
49 #include <net/tcp.h>
50 #include <net/netlabel.h>
51 #include <net/cipso_ipv4.h>
52 #include <linux/atomic.h>
53 #include <linux/bug.h>
54 #include <asm/unaligned.h>
55
56 /* List of available DOI definitions */
57 /* XXX - This currently assumes a minimal number of different DOIs in use,
58  * if in practice there are a lot of different DOIs this list should
59  * probably be turned into a hash table or something similar so we
60  * can do quick lookups. */
61 static DEFINE_SPINLOCK(cipso_v4_doi_list_lock);
62 static LIST_HEAD(cipso_v4_doi_list);
63
64 /* Label mapping cache */
65 int cipso_v4_cache_enabled = 1;
66 int cipso_v4_cache_bucketsize = 10;
67 #define CIPSO_V4_CACHE_BUCKETBITS     7
68 #define CIPSO_V4_CACHE_BUCKETS        (1 << CIPSO_V4_CACHE_BUCKETBITS)
69 #define CIPSO_V4_CACHE_REORDERLIMIT   10
70 struct cipso_v4_map_cache_bkt {
71         spinlock_t lock;
72         u32 size;
73         struct list_head list;
74 };
75
76 struct cipso_v4_map_cache_entry {
77         u32 hash;
78         unsigned char *key;
79         size_t key_len;
80
81         struct netlbl_lsm_cache *lsm_data;
82
83         u32 activity;
84         struct list_head list;
85 };
86
87 static struct cipso_v4_map_cache_bkt *cipso_v4_cache;
88
89 /* Restricted bitmap (tag #1) flags */
90 int cipso_v4_rbm_optfmt = 0;
91 int cipso_v4_rbm_strictvalid = 1;
92
93 /*
94  * Protocol Constants
95  */
96
97 /* Maximum size of the CIPSO IP option, derived from the fact that the maximum
98  * IPv4 header size is 60 bytes and the base IPv4 header is 20 bytes long. */
99 #define CIPSO_V4_OPT_LEN_MAX          40
100
101 /* Length of the base CIPSO option, this includes the option type (1 byte), the
102  * option length (1 byte), and the DOI (4 bytes). */
103 #define CIPSO_V4_HDR_LEN              6
104
105 /* Base length of the restrictive category bitmap tag (tag #1). */
106 #define CIPSO_V4_TAG_RBM_BLEN         4
107
108 /* Base length of the enumerated category tag (tag #2). */
109 #define CIPSO_V4_TAG_ENUM_BLEN        4
110
111 /* Base length of the ranged categories bitmap tag (tag #5). */
112 #define CIPSO_V4_TAG_RNG_BLEN         4
113 /* The maximum number of category ranges permitted in the ranged category tag
114  * (tag #5).  You may note that the IETF draft states that the maximum number
115  * of category ranges is 7, but if the low end of the last category range is
116  * zero then it is possible to fit 8 category ranges because the zero should
117  * be omitted. */
118 #define CIPSO_V4_TAG_RNG_CAT_MAX      8
119
120 /* Base length of the local tag (non-standard tag).
121  *  Tag definition (may change between kernel versions)
122  *
123  * 0          8          16         24         32
124  * +----------+----------+----------+----------+
125  * | 10000000 | 00000110 | 32-bit secid value  |
126  * +----------+----------+----------+----------+
127  * | in (host byte order)|
128  * +----------+----------+
129  *
130  */
131 #define CIPSO_V4_TAG_LOC_BLEN         6
132
133 /*
134  * Helper Functions
135  */
136
137 /**
138  * cipso_v4_bitmap_walk - Walk a bitmap looking for a bit
139  * @bitmap: the bitmap
140  * @bitmap_len: length in bits
141  * @offset: starting offset
142  * @state: if non-zero, look for a set (1) bit else look for a cleared (0) bit
143  *
144  * Description:
145  * Starting at @offset, walk the bitmap from left to right until either the
146  * desired bit is found or we reach the end.  Return the bit offset, -1 if
147  * not found, or -2 if error.
148  */
149 static int cipso_v4_bitmap_walk(const unsigned char *bitmap,
150                                 u32 bitmap_len,
151                                 u32 offset,
152                                 u8 state)
153 {
154         u32 bit_spot;
155         u32 byte_offset;
156         unsigned char bitmask;
157         unsigned char byte;
158
159         /* gcc always rounds to zero when doing integer division */
160         byte_offset = offset / 8;
161         byte = bitmap[byte_offset];
162         bit_spot = offset;
163         bitmask = 0x80 >> (offset % 8);
164
165         while (bit_spot < bitmap_len) {
166                 if ((state && (byte & bitmask) == bitmask) ||
167                     (state == 0 && (byte & bitmask) == 0))
168                         return bit_spot;
169
170                 if (++bit_spot >= bitmap_len)
171                         return -1;
172                 bitmask >>= 1;
173                 if (bitmask == 0) {
174                         byte = bitmap[++byte_offset];
175                         bitmask = 0x80;
176                 }
177         }
178
179         return -1;
180 }
181
182 /**
183  * cipso_v4_bitmap_setbit - Sets a single bit in a bitmap
184  * @bitmap: the bitmap
185  * @bit: the bit
186  * @state: if non-zero, set the bit (1) else clear the bit (0)
187  *
188  * Description:
189  * Set a single bit in the bitmask.  Returns zero on success, negative values
190  * on error.
191  */
192 static void cipso_v4_bitmap_setbit(unsigned char *bitmap,
193                                    u32 bit,
194                                    u8 state)
195 {
196         u32 byte_spot;
197         u8 bitmask;
198
199         /* gcc always rounds to zero when doing integer division */
200         byte_spot = bit / 8;
201         bitmask = 0x80 >> (bit % 8);
202         if (state)
203                 bitmap[byte_spot] |= bitmask;
204         else
205                 bitmap[byte_spot] &= ~bitmask;
206 }
207
208 /**
209  * cipso_v4_cache_entry_free - Frees a cache entry
210  * @entry: the entry to free
211  *
212  * Description:
213  * This function frees the memory associated with a cache entry including the
214  * LSM cache data if there are no longer any users, i.e. reference count == 0.
215  *
216  */
217 static void cipso_v4_cache_entry_free(struct cipso_v4_map_cache_entry *entry)
218 {
219         if (entry->lsm_data)
220                 netlbl_secattr_cache_free(entry->lsm_data);
221         kfree(entry->key);
222         kfree(entry);
223 }
224
225 /**
226  * cipso_v4_map_cache_hash - Hashing function for the CIPSO cache
227  * @key: the hash key
228  * @key_len: the length of the key in bytes
229  *
230  * Description:
231  * The CIPSO tag hashing function.  Returns a 32-bit hash value.
232  *
233  */
234 static u32 cipso_v4_map_cache_hash(const unsigned char *key, u32 key_len)
235 {
236         return jhash(key, key_len, 0);
237 }
238
239 /*
240  * Label Mapping Cache Functions
241  */
242
243 /**
244  * cipso_v4_cache_init - Initialize the CIPSO cache
245  *
246  * Description:
247  * Initializes the CIPSO label mapping cache, this function should be called
248  * before any of the other functions defined in this file.  Returns zero on
249  * success, negative values on error.
250  *
251  */
252 static int __init cipso_v4_cache_init(void)
253 {
254         u32 iter;
255
256         cipso_v4_cache = kcalloc(CIPSO_V4_CACHE_BUCKETS,
257                                  sizeof(struct cipso_v4_map_cache_bkt),
258                                  GFP_KERNEL);
259         if (!cipso_v4_cache)
260                 return -ENOMEM;
261
262         for (iter = 0; iter < CIPSO_V4_CACHE_BUCKETS; iter++) {
263                 spin_lock_init(&cipso_v4_cache[iter].lock);
264                 cipso_v4_cache[iter].size = 0;
265                 INIT_LIST_HEAD(&cipso_v4_cache[iter].list);
266         }
267
268         return 0;
269 }
270
271 /**
272  * cipso_v4_cache_invalidate - Invalidates the current CIPSO cache
273  *
274  * Description:
275  * Invalidates and frees any entries in the CIPSO cache.  Returns zero on
276  * success and negative values on failure.
277  *
278  */
279 void cipso_v4_cache_invalidate(void)
280 {
281         struct cipso_v4_map_cache_entry *entry, *tmp_entry;
282         u32 iter;
283
284         for (iter = 0; iter < CIPSO_V4_CACHE_BUCKETS; iter++) {
285                 spin_lock_bh(&cipso_v4_cache[iter].lock);
286                 list_for_each_entry_safe(entry,
287                                          tmp_entry,
288                                          &cipso_v4_cache[iter].list, list) {
289                         list_del(&entry->list);
290                         cipso_v4_cache_entry_free(entry);
291                 }
292                 cipso_v4_cache[iter].size = 0;
293                 spin_unlock_bh(&cipso_v4_cache[iter].lock);
294         }
295 }
296
297 /**
298  * cipso_v4_cache_check - Check the CIPSO cache for a label mapping
299  * @key: the buffer to check
300  * @key_len: buffer length in bytes
301  * @secattr: the security attribute struct to use
302  *
303  * Description:
304  * This function checks the cache to see if a label mapping already exists for
305  * the given key.  If there is a match then the cache is adjusted and the
306  * @secattr struct is populated with the correct LSM security attributes.  The
307  * cache is adjusted in the following manner if the entry is not already the
308  * first in the cache bucket:
309  *
310  *  1. The cache entry's activity counter is incremented
311  *  2. The previous (higher ranking) entry's activity counter is decremented
312  *  3. If the difference between the two activity counters is geater than
313  *     CIPSO_V4_CACHE_REORDERLIMIT the two entries are swapped
314  *
315  * Returns zero on success, -ENOENT for a cache miss, and other negative values
316  * on error.
317  *
318  */
319 static int cipso_v4_cache_check(const unsigned char *key,
320                                 u32 key_len,
321                                 struct netlbl_lsm_secattr *secattr)
322 {
323         u32 bkt;
324         struct cipso_v4_map_cache_entry *entry;
325         struct cipso_v4_map_cache_entry *prev_entry = NULL;
326         u32 hash;
327
328         if (!cipso_v4_cache_enabled)
329                 return -ENOENT;
330
331         hash = cipso_v4_map_cache_hash(key, key_len);
332         bkt = hash & (CIPSO_V4_CACHE_BUCKETS - 1);
333         spin_lock_bh(&cipso_v4_cache[bkt].lock);
334         list_for_each_entry(entry, &cipso_v4_cache[bkt].list, list) {
335                 if (entry->hash == hash &&
336                     entry->key_len == key_len &&
337                     memcmp(entry->key, key, key_len) == 0) {
338                         entry->activity += 1;
339                         atomic_inc(&entry->lsm_data->refcount);
340                         secattr->cache = entry->lsm_data;
341                         secattr->flags |= NETLBL_SECATTR_CACHE;
342                         secattr->type = NETLBL_NLTYPE_CIPSOV4;
343                         if (!prev_entry) {
344                                 spin_unlock_bh(&cipso_v4_cache[bkt].lock);
345                                 return 0;
346                         }
347
348                         if (prev_entry->activity > 0)
349                                 prev_entry->activity -= 1;
350                         if (entry->activity > prev_entry->activity &&
351                             entry->activity - prev_entry->activity >
352                             CIPSO_V4_CACHE_REORDERLIMIT) {
353                                 __list_del(entry->list.prev, entry->list.next);
354                                 __list_add(&entry->list,
355                                            prev_entry->list.prev,
356                                            &prev_entry->list);
357                         }
358
359                         spin_unlock_bh(&cipso_v4_cache[bkt].lock);
360                         return 0;
361                 }
362                 prev_entry = entry;
363         }
364         spin_unlock_bh(&cipso_v4_cache[bkt].lock);
365
366         return -ENOENT;
367 }
368
369 /**
370  * cipso_v4_cache_add - Add an entry to the CIPSO cache
371  * @skb: the packet
372  * @secattr: the packet's security attributes
373  *
374  * Description:
375  * Add a new entry into the CIPSO label mapping cache.  Add the new entry to
376  * head of the cache bucket's list, if the cache bucket is out of room remove
377  * the last entry in the list first.  It is important to note that there is
378  * currently no checking for duplicate keys.  Returns zero on success,
379  * negative values on failure.
380  *
381  */
382 int cipso_v4_cache_add(const unsigned char *cipso_ptr,
383                        const struct netlbl_lsm_secattr *secattr)
384 {
385         int ret_val = -EPERM;
386         u32 bkt;
387         struct cipso_v4_map_cache_entry *entry = NULL;
388         struct cipso_v4_map_cache_entry *old_entry = NULL;
389         u32 cipso_ptr_len;
390
391         if (!cipso_v4_cache_enabled || cipso_v4_cache_bucketsize <= 0)
392                 return 0;
393
394         cipso_ptr_len = cipso_ptr[1];
395
396         entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
397         if (!entry)
398                 return -ENOMEM;
399         entry->key = kmemdup(cipso_ptr, cipso_ptr_len, GFP_ATOMIC);
400         if (!entry->key) {
401                 ret_val = -ENOMEM;
402                 goto cache_add_failure;
403         }
404         entry->key_len = cipso_ptr_len;
405         entry->hash = cipso_v4_map_cache_hash(cipso_ptr, cipso_ptr_len);
406         atomic_inc(&secattr->cache->refcount);
407         entry->lsm_data = secattr->cache;
408
409         bkt = entry->hash & (CIPSO_V4_CACHE_BUCKETS - 1);
410         spin_lock_bh(&cipso_v4_cache[bkt].lock);
411         if (cipso_v4_cache[bkt].size < cipso_v4_cache_bucketsize) {
412                 list_add(&entry->list, &cipso_v4_cache[bkt].list);
413                 cipso_v4_cache[bkt].size += 1;
414         } else {
415                 old_entry = list_entry(cipso_v4_cache[bkt].list.prev,
416                                        struct cipso_v4_map_cache_entry, list);
417                 list_del(&old_entry->list);
418                 list_add(&entry->list, &cipso_v4_cache[bkt].list);
419                 cipso_v4_cache_entry_free(old_entry);
420         }
421         spin_unlock_bh(&cipso_v4_cache[bkt].lock);
422
423         return 0;
424
425 cache_add_failure:
426         if (entry)
427                 cipso_v4_cache_entry_free(entry);
428         return ret_val;
429 }
430
431 /*
432  * DOI List Functions
433  */
434
435 /**
436  * cipso_v4_doi_search - Searches for a DOI definition
437  * @doi: the DOI to search for
438  *
439  * Description:
440  * Search the DOI definition list for a DOI definition with a DOI value that
441  * matches @doi.  The caller is responsible for calling rcu_read_[un]lock().
442  * Returns a pointer to the DOI definition on success and NULL on failure.
443  */
444 static struct cipso_v4_doi *cipso_v4_doi_search(u32 doi)
445 {
446         struct cipso_v4_doi *iter;
447
448         list_for_each_entry_rcu(iter, &cipso_v4_doi_list, list)
449                 if (iter->doi == doi && atomic_read(&iter->refcount))
450                         return iter;
451         return NULL;
452 }
453
454 /**
455  * cipso_v4_doi_add - Add a new DOI to the CIPSO protocol engine
456  * @doi_def: the DOI structure
457  * @audit_info: NetLabel audit information
458  *
459  * Description:
460  * The caller defines a new DOI for use by the CIPSO engine and calls this
461  * function to add it to the list of acceptable domains.  The caller must
462  * ensure that the mapping table specified in @doi_def->map meets all of the
463  * requirements of the mapping type (see cipso_ipv4.h for details).  Returns
464  * zero on success and non-zero on failure.
465  *
466  */
467 int cipso_v4_doi_add(struct cipso_v4_doi *doi_def,
468                      struct netlbl_audit *audit_info)
469 {
470         int ret_val = -EINVAL;
471         u32 iter;
472         u32 doi;
473         u32 doi_type;
474         struct audit_buffer *audit_buf;
475
476         doi = doi_def->doi;
477         doi_type = doi_def->type;
478
479         if (doi_def->doi == CIPSO_V4_DOI_UNKNOWN)
480                 goto doi_add_return;
481         for (iter = 0; iter < CIPSO_V4_TAG_MAXCNT; iter++) {
482                 switch (doi_def->tags[iter]) {
483                 case CIPSO_V4_TAG_RBITMAP:
484                         break;
485                 case CIPSO_V4_TAG_RANGE:
486                 case CIPSO_V4_TAG_ENUM:
487                         if (doi_def->type != CIPSO_V4_MAP_PASS)
488                                 goto doi_add_return;
489                         break;
490                 case CIPSO_V4_TAG_LOCAL:
491                         if (doi_def->type != CIPSO_V4_MAP_LOCAL)
492                                 goto doi_add_return;
493                         break;
494                 case CIPSO_V4_TAG_INVALID:
495                         if (iter == 0)
496                                 goto doi_add_return;
497                         break;
498                 default:
499                         goto doi_add_return;
500                 }
501         }
502
503         atomic_set(&doi_def->refcount, 1);
504
505         spin_lock(&cipso_v4_doi_list_lock);
506         if (cipso_v4_doi_search(doi_def->doi)) {
507                 spin_unlock(&cipso_v4_doi_list_lock);
508                 ret_val = -EEXIST;
509                 goto doi_add_return;
510         }
511         list_add_tail_rcu(&doi_def->list, &cipso_v4_doi_list);
512         spin_unlock(&cipso_v4_doi_list_lock);
513         ret_val = 0;
514
515 doi_add_return:
516         audit_buf = netlbl_audit_start(AUDIT_MAC_CIPSOV4_ADD, audit_info);
517         if (audit_buf) {
518                 const char *type_str;
519                 switch (doi_type) {
520                 case CIPSO_V4_MAP_TRANS:
521                         type_str = "trans";
522                         break;
523                 case CIPSO_V4_MAP_PASS:
524                         type_str = "pass";
525                         break;
526                 case CIPSO_V4_MAP_LOCAL:
527                         type_str = "local";
528                         break;
529                 default:
530                         type_str = "(unknown)";
531                 }
532                 audit_log_format(audit_buf,
533                                  " cipso_doi=%u cipso_type=%s res=%u",
534                                  doi, type_str, ret_val == 0 ? 1 : 0);
535                 audit_log_end(audit_buf);
536         }
537
538         return ret_val;
539 }
540
541 /**
542  * cipso_v4_doi_free - Frees a DOI definition
543  * @doi_def: the DOI definition
544  *
545  * Description:
546  * This function frees all of the memory associated with a DOI definition.
547  *
548  */
549 void cipso_v4_doi_free(struct cipso_v4_doi *doi_def)
550 {
551         if (!doi_def)
552                 return;
553
554         switch (doi_def->type) {
555         case CIPSO_V4_MAP_TRANS:
556                 kfree(doi_def->map.std->lvl.cipso);
557                 kfree(doi_def->map.std->lvl.local);
558                 kfree(doi_def->map.std->cat.cipso);
559                 kfree(doi_def->map.std->cat.local);
560                 kfree(doi_def->map.std);
561                 break;
562         }
563         kfree(doi_def);
564 }
565
566 /**
567  * cipso_v4_doi_free_rcu - Frees a DOI definition via the RCU pointer
568  * @entry: the entry's RCU field
569  *
570  * Description:
571  * This function is designed to be used as a callback to the call_rcu()
572  * function so that the memory allocated to the DOI definition can be released
573  * safely.
574  *
575  */
576 static void cipso_v4_doi_free_rcu(struct rcu_head *entry)
577 {
578         struct cipso_v4_doi *doi_def;
579
580         doi_def = container_of(entry, struct cipso_v4_doi, rcu);
581         cipso_v4_doi_free(doi_def);
582 }
583
584 /**
585  * cipso_v4_doi_remove - Remove an existing DOI from the CIPSO protocol engine
586  * @doi: the DOI value
587  * @audit_secid: the LSM secid to use in the audit message
588  *
589  * Description:
590  * Removes a DOI definition from the CIPSO engine.  The NetLabel routines will
591  * be called to release their own LSM domain mappings as well as our own
592  * domain list.  Returns zero on success and negative values on failure.
593  *
594  */
595 int cipso_v4_doi_remove(u32 doi, struct netlbl_audit *audit_info)
596 {
597         int ret_val;
598         struct cipso_v4_doi *doi_def;
599         struct audit_buffer *audit_buf;
600
601         spin_lock(&cipso_v4_doi_list_lock);
602         doi_def = cipso_v4_doi_search(doi);
603         if (!doi_def) {
604                 spin_unlock(&cipso_v4_doi_list_lock);
605                 ret_val = -ENOENT;
606                 goto doi_remove_return;
607         }
608         if (!atomic_dec_and_test(&doi_def->refcount)) {
609                 spin_unlock(&cipso_v4_doi_list_lock);
610                 ret_val = -EBUSY;
611                 goto doi_remove_return;
612         }
613         list_del_rcu(&doi_def->list);
614         spin_unlock(&cipso_v4_doi_list_lock);
615
616         cipso_v4_cache_invalidate();
617         call_rcu(&doi_def->rcu, cipso_v4_doi_free_rcu);
618         ret_val = 0;
619
620 doi_remove_return:
621         audit_buf = netlbl_audit_start(AUDIT_MAC_CIPSOV4_DEL, audit_info);
622         if (audit_buf) {
623                 audit_log_format(audit_buf,
624                                  " cipso_doi=%u res=%u",
625                                  doi, ret_val == 0 ? 1 : 0);
626                 audit_log_end(audit_buf);
627         }
628
629         return ret_val;
630 }
631
632 /**
633  * cipso_v4_doi_getdef - Returns a reference to a valid DOI definition
634  * @doi: the DOI value
635  *
636  * Description:
637  * Searches for a valid DOI definition and if one is found it is returned to
638  * the caller.  Otherwise NULL is returned.  The caller must ensure that
639  * rcu_read_lock() is held while accessing the returned definition and the DOI
640  * definition reference count is decremented when the caller is done.
641  *
642  */
643 struct cipso_v4_doi *cipso_v4_doi_getdef(u32 doi)
644 {
645         struct cipso_v4_doi *doi_def;
646
647         rcu_read_lock();
648         doi_def = cipso_v4_doi_search(doi);
649         if (!doi_def)
650                 goto doi_getdef_return;
651         if (!atomic_inc_not_zero(&doi_def->refcount))
652                 doi_def = NULL;
653
654 doi_getdef_return:
655         rcu_read_unlock();
656         return doi_def;
657 }
658
659 /**
660  * cipso_v4_doi_putdef - Releases a reference for the given DOI definition
661  * @doi_def: the DOI definition
662  *
663  * Description:
664  * Releases a DOI definition reference obtained from cipso_v4_doi_getdef().
665  *
666  */
667 void cipso_v4_doi_putdef(struct cipso_v4_doi *doi_def)
668 {
669         if (!doi_def)
670                 return;
671
672         if (!atomic_dec_and_test(&doi_def->refcount))
673                 return;
674         spin_lock(&cipso_v4_doi_list_lock);
675         list_del_rcu(&doi_def->list);
676         spin_unlock(&cipso_v4_doi_list_lock);
677
678         cipso_v4_cache_invalidate();
679         call_rcu(&doi_def->rcu, cipso_v4_doi_free_rcu);
680 }
681
682 /**
683  * cipso_v4_doi_walk - Iterate through the DOI definitions
684  * @skip_cnt: skip past this number of DOI definitions, updated
685  * @callback: callback for each DOI definition
686  * @cb_arg: argument for the callback function
687  *
688  * Description:
689  * Iterate over the DOI definition list, skipping the first @skip_cnt entries.
690  * For each entry call @callback, if @callback returns a negative value stop
691  * 'walking' through the list and return.  Updates the value in @skip_cnt upon
692  * return.  Returns zero on success, negative values on failure.
693  *
694  */
695 int cipso_v4_doi_walk(u32 *skip_cnt,
696                      int (*callback) (struct cipso_v4_doi *doi_def, void *arg),
697                      void *cb_arg)
698 {
699         int ret_val = -ENOENT;
700         u32 doi_cnt = 0;
701         struct cipso_v4_doi *iter_doi;
702
703         rcu_read_lock();
704         list_for_each_entry_rcu(iter_doi, &cipso_v4_doi_list, list)
705                 if (atomic_read(&iter_doi->refcount) > 0) {
706                         if (doi_cnt++ < *skip_cnt)
707                                 continue;
708                         ret_val = callback(iter_doi, cb_arg);
709                         if (ret_val < 0) {
710                                 doi_cnt--;
711                                 goto doi_walk_return;
712                         }
713                 }
714
715 doi_walk_return:
716         rcu_read_unlock();
717         *skip_cnt = doi_cnt;
718         return ret_val;
719 }
720
721 /*
722  * Label Mapping Functions
723  */
724
725 /**
726  * cipso_v4_map_lvl_valid - Checks to see if the given level is understood
727  * @doi_def: the DOI definition
728  * @level: the level to check
729  *
730  * Description:
731  * Checks the given level against the given DOI definition and returns a
732  * negative value if the level does not have a valid mapping and a zero value
733  * if the level is defined by the DOI.
734  *
735  */
736 static int cipso_v4_map_lvl_valid(const struct cipso_v4_doi *doi_def, u8 level)
737 {
738         switch (doi_def->type) {
739         case CIPSO_V4_MAP_PASS:
740                 return 0;
741         case CIPSO_V4_MAP_TRANS:
742                 if ((level < doi_def->map.std->lvl.cipso_size) &&
743                     (doi_def->map.std->lvl.cipso[level] < CIPSO_V4_INV_LVL))
744                         return 0;
745                 break;
746         }
747
748         return -EFAULT;
749 }
750
751 /**
752  * cipso_v4_map_lvl_hton - Perform a level mapping from the host to the network
753  * @doi_def: the DOI definition
754  * @host_lvl: the host MLS level
755  * @net_lvl: the network/CIPSO MLS level
756  *
757  * Description:
758  * Perform a label mapping to translate a local MLS level to the correct
759  * CIPSO level using the given DOI definition.  Returns zero on success,
760  * negative values otherwise.
761  *
762  */
763 static int cipso_v4_map_lvl_hton(const struct cipso_v4_doi *doi_def,
764                                  u32 host_lvl,
765                                  u32 *net_lvl)
766 {
767         switch (doi_def->type) {
768         case CIPSO_V4_MAP_PASS:
769                 *net_lvl = host_lvl;
770                 return 0;
771         case CIPSO_V4_MAP_TRANS:
772                 if (host_lvl < doi_def->map.std->lvl.local_size &&
773                     doi_def->map.std->lvl.local[host_lvl] < CIPSO_V4_INV_LVL) {
774                         *net_lvl = doi_def->map.std->lvl.local[host_lvl];
775                         return 0;
776                 }
777                 return -EPERM;
778         }
779
780         return -EINVAL;
781 }
782
783 /**
784  * cipso_v4_map_lvl_ntoh - Perform a level mapping from the network to the host
785  * @doi_def: the DOI definition
786  * @net_lvl: the network/CIPSO MLS level
787  * @host_lvl: the host MLS level
788  *
789  * Description:
790  * Perform a label mapping to translate a CIPSO level to the correct local MLS
791  * level using the given DOI definition.  Returns zero on success, negative
792  * values otherwise.
793  *
794  */
795 static int cipso_v4_map_lvl_ntoh(const struct cipso_v4_doi *doi_def,
796                                  u32 net_lvl,
797                                  u32 *host_lvl)
798 {
799         struct cipso_v4_std_map_tbl *map_tbl;
800
801         switch (doi_def->type) {
802         case CIPSO_V4_MAP_PASS:
803                 *host_lvl = net_lvl;
804                 return 0;
805         case CIPSO_V4_MAP_TRANS:
806                 map_tbl = doi_def->map.std;
807                 if (net_lvl < map_tbl->lvl.cipso_size &&
808                     map_tbl->lvl.cipso[net_lvl] < CIPSO_V4_INV_LVL) {
809                         *host_lvl = doi_def->map.std->lvl.cipso[net_lvl];
810                         return 0;
811                 }
812                 return -EPERM;
813         }
814
815         return -EINVAL;
816 }
817
818 /**
819  * cipso_v4_map_cat_rbm_valid - Checks to see if the category bitmap is valid
820  * @doi_def: the DOI definition
821  * @bitmap: category bitmap
822  * @bitmap_len: bitmap length in bytes
823  *
824  * Description:
825  * Checks the given category bitmap against the given DOI definition and
826  * returns a negative value if any of the categories in the bitmap do not have
827  * a valid mapping and a zero value if all of the categories are valid.
828  *
829  */
830 static int cipso_v4_map_cat_rbm_valid(const struct cipso_v4_doi *doi_def,
831                                       const unsigned char *bitmap,
832                                       u32 bitmap_len)
833 {
834         int cat = -1;
835         u32 bitmap_len_bits = bitmap_len * 8;
836         u32 cipso_cat_size;
837         u32 *cipso_array;
838
839         switch (doi_def->type) {
840         case CIPSO_V4_MAP_PASS:
841                 return 0;
842         case CIPSO_V4_MAP_TRANS:
843                 cipso_cat_size = doi_def->map.std->cat.cipso_size;
844                 cipso_array = doi_def->map.std->cat.cipso;
845                 for (;;) {
846                         cat = cipso_v4_bitmap_walk(bitmap,
847                                                    bitmap_len_bits,
848                                                    cat + 1,
849                                                    1);
850                         if (cat < 0)
851                                 break;
852                         if (cat >= cipso_cat_size ||
853                             cipso_array[cat] >= CIPSO_V4_INV_CAT)
854                                 return -EFAULT;
855                 }
856
857                 if (cat == -1)
858                         return 0;
859                 break;
860         }
861
862         return -EFAULT;
863 }
864
865 /**
866  * cipso_v4_map_cat_rbm_hton - Perform a category mapping from host to network
867  * @doi_def: the DOI definition
868  * @secattr: the security attributes
869  * @net_cat: the zero'd out category bitmap in network/CIPSO format
870  * @net_cat_len: the length of the CIPSO bitmap in bytes
871  *
872  * Description:
873  * Perform a label mapping to translate a local MLS category bitmap to the
874  * correct CIPSO bitmap using the given DOI definition.  Returns the minimum
875  * size in bytes of the network bitmap on success, negative values otherwise.
876  *
877  */
878 static int cipso_v4_map_cat_rbm_hton(const struct cipso_v4_doi *doi_def,
879                                      const struct netlbl_lsm_secattr *secattr,
880                                      unsigned char *net_cat,
881                                      u32 net_cat_len)
882 {
883         int host_spot = -1;
884         u32 net_spot = CIPSO_V4_INV_CAT;
885         u32 net_spot_max = 0;
886         u32 net_clen_bits = net_cat_len * 8;
887         u32 host_cat_size = 0;
888         u32 *host_cat_array = NULL;
889
890         if (doi_def->type == CIPSO_V4_MAP_TRANS) {
891                 host_cat_size = doi_def->map.std->cat.local_size;
892                 host_cat_array = doi_def->map.std->cat.local;
893         }
894
895         for (;;) {
896                 host_spot = netlbl_catmap_walk(secattr->attr.mls.cat,
897                                                host_spot + 1);
898                 if (host_spot < 0)
899                         break;
900
901                 switch (doi_def->type) {
902                 case CIPSO_V4_MAP_PASS:
903                         net_spot = host_spot;
904                         break;
905                 case CIPSO_V4_MAP_TRANS:
906                         if (host_spot >= host_cat_size)
907                                 return -EPERM;
908                         net_spot = host_cat_array[host_spot];
909                         if (net_spot >= CIPSO_V4_INV_CAT)
910                                 return -EPERM;
911                         break;
912                 }
913                 if (net_spot >= net_clen_bits)
914                         return -ENOSPC;
915                 cipso_v4_bitmap_setbit(net_cat, net_spot, 1);
916
917                 if (net_spot > net_spot_max)
918                         net_spot_max = net_spot;
919         }
920
921         if (++net_spot_max % 8)
922                 return net_spot_max / 8 + 1;
923         return net_spot_max / 8;
924 }
925
926 /**
927  * cipso_v4_map_cat_rbm_ntoh - Perform a category mapping from network to host
928  * @doi_def: the DOI definition
929  * @net_cat: the category bitmap in network/CIPSO format
930  * @net_cat_len: the length of the CIPSO bitmap in bytes
931  * @secattr: the security attributes
932  *
933  * Description:
934  * Perform a label mapping to translate a CIPSO bitmap to the correct local
935  * MLS category bitmap using the given DOI definition.  Returns zero on
936  * success, negative values on failure.
937  *
938  */
939 static int cipso_v4_map_cat_rbm_ntoh(const struct cipso_v4_doi *doi_def,
940                                      const unsigned char *net_cat,
941                                      u32 net_cat_len,
942                                      struct netlbl_lsm_secattr *secattr)
943 {
944         int ret_val;
945         int net_spot = -1;
946         u32 host_spot = CIPSO_V4_INV_CAT;
947         u32 net_clen_bits = net_cat_len * 8;
948         u32 net_cat_size = 0;
949         u32 *net_cat_array = NULL;
950
951         if (doi_def->type == CIPSO_V4_MAP_TRANS) {
952                 net_cat_size = doi_def->map.std->cat.cipso_size;
953                 net_cat_array = doi_def->map.std->cat.cipso;
954         }
955
956         for (;;) {
957                 net_spot = cipso_v4_bitmap_walk(net_cat,
958                                                 net_clen_bits,
959                                                 net_spot + 1,
960                                                 1);
961                 if (net_spot < 0) {
962                         if (net_spot == -2)
963                                 return -EFAULT;
964                         return 0;
965                 }
966
967                 switch (doi_def->type) {
968                 case CIPSO_V4_MAP_PASS:
969                         host_spot = net_spot;
970                         break;
971                 case CIPSO_V4_MAP_TRANS:
972                         if (net_spot >= net_cat_size)
973                                 return -EPERM;
974                         host_spot = net_cat_array[net_spot];
975                         if (host_spot >= CIPSO_V4_INV_CAT)
976                                 return -EPERM;
977                         break;
978                 }
979                 ret_val = netlbl_catmap_setbit(&secattr->attr.mls.cat,
980                                                        host_spot,
981                                                        GFP_ATOMIC);
982                 if (ret_val != 0)
983                         return ret_val;
984         }
985
986         return -EINVAL;
987 }
988
989 /**
990  * cipso_v4_map_cat_enum_valid - Checks to see if the categories are valid
991  * @doi_def: the DOI definition
992  * @enumcat: category list
993  * @enumcat_len: length of the category list in bytes
994  *
995  * Description:
996  * Checks the given categories against the given DOI definition and returns a
997  * negative value if any of the categories do not have a valid mapping and a
998  * zero value if all of the categories are valid.
999  *
1000  */
1001 static int cipso_v4_map_cat_enum_valid(const struct cipso_v4_doi *doi_def,
1002                                        const unsigned char *enumcat,
1003                                        u32 enumcat_len)
1004 {
1005         u16 cat;
1006         int cat_prev = -1;
1007         u32 iter;
1008
1009         if (doi_def->type != CIPSO_V4_MAP_PASS || enumcat_len & 0x01)
1010                 return -EFAULT;
1011
1012         for (iter = 0; iter < enumcat_len; iter += 2) {
1013                 cat = get_unaligned_be16(&enumcat[iter]);
1014                 if (cat <= cat_prev)
1015                         return -EFAULT;
1016                 cat_prev = cat;
1017         }
1018
1019         return 0;
1020 }
1021
1022 /**
1023  * cipso_v4_map_cat_enum_hton - Perform a category mapping from host to network
1024  * @doi_def: the DOI definition
1025  * @secattr: the security attributes
1026  * @net_cat: the zero'd out category list in network/CIPSO format
1027  * @net_cat_len: the length of the CIPSO category list in bytes
1028  *
1029  * Description:
1030  * Perform a label mapping to translate a local MLS category bitmap to the
1031  * correct CIPSO category list using the given DOI definition.   Returns the
1032  * size in bytes of the network category bitmap on success, negative values
1033  * otherwise.
1034  *
1035  */
1036 static int cipso_v4_map_cat_enum_hton(const struct cipso_v4_doi *doi_def,
1037                                       const struct netlbl_lsm_secattr *secattr,
1038                                       unsigned char *net_cat,
1039                                       u32 net_cat_len)
1040 {
1041         int cat = -1;
1042         u32 cat_iter = 0;
1043
1044         for (;;) {
1045                 cat = netlbl_catmap_walk(secattr->attr.mls.cat, cat + 1);
1046                 if (cat < 0)
1047                         break;
1048                 if ((cat_iter + 2) > net_cat_len)
1049                         return -ENOSPC;
1050
1051                 *((__be16 *)&net_cat[cat_iter]) = htons(cat);
1052                 cat_iter += 2;
1053         }
1054
1055         return cat_iter;
1056 }
1057
1058 /**
1059  * cipso_v4_map_cat_enum_ntoh - Perform a category mapping from network to host
1060  * @doi_def: the DOI definition
1061  * @net_cat: the category list in network/CIPSO format
1062  * @net_cat_len: the length of the CIPSO bitmap in bytes
1063  * @secattr: the security attributes
1064  *
1065  * Description:
1066  * Perform a label mapping to translate a CIPSO category list to the correct
1067  * local MLS category bitmap using the given DOI definition.  Returns zero on
1068  * success, negative values on failure.
1069  *
1070  */
1071 static int cipso_v4_map_cat_enum_ntoh(const struct cipso_v4_doi *doi_def,
1072                                       const unsigned char *net_cat,
1073                                       u32 net_cat_len,
1074                                       struct netlbl_lsm_secattr *secattr)
1075 {
1076         int ret_val;
1077         u32 iter;
1078
1079         for (iter = 0; iter < net_cat_len; iter += 2) {
1080                 ret_val = netlbl_catmap_setbit(&secattr->attr.mls.cat,
1081                                              get_unaligned_be16(&net_cat[iter]),
1082                                              GFP_ATOMIC);
1083                 if (ret_val != 0)
1084                         return ret_val;
1085         }
1086
1087         return 0;
1088 }
1089
1090 /**
1091  * cipso_v4_map_cat_rng_valid - Checks to see if the categories are valid
1092  * @doi_def: the DOI definition
1093  * @rngcat: category list
1094  * @rngcat_len: length of the category list in bytes
1095  *
1096  * Description:
1097  * Checks the given categories against the given DOI definition and returns a
1098  * negative value if any of the categories do not have a valid mapping and a
1099  * zero value if all of the categories are valid.
1100  *
1101  */
1102 static int cipso_v4_map_cat_rng_valid(const struct cipso_v4_doi *doi_def,
1103                                       const unsigned char *rngcat,
1104                                       u32 rngcat_len)
1105 {
1106         u16 cat_high;
1107         u16 cat_low;
1108         u32 cat_prev = CIPSO_V4_MAX_REM_CATS + 1;
1109         u32 iter;
1110
1111         if (doi_def->type != CIPSO_V4_MAP_PASS || rngcat_len & 0x01)
1112                 return -EFAULT;
1113
1114         for (iter = 0; iter < rngcat_len; iter += 4) {
1115                 cat_high = get_unaligned_be16(&rngcat[iter]);
1116                 if ((iter + 4) <= rngcat_len)
1117                         cat_low = get_unaligned_be16(&rngcat[iter + 2]);
1118                 else
1119                         cat_low = 0;
1120
1121                 if (cat_high > cat_prev)
1122                         return -EFAULT;
1123
1124                 cat_prev = cat_low;
1125         }
1126
1127         return 0;
1128 }
1129
1130 /**
1131  * cipso_v4_map_cat_rng_hton - Perform a category mapping from host to network
1132  * @doi_def: the DOI definition
1133  * @secattr: the security attributes
1134  * @net_cat: the zero'd out category list in network/CIPSO format
1135  * @net_cat_len: the length of the CIPSO category list in bytes
1136  *
1137  * Description:
1138  * Perform a label mapping to translate a local MLS category bitmap to the
1139  * correct CIPSO category list using the given DOI definition.   Returns the
1140  * size in bytes of the network category bitmap on success, negative values
1141  * otherwise.
1142  *
1143  */
1144 static int cipso_v4_map_cat_rng_hton(const struct cipso_v4_doi *doi_def,
1145                                      const struct netlbl_lsm_secattr *secattr,
1146                                      unsigned char *net_cat,
1147                                      u32 net_cat_len)
1148 {
1149         int iter = -1;
1150         u16 array[CIPSO_V4_TAG_RNG_CAT_MAX * 2];
1151         u32 array_cnt = 0;
1152         u32 cat_size = 0;
1153
1154         /* make sure we don't overflow the 'array[]' variable */
1155         if (net_cat_len >
1156             (CIPSO_V4_OPT_LEN_MAX - CIPSO_V4_HDR_LEN - CIPSO_V4_TAG_RNG_BLEN))
1157                 return -ENOSPC;
1158
1159         for (;;) {
1160                 iter = netlbl_catmap_walk(secattr->attr.mls.cat, iter + 1);
1161                 if (iter < 0)
1162                         break;
1163                 cat_size += (iter == 0 ? 0 : sizeof(u16));
1164                 if (cat_size > net_cat_len)
1165                         return -ENOSPC;
1166                 array[array_cnt++] = iter;
1167
1168                 iter = netlbl_catmap_walkrng(secattr->attr.mls.cat, iter);
1169                 if (iter < 0)
1170                         return -EFAULT;
1171                 cat_size += sizeof(u16);
1172                 if (cat_size > net_cat_len)
1173                         return -ENOSPC;
1174                 array[array_cnt++] = iter;
1175         }
1176
1177         for (iter = 0; array_cnt > 0;) {
1178                 *((__be16 *)&net_cat[iter]) = htons(array[--array_cnt]);
1179                 iter += 2;
1180                 array_cnt--;
1181                 if (array[array_cnt] != 0) {
1182                         *((__be16 *)&net_cat[iter]) = htons(array[array_cnt]);
1183                         iter += 2;
1184                 }
1185         }
1186
1187         return cat_size;
1188 }
1189
1190 /**
1191  * cipso_v4_map_cat_rng_ntoh - Perform a category mapping from network to host
1192  * @doi_def: the DOI definition
1193  * @net_cat: the category list in network/CIPSO format
1194  * @net_cat_len: the length of the CIPSO bitmap in bytes
1195  * @secattr: the security attributes
1196  *
1197  * Description:
1198  * Perform a label mapping to translate a CIPSO category list to the correct
1199  * local MLS category bitmap using the given DOI definition.  Returns zero on
1200  * success, negative values on failure.
1201  *
1202  */
1203 static int cipso_v4_map_cat_rng_ntoh(const struct cipso_v4_doi *doi_def,
1204                                      const unsigned char *net_cat,
1205                                      u32 net_cat_len,
1206                                      struct netlbl_lsm_secattr *secattr)
1207 {
1208         int ret_val;
1209         u32 net_iter;
1210         u16 cat_low;
1211         u16 cat_high;
1212
1213         for (net_iter = 0; net_iter < net_cat_len; net_iter += 4) {
1214                 cat_high = get_unaligned_be16(&net_cat[net_iter]);
1215                 if ((net_iter + 4) <= net_cat_len)
1216                         cat_low = get_unaligned_be16(&net_cat[net_iter + 2]);
1217                 else
1218                         cat_low = 0;
1219
1220                 ret_val = netlbl_catmap_setrng(&secattr->attr.mls.cat,
1221                                                cat_low,
1222                                                cat_high,
1223                                                GFP_ATOMIC);
1224                 if (ret_val != 0)
1225                         return ret_val;
1226         }
1227
1228         return 0;
1229 }
1230
1231 /*
1232  * Protocol Handling Functions
1233  */
1234
1235 /**
1236  * cipso_v4_gentag_hdr - Generate a CIPSO option header
1237  * @doi_def: the DOI definition
1238  * @len: the total tag length in bytes, not including this header
1239  * @buf: the CIPSO option buffer
1240  *
1241  * Description:
1242  * Write a CIPSO header into the beginning of @buffer.
1243  *
1244  */
1245 static void cipso_v4_gentag_hdr(const struct cipso_v4_doi *doi_def,
1246                                 unsigned char *buf,
1247                                 u32 len)
1248 {
1249         buf[0] = IPOPT_CIPSO;
1250         buf[1] = CIPSO_V4_HDR_LEN + len;
1251         *(__be32 *)&buf[2] = htonl(doi_def->doi);
1252 }
1253
1254 /**
1255  * cipso_v4_gentag_rbm - Generate a CIPSO restricted bitmap tag (type #1)
1256  * @doi_def: the DOI definition
1257  * @secattr: the security attributes
1258  * @buffer: the option buffer
1259  * @buffer_len: length of buffer in bytes
1260  *
1261  * Description:
1262  * Generate a CIPSO option using the restricted bitmap tag, tag type #1.  The
1263  * actual buffer length may be larger than the indicated size due to
1264  * translation between host and network category bitmaps.  Returns the size of
1265  * the tag on success, negative values on failure.
1266  *
1267  */
1268 static int cipso_v4_gentag_rbm(const struct cipso_v4_doi *doi_def,
1269                                const struct netlbl_lsm_secattr *secattr,
1270                                unsigned char *buffer,
1271                                u32 buffer_len)
1272 {
1273         int ret_val;
1274         u32 tag_len;
1275         u32 level;
1276
1277         if ((secattr->flags & NETLBL_SECATTR_MLS_LVL) == 0)
1278                 return -EPERM;
1279
1280         ret_val = cipso_v4_map_lvl_hton(doi_def,
1281                                         secattr->attr.mls.lvl,
1282                                         &level);
1283         if (ret_val != 0)
1284                 return ret_val;
1285
1286         if (secattr->flags & NETLBL_SECATTR_MLS_CAT) {
1287                 ret_val = cipso_v4_map_cat_rbm_hton(doi_def,
1288                                                     secattr,
1289                                                     &buffer[4],
1290                                                     buffer_len - 4);
1291                 if (ret_val < 0)
1292                         return ret_val;
1293
1294                 /* This will send packets using the "optimized" format when
1295                  * possible as specified in  section 3.4.2.6 of the
1296                  * CIPSO draft. */
1297                 if (cipso_v4_rbm_optfmt && ret_val > 0 && ret_val <= 10)
1298                         tag_len = 14;
1299                 else
1300                         tag_len = 4 + ret_val;
1301         } else
1302                 tag_len = 4;
1303
1304         buffer[0] = CIPSO_V4_TAG_RBITMAP;
1305         buffer[1] = tag_len;
1306         buffer[3] = level;
1307
1308         return tag_len;
1309 }
1310
1311 /**
1312  * cipso_v4_parsetag_rbm - Parse a CIPSO restricted bitmap tag
1313  * @doi_def: the DOI definition
1314  * @tag: the CIPSO tag
1315  * @secattr: the security attributes
1316  *
1317  * Description:
1318  * Parse a CIPSO restricted bitmap tag (tag type #1) and return the security
1319  * attributes in @secattr.  Return zero on success, negatives values on
1320  * failure.
1321  *
1322  */
1323 static int cipso_v4_parsetag_rbm(const struct cipso_v4_doi *doi_def,
1324                                  const unsigned char *tag,
1325                                  struct netlbl_lsm_secattr *secattr)
1326 {
1327         int ret_val;
1328         u8 tag_len = tag[1];
1329         u32 level;
1330
1331         ret_val = cipso_v4_map_lvl_ntoh(doi_def, tag[3], &level);
1332         if (ret_val != 0)
1333                 return ret_val;
1334         secattr->attr.mls.lvl = level;
1335         secattr->flags |= NETLBL_SECATTR_MLS_LVL;
1336
1337         if (tag_len > 4) {
1338                 ret_val = cipso_v4_map_cat_rbm_ntoh(doi_def,
1339                                                     &tag[4],
1340                                                     tag_len - 4,
1341                                                     secattr);
1342                 if (ret_val != 0) {
1343                         netlbl_catmap_free(secattr->attr.mls.cat);
1344                         return ret_val;
1345                 }
1346
1347                 if (secattr->attr.mls.cat)
1348                         secattr->flags |= NETLBL_SECATTR_MLS_CAT;
1349         }
1350
1351         return 0;
1352 }
1353
1354 /**
1355  * cipso_v4_gentag_enum - Generate a CIPSO enumerated tag (type #2)
1356  * @doi_def: the DOI definition
1357  * @secattr: the security attributes
1358  * @buffer: the option buffer
1359  * @buffer_len: length of buffer in bytes
1360  *
1361  * Description:
1362  * Generate a CIPSO option using the enumerated tag, tag type #2.  Returns the
1363  * size of the tag on success, negative values on failure.
1364  *
1365  */
1366 static int cipso_v4_gentag_enum(const struct cipso_v4_doi *doi_def,
1367                                 const struct netlbl_lsm_secattr *secattr,
1368                                 unsigned char *buffer,
1369                                 u32 buffer_len)
1370 {
1371         int ret_val;
1372         u32 tag_len;
1373         u32 level;
1374
1375         if (!(secattr->flags & NETLBL_SECATTR_MLS_LVL))
1376                 return -EPERM;
1377
1378         ret_val = cipso_v4_map_lvl_hton(doi_def,
1379                                         secattr->attr.mls.lvl,
1380                                         &level);
1381         if (ret_val != 0)
1382                 return ret_val;
1383
1384         if (secattr->flags & NETLBL_SECATTR_MLS_CAT) {
1385                 ret_val = cipso_v4_map_cat_enum_hton(doi_def,
1386                                                      secattr,
1387                                                      &buffer[4],
1388                                                      buffer_len - 4);
1389                 if (ret_val < 0)
1390                         return ret_val;
1391
1392                 tag_len = 4 + ret_val;
1393         } else
1394                 tag_len = 4;
1395
1396         buffer[0] = CIPSO_V4_TAG_ENUM;
1397         buffer[1] = tag_len;
1398         buffer[3] = level;
1399
1400         return tag_len;
1401 }
1402
1403 /**
1404  * cipso_v4_parsetag_enum - Parse a CIPSO enumerated tag
1405  * @doi_def: the DOI definition
1406  * @tag: the CIPSO tag
1407  * @secattr: the security attributes
1408  *
1409  * Description:
1410  * Parse a CIPSO enumerated tag (tag type #2) and return the security
1411  * attributes in @secattr.  Return zero on success, negatives values on
1412  * failure.
1413  *
1414  */
1415 static int cipso_v4_parsetag_enum(const struct cipso_v4_doi *doi_def,
1416                                   const unsigned char *tag,
1417                                   struct netlbl_lsm_secattr *secattr)
1418 {
1419         int ret_val;
1420         u8 tag_len = tag[1];
1421         u32 level;
1422
1423         ret_val = cipso_v4_map_lvl_ntoh(doi_def, tag[3], &level);
1424         if (ret_val != 0)
1425                 return ret_val;
1426         secattr->attr.mls.lvl = level;
1427         secattr->flags |= NETLBL_SECATTR_MLS_LVL;
1428
1429         if (tag_len > 4) {
1430                 ret_val = cipso_v4_map_cat_enum_ntoh(doi_def,
1431                                                      &tag[4],
1432                                                      tag_len - 4,
1433                                                      secattr);
1434                 if (ret_val != 0) {
1435                         netlbl_catmap_free(secattr->attr.mls.cat);
1436                         return ret_val;
1437                 }
1438
1439                 secattr->flags |= NETLBL_SECATTR_MLS_CAT;
1440         }
1441
1442         return 0;
1443 }
1444
1445 /**
1446  * cipso_v4_gentag_rng - Generate a CIPSO ranged tag (type #5)
1447  * @doi_def: the DOI definition
1448  * @secattr: the security attributes
1449  * @buffer: the option buffer
1450  * @buffer_len: length of buffer in bytes
1451  *
1452  * Description:
1453  * Generate a CIPSO option using the ranged tag, tag type #5.  Returns the
1454  * size of the tag on success, negative values on failure.
1455  *
1456  */
1457 static int cipso_v4_gentag_rng(const struct cipso_v4_doi *doi_def,
1458                                const struct netlbl_lsm_secattr *secattr,
1459                                unsigned char *buffer,
1460                                u32 buffer_len)
1461 {
1462         int ret_val;
1463         u32 tag_len;
1464         u32 level;
1465
1466         if (!(secattr->flags & NETLBL_SECATTR_MLS_LVL))
1467                 return -EPERM;
1468
1469         ret_val = cipso_v4_map_lvl_hton(doi_def,
1470                                         secattr->attr.mls.lvl,
1471                                         &level);
1472         if (ret_val != 0)
1473                 return ret_val;
1474
1475         if (secattr->flags & NETLBL_SECATTR_MLS_CAT) {
1476                 ret_val = cipso_v4_map_cat_rng_hton(doi_def,
1477                                                     secattr,
1478                                                     &buffer[4],
1479                                                     buffer_len - 4);
1480                 if (ret_val < 0)
1481                         return ret_val;
1482
1483                 tag_len = 4 + ret_val;
1484         } else
1485                 tag_len = 4;
1486
1487         buffer[0] = CIPSO_V4_TAG_RANGE;
1488         buffer[1] = tag_len;
1489         buffer[3] = level;
1490
1491         return tag_len;
1492 }
1493
1494 /**
1495  * cipso_v4_parsetag_rng - Parse a CIPSO ranged tag
1496  * @doi_def: the DOI definition
1497  * @tag: the CIPSO tag
1498  * @secattr: the security attributes
1499  *
1500  * Description:
1501  * Parse a CIPSO ranged tag (tag type #5) and return the security attributes
1502  * in @secattr.  Return zero on success, negatives values on failure.
1503  *
1504  */
1505 static int cipso_v4_parsetag_rng(const struct cipso_v4_doi *doi_def,
1506                                  const unsigned char *tag,
1507                                  struct netlbl_lsm_secattr *secattr)
1508 {
1509         int ret_val;
1510         u8 tag_len = tag[1];
1511         u32 level;
1512
1513         ret_val = cipso_v4_map_lvl_ntoh(doi_def, tag[3], &level);
1514         if (ret_val != 0)
1515                 return ret_val;
1516         secattr->attr.mls.lvl = level;
1517         secattr->flags |= NETLBL_SECATTR_MLS_LVL;
1518
1519         if (tag_len > 4) {
1520                 ret_val = cipso_v4_map_cat_rng_ntoh(doi_def,
1521                                                     &tag[4],
1522                                                     tag_len - 4,
1523                                                     secattr);
1524                 if (ret_val != 0) {
1525                         netlbl_catmap_free(secattr->attr.mls.cat);
1526                         return ret_val;
1527                 }
1528
1529                 if (secattr->attr.mls.cat)
1530                         secattr->flags |= NETLBL_SECATTR_MLS_CAT;
1531         }
1532
1533         return 0;
1534 }
1535
1536 /**
1537  * cipso_v4_gentag_loc - Generate a CIPSO local tag (non-standard)
1538  * @doi_def: the DOI definition
1539  * @secattr: the security attributes
1540  * @buffer: the option buffer
1541  * @buffer_len: length of buffer in bytes
1542  *
1543  * Description:
1544  * Generate a CIPSO option using the local tag.  Returns the size of the tag
1545  * on success, negative values on failure.
1546  *
1547  */
1548 static int cipso_v4_gentag_loc(const struct cipso_v4_doi *doi_def,
1549                                const struct netlbl_lsm_secattr *secattr,
1550                                unsigned char *buffer,
1551                                u32 buffer_len)
1552 {
1553         if (!(secattr->flags & NETLBL_SECATTR_SECID))
1554                 return -EPERM;
1555
1556         buffer[0] = CIPSO_V4_TAG_LOCAL;
1557         buffer[1] = CIPSO_V4_TAG_LOC_BLEN;
1558         *(u32 *)&buffer[2] = secattr->attr.secid;
1559
1560         return CIPSO_V4_TAG_LOC_BLEN;
1561 }
1562
1563 /**
1564  * cipso_v4_parsetag_loc - Parse a CIPSO local tag
1565  * @doi_def: the DOI definition
1566  * @tag: the CIPSO tag
1567  * @secattr: the security attributes
1568  *
1569  * Description:
1570  * Parse a CIPSO local tag and return the security attributes in @secattr.
1571  * Return zero on success, negatives values on failure.
1572  *
1573  */
1574 static int cipso_v4_parsetag_loc(const struct cipso_v4_doi *doi_def,
1575                                  const unsigned char *tag,
1576                                  struct netlbl_lsm_secattr *secattr)
1577 {
1578         secattr->attr.secid = *(u32 *)&tag[2];
1579         secattr->flags |= NETLBL_SECATTR_SECID;
1580
1581         return 0;
1582 }
1583
1584 /**
1585  * cipso_v4_optptr - Find the CIPSO option in the packet
1586  * @skb: the packet
1587  *
1588  * Description:
1589  * Parse the packet's IP header looking for a CIPSO option.  Returns a pointer
1590  * to the start of the CIPSO option on success, NULL if one is not found.
1591  *
1592  */
1593 unsigned char *cipso_v4_optptr(const struct sk_buff *skb)
1594 {
1595         const struct iphdr *iph = ip_hdr(skb);
1596         unsigned char *optptr = (unsigned char *)&(ip_hdr(skb)[1]);
1597         int optlen;
1598         int taglen;
1599
1600         for (optlen = iph->ihl*4 - sizeof(struct iphdr); optlen > 1; ) {
1601                 switch (optptr[0]) {
1602                 case IPOPT_END:
1603                         return NULL;
1604                 case IPOPT_NOOP:
1605                         taglen = 1;
1606                         break;
1607                 default:
1608                         taglen = optptr[1];
1609                 }
1610                 if (!taglen || taglen > optlen)
1611                         return NULL;
1612                 if (optptr[0] == IPOPT_CIPSO)
1613                         return optptr;
1614
1615                 optlen -= taglen;
1616                 optptr += taglen;
1617         }
1618
1619         return NULL;
1620 }
1621
1622 /**
1623  * cipso_v4_validate - Validate a CIPSO option
1624  * @option: the start of the option, on error it is set to point to the error
1625  *
1626  * Description:
1627  * This routine is called to validate a CIPSO option, it checks all of the
1628  * fields to ensure that they are at least valid, see the draft snippet below
1629  * for details.  If the option is valid then a zero value is returned and
1630  * the value of @option is unchanged.  If the option is invalid then a
1631  * non-zero value is returned and @option is adjusted to point to the
1632  * offending portion of the option.  From the IETF draft ...
1633  *
1634  *  "If any field within the CIPSO options, such as the DOI identifier, is not
1635  *   recognized the IP datagram is discarded and an ICMP 'parameter problem'
1636  *   (type 12) is generated and returned.  The ICMP code field is set to 'bad
1637  *   parameter' (code 0) and the pointer is set to the start of the CIPSO field
1638  *   that is unrecognized."
1639  *
1640  */
1641 int cipso_v4_validate(const struct sk_buff *skb, unsigned char **option)
1642 {
1643         unsigned char *opt = *option;
1644         unsigned char *tag;
1645         unsigned char opt_iter;
1646         unsigned char err_offset = 0;
1647         u8 opt_len;
1648         u8 tag_len;
1649         struct cipso_v4_doi *doi_def = NULL;
1650         u32 tag_iter;
1651
1652         /* caller already checks for length values that are too large */
1653         opt_len = opt[1];
1654         if (opt_len < 8) {
1655                 err_offset = 1;
1656                 goto validate_return;
1657         }
1658
1659         rcu_read_lock();
1660         doi_def = cipso_v4_doi_search(get_unaligned_be32(&opt[2]));
1661         if (!doi_def) {
1662                 err_offset = 2;
1663                 goto validate_return_locked;
1664         }
1665
1666         opt_iter = CIPSO_V4_HDR_LEN;
1667         tag = opt + opt_iter;
1668         while (opt_iter < opt_len) {
1669                 for (tag_iter = 0; doi_def->tags[tag_iter] != tag[0];)
1670                         if (doi_def->tags[tag_iter] == CIPSO_V4_TAG_INVALID ||
1671                             ++tag_iter == CIPSO_V4_TAG_MAXCNT) {
1672                                 err_offset = opt_iter;
1673                                 goto validate_return_locked;
1674                         }
1675
1676                 if (opt_iter + 1 == opt_len) {
1677                         err_offset = opt_iter;
1678                         goto validate_return_locked;
1679                 }
1680                 tag_len = tag[1];
1681                 if (tag_len > (opt_len - opt_iter)) {
1682                         err_offset = opt_iter + 1;
1683                         goto validate_return_locked;
1684                 }
1685
1686                 switch (tag[0]) {
1687                 case CIPSO_V4_TAG_RBITMAP:
1688                         if (tag_len < CIPSO_V4_TAG_RBM_BLEN) {
1689                                 err_offset = opt_iter + 1;
1690                                 goto validate_return_locked;
1691                         }
1692
1693                         /* We are already going to do all the verification
1694                          * necessary at the socket layer so from our point of
1695                          * view it is safe to turn these checks off (and less
1696                          * work), however, the CIPSO draft says we should do
1697                          * all the CIPSO validations here but it doesn't
1698                          * really specify _exactly_ what we need to validate
1699                          * ... so, just make it a sysctl tunable. */
1700                         if (cipso_v4_rbm_strictvalid) {
1701                                 if (cipso_v4_map_lvl_valid(doi_def,
1702                                                            tag[3]) < 0) {
1703                                         err_offset = opt_iter + 3;
1704                                         goto validate_return_locked;
1705                                 }
1706                                 if (tag_len > CIPSO_V4_TAG_RBM_BLEN &&
1707                                     cipso_v4_map_cat_rbm_valid(doi_def,
1708                                                             &tag[4],
1709                                                             tag_len - 4) < 0) {
1710                                         err_offset = opt_iter + 4;
1711                                         goto validate_return_locked;
1712                                 }
1713                         }
1714                         break;
1715                 case CIPSO_V4_TAG_ENUM:
1716                         if (tag_len < CIPSO_V4_TAG_ENUM_BLEN) {
1717                                 err_offset = opt_iter + 1;
1718                                 goto validate_return_locked;
1719                         }
1720
1721                         if (cipso_v4_map_lvl_valid(doi_def,
1722                                                    tag[3]) < 0) {
1723                                 err_offset = opt_iter + 3;
1724                                 goto validate_return_locked;
1725                         }
1726                         if (tag_len > CIPSO_V4_TAG_ENUM_BLEN &&
1727                             cipso_v4_map_cat_enum_valid(doi_def,
1728                                                         &tag[4],
1729                                                         tag_len - 4) < 0) {
1730                                 err_offset = opt_iter + 4;
1731                                 goto validate_return_locked;
1732                         }
1733                         break;
1734                 case CIPSO_V4_TAG_RANGE:
1735                         if (tag_len < CIPSO_V4_TAG_RNG_BLEN) {
1736                                 err_offset = opt_iter + 1;
1737                                 goto validate_return_locked;
1738                         }
1739
1740                         if (cipso_v4_map_lvl_valid(doi_def,
1741                                                    tag[3]) < 0) {
1742                                 err_offset = opt_iter + 3;
1743                                 goto validate_return_locked;
1744                         }
1745                         if (tag_len > CIPSO_V4_TAG_RNG_BLEN &&
1746                             cipso_v4_map_cat_rng_valid(doi_def,
1747                                                        &tag[4],
1748                                                        tag_len - 4) < 0) {
1749                                 err_offset = opt_iter + 4;
1750                                 goto validate_return_locked;
1751                         }
1752                         break;
1753                 case CIPSO_V4_TAG_LOCAL:
1754                         /* This is a non-standard tag that we only allow for
1755                          * local connections, so if the incoming interface is
1756                          * not the loopback device drop the packet. Further,
1757                          * there is no legitimate reason for setting this from
1758                          * userspace so reject it if skb is NULL. */
1759                         if (!skb || !(skb->dev->flags & IFF_LOOPBACK)) {
1760                                 err_offset = opt_iter;
1761                                 goto validate_return_locked;
1762                         }
1763                         if (tag_len != CIPSO_V4_TAG_LOC_BLEN) {
1764                                 err_offset = opt_iter + 1;
1765                                 goto validate_return_locked;
1766                         }
1767                         break;
1768                 default:
1769                         err_offset = opt_iter;
1770                         goto validate_return_locked;
1771                 }
1772
1773                 tag += tag_len;
1774                 opt_iter += tag_len;
1775         }
1776
1777 validate_return_locked:
1778         rcu_read_unlock();
1779 validate_return:
1780         *option = opt + err_offset;
1781         return err_offset;
1782 }
1783
1784 /**
1785  * cipso_v4_error - Send the correct response for a bad packet
1786  * @skb: the packet
1787  * @error: the error code
1788  * @gateway: CIPSO gateway flag
1789  *
1790  * Description:
1791  * Based on the error code given in @error, send an ICMP error message back to
1792  * the originating host.  From the IETF draft ...
1793  *
1794  *  "If the contents of the CIPSO [option] are valid but the security label is
1795  *   outside of the configured host or port label range, the datagram is
1796  *   discarded and an ICMP 'destination unreachable' (type 3) is generated and
1797  *   returned.  The code field of the ICMP is set to 'communication with
1798  *   destination network administratively prohibited' (code 9) or to
1799  *   'communication with destination host administratively prohibited'
1800  *   (code 10).  The value of the code is dependent on whether the originator
1801  *   of the ICMP message is acting as a CIPSO host or a CIPSO gateway.  The
1802  *   recipient of the ICMP message MUST be able to handle either value.  The
1803  *   same procedure is performed if a CIPSO [option] can not be added to an
1804  *   IP packet because it is too large to fit in the IP options area."
1805  *
1806  *  "If the error is triggered by receipt of an ICMP message, the message is
1807  *   discarded and no response is permitted (consistent with general ICMP
1808  *   processing rules)."
1809  *
1810  */
1811 void cipso_v4_error(struct sk_buff *skb, int error, u32 gateway)
1812 {
1813         unsigned char optbuf[sizeof(struct ip_options) + 40];
1814         struct ip_options *opt = (struct ip_options *)optbuf;
1815         int res;
1816
1817         if (ip_hdr(skb)->protocol == IPPROTO_ICMP || error != -EACCES)
1818                 return;
1819
1820         /*
1821          * We might be called above the IP layer,
1822          * so we can not use icmp_send and IPCB here.
1823          */
1824
1825         memset(opt, 0, sizeof(struct ip_options));
1826         opt->optlen = ip_hdr(skb)->ihl*4 - sizeof(struct iphdr);
1827         rcu_read_lock();
1828         res = __ip_options_compile(dev_net(skb->dev), opt, skb, NULL);
1829         rcu_read_unlock();
1830
1831         if (res)
1832                 return;
1833
1834         if (gateway)
1835                 __icmp_send(skb, ICMP_DEST_UNREACH, ICMP_NET_ANO, 0, opt);
1836         else
1837                 __icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_ANO, 0, opt);
1838 }
1839
1840 /**
1841  * cipso_v4_genopt - Generate a CIPSO option
1842  * @buf: the option buffer
1843  * @buf_len: the size of opt_buf
1844  * @doi_def: the CIPSO DOI to use
1845  * @secattr: the security attributes
1846  *
1847  * Description:
1848  * Generate a CIPSO option using the DOI definition and security attributes
1849  * passed to the function.  Returns the length of the option on success and
1850  * negative values on failure.
1851  *
1852  */
1853 static int cipso_v4_genopt(unsigned char *buf, u32 buf_len,
1854                            const struct cipso_v4_doi *doi_def,
1855                            const struct netlbl_lsm_secattr *secattr)
1856 {
1857         int ret_val;
1858         u32 iter;
1859
1860         if (buf_len <= CIPSO_V4_HDR_LEN)
1861                 return -ENOSPC;
1862
1863         /* XXX - This code assumes only one tag per CIPSO option which isn't
1864          * really a good assumption to make but since we only support the MAC
1865          * tags right now it is a safe assumption. */
1866         iter = 0;
1867         do {
1868                 memset(buf, 0, buf_len);
1869                 switch (doi_def->tags[iter]) {
1870                 case CIPSO_V4_TAG_RBITMAP:
1871                         ret_val = cipso_v4_gentag_rbm(doi_def,
1872                                                    secattr,
1873                                                    &buf[CIPSO_V4_HDR_LEN],
1874                                                    buf_len - CIPSO_V4_HDR_LEN);
1875                         break;
1876                 case CIPSO_V4_TAG_ENUM:
1877                         ret_val = cipso_v4_gentag_enum(doi_def,
1878                                                    secattr,
1879                                                    &buf[CIPSO_V4_HDR_LEN],
1880                                                    buf_len - CIPSO_V4_HDR_LEN);
1881                         break;
1882                 case CIPSO_V4_TAG_RANGE:
1883                         ret_val = cipso_v4_gentag_rng(doi_def,
1884                                                    secattr,
1885                                                    &buf[CIPSO_V4_HDR_LEN],
1886                                                    buf_len - CIPSO_V4_HDR_LEN);
1887                         break;
1888                 case CIPSO_V4_TAG_LOCAL:
1889                         ret_val = cipso_v4_gentag_loc(doi_def,
1890                                                    secattr,
1891                                                    &buf[CIPSO_V4_HDR_LEN],
1892                                                    buf_len - CIPSO_V4_HDR_LEN);
1893                         break;
1894                 default:
1895                         return -EPERM;
1896                 }
1897
1898                 iter++;
1899         } while (ret_val < 0 &&
1900                  iter < CIPSO_V4_TAG_MAXCNT &&
1901                  doi_def->tags[iter] != CIPSO_V4_TAG_INVALID);
1902         if (ret_val < 0)
1903                 return ret_val;
1904         cipso_v4_gentag_hdr(doi_def, buf, ret_val);
1905         return CIPSO_V4_HDR_LEN + ret_val;
1906 }
1907
1908 /**
1909  * cipso_v4_sock_setattr - Add a CIPSO option to a socket
1910  * @sk: the socket
1911  * @doi_def: the CIPSO DOI to use
1912  * @secattr: the specific security attributes of the socket
1913  *
1914  * Description:
1915  * Set the CIPSO option on the given socket using the DOI definition and
1916  * security attributes passed to the function.  This function requires
1917  * exclusive access to @sk, which means it either needs to be in the
1918  * process of being created or locked.  Returns zero on success and negative
1919  * values on failure.
1920  *
1921  */
1922 int cipso_v4_sock_setattr(struct sock *sk,
1923                           const struct cipso_v4_doi *doi_def,
1924                           const struct netlbl_lsm_secattr *secattr)
1925 {
1926         int ret_val = -EPERM;
1927         unsigned char *buf = NULL;
1928         u32 buf_len;
1929         u32 opt_len;
1930         struct ip_options_rcu *old, *opt = NULL;
1931         struct inet_sock *sk_inet;
1932         struct inet_connection_sock *sk_conn;
1933
1934         /* In the case of sock_create_lite(), the sock->sk field is not
1935          * defined yet but it is not a problem as the only users of these
1936          * "lite" PF_INET sockets are functions which do an accept() call
1937          * afterwards so we will label the socket as part of the accept(). */
1938         if (!sk)
1939                 return 0;
1940
1941         /* We allocate the maximum CIPSO option size here so we are probably
1942          * being a little wasteful, but it makes our life _much_ easier later
1943          * on and after all we are only talking about 40 bytes. */
1944         buf_len = CIPSO_V4_OPT_LEN_MAX;
1945         buf = kmalloc(buf_len, GFP_ATOMIC);
1946         if (!buf) {
1947                 ret_val = -ENOMEM;
1948                 goto socket_setattr_failure;
1949         }
1950
1951         ret_val = cipso_v4_genopt(buf, buf_len, doi_def, secattr);
1952         if (ret_val < 0)
1953                 goto socket_setattr_failure;
1954         buf_len = ret_val;
1955
1956         /* We can't use ip_options_get() directly because it makes a call to
1957          * ip_options_get_alloc() which allocates memory with GFP_KERNEL and
1958          * we won't always have CAP_NET_RAW even though we _always_ want to
1959          * set the IPOPT_CIPSO option. */
1960         opt_len = (buf_len + 3) & ~3;
1961         opt = kzalloc(sizeof(*opt) + opt_len, GFP_ATOMIC);
1962         if (!opt) {
1963                 ret_val = -ENOMEM;
1964                 goto socket_setattr_failure;
1965         }
1966         memcpy(opt->opt.__data, buf, buf_len);
1967         opt->opt.optlen = opt_len;
1968         opt->opt.cipso = sizeof(struct iphdr);
1969         kfree(buf);
1970         buf = NULL;
1971
1972         sk_inet = inet_sk(sk);
1973
1974         old = rcu_dereference_protected(sk_inet->inet_opt, sock_owned_by_user(sk));
1975         if (sk_inet->is_icsk) {
1976                 sk_conn = inet_csk(sk);
1977                 if (old)
1978                         sk_conn->icsk_ext_hdr_len -= old->opt.optlen;
1979                 sk_conn->icsk_ext_hdr_len += opt->opt.optlen;
1980                 sk_conn->icsk_sync_mss(sk, sk_conn->icsk_pmtu_cookie);
1981         }
1982         rcu_assign_pointer(sk_inet->inet_opt, opt);
1983         if (old)
1984                 kfree_rcu(old, rcu);
1985
1986         return 0;
1987
1988 socket_setattr_failure:
1989         kfree(buf);
1990         kfree(opt);
1991         return ret_val;
1992 }
1993
1994 /**
1995  * cipso_v4_req_setattr - Add a CIPSO option to a connection request socket
1996  * @req: the connection request socket
1997  * @doi_def: the CIPSO DOI to use
1998  * @secattr: the specific security attributes of the socket
1999  *
2000  * Description:
2001  * Set the CIPSO option on the given socket using the DOI definition and
2002  * security attributes passed to the function.  Returns zero on success and
2003  * negative values on failure.
2004  *
2005  */
2006 int cipso_v4_req_setattr(struct request_sock *req,
2007                          const struct cipso_v4_doi *doi_def,
2008                          const struct netlbl_lsm_secattr *secattr)
2009 {
2010         int ret_val = -EPERM;
2011         unsigned char *buf = NULL;
2012         u32 buf_len;
2013         u32 opt_len;
2014         struct ip_options_rcu *opt = NULL;
2015         struct inet_request_sock *req_inet;
2016
2017         /* We allocate the maximum CIPSO option size here so we are probably
2018          * being a little wasteful, but it makes our life _much_ easier later
2019          * on and after all we are only talking about 40 bytes. */
2020         buf_len = CIPSO_V4_OPT_LEN_MAX;
2021         buf = kmalloc(buf_len, GFP_ATOMIC);
2022         if (!buf) {
2023                 ret_val = -ENOMEM;
2024                 goto req_setattr_failure;
2025         }
2026
2027         ret_val = cipso_v4_genopt(buf, buf_len, doi_def, secattr);
2028         if (ret_val < 0)
2029                 goto req_setattr_failure;
2030         buf_len = ret_val;
2031
2032         /* We can't use ip_options_get() directly because it makes a call to
2033          * ip_options_get_alloc() which allocates memory with GFP_KERNEL and
2034          * we won't always have CAP_NET_RAW even though we _always_ want to
2035          * set the IPOPT_CIPSO option. */
2036         opt_len = (buf_len + 3) & ~3;
2037         opt = kzalloc(sizeof(*opt) + opt_len, GFP_ATOMIC);
2038         if (!opt) {
2039                 ret_val = -ENOMEM;
2040                 goto req_setattr_failure;
2041         }
2042         memcpy(opt->opt.__data, buf, buf_len);
2043         opt->opt.optlen = opt_len;
2044         opt->opt.cipso = sizeof(struct iphdr);
2045         kfree(buf);
2046         buf = NULL;
2047
2048         req_inet = inet_rsk(req);
2049         opt = xchg((__force struct ip_options_rcu **)&req_inet->ireq_opt, opt);
2050         if (opt)
2051                 kfree_rcu(opt, rcu);
2052
2053         return 0;
2054
2055 req_setattr_failure:
2056         kfree(buf);
2057         kfree(opt);
2058         return ret_val;
2059 }
2060
2061 /**
2062  * cipso_v4_delopt - Delete the CIPSO option from a set of IP options
2063  * @opt_ptr: IP option pointer
2064  *
2065  * Description:
2066  * Deletes the CIPSO IP option from a set of IP options and makes the necessary
2067  * adjustments to the IP option structure.  Returns zero on success, negative
2068  * values on failure.
2069  *
2070  */
2071 static int cipso_v4_delopt(struct ip_options_rcu __rcu **opt_ptr)
2072 {
2073         struct ip_options_rcu *opt = rcu_dereference_protected(*opt_ptr, 1);
2074         int hdr_delta = 0;
2075
2076         if (!opt || opt->opt.cipso == 0)
2077                 return 0;
2078         if (opt->opt.srr || opt->opt.rr || opt->opt.ts || opt->opt.router_alert) {
2079                 u8 cipso_len;
2080                 u8 cipso_off;
2081                 unsigned char *cipso_ptr;
2082                 int iter;
2083                 int optlen_new;
2084
2085                 cipso_off = opt->opt.cipso - sizeof(struct iphdr);
2086                 cipso_ptr = &opt->opt.__data[cipso_off];
2087                 cipso_len = cipso_ptr[1];
2088
2089                 if (opt->opt.srr > opt->opt.cipso)
2090                         opt->opt.srr -= cipso_len;
2091                 if (opt->opt.rr > opt->opt.cipso)
2092                         opt->opt.rr -= cipso_len;
2093                 if (opt->opt.ts > opt->opt.cipso)
2094                         opt->opt.ts -= cipso_len;
2095                 if (opt->opt.router_alert > opt->opt.cipso)
2096                         opt->opt.router_alert -= cipso_len;
2097                 opt->opt.cipso = 0;
2098
2099                 memmove(cipso_ptr, cipso_ptr + cipso_len,
2100                         opt->opt.optlen - cipso_off - cipso_len);
2101
2102                 /* determining the new total option length is tricky because of
2103                  * the padding necessary, the only thing i can think to do at
2104                  * this point is walk the options one-by-one, skipping the
2105                  * padding at the end to determine the actual option size and
2106                  * from there we can determine the new total option length */
2107                 iter = 0;
2108                 optlen_new = 0;
2109                 while (iter < opt->opt.optlen)
2110                         if (opt->opt.__data[iter] != IPOPT_NOP) {
2111                                 iter += opt->opt.__data[iter + 1];
2112                                 optlen_new = iter;
2113                         } else
2114                                 iter++;
2115                 hdr_delta = opt->opt.optlen;
2116                 opt->opt.optlen = (optlen_new + 3) & ~3;
2117                 hdr_delta -= opt->opt.optlen;
2118         } else {
2119                 /* only the cipso option was present on the socket so we can
2120                  * remove the entire option struct */
2121                 *opt_ptr = NULL;
2122                 hdr_delta = opt->opt.optlen;
2123                 kfree_rcu(opt, rcu);
2124         }
2125
2126         return hdr_delta;
2127 }
2128
2129 /**
2130  * cipso_v4_sock_delattr - Delete the CIPSO option from a socket
2131  * @sk: the socket
2132  *
2133  * Description:
2134  * Removes the CIPSO option from a socket, if present.
2135  *
2136  */
2137 void cipso_v4_sock_delattr(struct sock *sk)
2138 {
2139         struct inet_sock *sk_inet;
2140         int hdr_delta;
2141
2142         sk_inet = inet_sk(sk);
2143
2144         hdr_delta = cipso_v4_delopt(&sk_inet->inet_opt);
2145         if (sk_inet->is_icsk && hdr_delta > 0) {
2146                 struct inet_connection_sock *sk_conn = inet_csk(sk);
2147                 sk_conn->icsk_ext_hdr_len -= hdr_delta;
2148                 sk_conn->icsk_sync_mss(sk, sk_conn->icsk_pmtu_cookie);
2149         }
2150 }
2151
2152 /**
2153  * cipso_v4_req_delattr - Delete the CIPSO option from a request socket
2154  * @reg: the request socket
2155  *
2156  * Description:
2157  * Removes the CIPSO option from a request socket, if present.
2158  *
2159  */
2160 void cipso_v4_req_delattr(struct request_sock *req)
2161 {
2162         cipso_v4_delopt(&inet_rsk(req)->ireq_opt);
2163 }
2164
2165 /**
2166  * cipso_v4_getattr - Helper function for the cipso_v4_*_getattr functions
2167  * @cipso: the CIPSO v4 option
2168  * @secattr: the security attributes
2169  *
2170  * Description:
2171  * Inspect @cipso and return the security attributes in @secattr.  Returns zero
2172  * on success and negative values on failure.
2173  *
2174  */
2175 int cipso_v4_getattr(const unsigned char *cipso,
2176                      struct netlbl_lsm_secattr *secattr)
2177 {
2178         int ret_val = -ENOMSG;
2179         u32 doi;
2180         struct cipso_v4_doi *doi_def;
2181
2182         if (cipso_v4_cache_check(cipso, cipso[1], secattr) == 0)
2183                 return 0;
2184
2185         doi = get_unaligned_be32(&cipso[2]);
2186         rcu_read_lock();
2187         doi_def = cipso_v4_doi_search(doi);
2188         if (!doi_def)
2189                 goto getattr_return;
2190         /* XXX - This code assumes only one tag per CIPSO option which isn't
2191          * really a good assumption to make but since we only support the MAC
2192          * tags right now it is a safe assumption. */
2193         switch (cipso[6]) {
2194         case CIPSO_V4_TAG_RBITMAP:
2195                 ret_val = cipso_v4_parsetag_rbm(doi_def, &cipso[6], secattr);
2196                 break;
2197         case CIPSO_V4_TAG_ENUM:
2198                 ret_val = cipso_v4_parsetag_enum(doi_def, &cipso[6], secattr);
2199                 break;
2200         case CIPSO_V4_TAG_RANGE:
2201                 ret_val = cipso_v4_parsetag_rng(doi_def, &cipso[6], secattr);
2202                 break;
2203         case CIPSO_V4_TAG_LOCAL:
2204                 ret_val = cipso_v4_parsetag_loc(doi_def, &cipso[6], secattr);
2205                 break;
2206         }
2207         if (ret_val == 0)
2208                 secattr->type = NETLBL_NLTYPE_CIPSOV4;
2209
2210 getattr_return:
2211         rcu_read_unlock();
2212         return ret_val;
2213 }
2214
2215 /**
2216  * cipso_v4_sock_getattr - Get the security attributes from a sock
2217  * @sk: the sock
2218  * @secattr: the security attributes
2219  *
2220  * Description:
2221  * Query @sk to see if there is a CIPSO option attached to the sock and if
2222  * there is return the CIPSO security attributes in @secattr.  This function
2223  * requires that @sk be locked, or privately held, but it does not do any
2224  * locking itself.  Returns zero on success and negative values on failure.
2225  *
2226  */
2227 int cipso_v4_sock_getattr(struct sock *sk, struct netlbl_lsm_secattr *secattr)
2228 {
2229         struct ip_options_rcu *opt;
2230         int res = -ENOMSG;
2231
2232         rcu_read_lock();
2233         opt = rcu_dereference(inet_sk(sk)->inet_opt);
2234         if (opt && opt->opt.cipso)
2235                 res = cipso_v4_getattr(opt->opt.__data +
2236                                                 opt->opt.cipso -
2237                                                 sizeof(struct iphdr),
2238                                        secattr);
2239         rcu_read_unlock();
2240         return res;
2241 }
2242
2243 /**
2244  * cipso_v4_skbuff_setattr - Set the CIPSO option on a packet
2245  * @skb: the packet
2246  * @secattr: the security attributes
2247  *
2248  * Description:
2249  * Set the CIPSO option on the given packet based on the security attributes.
2250  * Returns a pointer to the IP header on success and NULL on failure.
2251  *
2252  */
2253 int cipso_v4_skbuff_setattr(struct sk_buff *skb,
2254                             const struct cipso_v4_doi *doi_def,
2255                             const struct netlbl_lsm_secattr *secattr)
2256 {
2257         int ret_val;
2258         struct iphdr *iph;
2259         struct ip_options *opt = &IPCB(skb)->opt;
2260         unsigned char buf[CIPSO_V4_OPT_LEN_MAX];
2261         u32 buf_len = CIPSO_V4_OPT_LEN_MAX;
2262         u32 opt_len;
2263         int len_delta;
2264
2265         ret_val = cipso_v4_genopt(buf, buf_len, doi_def, secattr);
2266         if (ret_val < 0)
2267                 return ret_val;
2268         buf_len = ret_val;
2269         opt_len = (buf_len + 3) & ~3;
2270
2271         /* we overwrite any existing options to ensure that we have enough
2272          * room for the CIPSO option, the reason is that we _need_ to guarantee
2273          * that the security label is applied to the packet - we do the same
2274          * thing when using the socket options and it hasn't caused a problem,
2275          * if we need to we can always revisit this choice later */
2276
2277         len_delta = opt_len - opt->optlen;
2278         /* if we don't ensure enough headroom we could panic on the skb_push()
2279          * call below so make sure we have enough, we are also "mangling" the
2280          * packet so we should probably do a copy-on-write call anyway */
2281         ret_val = skb_cow(skb, skb_headroom(skb) + len_delta);
2282         if (ret_val < 0)
2283                 return ret_val;
2284
2285         if (len_delta > 0) {
2286                 /* we assume that the header + opt->optlen have already been
2287                  * "pushed" in ip_options_build() or similar */
2288                 iph = ip_hdr(skb);
2289                 skb_push(skb, len_delta);
2290                 memmove((char *)iph - len_delta, iph, iph->ihl << 2);
2291                 skb_reset_network_header(skb);
2292                 iph = ip_hdr(skb);
2293         } else if (len_delta < 0) {
2294                 iph = ip_hdr(skb);
2295                 memset(iph + 1, IPOPT_NOP, opt->optlen);
2296         } else
2297                 iph = ip_hdr(skb);
2298
2299         if (opt->optlen > 0)
2300                 memset(opt, 0, sizeof(*opt));
2301         opt->optlen = opt_len;
2302         opt->cipso = sizeof(struct iphdr);
2303         opt->is_changed = 1;
2304
2305         /* we have to do the following because we are being called from a
2306          * netfilter hook which means the packet already has had the header
2307          * fields populated and the checksum calculated - yes this means we
2308          * are doing more work than needed but we do it to keep the core
2309          * stack clean and tidy */
2310         memcpy(iph + 1, buf, buf_len);
2311         if (opt_len > buf_len)
2312                 memset((char *)(iph + 1) + buf_len, 0, opt_len - buf_len);
2313         if (len_delta != 0) {
2314                 iph->ihl = 5 + (opt_len >> 2);
2315                 iph->tot_len = htons(skb->len);
2316         }
2317         ip_send_check(iph);
2318
2319         return 0;
2320 }
2321
2322 /**
2323  * cipso_v4_skbuff_delattr - Delete any CIPSO options from a packet
2324  * @skb: the packet
2325  *
2326  * Description:
2327  * Removes any and all CIPSO options from the given packet.  Returns zero on
2328  * success, negative values on failure.
2329  *
2330  */
2331 int cipso_v4_skbuff_delattr(struct sk_buff *skb)
2332 {
2333         int ret_val;
2334         struct iphdr *iph;
2335         struct ip_options *opt = &IPCB(skb)->opt;
2336         unsigned char *cipso_ptr;
2337
2338         if (opt->cipso == 0)
2339                 return 0;
2340
2341         /* since we are changing the packet we should make a copy */
2342         ret_val = skb_cow(skb, skb_headroom(skb));
2343         if (ret_val < 0)
2344                 return ret_val;
2345
2346         /* the easiest thing to do is just replace the cipso option with noop
2347          * options since we don't change the size of the packet, although we
2348          * still need to recalculate the checksum */
2349
2350         iph = ip_hdr(skb);
2351         cipso_ptr = (unsigned char *)iph + opt->cipso;
2352         memset(cipso_ptr, IPOPT_NOOP, cipso_ptr[1]);
2353         opt->cipso = 0;
2354         opt->is_changed = 1;
2355
2356         ip_send_check(iph);
2357
2358         return 0;
2359 }
2360
2361 /*
2362  * Setup Functions
2363  */
2364
2365 /**
2366  * cipso_v4_init - Initialize the CIPSO module
2367  *
2368  * Description:
2369  * Initialize the CIPSO module and prepare it for use.  Returns zero on success
2370  * and negative values on failure.
2371  *
2372  */
2373 static int __init cipso_v4_init(void)
2374 {
2375         int ret_val;
2376
2377         ret_val = cipso_v4_cache_init();
2378         if (ret_val != 0)
2379                 panic("Failed to initialize the CIPSO/IPv4 cache (%d)\n",
2380                       ret_val);
2381
2382         return 0;
2383 }
2384
2385 subsys_initcall(cipso_v4_init);