LCOV - code coverage report
Current view: top level - net/netlabel - netlabel_kapi.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 238 0.0 %
Date: 2014-04-07 Functions: 0 25 0.0 %
Branches: 0 161 0.0 %

           Branch data     Line data    Source code
       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, write to the Free Software
      27                 :            :  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
      28                 :            :  *
      29                 :            :  */
      30                 :            : 
      31                 :            : #include <linux/init.h>
      32                 :            : #include <linux/types.h>
      33                 :            : #include <linux/slab.h>
      34                 :            : #include <linux/audit.h>
      35                 :            : #include <linux/in.h>
      36                 :            : #include <linux/in6.h>
      37                 :            : #include <net/ip.h>
      38                 :            : #include <net/ipv6.h>
      39                 :            : #include <net/netlabel.h>
      40                 :            : #include <net/cipso_ipv4.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_user.h"
      48                 :            : #include "netlabel_mgmt.h"
      49                 :            : #include "netlabel_addrlist.h"
      50                 :            : 
      51                 :            : /*
      52                 :            :  * Configuration Functions
      53                 :            :  */
      54                 :            : 
      55                 :            : /**
      56                 :            :  * netlbl_cfg_map_del - Remove a NetLabel/LSM domain mapping
      57                 :            :  * @domain: the domain mapping to remove
      58                 :            :  * @family: address family
      59                 :            :  * @addr: IP address
      60                 :            :  * @mask: IP address mask
      61                 :            :  * @audit_info: NetLabel audit information
      62                 :            :  *
      63                 :            :  * Description:
      64                 :            :  * Removes a NetLabel/LSM domain mapping.  A @domain value of NULL causes the
      65                 :            :  * default domain mapping to be removed.  Returns zero on success, negative
      66                 :            :  * values on failure.
      67                 :            :  *
      68                 :            :  */
      69                 :          0 : int netlbl_cfg_map_del(const char *domain,
      70                 :            :                        u16 family,
      71                 :            :                        const void *addr,
      72                 :            :                        const void *mask,
      73                 :            :                        struct netlbl_audit *audit_info)
      74                 :            : {
      75         [ #  # ]:          0 :         if (addr == NULL && mask == NULL) {
      76                 :          0 :                 return netlbl_domhsh_remove(domain, audit_info);
      77         [ #  # ]:          0 :         } else if (addr != NULL && mask != NULL) {
      78         [ #  # ]:          0 :                 switch (family) {
      79                 :            :                 case AF_INET:
      80                 :          0 :                         return netlbl_domhsh_remove_af4(domain, addr, mask,
      81                 :            :                                                         audit_info);
      82                 :            :                 default:
      83                 :            :                         return -EPFNOSUPPORT;
      84                 :            :                 }
      85                 :            :         } else
      86                 :            :                 return -EINVAL;
      87                 :            : }
      88                 :            : 
      89                 :            : /**
      90                 :            :  * netlbl_cfg_unlbl_map_add - Add a new unlabeled mapping
      91                 :            :  * @domain: the domain mapping to add
      92                 :            :  * @family: address family
      93                 :            :  * @addr: IP address
      94                 :            :  * @mask: IP address mask
      95                 :            :  * @audit_info: NetLabel audit information
      96                 :            :  *
      97                 :            :  * Description:
      98                 :            :  * Adds a new unlabeled NetLabel/LSM domain mapping.  A @domain value of NULL
      99                 :            :  * causes a new default domain mapping to be added.  Returns zero on success,
     100                 :            :  * negative values on failure.
     101                 :            :  *
     102                 :            :  */
     103                 :          0 : int netlbl_cfg_unlbl_map_add(const char *domain,
     104                 :            :                              u16 family,
     105                 :            :                              const void *addr,
     106                 :            :                              const void *mask,
     107                 :            :                              struct netlbl_audit *audit_info)
     108                 :            : {
     109                 :            :         int ret_val = -ENOMEM;
     110                 :            :         struct netlbl_dom_map *entry;
     111                 :            :         struct netlbl_domaddr_map *addrmap = NULL;
     112                 :            :         struct netlbl_domaddr4_map *map4 = NULL;
     113                 :            :         struct netlbl_domaddr6_map *map6 = NULL;
     114                 :            : 
     115                 :            :         entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
     116         [ #  # ]:          0 :         if (entry == NULL)
     117                 :            :                 return -ENOMEM;
     118         [ #  # ]:          0 :         if (domain != NULL) {
     119                 :          0 :                 entry->domain = kstrdup(domain, GFP_ATOMIC);
     120         [ #  # ]:          0 :                 if (entry->domain == NULL)
     121                 :            :                         goto cfg_unlbl_map_add_failure;
     122                 :            :         }
     123                 :            : 
     124         [ #  # ]:          0 :         if (addr == NULL && mask == NULL)
     125                 :          0 :                 entry->def.type = NETLBL_NLTYPE_UNLABELED;
     126         [ #  # ]:          0 :         else if (addr != NULL && mask != NULL) {
     127                 :            :                 addrmap = kzalloc(sizeof(*addrmap), GFP_ATOMIC);
     128         [ #  # ]:          0 :                 if (addrmap == NULL)
     129                 :            :                         goto cfg_unlbl_map_add_failure;
     130                 :          0 :                 INIT_LIST_HEAD(&addrmap->list4);
     131                 :          0 :                 INIT_LIST_HEAD(&addrmap->list6);
     132                 :            : 
     133      [ #  #  # ]:          0 :                 switch (family) {
     134                 :            :                 case AF_INET: {
     135                 :            :                         const struct in_addr *addr4 = addr;
     136                 :            :                         const struct in_addr *mask4 = mask;
     137                 :            :                         map4 = kzalloc(sizeof(*map4), GFP_ATOMIC);
     138         [ #  # ]:          0 :                         if (map4 == NULL)
     139                 :            :                                 goto cfg_unlbl_map_add_failure;
     140                 :          0 :                         map4->def.type = NETLBL_NLTYPE_UNLABELED;
     141                 :          0 :                         map4->list.addr = addr4->s_addr & mask4->s_addr;
     142                 :          0 :                         map4->list.mask = mask4->s_addr;
     143                 :          0 :                         map4->list.valid = 1;
     144                 :          0 :                         ret_val = netlbl_af4list_add(&map4->list,
     145                 :            :                                                      &addrmap->list4);
     146         [ #  # ]:          0 :                         if (ret_val != 0)
     147                 :            :                                 goto cfg_unlbl_map_add_failure;
     148                 :            :                         break;
     149                 :            :                         }
     150                 :            : #if IS_ENABLED(CONFIG_IPV6)
     151                 :            :                 case AF_INET6: {
     152                 :            :                         const struct in6_addr *addr6 = addr;
     153                 :            :                         const struct in6_addr *mask6 = mask;
     154                 :            :                         map6 = kzalloc(sizeof(*map6), GFP_ATOMIC);
     155         [ #  # ]:          0 :                         if (map6 == NULL)
     156                 :            :                                 goto cfg_unlbl_map_add_failure;
     157                 :          0 :                         map6->def.type = NETLBL_NLTYPE_UNLABELED;
     158                 :          0 :                         map6->list.addr = *addr6;
     159                 :          0 :                         map6->list.addr.s6_addr32[0] &= mask6->s6_addr32[0];
     160                 :          0 :                         map6->list.addr.s6_addr32[1] &= mask6->s6_addr32[1];
     161                 :          0 :                         map6->list.addr.s6_addr32[2] &= mask6->s6_addr32[2];
     162                 :          0 :                         map6->list.addr.s6_addr32[3] &= mask6->s6_addr32[3];
     163                 :          0 :                         map6->list.mask = *mask6;
     164                 :          0 :                         map6->list.valid = 1;
     165                 :          0 :                         ret_val = netlbl_af6list_add(&map6->list,
     166                 :            :                                                      &addrmap->list6);
     167         [ #  # ]:          0 :                         if (ret_val != 0)
     168                 :            :                                 goto cfg_unlbl_map_add_failure;
     169                 :            :                         break;
     170                 :            :                         }
     171                 :            : #endif /* IPv6 */
     172                 :            :                 default:
     173                 :            :                         goto cfg_unlbl_map_add_failure;
     174                 :            :                         break;
     175                 :            :                 }
     176                 :            : 
     177                 :          0 :                 entry->def.addrsel = addrmap;
     178                 :          0 :                 entry->def.type = NETLBL_NLTYPE_ADDRSELECT;
     179                 :            :         } else {
     180                 :            :                 ret_val = -EINVAL;
     181                 :            :                 goto cfg_unlbl_map_add_failure;
     182                 :            :         }
     183                 :            : 
     184                 :          0 :         ret_val = netlbl_domhsh_add(entry, audit_info);
     185         [ #  # ]:          0 :         if (ret_val != 0)
     186                 :            :                 goto cfg_unlbl_map_add_failure;
     187                 :            : 
     188                 :            :         return 0;
     189                 :            : 
     190                 :            : cfg_unlbl_map_add_failure:
     191                 :          0 :         kfree(entry->domain);
     192                 :          0 :         kfree(entry);
     193                 :          0 :         kfree(addrmap);
     194                 :          0 :         kfree(map4);
     195                 :          0 :         kfree(map6);
     196                 :          0 :         return ret_val;
     197                 :            : }
     198                 :            : 
     199                 :            : 
     200                 :            : /**
     201                 :            :  * netlbl_cfg_unlbl_static_add - Adds a new static label
     202                 :            :  * @net: network namespace
     203                 :            :  * @dev_name: interface name
     204                 :            :  * @addr: IP address in network byte order (struct in[6]_addr)
     205                 :            :  * @mask: address mask in network byte order (struct in[6]_addr)
     206                 :            :  * @family: address family
     207                 :            :  * @secid: LSM secid value for the entry
     208                 :            :  * @audit_info: NetLabel audit information
     209                 :            :  *
     210                 :            :  * Description:
     211                 :            :  * Adds a new NetLabel static label to be used when protocol provided labels
     212                 :            :  * are not present on incoming traffic.  If @dev_name is NULL then the default
     213                 :            :  * interface will be used.  Returns zero on success, negative values on failure.
     214                 :            :  *
     215                 :            :  */
     216                 :          0 : int netlbl_cfg_unlbl_static_add(struct net *net,
     217                 :            :                                 const char *dev_name,
     218                 :            :                                 const void *addr,
     219                 :            :                                 const void *mask,
     220                 :            :                                 u16 family,
     221                 :            :                                 u32 secid,
     222                 :            :                                 struct netlbl_audit *audit_info)
     223                 :            : {
     224                 :            :         u32 addr_len;
     225                 :            : 
     226      [ #  #  # ]:          0 :         switch (family) {
     227                 :            :         case AF_INET:
     228                 :            :                 addr_len = sizeof(struct in_addr);
     229                 :            :                 break;
     230                 :            : #if IS_ENABLED(CONFIG_IPV6)
     231                 :            :         case AF_INET6:
     232                 :            :                 addr_len = sizeof(struct in6_addr);
     233                 :          0 :                 break;
     234                 :            : #endif /* IPv6 */
     235                 :            :         default:
     236                 :            :                 return -EPFNOSUPPORT;
     237                 :            :         }
     238                 :            : 
     239                 :          0 :         return netlbl_unlhsh_add(net,
     240                 :            :                                  dev_name, addr, mask, addr_len,
     241                 :            :                                  secid, audit_info);
     242                 :            : }
     243                 :            : 
     244                 :            : /**
     245                 :            :  * netlbl_cfg_unlbl_static_del - Removes an existing static label
     246                 :            :  * @net: network namespace
     247                 :            :  * @dev_name: interface name
     248                 :            :  * @addr: IP address in network byte order (struct in[6]_addr)
     249                 :            :  * @mask: address mask in network byte order (struct in[6]_addr)
     250                 :            :  * @family: address family
     251                 :            :  * @secid: LSM secid value for the entry
     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                 :          0 : 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      [ #  #  # ]:          0 :         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                 :          0 :                 break;
     277                 :            : #endif /* IPv6 */
     278                 :            :         default:
     279                 :            :                 return -EPFNOSUPPORT;
     280                 :            :         }
     281                 :            : 
     282                 :          0 :         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                 :          0 : int netlbl_cfg_cipsov4_add(struct cipso_v4_doi *doi_def,
     298                 :            :                            struct netlbl_audit *audit_info)
     299                 :            : {
     300                 :          0 :         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                 :          0 : void netlbl_cfg_cipsov4_del(u32 doi, struct netlbl_audit *audit_info)
     314                 :            : {
     315                 :          0 :         cipso_v4_doi_remove(doi, audit_info);
     316                 :          0 : }
     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                 :          0 : 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                 :          0 :         doi_def = cipso_v4_doi_getdef(doi);
     345         [ #  # ]:          0 :         if (doi_def == NULL)
     346                 :            :                 return -ENOENT;
     347                 :            : 
     348                 :            :         entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
     349         [ #  # ]:          0 :         if (entry == NULL)
     350                 :            :                 goto out_entry;
     351         [ #  # ]:          0 :         if (domain != NULL) {
     352                 :          0 :                 entry->domain = kstrdup(domain, GFP_ATOMIC);
     353         [ #  # ]:          0 :                 if (entry->domain == NULL)
     354                 :            :                         goto out_domain;
     355                 :            :         }
     356                 :            : 
     357         [ #  # ]:          0 :         if (addr == NULL && mask == NULL) {
     358                 :          0 :                 entry->def.cipso = doi_def;
     359                 :          0 :                 entry->def.type = NETLBL_NLTYPE_CIPSOV4;
     360         [ #  # ]:          0 :         } else if (addr != NULL && mask != NULL) {
     361                 :            :                 addrmap = kzalloc(sizeof(*addrmap), GFP_ATOMIC);
     362         [ #  # ]:          0 :                 if (addrmap == NULL)
     363                 :            :                         goto out_addrmap;
     364                 :          0 :                 INIT_LIST_HEAD(&addrmap->list4);
     365                 :          0 :                 INIT_LIST_HEAD(&addrmap->list6);
     366                 :            : 
     367                 :            :                 addrinfo = kzalloc(sizeof(*addrinfo), GFP_ATOMIC);
     368         [ #  # ]:          0 :                 if (addrinfo == NULL)
     369                 :            :                         goto out_addrinfo;
     370                 :          0 :                 addrinfo->def.cipso = doi_def;
     371                 :          0 :                 addrinfo->def.type = NETLBL_NLTYPE_CIPSOV4;
     372                 :          0 :                 addrinfo->list.addr = addr->s_addr & mask->s_addr;
     373                 :          0 :                 addrinfo->list.mask = mask->s_addr;
     374                 :          0 :                 addrinfo->list.valid = 1;
     375                 :          0 :                 ret_val = netlbl_af4list_add(&addrinfo->list, &addrmap->list4);
     376         [ #  # ]:          0 :                 if (ret_val != 0)
     377                 :            :                         goto cfg_cipsov4_map_add_failure;
     378                 :            : 
     379                 :          0 :                 entry->def.addrsel = addrmap;
     380                 :          0 :                 entry->def.type = NETLBL_NLTYPE_ADDRSELECT;
     381                 :            :         } else {
     382                 :            :                 ret_val = -EINVAL;
     383                 :            :                 goto out_addrmap;
     384                 :            :         }
     385                 :            : 
     386                 :          0 :         ret_val = netlbl_domhsh_add(entry, audit_info);
     387         [ #  # ]:          0 :         if (ret_val != 0)
     388                 :            :                 goto cfg_cipsov4_map_add_failure;
     389                 :            : 
     390                 :            :         return 0;
     391                 :            : 
     392                 :            : cfg_cipsov4_map_add_failure:
     393                 :          0 :         kfree(addrinfo);
     394                 :            : out_addrinfo:
     395                 :          0 :         kfree(addrmap);
     396                 :            : out_addrmap:
     397                 :          0 :         kfree(entry->domain);
     398                 :            : out_domain:
     399                 :          0 :         kfree(entry);
     400                 :            : out_entry:
     401                 :          0 :         cipso_v4_doi_putdef(doi_def);
     402                 :          0 :         return ret_val;
     403                 :            : }
     404                 :            : 
     405                 :            : /*
     406                 :            :  * Security Attribute Functions
     407                 :            :  */
     408                 :            : 
     409                 :            : /**
     410                 :            :  * netlbl_secattr_catmap_walk - Walk a LSM secattr catmap looking for a bit
     411                 :            :  * @catmap: the category bitmap
     412                 :            :  * @offset: the offset to start searching at, in bits
     413                 :            :  *
     414                 :            :  * Description:
     415                 :            :  * This function walks a LSM secattr category bitmap starting at @offset and
     416                 :            :  * returns the spot of the first set bit or -ENOENT if no bits are set.
     417                 :            :  *
     418                 :            :  */
     419                 :          0 : int netlbl_secattr_catmap_walk(struct netlbl_lsm_secattr_catmap *catmap,
     420                 :            :                                u32 offset)
     421                 :            : {
     422                 :            :         struct netlbl_lsm_secattr_catmap *iter = catmap;
     423                 :            :         u32 node_idx;
     424                 :            :         u32 node_bit;
     425                 :            :         NETLBL_CATMAP_MAPTYPE bitmap;
     426                 :            : 
     427         [ #  # ]:          0 :         if (offset > iter->startbit) {
     428         [ #  # ]:          0 :                 while (offset >= (iter->startbit + NETLBL_CATMAP_SIZE)) {
     429                 :          0 :                         iter = iter->next;
     430         [ #  # ]:          0 :                         if (iter == NULL)
     431                 :            :                                 return -ENOENT;
     432                 :            :                 }
     433                 :          0 :                 node_idx = (offset - iter->startbit) / NETLBL_CATMAP_MAPSIZE;
     434                 :          0 :                 node_bit = offset - iter->startbit -
     435                 :          0 :                            (NETLBL_CATMAP_MAPSIZE * node_idx);
     436                 :            :         } else {
     437                 :            :                 node_idx = 0;
     438                 :            :                 node_bit = 0;
     439                 :            :         }
     440                 :          0 :         bitmap = iter->bitmap[node_idx] >> node_bit;
     441                 :            : 
     442                 :            :         for (;;) {
     443         [ #  # ]:          0 :                 if (bitmap != 0) {
     444         [ #  # ]:          0 :                         while ((bitmap & NETLBL_CATMAP_BIT) == 0) {
     445                 :          0 :                                 bitmap >>= 1;
     446                 :          0 :                                 node_bit++;
     447                 :            :                         }
     448                 :          0 :                         return iter->startbit +
     449                 :          0 :                                 (NETLBL_CATMAP_MAPSIZE * node_idx) + node_bit;
     450                 :            :                 }
     451         [ #  # ]:          0 :                 if (++node_idx >= NETLBL_CATMAP_MAPCNT) {
     452         [ #  # ]:          0 :                         if (iter->next != NULL) {
     453                 :            :                                 iter = iter->next;
     454                 :            :                                 node_idx = 0;
     455                 :            :                         } else
     456                 :            :                                 return -ENOENT;
     457                 :            :                 }
     458                 :          0 :                 bitmap = iter->bitmap[node_idx];
     459                 :            :                 node_bit = 0;
     460                 :          0 :         }
     461                 :            : 
     462                 :            :         return -ENOENT;
     463                 :            : }
     464                 :            : 
     465                 :            : /**
     466                 :            :  * netlbl_secattr_catmap_walk_rng - Find the end of a string of set bits
     467                 :            :  * @catmap: the category bitmap
     468                 :            :  * @offset: the offset to start searching at, in bits
     469                 :            :  *
     470                 :            :  * Description:
     471                 :            :  * This function walks a LSM secattr category bitmap starting at @offset and
     472                 :            :  * returns the spot of the first cleared bit or -ENOENT if the offset is past
     473                 :            :  * the end of the bitmap.
     474                 :            :  *
     475                 :            :  */
     476                 :          0 : int netlbl_secattr_catmap_walk_rng(struct netlbl_lsm_secattr_catmap *catmap,
     477                 :            :                                    u32 offset)
     478                 :            : {
     479                 :            :         struct netlbl_lsm_secattr_catmap *iter = catmap;
     480                 :            :         u32 node_idx;
     481                 :            :         u32 node_bit;
     482                 :            :         NETLBL_CATMAP_MAPTYPE bitmask;
     483                 :            :         NETLBL_CATMAP_MAPTYPE bitmap;
     484                 :            : 
     485         [ #  # ]:          0 :         if (offset > iter->startbit) {
     486         [ #  # ]:          0 :                 while (offset >= (iter->startbit + NETLBL_CATMAP_SIZE)) {
     487                 :          0 :                         iter = iter->next;
     488         [ #  # ]:          0 :                         if (iter == NULL)
     489                 :            :                                 return -ENOENT;
     490                 :            :                 }
     491                 :          0 :                 node_idx = (offset - iter->startbit) / NETLBL_CATMAP_MAPSIZE;
     492                 :          0 :                 node_bit = offset - iter->startbit -
     493                 :          0 :                            (NETLBL_CATMAP_MAPSIZE * node_idx);
     494                 :            :         } else {
     495                 :            :                 node_idx = 0;
     496                 :            :                 node_bit = 0;
     497                 :            :         }
     498                 :          0 :         bitmask = NETLBL_CATMAP_BIT << node_bit;
     499                 :            : 
     500                 :            :         for (;;) {
     501                 :          0 :                 bitmap = iter->bitmap[node_idx];
     502 [ #  # ][ #  # ]:          0 :                 while (bitmask != 0 && (bitmap & bitmask) != 0) {
     503                 :          0 :                         bitmask <<= 1;
     504                 :          0 :                         node_bit++;
     505                 :            :                 }
     506                 :            : 
     507         [ #  # ]:          0 :                 if (bitmask != 0)
     508                 :          0 :                         return iter->startbit +
     509                 :          0 :                                 (NETLBL_CATMAP_MAPSIZE * node_idx) +
     510                 :          0 :                                 node_bit - 1;
     511         [ #  # ]:          0 :                 else if (++node_idx >= NETLBL_CATMAP_MAPCNT) {
     512         [ #  # ]:          0 :                         if (iter->next == NULL)
     513                 :          0 :                                 return iter->startbit +      NETLBL_CATMAP_SIZE - 1;
     514                 :            :                         iter = iter->next;
     515                 :            :                         node_idx = 0;
     516                 :            :                 }
     517                 :            :                 bitmask = NETLBL_CATMAP_BIT;
     518                 :            :                 node_bit = 0;
     519                 :            :         }
     520                 :            : 
     521                 :            :         return -ENOENT;
     522                 :            : }
     523                 :            : 
     524                 :            : /**
     525                 :            :  * netlbl_secattr_catmap_setbit - Set a bit in a LSM secattr catmap
     526                 :            :  * @catmap: the category bitmap
     527                 :            :  * @bit: the bit to set
     528                 :            :  * @flags: memory allocation flags
     529                 :            :  *
     530                 :            :  * Description:
     531                 :            :  * Set the bit specified by @bit in @catmap.  Returns zero on success,
     532                 :            :  * negative values on failure.
     533                 :            :  *
     534                 :            :  */
     535                 :          0 : int netlbl_secattr_catmap_setbit(struct netlbl_lsm_secattr_catmap *catmap,
     536                 :            :                                  u32 bit,
     537                 :            :                                  gfp_t flags)
     538                 :            : {
     539                 :            :         struct netlbl_lsm_secattr_catmap *iter = catmap;
     540                 :            :         u32 node_bit;
     541                 :            :         u32 node_idx;
     542                 :            : 
     543 [ #  # ][ #  # ]:          0 :         while (iter->next != NULL &&
     544                 :          0 :                bit >= (iter->startbit + NETLBL_CATMAP_SIZE))
     545                 :            :                 iter = iter->next;
     546         [ #  # ]:          0 :         if (bit >= (iter->startbit + NETLBL_CATMAP_SIZE)) {
     547                 :          0 :                 iter->next = netlbl_secattr_catmap_alloc(flags);
     548         [ #  # ]:          0 :                 if (iter->next == NULL)
     549                 :            :                         return -ENOMEM;
     550                 :            :                 iter = iter->next;
     551                 :          0 :                 iter->startbit = bit & ~(NETLBL_CATMAP_SIZE - 1);
     552                 :            :         }
     553                 :            : 
     554                 :            :         /* gcc always rounds to zero when doing integer division */
     555                 :          0 :         node_idx = (bit - iter->startbit) / NETLBL_CATMAP_MAPSIZE;
     556                 :          0 :         node_bit = bit - iter->startbit - (NETLBL_CATMAP_MAPSIZE * node_idx);
     557                 :          0 :         iter->bitmap[node_idx] |= NETLBL_CATMAP_BIT << node_bit;
     558                 :            : 
     559                 :          0 :         return 0;
     560                 :            : }
     561                 :            : 
     562                 :            : /**
     563                 :            :  * netlbl_secattr_catmap_setrng - Set a range of bits in a LSM secattr catmap
     564                 :            :  * @catmap: the category bitmap
     565                 :            :  * @start: the starting bit
     566                 :            :  * @end: the last bit in the string
     567                 :            :  * @flags: memory allocation flags
     568                 :            :  *
     569                 :            :  * Description:
     570                 :            :  * Set a range of bits, starting at @start and ending with @end.  Returns zero
     571                 :            :  * on success, negative values on failure.
     572                 :            :  *
     573                 :            :  */
     574                 :          0 : int netlbl_secattr_catmap_setrng(struct netlbl_lsm_secattr_catmap *catmap,
     575                 :            :                                  u32 start,
     576                 :            :                                  u32 end,
     577                 :            :                                  gfp_t flags)
     578                 :            : {
     579                 :            :         int ret_val = 0;
     580                 :            :         struct netlbl_lsm_secattr_catmap *iter = catmap;
     581                 :            :         u32 iter_max_spot;
     582                 :            :         u32 spot;
     583                 :            : 
     584                 :            :         /* XXX - This could probably be made a bit faster by combining writes
     585                 :            :          * to the catmap instead of setting a single bit each time, but for
     586                 :            :          * right now skipping to the start of the range in the catmap should
     587                 :            :          * be a nice improvement over calling the individual setbit function
     588                 :            :          * repeatedly from a loop. */
     589                 :            : 
     590 [ #  # ][ #  # ]:          0 :         while (iter->next != NULL &&
     591                 :          0 :                start >= (iter->startbit + NETLBL_CATMAP_SIZE))
     592                 :            :                 iter = iter->next;
     593                 :          0 :         iter_max_spot = iter->startbit + NETLBL_CATMAP_SIZE;
     594                 :            : 
     595         [ #  # ]:          0 :         for (spot = start; spot <= end && ret_val == 0; spot++) {
     596 [ #  # ][ #  # ]:          0 :                 if (spot >= iter_max_spot && iter->next != NULL) {
     597                 :            :                         iter = iter->next;
     598                 :          0 :                         iter_max_spot = iter->startbit + NETLBL_CATMAP_SIZE;
     599                 :            :                 }
     600                 :          0 :                 ret_val = netlbl_secattr_catmap_setbit(iter, spot, flags);
     601                 :            :         }
     602                 :            : 
     603                 :          0 :         return ret_val;
     604                 :            : }
     605                 :            : 
     606                 :            : /*
     607                 :            :  * LSM Functions
     608                 :            :  */
     609                 :            : 
     610                 :            : /**
     611                 :            :  * netlbl_enabled - Determine if the NetLabel subsystem is enabled
     612                 :            :  *
     613                 :            :  * Description:
     614                 :            :  * The LSM can use this function to determine if it should use NetLabel
     615                 :            :  * security attributes in it's enforcement mechanism.  Currently, NetLabel is
     616                 :            :  * considered to be enabled when it's configuration contains a valid setup for
     617                 :            :  * at least one labeled protocol (i.e. NetLabel can understand incoming
     618                 :            :  * labeled packets of at least one type); otherwise NetLabel is considered to
     619                 :            :  * be disabled.
     620                 :            :  *
     621                 :            :  */
     622                 :          0 : int netlbl_enabled(void)
     623                 :            : {
     624                 :            :         /* At some point we probably want to expose this mechanism to the user
     625                 :            :          * as well so that admins can toggle NetLabel regardless of the
     626                 :            :          * configuration */
     627                 :          0 :         return (atomic_read(&netlabel_mgmt_protocount) > 0);
     628                 :            : }
     629                 :            : 
     630                 :            : /**
     631                 :            :  * netlbl_sock_setattr - Label a socket using the correct protocol
     632                 :            :  * @sk: the socket to label
     633                 :            :  * @family: protocol family
     634                 :            :  * @secattr: the security attributes
     635                 :            :  *
     636                 :            :  * Description:
     637                 :            :  * Attach the correct label to the given socket using the security attributes
     638                 :            :  * specified in @secattr.  This function requires exclusive access to @sk,
     639                 :            :  * which means it either needs to be in the process of being created or locked.
     640                 :            :  * Returns zero on success, -EDESTADDRREQ if the domain is configured to use
     641                 :            :  * network address selectors (can't blindly label the socket), and negative
     642                 :            :  * values on all other failures.
     643                 :            :  *
     644                 :            :  */
     645                 :          0 : int netlbl_sock_setattr(struct sock *sk,
     646                 :            :                         u16 family,
     647                 :            :                         const struct netlbl_lsm_secattr *secattr)
     648                 :            : {
     649                 :            :         int ret_val;
     650                 :            :         struct netlbl_dom_map *dom_entry;
     651                 :            : 
     652                 :            :         rcu_read_lock();
     653                 :          0 :         dom_entry = netlbl_domhsh_getentry(secattr->domain);
     654         [ #  # ]:          0 :         if (dom_entry == NULL) {
     655                 :            :                 ret_val = -ENOENT;
     656                 :            :                 goto socket_setattr_return;
     657                 :            :         }
     658      [ #  #  # ]:          0 :         switch (family) {
     659                 :            :         case AF_INET:
     660   [ #  #  #  # ]:          0 :                 switch (dom_entry->def.type) {
     661                 :            :                 case NETLBL_NLTYPE_ADDRSELECT:
     662                 :            :                         ret_val = -EDESTADDRREQ;
     663                 :            :                         break;
     664                 :            :                 case NETLBL_NLTYPE_CIPSOV4:
     665                 :          0 :                         ret_val = cipso_v4_sock_setattr(sk,
     666                 :          0 :                                                         dom_entry->def.cipso,
     667                 :            :                                                         secattr);
     668                 :          0 :                         break;
     669                 :            :                 case NETLBL_NLTYPE_UNLABELED:
     670                 :            :                         ret_val = 0;
     671                 :          0 :                         break;
     672                 :            :                 default:
     673                 :            :                         ret_val = -ENOENT;
     674                 :            :                 }
     675                 :            :                 break;
     676                 :            : #if IS_ENABLED(CONFIG_IPV6)
     677                 :            :         case AF_INET6:
     678                 :            :                 /* since we don't support any IPv6 labeling protocols right
     679                 :            :                  * now we can optimize everything away until we do */
     680                 :            :                 ret_val = 0;
     681                 :            :                 break;
     682                 :            : #endif /* IPv6 */
     683                 :            :         default:
     684                 :            :                 ret_val = -EPROTONOSUPPORT;
     685                 :            :         }
     686                 :            : 
     687                 :            : socket_setattr_return:
     688                 :            :         rcu_read_unlock();
     689                 :          0 :         return ret_val;
     690                 :            : }
     691                 :            : 
     692                 :            : /**
     693                 :            :  * netlbl_sock_delattr - Delete all the NetLabel labels on a socket
     694                 :            :  * @sk: the socket
     695                 :            :  *
     696                 :            :  * Description:
     697                 :            :  * Remove all the NetLabel labeling from @sk.  The caller is responsible for
     698                 :            :  * ensuring that @sk is locked.
     699                 :            :  *
     700                 :            :  */
     701                 :          0 : void netlbl_sock_delattr(struct sock *sk)
     702                 :            : {
     703                 :          0 :         cipso_v4_sock_delattr(sk);
     704                 :          0 : }
     705                 :            : 
     706                 :            : /**
     707                 :            :  * netlbl_sock_getattr - Determine the security attributes of a sock
     708                 :            :  * @sk: the sock
     709                 :            :  * @secattr: the security attributes
     710                 :            :  *
     711                 :            :  * Description:
     712                 :            :  * Examines the given sock to see if any NetLabel style labeling has been
     713                 :            :  * applied to the sock, if so it parses the socket label and returns the
     714                 :            :  * security attributes in @secattr.  Returns zero on success, negative values
     715                 :            :  * on failure.
     716                 :            :  *
     717                 :            :  */
     718                 :          0 : int netlbl_sock_getattr(struct sock *sk,
     719                 :            :                         struct netlbl_lsm_secattr *secattr)
     720                 :            : {
     721                 :            :         int ret_val;
     722                 :            : 
     723      [ #  #  # ]:          0 :         switch (sk->sk_family) {
     724                 :            :         case AF_INET:
     725                 :          0 :                 ret_val = cipso_v4_sock_getattr(sk, secattr);
     726                 :          0 :                 break;
     727                 :            : #if IS_ENABLED(CONFIG_IPV6)
     728                 :            :         case AF_INET6:
     729                 :            :                 ret_val = -ENOMSG;
     730                 :            :                 break;
     731                 :            : #endif /* IPv6 */
     732                 :            :         default:
     733                 :            :                 ret_val = -EPROTONOSUPPORT;
     734                 :            :         }
     735                 :            : 
     736                 :          0 :         return ret_val;
     737                 :            : }
     738                 :            : 
     739                 :            : /**
     740                 :            :  * netlbl_conn_setattr - Label a connected socket using the correct protocol
     741                 :            :  * @sk: the socket to label
     742                 :            :  * @addr: the destination address
     743                 :            :  * @secattr: the security attributes
     744                 :            :  *
     745                 :            :  * Description:
     746                 :            :  * Attach the correct label to the given connected socket using the security
     747                 :            :  * attributes specified in @secattr.  The caller is responsible for ensuring
     748                 :            :  * that @sk is locked.  Returns zero on success, negative values on failure.
     749                 :            :  *
     750                 :            :  */
     751                 :          0 : int netlbl_conn_setattr(struct sock *sk,
     752                 :            :                         struct sockaddr *addr,
     753                 :            :                         const struct netlbl_lsm_secattr *secattr)
     754                 :            : {
     755                 :            :         int ret_val;
     756                 :            :         struct sockaddr_in *addr4;
     757                 :            :         struct netlbl_dommap_def *entry;
     758                 :            : 
     759                 :            :         rcu_read_lock();
     760      [ #  #  # ]:          0 :         switch (addr->sa_family) {
     761                 :            :         case AF_INET:
     762                 :            :                 addr4 = (struct sockaddr_in *)addr;
     763                 :          0 :                 entry = netlbl_domhsh_getentry_af4(secattr->domain,
     764                 :            :                                                    addr4->sin_addr.s_addr);
     765         [ #  # ]:          0 :                 if (entry == NULL) {
     766                 :            :                         ret_val = -ENOENT;
     767                 :            :                         goto conn_setattr_return;
     768                 :            :                 }
     769      [ #  #  # ]:          0 :                 switch (entry->type) {
     770                 :            :                 case NETLBL_NLTYPE_CIPSOV4:
     771                 :          0 :                         ret_val = cipso_v4_sock_setattr(sk,
     772                 :          0 :                                                         entry->cipso, secattr);
     773                 :          0 :                         break;
     774                 :            :                 case NETLBL_NLTYPE_UNLABELED:
     775                 :            :                         /* just delete the protocols we support for right now
     776                 :            :                          * but we could remove other protocols if needed */
     777                 :          0 :                         cipso_v4_sock_delattr(sk);
     778                 :            :                         ret_val = 0;
     779                 :          0 :                         break;
     780                 :            :                 default:
     781                 :            :                         ret_val = -ENOENT;
     782                 :            :                 }
     783                 :            :                 break;
     784                 :            : #if IS_ENABLED(CONFIG_IPV6)
     785                 :            :         case AF_INET6:
     786                 :            :                 /* since we don't support any IPv6 labeling protocols right
     787                 :            :                  * now we can optimize everything away until we do */
     788                 :            :                 ret_val = 0;
     789                 :            :                 break;
     790                 :            : #endif /* IPv6 */
     791                 :            :         default:
     792                 :            :                 ret_val = -EPROTONOSUPPORT;
     793                 :            :         }
     794                 :            : 
     795                 :            : conn_setattr_return:
     796                 :            :         rcu_read_unlock();
     797                 :          0 :         return ret_val;
     798                 :            : }
     799                 :            : 
     800                 :            : /**
     801                 :            :  * netlbl_req_setattr - Label a request socket using the correct protocol
     802                 :            :  * @req: the request socket to label
     803                 :            :  * @secattr: the security attributes
     804                 :            :  *
     805                 :            :  * Description:
     806                 :            :  * Attach the correct label to the given socket using the security attributes
     807                 :            :  * specified in @secattr.  Returns zero on success, negative values on failure.
     808                 :            :  *
     809                 :            :  */
     810                 :          0 : int netlbl_req_setattr(struct request_sock *req,
     811                 :            :                        const struct netlbl_lsm_secattr *secattr)
     812                 :            : {
     813                 :            :         int ret_val;
     814                 :            :         struct netlbl_dommap_def *entry;
     815                 :            : 
     816                 :            :         rcu_read_lock();
     817      [ #  #  # ]:          0 :         switch (req->rsk_ops->family) {
     818                 :            :         case AF_INET:
     819                 :          0 :                 entry = netlbl_domhsh_getentry_af4(secattr->domain,
     820                 :            :                                                    inet_rsk(req)->ir_rmt_addr);
     821         [ #  # ]:          0 :                 if (entry == NULL) {
     822                 :            :                         ret_val = -ENOENT;
     823                 :            :                         goto req_setattr_return;
     824                 :            :                 }
     825      [ #  #  # ]:          0 :                 switch (entry->type) {
     826                 :            :                 case NETLBL_NLTYPE_CIPSOV4:
     827                 :          0 :                         ret_val = cipso_v4_req_setattr(req,
     828                 :          0 :                                                        entry->cipso, secattr);
     829                 :          0 :                         break;
     830                 :            :                 case NETLBL_NLTYPE_UNLABELED:
     831                 :            :                         /* just delete the protocols we support for right now
     832                 :            :                          * but we could remove other protocols if needed */
     833                 :          0 :                         cipso_v4_req_delattr(req);
     834                 :            :                         ret_val = 0;
     835                 :          0 :                         break;
     836                 :            :                 default:
     837                 :            :                         ret_val = -ENOENT;
     838                 :            :                 }
     839                 :            :                 break;
     840                 :            : #if IS_ENABLED(CONFIG_IPV6)
     841                 :            :         case AF_INET6:
     842                 :            :                 /* since we don't support any IPv6 labeling protocols right
     843                 :            :                  * now we can optimize everything away until we do */
     844                 :            :                 ret_val = 0;
     845                 :            :                 break;
     846                 :            : #endif /* IPv6 */
     847                 :            :         default:
     848                 :            :                 ret_val = -EPROTONOSUPPORT;
     849                 :            :         }
     850                 :            : 
     851                 :            : req_setattr_return:
     852                 :            :         rcu_read_unlock();
     853                 :          0 :         return ret_val;
     854                 :            : }
     855                 :            : 
     856                 :            : /**
     857                 :            : * netlbl_req_delattr - Delete all the NetLabel labels on a socket
     858                 :            : * @req: the socket
     859                 :            : *
     860                 :            : * Description:
     861                 :            : * Remove all the NetLabel labeling from @req.
     862                 :            : *
     863                 :            : */
     864                 :          0 : void netlbl_req_delattr(struct request_sock *req)
     865                 :            : {
     866                 :          0 :         cipso_v4_req_delattr(req);
     867                 :          0 : }
     868                 :            : 
     869                 :            : /**
     870                 :            :  * netlbl_skbuff_setattr - Label a packet using the correct protocol
     871                 :            :  * @skb: the packet
     872                 :            :  * @family: protocol family
     873                 :            :  * @secattr: the security attributes
     874                 :            :  *
     875                 :            :  * Description:
     876                 :            :  * Attach the correct label to the given packet using the security attributes
     877                 :            :  * specified in @secattr.  Returns zero on success, negative values on failure.
     878                 :            :  *
     879                 :            :  */
     880                 :          0 : int netlbl_skbuff_setattr(struct sk_buff *skb,
     881                 :            :                           u16 family,
     882                 :            :                           const struct netlbl_lsm_secattr *secattr)
     883                 :            : {
     884                 :            :         int ret_val;
     885                 :            :         struct iphdr *hdr4;
     886                 :            :         struct netlbl_dommap_def *entry;
     887                 :            : 
     888                 :            :         rcu_read_lock();
     889      [ #  #  # ]:          0 :         switch (family) {
     890                 :            :         case AF_INET:
     891                 :            :                 hdr4 = ip_hdr(skb);
     892                 :          0 :                 entry = netlbl_domhsh_getentry_af4(secattr->domain,hdr4->daddr);
     893         [ #  # ]:          0 :                 if (entry == NULL) {
     894                 :            :                         ret_val = -ENOENT;
     895                 :            :                         goto skbuff_setattr_return;
     896                 :            :                 }
     897      [ #  #  # ]:          0 :                 switch (entry->type) {
     898                 :            :                 case NETLBL_NLTYPE_CIPSOV4:
     899                 :          0 :                         ret_val = cipso_v4_skbuff_setattr(skb, entry->cipso,
     900                 :            :                                                           secattr);
     901                 :          0 :                         break;
     902                 :            :                 case NETLBL_NLTYPE_UNLABELED:
     903                 :            :                         /* just delete the protocols we support for right now
     904                 :            :                          * but we could remove other protocols if needed */
     905                 :          0 :                         ret_val = cipso_v4_skbuff_delattr(skb);
     906                 :          0 :                         break;
     907                 :            :                 default:
     908                 :            :                         ret_val = -ENOENT;
     909                 :            :                 }
     910                 :            :                 break;
     911                 :            : #if IS_ENABLED(CONFIG_IPV6)
     912                 :            :         case AF_INET6:
     913                 :            :                 /* since we don't support any IPv6 labeling protocols right
     914                 :            :                  * now we can optimize everything away until we do */
     915                 :            :                 ret_val = 0;
     916                 :            :                 break;
     917                 :            : #endif /* IPv6 */
     918                 :            :         default:
     919                 :            :                 ret_val = -EPROTONOSUPPORT;
     920                 :            :         }
     921                 :            : 
     922                 :            : skbuff_setattr_return:
     923                 :            :         rcu_read_unlock();
     924                 :          0 :         return ret_val;
     925                 :            : }
     926                 :            : 
     927                 :            : /**
     928                 :            :  * netlbl_skbuff_getattr - Determine the security attributes of a packet
     929                 :            :  * @skb: the packet
     930                 :            :  * @family: protocol family
     931                 :            :  * @secattr: the security attributes
     932                 :            :  *
     933                 :            :  * Description:
     934                 :            :  * Examines the given packet to see if a recognized form of packet labeling
     935                 :            :  * is present, if so it parses the packet label and returns the security
     936                 :            :  * attributes in @secattr.  Returns zero on success, negative values on
     937                 :            :  * failure.
     938                 :            :  *
     939                 :            :  */
     940                 :          0 : int netlbl_skbuff_getattr(const struct sk_buff *skb,
     941                 :            :                           u16 family,
     942                 :            :                           struct netlbl_lsm_secattr *secattr)
     943                 :            : {
     944         [ #  # ]:          0 :         switch (family) {
     945                 :            :         case AF_INET:
     946   [ #  #  #  # ]:          0 :                 if (CIPSO_V4_OPTEXIST(skb) &&
     947                 :          0 :                     cipso_v4_skbuff_getattr(skb, secattr) == 0)
     948                 :            :                         return 0;
     949                 :            :                 break;
     950                 :            : #if IS_ENABLED(CONFIG_IPV6)
     951                 :            :         case AF_INET6:
     952                 :            :                 break;
     953                 :            : #endif /* IPv6 */
     954                 :            :         }
     955                 :            : 
     956                 :          0 :         return netlbl_unlabel_getattr(skb, family, secattr);
     957                 :            : }
     958                 :            : 
     959                 :            : /**
     960                 :            :  * netlbl_skbuff_err - Handle a LSM error on a sk_buff
     961                 :            :  * @skb: the packet
     962                 :            :  * @error: the error code
     963                 :            :  * @gateway: true if host is acting as a gateway, false otherwise
     964                 :            :  *
     965                 :            :  * Description:
     966                 :            :  * Deal with a LSM problem when handling the packet in @skb, typically this is
     967                 :            :  * a permission denied problem (-EACCES).  The correct action is determined
     968                 :            :  * according to the packet's labeling protocol.
     969                 :            :  *
     970                 :            :  */
     971                 :          0 : void netlbl_skbuff_err(struct sk_buff *skb, int error, int gateway)
     972                 :            : {
     973         [ #  # ]:          0 :         if (CIPSO_V4_OPTEXIST(skb))
     974                 :          0 :                 cipso_v4_error(skb, error, gateway);
     975                 :          0 : }
     976                 :            : 
     977                 :            : /**
     978                 :            :  * netlbl_cache_invalidate - Invalidate all of the NetLabel protocol caches
     979                 :            :  *
     980                 :            :  * Description:
     981                 :            :  * For all of the NetLabel protocols that support some form of label mapping
     982                 :            :  * cache, invalidate the cache.  Returns zero on success, negative values on
     983                 :            :  * error.
     984                 :            :  *
     985                 :            :  */
     986                 :          0 : void netlbl_cache_invalidate(void)
     987                 :            : {
     988                 :          0 :         cipso_v4_cache_invalidate();
     989                 :          0 : }
     990                 :            : 
     991                 :            : /**
     992                 :            :  * netlbl_cache_add - Add an entry to a NetLabel protocol cache
     993                 :            :  * @skb: the packet
     994                 :            :  * @secattr: the packet's security attributes
     995                 :            :  *
     996                 :            :  * Description:
     997                 :            :  * Add the LSM security attributes for the given packet to the underlying
     998                 :            :  * NetLabel protocol's label mapping cache.  Returns zero on success, negative
     999                 :            :  * values on error.
    1000                 :            :  *
    1001                 :            :  */
    1002                 :          0 : int netlbl_cache_add(const struct sk_buff *skb,
    1003                 :            :                      const struct netlbl_lsm_secattr *secattr)
    1004                 :            : {
    1005         [ #  # ]:          0 :         if ((secattr->flags & NETLBL_SECATTR_CACHE) == 0)
    1006                 :            :                 return -ENOMSG;
    1007                 :            : 
    1008         [ #  # ]:          0 :         if (CIPSO_V4_OPTEXIST(skb))
    1009                 :          0 :                 return cipso_v4_cache_add(skb, secattr);
    1010                 :            : 
    1011                 :            :         return -ENOMSG;
    1012                 :            : }
    1013                 :            : 
    1014                 :            : /*
    1015                 :            :  * Protocol Engine Functions
    1016                 :            :  */
    1017                 :            : 
    1018                 :            : /**
    1019                 :            :  * netlbl_audit_start - Start an audit message
    1020                 :            :  * @type: audit message type
    1021                 :            :  * @audit_info: NetLabel audit information
    1022                 :            :  *
    1023                 :            :  * Description:
    1024                 :            :  * Start an audit message using the type specified in @type and fill the audit
    1025                 :            :  * message with some fields common to all NetLabel audit messages.  This
    1026                 :            :  * function should only be used by protocol engines, not LSMs.  Returns a
    1027                 :            :  * pointer to the audit buffer on success, NULL on failure.
    1028                 :            :  *
    1029                 :            :  */
    1030                 :          0 : struct audit_buffer *netlbl_audit_start(int type,
    1031                 :            :                                         struct netlbl_audit *audit_info)
    1032                 :            : {
    1033                 :          0 :         return netlbl_audit_start_common(type, audit_info);
    1034                 :            : }
    1035                 :            : 
    1036                 :            : /*
    1037                 :            :  * Setup Functions
    1038                 :            :  */
    1039                 :            : 
    1040                 :            : /**
    1041                 :            :  * netlbl_init - Initialize NetLabel
    1042                 :            :  *
    1043                 :            :  * Description:
    1044                 :            :  * Perform the required NetLabel initialization before first use.
    1045                 :            :  *
    1046                 :            :  */
    1047                 :          0 : static int __init netlbl_init(void)
    1048                 :            : {
    1049                 :            :         int ret_val;
    1050                 :            : 
    1051                 :          0 :         printk(KERN_INFO "NetLabel: Initializing\n");
    1052                 :          0 :         printk(KERN_INFO "NetLabel:  domain hash size = %u\n",
    1053                 :            :                (1 << NETLBL_DOMHSH_BITSIZE));
    1054                 :          0 :         printk(KERN_INFO "NetLabel:  protocols ="
    1055                 :            :                " UNLABELED"
    1056                 :            :                " CIPSOv4"
    1057                 :            :                "\n");
    1058                 :            : 
    1059                 :          0 :         ret_val = netlbl_domhsh_init(NETLBL_DOMHSH_BITSIZE);
    1060         [ #  # ]:          0 :         if (ret_val != 0)
    1061                 :            :                 goto init_failure;
    1062                 :            : 
    1063                 :          0 :         ret_val = netlbl_unlabel_init(NETLBL_UNLHSH_BITSIZE);
    1064         [ #  # ]:          0 :         if (ret_val != 0)
    1065                 :            :                 goto init_failure;
    1066                 :            : 
    1067                 :          0 :         ret_val = netlbl_netlink_init();
    1068         [ #  # ]:          0 :         if (ret_val != 0)
    1069                 :            :                 goto init_failure;
    1070                 :            : 
    1071                 :          0 :         ret_val = netlbl_unlabel_defconf();
    1072         [ #  # ]:          0 :         if (ret_val != 0)
    1073                 :            :                 goto init_failure;
    1074                 :          0 :         printk(KERN_INFO "NetLabel:  unlabeled traffic allowed by default\n");
    1075                 :            : 
    1076                 :          0 :         return 0;
    1077                 :            : 
    1078                 :            : init_failure:
    1079                 :          0 :         panic("NetLabel: failed to initialize properly (%d)\n", ret_val);
    1080                 :            : }
    1081                 :            : 
    1082                 :            : subsys_initcall(netlbl_init);

Generated by: LCOV version 1.9