netlabel: Pass a family parameter to netlbl_skbuff_err().
[linux-2.6-microblaze.git] / net / netlabel / netlabel_kapi.c
1 /*
2  * NetLabel Kernel API
3  *
4  * This file defines the kernel API for the NetLabel system.  The NetLabel
5  * system manages static and dynamic label mappings for network protocols such
6  * as CIPSO and RIPSO.
7  *
8  * Author: Paul Moore <paul@paul-moore.com>
9  *
10  */
11
12 /*
13  * (c) Copyright Hewlett-Packard Development Company, L.P., 2006, 2008
14  *
15  * This program is free software;  you can redistribute it and/or modify
16  * it under the terms of the GNU General Public License as published by
17  * the Free Software Foundation; either version 2 of the License, or
18  * (at your option) any later version.
19  *
20  * This program is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY;  without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
23  * the GNU General Public License for more details.
24  *
25  * You should have received a copy of the GNU General Public License
26  * along with this program;  if not, see <http://www.gnu.org/licenses/>.
27  *
28  */
29
30 #include <linux/init.h>
31 #include <linux/types.h>
32 #include <linux/slab.h>
33 #include <linux/audit.h>
34 #include <linux/in.h>
35 #include <linux/in6.h>
36 #include <net/ip.h>
37 #include <net/ipv6.h>
38 #include <net/netlabel.h>
39 #include <net/cipso_ipv4.h>
40 #include <net/calipso.h>
41 #include <asm/bug.h>
42 #include <linux/atomic.h>
43
44 #include "netlabel_domainhash.h"
45 #include "netlabel_unlabeled.h"
46 #include "netlabel_cipso_v4.h"
47 #include "netlabel_calipso.h"
48 #include "netlabel_user.h"
49 #include "netlabel_mgmt.h"
50 #include "netlabel_addrlist.h"
51
52 /*
53  * Configuration Functions
54  */
55
56 /**
57  * netlbl_cfg_map_del - Remove a NetLabel/LSM domain mapping
58  * @domain: the domain mapping to remove
59  * @family: address family
60  * @addr: IP address
61  * @mask: IP address mask
62  * @audit_info: NetLabel audit information
63  *
64  * Description:
65  * Removes a NetLabel/LSM domain mapping.  A @domain value of NULL causes the
66  * default domain mapping to be removed.  Returns zero on success, negative
67  * values on failure.
68  *
69  */
70 int netlbl_cfg_map_del(const char *domain,
71                        u16 family,
72                        const void *addr,
73                        const void *mask,
74                        struct netlbl_audit *audit_info)
75 {
76         if (addr == NULL && mask == NULL) {
77                 return netlbl_domhsh_remove(domain, family, audit_info);
78         } else if (addr != NULL && mask != NULL) {
79                 switch (family) {
80                 case AF_INET:
81                         return netlbl_domhsh_remove_af4(domain, addr, mask,
82                                                         audit_info);
83                 default:
84                         return -EPFNOSUPPORT;
85                 }
86         } else
87                 return -EINVAL;
88 }
89
90 /**
91  * netlbl_cfg_unlbl_map_add - Add a new unlabeled mapping
92  * @domain: the domain mapping to add
93  * @family: address family
94  * @addr: IP address
95  * @mask: IP address mask
96  * @audit_info: NetLabel audit information
97  *
98  * Description:
99  * Adds a new unlabeled NetLabel/LSM domain mapping.  A @domain value of NULL
100  * causes a new default domain mapping to be added.  Returns zero on success,
101  * negative values on failure.
102  *
103  */
104 int netlbl_cfg_unlbl_map_add(const char *domain,
105                              u16 family,
106                              const void *addr,
107                              const void *mask,
108                              struct netlbl_audit *audit_info)
109 {
110         int ret_val = -ENOMEM;
111         struct netlbl_dom_map *entry;
112         struct netlbl_domaddr_map *addrmap = NULL;
113         struct netlbl_domaddr4_map *map4 = NULL;
114         struct netlbl_domaddr6_map *map6 = NULL;
115
116         entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
117         if (entry == NULL)
118                 return -ENOMEM;
119         if (domain != NULL) {
120                 entry->domain = kstrdup(domain, GFP_ATOMIC);
121                 if (entry->domain == NULL)
122                         goto cfg_unlbl_map_add_failure;
123         }
124         entry->family = family;
125
126         if (addr == NULL && mask == NULL)
127                 entry->def.type = NETLBL_NLTYPE_UNLABELED;
128         else if (addr != NULL && mask != NULL) {
129                 addrmap = kzalloc(sizeof(*addrmap), GFP_ATOMIC);
130                 if (addrmap == NULL)
131                         goto cfg_unlbl_map_add_failure;
132                 INIT_LIST_HEAD(&addrmap->list4);
133                 INIT_LIST_HEAD(&addrmap->list6);
134
135                 switch (family) {
136                 case AF_INET: {
137                         const struct in_addr *addr4 = addr;
138                         const struct in_addr *mask4 = mask;
139                         map4 = kzalloc(sizeof(*map4), GFP_ATOMIC);
140                         if (map4 == NULL)
141                                 goto cfg_unlbl_map_add_failure;
142                         map4->def.type = NETLBL_NLTYPE_UNLABELED;
143                         map4->list.addr = addr4->s_addr & mask4->s_addr;
144                         map4->list.mask = mask4->s_addr;
145                         map4->list.valid = 1;
146                         ret_val = netlbl_af4list_add(&map4->list,
147                                                      &addrmap->list4);
148                         if (ret_val != 0)
149                                 goto cfg_unlbl_map_add_failure;
150                         break;
151                         }
152 #if IS_ENABLED(CONFIG_IPV6)
153                 case AF_INET6: {
154                         const struct in6_addr *addr6 = addr;
155                         const struct in6_addr *mask6 = mask;
156                         map6 = kzalloc(sizeof(*map6), GFP_ATOMIC);
157                         if (map6 == NULL)
158                                 goto cfg_unlbl_map_add_failure;
159                         map6->def.type = NETLBL_NLTYPE_UNLABELED;
160                         map6->list.addr = *addr6;
161                         map6->list.addr.s6_addr32[0] &= mask6->s6_addr32[0];
162                         map6->list.addr.s6_addr32[1] &= mask6->s6_addr32[1];
163                         map6->list.addr.s6_addr32[2] &= mask6->s6_addr32[2];
164                         map6->list.addr.s6_addr32[3] &= mask6->s6_addr32[3];
165                         map6->list.mask = *mask6;
166                         map6->list.valid = 1;
167                         ret_val = netlbl_af6list_add(&map6->list,
168                                                      &addrmap->list6);
169                         if (ret_val != 0)
170                                 goto cfg_unlbl_map_add_failure;
171                         break;
172                         }
173 #endif /* IPv6 */
174                 default:
175                         goto cfg_unlbl_map_add_failure;
176                 }
177
178                 entry->def.addrsel = addrmap;
179                 entry->def.type = NETLBL_NLTYPE_ADDRSELECT;
180         } else {
181                 ret_val = -EINVAL;
182                 goto cfg_unlbl_map_add_failure;
183         }
184
185         ret_val = netlbl_domhsh_add(entry, audit_info);
186         if (ret_val != 0)
187                 goto cfg_unlbl_map_add_failure;
188
189         return 0;
190
191 cfg_unlbl_map_add_failure:
192         kfree(entry->domain);
193         kfree(entry);
194         kfree(addrmap);
195         kfree(map4);
196         kfree(map6);
197         return ret_val;
198 }
199
200
201 /**
202  * netlbl_cfg_unlbl_static_add - Adds a new static label
203  * @net: network namespace
204  * @dev_name: interface name
205  * @addr: IP address in network byte order (struct in[6]_addr)
206  * @mask: address mask in network byte order (struct in[6]_addr)
207  * @family: address family
208  * @secid: LSM secid value for the entry
209  * @audit_info: NetLabel audit information
210  *
211  * Description:
212  * Adds a new NetLabel static label to be used when protocol provided labels
213  * are not present on incoming traffic.  If @dev_name is NULL then the default
214  * interface will be used.  Returns zero on success, negative values on failure.
215  *
216  */
217 int netlbl_cfg_unlbl_static_add(struct net *net,
218                                 const char *dev_name,
219                                 const void *addr,
220                                 const void *mask,
221                                 u16 family,
222                                 u32 secid,
223                                 struct netlbl_audit *audit_info)
224 {
225         u32 addr_len;
226
227         switch (family) {
228         case AF_INET:
229                 addr_len = sizeof(struct in_addr);
230                 break;
231 #if IS_ENABLED(CONFIG_IPV6)
232         case AF_INET6:
233                 addr_len = sizeof(struct in6_addr);
234                 break;
235 #endif /* IPv6 */
236         default:
237                 return -EPFNOSUPPORT;
238         }
239
240         return netlbl_unlhsh_add(net,
241                                  dev_name, addr, mask, addr_len,
242                                  secid, audit_info);
243 }
244
245 /**
246  * netlbl_cfg_unlbl_static_del - Removes an existing static label
247  * @net: network namespace
248  * @dev_name: interface name
249  * @addr: IP address in network byte order (struct in[6]_addr)
250  * @mask: address mask in network byte order (struct in[6]_addr)
251  * @family: address family
252  * @audit_info: NetLabel audit information
253  *
254  * Description:
255  * Removes an existing NetLabel static label used when protocol provided labels
256  * are not present on incoming traffic.  If @dev_name is NULL then the default
257  * interface will be used.  Returns zero on success, negative values on failure.
258  *
259  */
260 int netlbl_cfg_unlbl_static_del(struct net *net,
261                                 const char *dev_name,
262                                 const void *addr,
263                                 const void *mask,
264                                 u16 family,
265                                 struct netlbl_audit *audit_info)
266 {
267         u32 addr_len;
268
269         switch (family) {
270         case AF_INET:
271                 addr_len = sizeof(struct in_addr);
272                 break;
273 #if IS_ENABLED(CONFIG_IPV6)
274         case AF_INET6:
275                 addr_len = sizeof(struct in6_addr);
276                 break;
277 #endif /* IPv6 */
278         default:
279                 return -EPFNOSUPPORT;
280         }
281
282         return netlbl_unlhsh_remove(net,
283                                     dev_name, addr, mask, addr_len,
284                                     audit_info);
285 }
286
287 /**
288  * netlbl_cfg_cipsov4_add - Add a new CIPSOv4 DOI definition
289  * @doi_def: CIPSO DOI definition
290  * @audit_info: NetLabel audit information
291  *
292  * Description:
293  * Add a new CIPSO DOI definition as defined by @doi_def.  Returns zero on
294  * success and negative values on failure.
295  *
296  */
297 int netlbl_cfg_cipsov4_add(struct cipso_v4_doi *doi_def,
298                            struct netlbl_audit *audit_info)
299 {
300         return cipso_v4_doi_add(doi_def, audit_info);
301 }
302
303 /**
304  * netlbl_cfg_cipsov4_del - Remove an existing CIPSOv4 DOI definition
305  * @doi: CIPSO DOI
306  * @audit_info: NetLabel audit information
307  *
308  * Description:
309  * Remove an existing CIPSO DOI definition matching @doi.  Returns zero on
310  * success and negative values on failure.
311  *
312  */
313 void netlbl_cfg_cipsov4_del(u32 doi, struct netlbl_audit *audit_info)
314 {
315         cipso_v4_doi_remove(doi, audit_info);
316 }
317
318 /**
319  * netlbl_cfg_cipsov4_map_add - Add a new CIPSOv4 DOI mapping
320  * @doi: the CIPSO DOI
321  * @domain: the domain mapping to add
322  * @addr: IP address
323  * @mask: IP address mask
324  * @audit_info: NetLabel audit information
325  *
326  * Description:
327  * Add a new NetLabel/LSM domain mapping for the given CIPSO DOI to the NetLabel
328  * subsystem.  A @domain value of NULL adds a new default domain mapping.
329  * Returns zero on success, negative values on failure.
330  *
331  */
332 int netlbl_cfg_cipsov4_map_add(u32 doi,
333                                const char *domain,
334                                const struct in_addr *addr,
335                                const struct in_addr *mask,
336                                struct netlbl_audit *audit_info)
337 {
338         int ret_val = -ENOMEM;
339         struct cipso_v4_doi *doi_def;
340         struct netlbl_dom_map *entry;
341         struct netlbl_domaddr_map *addrmap = NULL;
342         struct netlbl_domaddr4_map *addrinfo = NULL;
343
344         doi_def = cipso_v4_doi_getdef(doi);
345         if (doi_def == NULL)
346                 return -ENOENT;
347
348         entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
349         if (entry == NULL)
350                 goto out_entry;
351         entry->family = AF_INET;
352         if (domain != NULL) {
353                 entry->domain = kstrdup(domain, GFP_ATOMIC);
354                 if (entry->domain == NULL)
355                         goto out_domain;
356         }
357
358         if (addr == NULL && mask == NULL) {
359                 entry->def.cipso = doi_def;
360                 entry->def.type = NETLBL_NLTYPE_CIPSOV4;
361         } else if (addr != NULL && mask != NULL) {
362                 addrmap = kzalloc(sizeof(*addrmap), GFP_ATOMIC);
363                 if (addrmap == NULL)
364                         goto out_addrmap;
365                 INIT_LIST_HEAD(&addrmap->list4);
366                 INIT_LIST_HEAD(&addrmap->list6);
367
368                 addrinfo = kzalloc(sizeof(*addrinfo), GFP_ATOMIC);
369                 if (addrinfo == NULL)
370                         goto out_addrinfo;
371                 addrinfo->def.cipso = doi_def;
372                 addrinfo->def.type = NETLBL_NLTYPE_CIPSOV4;
373                 addrinfo->list.addr = addr->s_addr & mask->s_addr;
374                 addrinfo->list.mask = mask->s_addr;
375                 addrinfo->list.valid = 1;
376                 ret_val = netlbl_af4list_add(&addrinfo->list, &addrmap->list4);
377                 if (ret_val != 0)
378                         goto cfg_cipsov4_map_add_failure;
379
380                 entry->def.addrsel = addrmap;
381                 entry->def.type = NETLBL_NLTYPE_ADDRSELECT;
382         } else {
383                 ret_val = -EINVAL;
384                 goto out_addrmap;
385         }
386
387         ret_val = netlbl_domhsh_add(entry, audit_info);
388         if (ret_val != 0)
389                 goto cfg_cipsov4_map_add_failure;
390
391         return 0;
392
393 cfg_cipsov4_map_add_failure:
394         kfree(addrinfo);
395 out_addrinfo:
396         kfree(addrmap);
397 out_addrmap:
398         kfree(entry->domain);
399 out_domain:
400         kfree(entry);
401 out_entry:
402         cipso_v4_doi_putdef(doi_def);
403         return ret_val;
404 }
405
406 /*
407  * Security Attribute Functions
408  */
409
410 #define _CM_F_NONE      0x00000000
411 #define _CM_F_ALLOC     0x00000001
412 #define _CM_F_WALK      0x00000002
413
414 /**
415  * _netlbl_catmap_getnode - Get a individual node from a catmap
416  * @catmap: pointer to the category bitmap
417  * @offset: the requested offset
418  * @cm_flags: catmap flags, see _CM_F_*
419  * @gfp_flags: memory allocation flags
420  *
421  * Description:
422  * Iterate through the catmap looking for the node associated with @offset.
423  * If the _CM_F_ALLOC flag is set in @cm_flags and there is no associated node,
424  * one will be created and inserted into the catmap.  If the _CM_F_WALK flag is
425  * set in @cm_flags and there is no associated node, the next highest node will
426  * be returned.  Returns a pointer to the node on success, NULL on failure.
427  *
428  */
429 static struct netlbl_lsm_catmap *_netlbl_catmap_getnode(
430                                              struct netlbl_lsm_catmap **catmap,
431                                              u32 offset,
432                                              unsigned int cm_flags,
433                                              gfp_t gfp_flags)
434 {
435         struct netlbl_lsm_catmap *iter = *catmap;
436         struct netlbl_lsm_catmap *prev = NULL;
437
438         if (iter == NULL)
439                 goto catmap_getnode_alloc;
440         if (offset < iter->startbit)
441                 goto catmap_getnode_walk;
442         while (iter && offset >= (iter->startbit + NETLBL_CATMAP_SIZE)) {
443                 prev = iter;
444                 iter = iter->next;
445         }
446         if (iter == NULL || offset < iter->startbit)
447                 goto catmap_getnode_walk;
448
449         return iter;
450
451 catmap_getnode_walk:
452         if (cm_flags & _CM_F_WALK)
453                 return iter;
454 catmap_getnode_alloc:
455         if (!(cm_flags & _CM_F_ALLOC))
456                 return NULL;
457
458         iter = netlbl_catmap_alloc(gfp_flags);
459         if (iter == NULL)
460                 return NULL;
461         iter->startbit = offset & ~(NETLBL_CATMAP_SIZE - 1);
462
463         if (prev == NULL) {
464                 iter->next = *catmap;
465                 *catmap = iter;
466         } else {
467                 iter->next = prev->next;
468                 prev->next = iter;
469         }
470
471         return iter;
472 }
473
474 /**
475  * netlbl_catmap_walk - Walk a LSM secattr catmap looking for a bit
476  * @catmap: the category bitmap
477  * @offset: the offset to start searching at, in bits
478  *
479  * Description:
480  * This function walks a LSM secattr category bitmap starting at @offset and
481  * returns the spot of the first set bit or -ENOENT if no bits are set.
482  *
483  */
484 int netlbl_catmap_walk(struct netlbl_lsm_catmap *catmap, u32 offset)
485 {
486         struct netlbl_lsm_catmap *iter = catmap;
487         u32 idx;
488         u32 bit;
489         NETLBL_CATMAP_MAPTYPE bitmap;
490
491         iter = _netlbl_catmap_getnode(&catmap, offset, _CM_F_WALK, 0);
492         if (iter == NULL)
493                 return -ENOENT;
494         if (offset > iter->startbit) {
495                 offset -= iter->startbit;
496                 idx = offset / NETLBL_CATMAP_MAPSIZE;
497                 bit = offset % NETLBL_CATMAP_MAPSIZE;
498         } else {
499                 idx = 0;
500                 bit = 0;
501         }
502         bitmap = iter->bitmap[idx] >> bit;
503
504         for (;;) {
505                 if (bitmap != 0) {
506                         while ((bitmap & NETLBL_CATMAP_BIT) == 0) {
507                                 bitmap >>= 1;
508                                 bit++;
509                         }
510                         return iter->startbit +
511                                (NETLBL_CATMAP_MAPSIZE * idx) + bit;
512                 }
513                 if (++idx >= NETLBL_CATMAP_MAPCNT) {
514                         if (iter->next != NULL) {
515                                 iter = iter->next;
516                                 idx = 0;
517                         } else
518                                 return -ENOENT;
519                 }
520                 bitmap = iter->bitmap[idx];
521                 bit = 0;
522         }
523
524         return -ENOENT;
525 }
526 EXPORT_SYMBOL(netlbl_catmap_walk);
527
528 /**
529  * netlbl_catmap_walkrng - Find the end of a string of set bits
530  * @catmap: the category bitmap
531  * @offset: the offset to start searching at, in bits
532  *
533  * Description:
534  * This function walks a LSM secattr category bitmap starting at @offset and
535  * returns the spot of the first cleared bit or -ENOENT if the offset is past
536  * the end of the bitmap.
537  *
538  */
539 int netlbl_catmap_walkrng(struct netlbl_lsm_catmap *catmap, u32 offset)
540 {
541         struct netlbl_lsm_catmap *iter;
542         struct netlbl_lsm_catmap *prev = NULL;
543         u32 idx;
544         u32 bit;
545         NETLBL_CATMAP_MAPTYPE bitmask;
546         NETLBL_CATMAP_MAPTYPE bitmap;
547
548         iter = _netlbl_catmap_getnode(&catmap, offset, _CM_F_WALK, 0);
549         if (iter == NULL)
550                 return -ENOENT;
551         if (offset > iter->startbit) {
552                 offset -= iter->startbit;
553                 idx = offset / NETLBL_CATMAP_MAPSIZE;
554                 bit = offset % NETLBL_CATMAP_MAPSIZE;
555         } else {
556                 idx = 0;
557                 bit = 0;
558         }
559         bitmask = NETLBL_CATMAP_BIT << bit;
560
561         for (;;) {
562                 bitmap = iter->bitmap[idx];
563                 while (bitmask != 0 && (bitmap & bitmask) != 0) {
564                         bitmask <<= 1;
565                         bit++;
566                 }
567
568                 if (prev && idx == 0 && bit == 0)
569                         return prev->startbit + NETLBL_CATMAP_SIZE - 1;
570                 else if (bitmask != 0)
571                         return iter->startbit +
572                                 (NETLBL_CATMAP_MAPSIZE * idx) + bit - 1;
573                 else if (++idx >= NETLBL_CATMAP_MAPCNT) {
574                         if (iter->next == NULL)
575                                 return iter->startbit + NETLBL_CATMAP_SIZE - 1;
576                         prev = iter;
577                         iter = iter->next;
578                         idx = 0;
579                 }
580                 bitmask = NETLBL_CATMAP_BIT;
581                 bit = 0;
582         }
583
584         return -ENOENT;
585 }
586
587 /**
588  * netlbl_catmap_getlong - Export an unsigned long bitmap
589  * @catmap: pointer to the category bitmap
590  * @offset: pointer to the requested offset
591  * @bitmap: the exported bitmap
592  *
593  * Description:
594  * Export a bitmap with an offset greater than or equal to @offset and return
595  * it in @bitmap.  The @offset must be aligned to an unsigned long and will be
596  * updated on return if different from what was requested; if the catmap is
597  * empty at the requested offset and beyond, the @offset is set to (u32)-1.
598  * Returns zero on sucess, negative values on failure.
599  *
600  */
601 int netlbl_catmap_getlong(struct netlbl_lsm_catmap *catmap,
602                           u32 *offset,
603                           unsigned long *bitmap)
604 {
605         struct netlbl_lsm_catmap *iter;
606         u32 off = *offset;
607         u32 idx;
608
609         /* only allow aligned offsets */
610         if ((off & (BITS_PER_LONG - 1)) != 0)
611                 return -EINVAL;
612
613         if (off < catmap->startbit) {
614                 off = catmap->startbit;
615                 *offset = off;
616         }
617         iter = _netlbl_catmap_getnode(&catmap, off, _CM_F_WALK, 0);
618         if (iter == NULL) {
619                 *offset = (u32)-1;
620                 return 0;
621         }
622
623         if (off < iter->startbit) {
624                 *offset = iter->startbit;
625                 off = 0;
626         } else
627                 off -= iter->startbit;
628         idx = off / NETLBL_CATMAP_MAPSIZE;
629         *bitmap = iter->bitmap[idx] >> (off % NETLBL_CATMAP_MAPSIZE);
630
631         return 0;
632 }
633
634 /**
635  * netlbl_catmap_setbit - Set a bit in a LSM secattr catmap
636  * @catmap: pointer to the category bitmap
637  * @bit: the bit to set
638  * @flags: memory allocation flags
639  *
640  * Description:
641  * Set the bit specified by @bit in @catmap.  Returns zero on success,
642  * negative values on failure.
643  *
644  */
645 int netlbl_catmap_setbit(struct netlbl_lsm_catmap **catmap,
646                          u32 bit,
647                          gfp_t flags)
648 {
649         struct netlbl_lsm_catmap *iter;
650         u32 idx;
651
652         iter = _netlbl_catmap_getnode(catmap, bit, _CM_F_ALLOC, flags);
653         if (iter == NULL)
654                 return -ENOMEM;
655
656         bit -= iter->startbit;
657         idx = bit / NETLBL_CATMAP_MAPSIZE;
658         iter->bitmap[idx] |= NETLBL_CATMAP_BIT << (bit % NETLBL_CATMAP_MAPSIZE);
659
660         return 0;
661 }
662 EXPORT_SYMBOL(netlbl_catmap_setbit);
663
664 /**
665  * netlbl_catmap_setrng - Set a range of bits in a LSM secattr catmap
666  * @catmap: pointer to the category bitmap
667  * @start: the starting bit
668  * @end: the last bit in the string
669  * @flags: memory allocation flags
670  *
671  * Description:
672  * Set a range of bits, starting at @start and ending with @end.  Returns zero
673  * on success, negative values on failure.
674  *
675  */
676 int netlbl_catmap_setrng(struct netlbl_lsm_catmap **catmap,
677                          u32 start,
678                          u32 end,
679                          gfp_t flags)
680 {
681         int rc = 0;
682         u32 spot = start;
683
684         while (rc == 0 && spot <= end) {
685                 if (((spot & (BITS_PER_LONG - 1)) == 0) &&
686                     ((end - spot) > BITS_PER_LONG)) {
687                         rc = netlbl_catmap_setlong(catmap,
688                                                    spot,
689                                                    (unsigned long)-1,
690                                                    flags);
691                         spot += BITS_PER_LONG;
692                 } else
693                         rc = netlbl_catmap_setbit(catmap, spot++, flags);
694         }
695
696         return rc;
697 }
698
699 /**
700  * netlbl_catmap_setlong - Import an unsigned long bitmap
701  * @catmap: pointer to the category bitmap
702  * @offset: offset to the start of the imported bitmap
703  * @bitmap: the bitmap to import
704  * @flags: memory allocation flags
705  *
706  * Description:
707  * Import the bitmap specified in @bitmap into @catmap, using the offset
708  * in @offset.  The offset must be aligned to an unsigned long.  Returns zero
709  * on success, negative values on failure.
710  *
711  */
712 int netlbl_catmap_setlong(struct netlbl_lsm_catmap **catmap,
713                           u32 offset,
714                           unsigned long bitmap,
715                           gfp_t flags)
716 {
717         struct netlbl_lsm_catmap *iter;
718         u32 idx;
719
720         /* only allow aligned offsets */
721         if ((offset & (BITS_PER_LONG - 1)) != 0)
722                 return -EINVAL;
723
724         iter = _netlbl_catmap_getnode(catmap, offset, _CM_F_ALLOC, flags);
725         if (iter == NULL)
726                 return -ENOMEM;
727
728         offset -= iter->startbit;
729         idx = offset / NETLBL_CATMAP_MAPSIZE;
730         iter->bitmap[idx] |= bitmap << (offset % NETLBL_CATMAP_MAPSIZE);
731
732         return 0;
733 }
734
735 /* Bitmap functions
736  */
737
738 /**
739  * netlbl_bitmap_walk - Walk a bitmap looking for a bit
740  * @bitmap: the bitmap
741  * @bitmap_len: length in bits
742  * @offset: starting offset
743  * @state: if non-zero, look for a set (1) bit else look for a cleared (0) bit
744  *
745  * Description:
746  * Starting at @offset, walk the bitmap from left to right until either the
747  * desired bit is found or we reach the end.  Return the bit offset, -1 if
748  * not found, or -2 if error.
749  */
750 int netlbl_bitmap_walk(const unsigned char *bitmap, u32 bitmap_len,
751                        u32 offset, u8 state)
752 {
753         u32 bit_spot;
754         u32 byte_offset;
755         unsigned char bitmask;
756         unsigned char byte;
757
758         byte_offset = offset / 8;
759         byte = bitmap[byte_offset];
760         bit_spot = offset;
761         bitmask = 0x80 >> (offset % 8);
762
763         while (bit_spot < bitmap_len) {
764                 if ((state && (byte & bitmask) == bitmask) ||
765                     (state == 0 && (byte & bitmask) == 0))
766                         return bit_spot;
767
768                 bit_spot++;
769                 bitmask >>= 1;
770                 if (bitmask == 0) {
771                         byte = bitmap[++byte_offset];
772                         bitmask = 0x80;
773                 }
774         }
775
776         return -1;
777 }
778 EXPORT_SYMBOL(netlbl_bitmap_walk);
779
780 /**
781  * netlbl_bitmap_setbit - Sets a single bit in a bitmap
782  * @bitmap: the bitmap
783  * @bit: the bit
784  * @state: if non-zero, set the bit (1) else clear the bit (0)
785  *
786  * Description:
787  * Set a single bit in the bitmask.  Returns zero on success, negative values
788  * on error.
789  */
790 void netlbl_bitmap_setbit(unsigned char *bitmap, u32 bit, u8 state)
791 {
792         u32 byte_spot;
793         u8 bitmask;
794
795         /* gcc always rounds to zero when doing integer division */
796         byte_spot = bit / 8;
797         bitmask = 0x80 >> (bit % 8);
798         if (state)
799                 bitmap[byte_spot] |= bitmask;
800         else
801                 bitmap[byte_spot] &= ~bitmask;
802 }
803 EXPORT_SYMBOL(netlbl_bitmap_setbit);
804
805 /*
806  * LSM Functions
807  */
808
809 /**
810  * netlbl_enabled - Determine if the NetLabel subsystem is enabled
811  *
812  * Description:
813  * The LSM can use this function to determine if it should use NetLabel
814  * security attributes in it's enforcement mechanism.  Currently, NetLabel is
815  * considered to be enabled when it's configuration contains a valid setup for
816  * at least one labeled protocol (i.e. NetLabel can understand incoming
817  * labeled packets of at least one type); otherwise NetLabel is considered to
818  * be disabled.
819  *
820  */
821 int netlbl_enabled(void)
822 {
823         /* At some point we probably want to expose this mechanism to the user
824          * as well so that admins can toggle NetLabel regardless of the
825          * configuration */
826         return (atomic_read(&netlabel_mgmt_protocount) > 0);
827 }
828
829 /**
830  * netlbl_sock_setattr - Label a socket using the correct protocol
831  * @sk: the socket to label
832  * @family: protocol family
833  * @secattr: the security attributes
834  *
835  * Description:
836  * Attach the correct label to the given socket using the security attributes
837  * specified in @secattr.  This function requires exclusive access to @sk,
838  * which means it either needs to be in the process of being created or locked.
839  * Returns zero on success, -EDESTADDRREQ if the domain is configured to use
840  * network address selectors (can't blindly label the socket), and negative
841  * values on all other failures.
842  *
843  */
844 int netlbl_sock_setattr(struct sock *sk,
845                         u16 family,
846                         const struct netlbl_lsm_secattr *secattr)
847 {
848         int ret_val;
849         struct netlbl_dom_map *dom_entry;
850
851         rcu_read_lock();
852         dom_entry = netlbl_domhsh_getentry(secattr->domain, family);
853         if (dom_entry == NULL) {
854                 ret_val = -ENOENT;
855                 goto socket_setattr_return;
856         }
857         switch (family) {
858         case AF_INET:
859                 switch (dom_entry->def.type) {
860                 case NETLBL_NLTYPE_ADDRSELECT:
861                         ret_val = -EDESTADDRREQ;
862                         break;
863                 case NETLBL_NLTYPE_CIPSOV4:
864                         ret_val = cipso_v4_sock_setattr(sk,
865                                                         dom_entry->def.cipso,
866                                                         secattr);
867                         break;
868                 case NETLBL_NLTYPE_UNLABELED:
869                         ret_val = 0;
870                         break;
871                 default:
872                         ret_val = -ENOENT;
873                 }
874                 break;
875 #if IS_ENABLED(CONFIG_IPV6)
876         case AF_INET6:
877                 switch (dom_entry->def.type) {
878                 case NETLBL_NLTYPE_ADDRSELECT:
879                         ret_val = -EDESTADDRREQ;
880                         break;
881                 case NETLBL_NLTYPE_CALIPSO:
882                         ret_val = calipso_sock_setattr(sk,
883                                                        dom_entry->def.calipso,
884                                                        secattr);
885                         break;
886                 case NETLBL_NLTYPE_UNLABELED:
887                         ret_val = 0;
888                         break;
889                 default:
890                         ret_val = -ENOENT;
891                 }
892                 break;
893 #endif /* IPv6 */
894         default:
895                 ret_val = -EPROTONOSUPPORT;
896         }
897
898 socket_setattr_return:
899         rcu_read_unlock();
900         return ret_val;
901 }
902
903 /**
904  * netlbl_sock_delattr - Delete all the NetLabel labels on a socket
905  * @sk: the socket
906  *
907  * Description:
908  * Remove all the NetLabel labeling from @sk.  The caller is responsible for
909  * ensuring that @sk is locked.
910  *
911  */
912 void netlbl_sock_delattr(struct sock *sk)
913 {
914         switch (sk->sk_family) {
915         case AF_INET:
916                 cipso_v4_sock_delattr(sk);
917                 break;
918 #if IS_ENABLED(CONFIG_IPV6)
919         case AF_INET6:
920                 calipso_sock_delattr(sk);
921                 break;
922 #endif /* IPv6 */
923         }
924 }
925
926 /**
927  * netlbl_sock_getattr - Determine the security attributes of a sock
928  * @sk: the sock
929  * @secattr: the security attributes
930  *
931  * Description:
932  * Examines the given sock to see if any NetLabel style labeling has been
933  * applied to the sock, if so it parses the socket label and returns the
934  * security attributes in @secattr.  Returns zero on success, negative values
935  * on failure.
936  *
937  */
938 int netlbl_sock_getattr(struct sock *sk,
939                         struct netlbl_lsm_secattr *secattr)
940 {
941         int ret_val;
942
943         switch (sk->sk_family) {
944         case AF_INET:
945                 ret_val = cipso_v4_sock_getattr(sk, secattr);
946                 break;
947 #if IS_ENABLED(CONFIG_IPV6)
948         case AF_INET6:
949                 ret_val = calipso_sock_getattr(sk, secattr);
950                 break;
951 #endif /* IPv6 */
952         default:
953                 ret_val = -EPROTONOSUPPORT;
954         }
955
956         return ret_val;
957 }
958
959 /**
960  * netlbl_conn_setattr - Label a connected socket using the correct protocol
961  * @sk: the socket to label
962  * @addr: the destination address
963  * @secattr: the security attributes
964  *
965  * Description:
966  * Attach the correct label to the given connected socket using the security
967  * attributes specified in @secattr.  The caller is responsible for ensuring
968  * that @sk is locked.  Returns zero on success, negative values on failure.
969  *
970  */
971 int netlbl_conn_setattr(struct sock *sk,
972                         struct sockaddr *addr,
973                         const struct netlbl_lsm_secattr *secattr)
974 {
975         int ret_val;
976         struct sockaddr_in *addr4;
977 #if IS_ENABLED(CONFIG_IPV6)
978         struct sockaddr_in6 *addr6;
979 #endif
980         struct netlbl_dommap_def *entry;
981
982         rcu_read_lock();
983         switch (addr->sa_family) {
984         case AF_INET:
985                 addr4 = (struct sockaddr_in *)addr;
986                 entry = netlbl_domhsh_getentry_af4(secattr->domain,
987                                                    addr4->sin_addr.s_addr);
988                 if (entry == NULL) {
989                         ret_val = -ENOENT;
990                         goto conn_setattr_return;
991                 }
992                 switch (entry->type) {
993                 case NETLBL_NLTYPE_CIPSOV4:
994                         ret_val = cipso_v4_sock_setattr(sk,
995                                                         entry->cipso, secattr);
996                         break;
997                 case NETLBL_NLTYPE_UNLABELED:
998                         /* just delete the protocols we support for right now
999                          * but we could remove other protocols if needed */
1000                         netlbl_sock_delattr(sk);
1001                         ret_val = 0;
1002                         break;
1003                 default:
1004                         ret_val = -ENOENT;
1005                 }
1006                 break;
1007 #if IS_ENABLED(CONFIG_IPV6)
1008         case AF_INET6:
1009                 addr6 = (struct sockaddr_in6 *)addr;
1010                 entry = netlbl_domhsh_getentry_af6(secattr->domain,
1011                                                    &addr6->sin6_addr);
1012                 if (entry == NULL) {
1013                         ret_val = -ENOENT;
1014                         goto conn_setattr_return;
1015                 }
1016                 switch (entry->type) {
1017                 case NETLBL_NLTYPE_CALIPSO:
1018                         ret_val = calipso_sock_setattr(sk,
1019                                                        entry->calipso, secattr);
1020                         break;
1021                 case NETLBL_NLTYPE_UNLABELED:
1022                         /* just delete the protocols we support for right now
1023                          * but we could remove other protocols if needed */
1024                         netlbl_sock_delattr(sk);
1025                         ret_val = 0;
1026                         break;
1027                 default:
1028                         ret_val = -ENOENT;
1029                 }
1030                 break;
1031 #endif /* IPv6 */
1032         default:
1033                 ret_val = -EPROTONOSUPPORT;
1034         }
1035
1036 conn_setattr_return:
1037         rcu_read_unlock();
1038         return ret_val;
1039 }
1040
1041 /**
1042  * netlbl_req_setattr - Label a request socket using the correct protocol
1043  * @req: the request socket to label
1044  * @secattr: the security attributes
1045  *
1046  * Description:
1047  * Attach the correct label to the given socket using the security attributes
1048  * specified in @secattr.  Returns zero on success, negative values on failure.
1049  *
1050  */
1051 int netlbl_req_setattr(struct request_sock *req,
1052                        const struct netlbl_lsm_secattr *secattr)
1053 {
1054         int ret_val;
1055         struct netlbl_dommap_def *entry;
1056         struct inet_request_sock *ireq = inet_rsk(req);
1057
1058         rcu_read_lock();
1059         switch (req->rsk_ops->family) {
1060         case AF_INET:
1061                 entry = netlbl_domhsh_getentry_af4(secattr->domain,
1062                                                    ireq->ir_rmt_addr);
1063                 if (entry == NULL) {
1064                         ret_val = -ENOENT;
1065                         goto req_setattr_return;
1066                 }
1067                 switch (entry->type) {
1068                 case NETLBL_NLTYPE_CIPSOV4:
1069                         ret_val = cipso_v4_req_setattr(req,
1070                                                        entry->cipso, secattr);
1071                         break;
1072                 case NETLBL_NLTYPE_UNLABELED:
1073                         netlbl_req_delattr(req);
1074                         ret_val = 0;
1075                         break;
1076                 default:
1077                         ret_val = -ENOENT;
1078                 }
1079                 break;
1080 #if IS_ENABLED(CONFIG_IPV6)
1081         case AF_INET6:
1082                 entry = netlbl_domhsh_getentry_af6(secattr->domain,
1083                                                    &ireq->ir_v6_rmt_addr);
1084                 if (entry == NULL) {
1085                         ret_val = -ENOENT;
1086                         goto req_setattr_return;
1087                 }
1088                 switch (entry->type) {
1089                 case NETLBL_NLTYPE_CALIPSO:
1090                         ret_val = calipso_req_setattr(req,
1091                                                       entry->calipso, secattr);
1092                         break;
1093                 case NETLBL_NLTYPE_UNLABELED:
1094                         netlbl_req_delattr(req);
1095                         ret_val = 0;
1096                         break;
1097                 default:
1098                         ret_val = -ENOENT;
1099                 }
1100                 break;
1101 #endif /* IPv6 */
1102         default:
1103                 ret_val = -EPROTONOSUPPORT;
1104         }
1105
1106 req_setattr_return:
1107         rcu_read_unlock();
1108         return ret_val;
1109 }
1110
1111 /**
1112 * netlbl_req_delattr - Delete all the NetLabel labels on a socket
1113 * @req: the socket
1114 *
1115 * Description:
1116 * Remove all the NetLabel labeling from @req.
1117 *
1118 */
1119 void netlbl_req_delattr(struct request_sock *req)
1120 {
1121         switch (req->rsk_ops->family) {
1122         case AF_INET:
1123                 cipso_v4_req_delattr(req);
1124                 break;
1125 #if IS_ENABLED(CONFIG_IPV6)
1126         case AF_INET6:
1127                 calipso_req_delattr(req);
1128                 break;
1129 #endif /* IPv6 */
1130         }
1131 }
1132
1133 /**
1134  * netlbl_skbuff_setattr - Label a packet using the correct protocol
1135  * @skb: the packet
1136  * @family: protocol family
1137  * @secattr: the security attributes
1138  *
1139  * Description:
1140  * Attach the correct label to the given packet using the security attributes
1141  * specified in @secattr.  Returns zero on success, negative values on failure.
1142  *
1143  */
1144 int netlbl_skbuff_setattr(struct sk_buff *skb,
1145                           u16 family,
1146                           const struct netlbl_lsm_secattr *secattr)
1147 {
1148         int ret_val;
1149         struct iphdr *hdr4;
1150 #if IS_ENABLED(CONFIG_IPV6)
1151         struct ipv6hdr *hdr6;
1152 #endif
1153         struct netlbl_dommap_def *entry;
1154
1155         rcu_read_lock();
1156         switch (family) {
1157         case AF_INET:
1158                 hdr4 = ip_hdr(skb);
1159                 entry = netlbl_domhsh_getentry_af4(secattr->domain,
1160                                                    hdr4->daddr);
1161                 if (entry == NULL) {
1162                         ret_val = -ENOENT;
1163                         goto skbuff_setattr_return;
1164                 }
1165                 switch (entry->type) {
1166                 case NETLBL_NLTYPE_CIPSOV4:
1167                         ret_val = cipso_v4_skbuff_setattr(skb, entry->cipso,
1168                                                           secattr);
1169                         break;
1170                 case NETLBL_NLTYPE_UNLABELED:
1171                         /* just delete the protocols we support for right now
1172                          * but we could remove other protocols if needed */
1173                         ret_val = cipso_v4_skbuff_delattr(skb);
1174                         break;
1175                 default:
1176                         ret_val = -ENOENT;
1177                 }
1178                 break;
1179 #if IS_ENABLED(CONFIG_IPV6)
1180         case AF_INET6:
1181                 hdr6 = ipv6_hdr(skb);
1182                 entry = netlbl_domhsh_getentry_af6(secattr->domain,
1183                                                    &hdr6->daddr);
1184                 if (entry == NULL) {
1185                         ret_val = -ENOENT;
1186                         goto skbuff_setattr_return;
1187                 }
1188                 switch (entry->type) {
1189                 case NETLBL_NLTYPE_CALIPSO:
1190                         ret_val = calipso_skbuff_setattr(skb, entry->calipso,
1191                                                          secattr);
1192                         break;
1193                 case NETLBL_NLTYPE_UNLABELED:
1194                         /* just delete the protocols we support for right now
1195                          * but we could remove other protocols if needed */
1196                         ret_val = calipso_skbuff_delattr(skb);
1197                         break;
1198                 default:
1199                         ret_val = -ENOENT;
1200                 }
1201                 break;
1202 #endif /* IPv6 */
1203         default:
1204                 ret_val = -EPROTONOSUPPORT;
1205         }
1206
1207 skbuff_setattr_return:
1208         rcu_read_unlock();
1209         return ret_val;
1210 }
1211
1212 /**
1213  * netlbl_skbuff_getattr - Determine the security attributes of a packet
1214  * @skb: the packet
1215  * @family: protocol family
1216  * @secattr: the security attributes
1217  *
1218  * Description:
1219  * Examines the given packet to see if a recognized form of packet labeling
1220  * is present, if so it parses the packet label and returns the security
1221  * attributes in @secattr.  Returns zero on success, negative values on
1222  * failure.
1223  *
1224  */
1225 int netlbl_skbuff_getattr(const struct sk_buff *skb,
1226                           u16 family,
1227                           struct netlbl_lsm_secattr *secattr)
1228 {
1229         unsigned char *ptr;
1230
1231         switch (family) {
1232         case AF_INET:
1233                 ptr = cipso_v4_optptr(skb);
1234                 if (ptr && cipso_v4_getattr(ptr, secattr) == 0)
1235                         return 0;
1236                 break;
1237 #if IS_ENABLED(CONFIG_IPV6)
1238         case AF_INET6:
1239                 ptr = calipso_optptr(skb);
1240                 if (ptr && calipso_getattr(ptr, secattr) == 0)
1241                         return 0;
1242                 break;
1243 #endif /* IPv6 */
1244         }
1245
1246         return netlbl_unlabel_getattr(skb, family, secattr);
1247 }
1248
1249 /**
1250  * netlbl_skbuff_err - Handle a LSM error on a sk_buff
1251  * @skb: the packet
1252  * @family: the family
1253  * @error: the error code
1254  * @gateway: true if host is acting as a gateway, false otherwise
1255  *
1256  * Description:
1257  * Deal with a LSM problem when handling the packet in @skb, typically this is
1258  * a permission denied problem (-EACCES).  The correct action is determined
1259  * according to the packet's labeling protocol.
1260  *
1261  */
1262 void netlbl_skbuff_err(struct sk_buff *skb, u16 family, int error, int gateway)
1263 {
1264         switch (family) {
1265         case AF_INET:
1266                 if (cipso_v4_optptr(skb))
1267                         cipso_v4_error(skb, error, gateway);
1268                 break;
1269         }
1270 }
1271
1272 /**
1273  * netlbl_cache_invalidate - Invalidate all of the NetLabel protocol caches
1274  *
1275  * Description:
1276  * For all of the NetLabel protocols that support some form of label mapping
1277  * cache, invalidate the cache.  Returns zero on success, negative values on
1278  * error.
1279  *
1280  */
1281 void netlbl_cache_invalidate(void)
1282 {
1283         cipso_v4_cache_invalidate();
1284 }
1285
1286 /**
1287  * netlbl_cache_add - Add an entry to a NetLabel protocol cache
1288  * @skb: the packet
1289  * @secattr: the packet's security attributes
1290  *
1291  * Description:
1292  * Add the LSM security attributes for the given packet to the underlying
1293  * NetLabel protocol's label mapping cache.  Returns zero on success, negative
1294  * values on error.
1295  *
1296  */
1297 int netlbl_cache_add(const struct sk_buff *skb,
1298                      const struct netlbl_lsm_secattr *secattr)
1299 {
1300         unsigned char *ptr;
1301
1302         if ((secattr->flags & NETLBL_SECATTR_CACHE) == 0)
1303                 return -ENOMSG;
1304
1305         ptr = cipso_v4_optptr(skb);
1306         if (ptr)
1307                 return cipso_v4_cache_add(ptr, secattr);
1308
1309         return -ENOMSG;
1310 }
1311
1312 /*
1313  * Protocol Engine Functions
1314  */
1315
1316 /**
1317  * netlbl_audit_start - Start an audit message
1318  * @type: audit message type
1319  * @audit_info: NetLabel audit information
1320  *
1321  * Description:
1322  * Start an audit message using the type specified in @type and fill the audit
1323  * message with some fields common to all NetLabel audit messages.  This
1324  * function should only be used by protocol engines, not LSMs.  Returns a
1325  * pointer to the audit buffer on success, NULL on failure.
1326  *
1327  */
1328 struct audit_buffer *netlbl_audit_start(int type,
1329                                         struct netlbl_audit *audit_info)
1330 {
1331         return netlbl_audit_start_common(type, audit_info);
1332 }
1333 EXPORT_SYMBOL(netlbl_audit_start);
1334
1335 /*
1336  * Setup Functions
1337  */
1338
1339 /**
1340  * netlbl_init - Initialize NetLabel
1341  *
1342  * Description:
1343  * Perform the required NetLabel initialization before first use.
1344  *
1345  */
1346 static int __init netlbl_init(void)
1347 {
1348         int ret_val;
1349
1350         printk(KERN_INFO "NetLabel: Initializing\n");
1351         printk(KERN_INFO "NetLabel:  domain hash size = %u\n",
1352                (1 << NETLBL_DOMHSH_BITSIZE));
1353         printk(KERN_INFO "NetLabel:  protocols ="
1354                " UNLABELED"
1355                " CIPSOv4"
1356                "\n");
1357
1358         ret_val = netlbl_domhsh_init(NETLBL_DOMHSH_BITSIZE);
1359         if (ret_val != 0)
1360                 goto init_failure;
1361
1362         ret_val = netlbl_unlabel_init(NETLBL_UNLHSH_BITSIZE);
1363         if (ret_val != 0)
1364                 goto init_failure;
1365
1366         ret_val = netlbl_netlink_init();
1367         if (ret_val != 0)
1368                 goto init_failure;
1369
1370         ret_val = netlbl_unlabel_defconf();
1371         if (ret_val != 0)
1372                 goto init_failure;
1373         printk(KERN_INFO "NetLabel:  unlabeled traffic allowed by default\n");
1374
1375         return 0;
1376
1377 init_failure:
1378         panic("NetLabel: failed to initialize properly (%d)\n", ret_val);
1379 }
1380
1381 subsys_initcall(netlbl_init);