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

Generated by: LCOV version 1.9