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