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