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