LCOV - code coverage report
Current view: top level - security/selinux/ss - mls.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 210 0.0 %
Date: 2014-02-18 Functions: 0 15 0.0 %
Branches: 0 199 0.0 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Implementation of the multi-level security (MLS) policy.
       3                 :            :  *
       4                 :            :  * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
       5                 :            :  */
       6                 :            : /*
       7                 :            :  * Updated: Trusted Computer Solutions, Inc. <dgoeddel@trustedcs.com>
       8                 :            :  *
       9                 :            :  *      Support for enhanced MLS infrastructure.
      10                 :            :  *
      11                 :            :  * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc.
      12                 :            :  */
      13                 :            : /*
      14                 :            :  * Updated: Hewlett-Packard <paul@paul-moore.com>
      15                 :            :  *
      16                 :            :  *      Added support to import/export the MLS label from NetLabel
      17                 :            :  *
      18                 :            :  * (c) Copyright Hewlett-Packard Development Company, L.P., 2006
      19                 :            :  */
      20                 :            : 
      21                 :            : #include <linux/kernel.h>
      22                 :            : #include <linux/slab.h>
      23                 :            : #include <linux/string.h>
      24                 :            : #include <linux/errno.h>
      25                 :            : #include <net/netlabel.h>
      26                 :            : #include "sidtab.h"
      27                 :            : #include "mls.h"
      28                 :            : #include "policydb.h"
      29                 :            : #include "services.h"
      30                 :            : 
      31                 :            : /*
      32                 :            :  * Return the length in bytes for the MLS fields of the
      33                 :            :  * security context string representation of `context'.
      34                 :            :  */
      35                 :          0 : int mls_compute_context_len(struct context *context)
      36                 :            : {
      37                 :            :         int i, l, len, head, prev;
      38                 :            :         char *nm;
      39                 :            :         struct ebitmap *e;
      40                 :            :         struct ebitmap_node *node;
      41                 :            : 
      42         [ #  # ]:          0 :         if (!policydb.mls_enabled)
      43                 :            :                 return 0;
      44                 :            : 
      45                 :            :         len = 1; /* for the beginning ":" */
      46         [ #  # ]:          0 :         for (l = 0; l < 2; l++) {
      47                 :          0 :                 int index_sens = context->range.level[l].sens;
      48                 :          0 :                 len += strlen(sym_name(&policydb, SYM_LEVELS, index_sens - 1));
      49                 :            : 
      50                 :            :                 /* categories */
      51                 :            :                 head = -2;
      52                 :            :                 prev = -2;
      53                 :          0 :                 e = &context->range.level[l].cat;
      54         [ #  # ]:          0 :                 ebitmap_for_each_positive_bit(e, node, i) {
      55         [ #  # ]:          0 :                         if (i - prev > 1) {
      56                 :            :                                 /* one or more negative bits are skipped */
      57         [ #  # ]:          0 :                                 if (head != prev) {
      58                 :          0 :                                         nm = sym_name(&policydb, SYM_CATS, prev);
      59                 :          0 :                                         len += strlen(nm) + 1;
      60                 :            :                                 }
      61                 :            :                                 nm = sym_name(&policydb, SYM_CATS, i);
      62                 :          0 :                                 len += strlen(nm) + 1;
      63                 :            :                                 head = i;
      64                 :            :                         }
      65                 :            :                         prev = i;
      66                 :            :                 }
      67         [ #  # ]:          0 :                 if (prev != head) {
      68                 :          0 :                         nm = sym_name(&policydb, SYM_CATS, prev);
      69                 :          0 :                         len += strlen(nm) + 1;
      70                 :            :                 }
      71         [ #  # ]:          0 :                 if (l == 0) {
      72         [ #  # ]:          0 :                         if (mls_level_eq(&context->range.level[0],
      73                 :            :                                          &context->range.level[1]))
      74                 :            :                                 break;
      75                 :            :                         else
      76                 :          0 :                                 len++;
      77                 :            :                 }
      78                 :            :         }
      79                 :            : 
      80                 :          0 :         return len;
      81                 :            : }
      82                 :            : 
      83                 :            : /*
      84                 :            :  * Write the security context string representation of
      85                 :            :  * the MLS fields of `context' into the string `*scontext'.
      86                 :            :  * Update `*scontext' to point to the end of the MLS fields.
      87                 :            :  */
      88                 :          0 : void mls_sid_to_context(struct context *context,
      89                 :            :                         char **scontext)
      90                 :            : {
      91                 :            :         char *scontextp, *nm;
      92                 :            :         int i, l, head, prev;
      93                 :            :         struct ebitmap *e;
      94                 :            :         struct ebitmap_node *node;
      95                 :            : 
      96         [ #  # ]:          0 :         if (!policydb.mls_enabled)
      97                 :            :                 return;
      98                 :            : 
      99                 :          0 :         scontextp = *scontext;
     100                 :            : 
     101                 :          0 :         *scontextp = ':';
     102                 :          0 :         scontextp++;
     103                 :            : 
     104         [ #  # ]:          0 :         for (l = 0; l < 2; l++) {
     105                 :          0 :                 strcpy(scontextp, sym_name(&policydb, SYM_LEVELS,
     106                 :          0 :                                            context->range.level[l].sens - 1));
     107                 :          0 :                 scontextp += strlen(scontextp);
     108                 :            : 
     109                 :            :                 /* categories */
     110                 :            :                 head = -2;
     111                 :            :                 prev = -2;
     112                 :          0 :                 e = &context->range.level[l].cat;
     113         [ #  # ]:          0 :                 ebitmap_for_each_positive_bit(e, node, i) {
     114         [ #  # ]:          0 :                         if (i - prev > 1) {
     115                 :            :                                 /* one or more negative bits are skipped */
     116         [ #  # ]:          0 :                                 if (prev != head) {
     117         [ #  # ]:          0 :                                         if (prev - head > 1)
     118                 :          0 :                                                 *scontextp++ = '.';
     119                 :            :                                         else
     120                 :          0 :                                                 *scontextp++ = ',';
     121                 :          0 :                                         nm = sym_name(&policydb, SYM_CATS, prev);
     122                 :          0 :                                         strcpy(scontextp, nm);
     123                 :          0 :                                         scontextp += strlen(nm);
     124                 :            :                                 }
     125         [ #  # ]:          0 :                                 if (prev < 0)
     126                 :          0 :                                         *scontextp++ = ':';
     127                 :            :                                 else
     128                 :          0 :                                         *scontextp++ = ',';
     129                 :            :                                 nm = sym_name(&policydb, SYM_CATS, i);
     130                 :          0 :                                 strcpy(scontextp, nm);
     131                 :          0 :                                 scontextp += strlen(nm);
     132                 :            :                                 head = i;
     133                 :            :                         }
     134                 :            :                         prev = i;
     135                 :            :                 }
     136                 :            : 
     137         [ #  # ]:          0 :                 if (prev != head) {
     138         [ #  # ]:          0 :                         if (prev - head > 1)
     139                 :          0 :                                 *scontextp++ = '.';
     140                 :            :                         else
     141                 :          0 :                                 *scontextp++ = ',';
     142                 :          0 :                         nm = sym_name(&policydb, SYM_CATS, prev);
     143                 :          0 :                         strcpy(scontextp, nm);
     144                 :          0 :                         scontextp += strlen(nm);
     145                 :            :                 }
     146                 :            : 
     147         [ #  # ]:          0 :                 if (l == 0) {
     148         [ #  # ]:          0 :                         if (mls_level_eq(&context->range.level[0],
     149                 :            :                                          &context->range.level[1]))
     150                 :            :                                 break;
     151                 :            :                         else
     152                 :          0 :                                 *scontextp++ = '-';
     153                 :            :                 }
     154                 :            :         }
     155                 :            : 
     156                 :          0 :         *scontext = scontextp;
     157                 :          0 :         return;
     158                 :            : }
     159                 :            : 
     160                 :          0 : int mls_level_isvalid(struct policydb *p, struct mls_level *l)
     161                 :            : {
     162                 :            :         struct level_datum *levdatum;
     163                 :            : 
     164 [ #  # ][ #  # ]:          0 :         if (!l->sens || l->sens > p->p_levels.nprim)
     165                 :            :                 return 0;
     166                 :          0 :         levdatum = hashtab_search(p->p_levels.table,
     167                 :          0 :                                   sym_name(p, SYM_LEVELS, l->sens - 1));
     168         [ #  # ]:          0 :         if (!levdatum)
     169                 :            :                 return 0;
     170                 :            : 
     171                 :            :         /*
     172                 :            :          * Return 1 iff all the bits set in l->cat are also be set in
     173                 :            :          * levdatum->level->cat and no bit in l->cat is larger than
     174                 :            :          * p->p_cats.nprim.
     175                 :            :          */
     176                 :          0 :         return ebitmap_contains(&levdatum->level->cat, &l->cat,
     177                 :            :                                 p->p_cats.nprim);
     178                 :            : }
     179                 :            : 
     180                 :          0 : int mls_range_isvalid(struct policydb *p, struct mls_range *r)
     181                 :            : {
     182         [ #  # ]:          0 :         return (mls_level_isvalid(p, &r->level[0]) &&
     183 [ #  # ][ #  # ]:          0 :                 mls_level_isvalid(p, &r->level[1]) &&
     184                 :            :                 mls_level_dom(&r->level[1], &r->level[0]));
     185                 :            : }
     186                 :            : 
     187                 :            : /*
     188                 :            :  * Return 1 if the MLS fields in the security context
     189                 :            :  * structure `c' are valid.  Return 0 otherwise.
     190                 :            :  */
     191                 :          0 : int mls_context_isvalid(struct policydb *p, struct context *c)
     192                 :            : {
     193                 :            :         struct user_datum *usrdatum;
     194                 :            : 
     195         [ #  # ]:          0 :         if (!p->mls_enabled)
     196                 :            :                 return 1;
     197                 :            : 
     198         [ #  # ]:          0 :         if (!mls_range_isvalid(p, &c->range))
     199                 :            :                 return 0;
     200                 :            : 
     201         [ #  # ]:          0 :         if (c->role == OBJECT_R_VAL)
     202                 :            :                 return 1;
     203                 :            : 
     204                 :            :         /*
     205                 :            :          * User must be authorized for the MLS range.
     206                 :            :          */
     207 [ #  # ][ #  # ]:          0 :         if (!c->user || c->user > p->p_users.nprim)
     208                 :            :                 return 0;
     209                 :          0 :         usrdatum = p->user_val_to_struct[c->user - 1];
     210 [ #  # ][ #  # ]:          0 :         if (!mls_range_contains(usrdatum->range, c->range))
     211                 :            :                 return 0; /* user may not be associated with range */
     212                 :            : 
     213                 :            :         return 1;
     214                 :            : }
     215                 :            : 
     216                 :            : /*
     217                 :            :  * Set the MLS fields in the security context structure
     218                 :            :  * `context' based on the string representation in
     219                 :            :  * the string `*scontext'.  Update `*scontext' to
     220                 :            :  * point to the end of the string representation of
     221                 :            :  * the MLS fields.
     222                 :            :  *
     223                 :            :  * This function modifies the string in place, inserting
     224                 :            :  * NULL characters to terminate the MLS fields.
     225                 :            :  *
     226                 :            :  * If a def_sid is provided and no MLS field is present,
     227                 :            :  * copy the MLS field of the associated default context.
     228                 :            :  * Used for upgraded to MLS systems where objects may lack
     229                 :            :  * MLS fields.
     230                 :            :  *
     231                 :            :  * Policy read-lock must be held for sidtab lookup.
     232                 :            :  *
     233                 :            :  */
     234                 :          0 : int mls_context_to_sid(struct policydb *pol,
     235                 :            :                        char oldc,
     236                 :            :                        char **scontext,
     237                 :            :                        struct context *context,
     238                 :            :                        struct sidtab *s,
     239                 :            :                        u32 def_sid)
     240                 :            : {
     241                 :            : 
     242                 :            :         char delim;
     243                 :            :         char *scontextp, *p, *rngptr;
     244                 :            :         struct level_datum *levdatum;
     245                 :            :         struct cat_datum *catdatum, *rngdatum;
     246                 :            :         int l, rc = -EINVAL;
     247                 :            : 
     248         [ #  # ]:          0 :         if (!pol->mls_enabled) {
     249         [ #  # ]:          0 :                 if (def_sid != SECSID_NULL && oldc)
     250                 :          0 :                         *scontext += strlen(*scontext) + 1;
     251                 :            :                 return 0;
     252                 :            :         }
     253                 :            : 
     254                 :            :         /*
     255                 :            :          * No MLS component to the security context, try and map to
     256                 :            :          * default if provided.
     257                 :            :          */
     258         [ #  # ]:          0 :         if (!oldc) {
     259                 :            :                 struct context *defcon;
     260                 :            : 
     261         [ #  # ]:          0 :                 if (def_sid == SECSID_NULL)
     262                 :            :                         goto out;
     263                 :            : 
     264                 :          0 :                 defcon = sidtab_search(s, def_sid);
     265         [ #  # ]:          0 :                 if (!defcon)
     266                 :            :                         goto out;
     267                 :            : 
     268                 :            :                 rc = mls_context_cpy(context, defcon);
     269                 :          0 :                 goto out;
     270                 :            :         }
     271                 :            : 
     272                 :            :         /* Extract low sensitivity. */
     273                 :          0 :         scontextp = p = *scontext;
     274 [ #  # ][ #  # ]:          0 :         while (*p && *p != ':' && *p != '-')
     275                 :          0 :                 p++;
     276                 :            : 
     277                 :            :         delim = *p;
     278         [ #  # ]:          0 :         if (delim != '\0')
     279                 :          0 :                 *p++ = '\0';
     280                 :            : 
     281         [ #  # ]:          0 :         for (l = 0; l < 2; l++) {
     282                 :          0 :                 levdatum = hashtab_search(pol->p_levels.table, scontextp);
     283         [ #  # ]:          0 :                 if (!levdatum) {
     284                 :            :                         rc = -EINVAL;
     285                 :            :                         goto out;
     286                 :            :                 }
     287                 :            : 
     288                 :          0 :                 context->range.level[l].sens = levdatum->level->sens;
     289                 :            : 
     290         [ #  # ]:          0 :                 if (delim == ':') {
     291                 :            :                         /* Extract category set. */
     292                 :            :                         while (1) {
     293                 :            :                                 scontextp = p;
     294 [ #  # ][ #  # ]:          0 :                                 while (*p && *p != ',' && *p != '-')
     295                 :          0 :                                         p++;
     296                 :            :                                 delim = *p;
     297         [ #  # ]:          0 :                                 if (delim != '\0')
     298                 :          0 :                                         *p++ = '\0';
     299                 :            : 
     300                 :            :                                 /* Separate into range if exists */
     301                 :          0 :                                 rngptr = strchr(scontextp, '.');
     302         [ #  # ]:          0 :                                 if (rngptr != NULL) {
     303                 :            :                                         /* Remove '.' */
     304                 :          0 :                                         *rngptr++ = '\0';
     305                 :            :                                 }
     306                 :            : 
     307                 :          0 :                                 catdatum = hashtab_search(pol->p_cats.table,
     308                 :            :                                                           scontextp);
     309         [ #  # ]:          0 :                                 if (!catdatum) {
     310                 :            :                                         rc = -EINVAL;
     311                 :            :                                         goto out;
     312                 :            :                                 }
     313                 :            : 
     314                 :          0 :                                 rc = ebitmap_set_bit(&context->range.level[l].cat,
     315                 :          0 :                                                      catdatum->value - 1, 1);
     316         [ #  # ]:          0 :                                 if (rc)
     317                 :            :                                         goto out;
     318                 :            : 
     319                 :            :                                 /* If range, set all categories in range */
     320         [ #  # ]:          0 :                                 if (rngptr) {
     321                 :            :                                         int i;
     322                 :            : 
     323                 :          0 :                                         rngdatum = hashtab_search(pol->p_cats.table, rngptr);
     324         [ #  # ]:          0 :                                         if (!rngdatum) {
     325                 :            :                                                 rc = -EINVAL;
     326                 :            :                                                 goto out;
     327                 :            :                                         }
     328                 :            : 
     329         [ #  # ]:          0 :                                         if (catdatum->value >= rngdatum->value) {
     330                 :            :                                                 rc = -EINVAL;
     331                 :            :                                                 goto out;
     332                 :            :                                         }
     333                 :            : 
     334         [ #  # ]:          0 :                                         for (i = catdatum->value; i < rngdatum->value; i++) {
     335                 :          0 :                                                 rc = ebitmap_set_bit(&context->range.level[l].cat, i, 1);
     336         [ #  # ]:          0 :                                                 if (rc)
     337                 :            :                                                         goto out;
     338                 :            :                                         }
     339                 :            :                                 }
     340                 :            : 
     341         [ #  # ]:          0 :                                 if (delim != ',')
     342                 :            :                                         break;
     343                 :            :                         }
     344                 :            :                 }
     345         [ #  # ]:          0 :                 if (delim == '-') {
     346                 :            :                         /* Extract high sensitivity. */
     347                 :            :                         scontextp = p;
     348         [ #  # ]:          0 :                         while (*p && *p != ':')
     349                 :          0 :                                 p++;
     350                 :            : 
     351                 :            :                         delim = *p;
     352         [ #  # ]:          0 :                         if (delim != '\0')
     353                 :          0 :                                 *p++ = '\0';
     354                 :            :                 } else
     355                 :            :                         break;
     356                 :            :         }
     357                 :            : 
     358         [ #  # ]:          0 :         if (l == 0) {
     359                 :          0 :                 context->range.level[1].sens = context->range.level[0].sens;
     360                 :          0 :                 rc = ebitmap_cpy(&context->range.level[1].cat,
     361                 :            :                                  &context->range.level[0].cat);
     362         [ #  # ]:          0 :                 if (rc)
     363                 :            :                         goto out;
     364                 :            :         }
     365                 :          0 :         *scontext = ++p;
     366                 :            :         rc = 0;
     367                 :            : out:
     368                 :          0 :         return rc;
     369                 :            : }
     370                 :            : 
     371                 :            : /*
     372                 :            :  * Set the MLS fields in the security context structure
     373                 :            :  * `context' based on the string representation in
     374                 :            :  * the string `str'.  This function will allocate temporary memory with the
     375                 :            :  * given constraints of gfp_mask.
     376                 :            :  */
     377                 :          0 : int mls_from_string(char *str, struct context *context, gfp_t gfp_mask)
     378                 :            : {
     379                 :            :         char *tmpstr, *freestr;
     380                 :            :         int rc;
     381                 :            : 
     382         [ #  # ]:          0 :         if (!policydb.mls_enabled)
     383                 :            :                 return -EINVAL;
     384                 :            : 
     385                 :            :         /* we need freestr because mls_context_to_sid will change
     386                 :            :            the value of tmpstr */
     387                 :          0 :         tmpstr = freestr = kstrdup(str, gfp_mask);
     388         [ #  # ]:          0 :         if (!tmpstr) {
     389                 :            :                 rc = -ENOMEM;
     390                 :            :         } else {
     391                 :          0 :                 rc = mls_context_to_sid(&policydb, ':', &tmpstr, context,
     392                 :            :                                         NULL, SECSID_NULL);
     393                 :          0 :                 kfree(freestr);
     394                 :            :         }
     395                 :            : 
     396                 :          0 :         return rc;
     397                 :            : }
     398                 :            : 
     399                 :            : /*
     400                 :            :  * Copies the MLS range `range' into `context'.
     401                 :            :  */
     402                 :          0 : int mls_range_set(struct context *context,
     403                 :            :                                 struct mls_range *range)
     404                 :            : {
     405                 :            :         int l, rc = 0;
     406                 :            : 
     407                 :            :         /* Copy the MLS range into the  context */
     408         [ #  # ]:          0 :         for (l = 0; l < 2; l++) {
     409                 :          0 :                 context->range.level[l].sens = range->level[l].sens;
     410                 :          0 :                 rc = ebitmap_cpy(&context->range.level[l].cat,
     411                 :            :                                  &range->level[l].cat);
     412         [ #  # ]:          0 :                 if (rc)
     413                 :            :                         break;
     414                 :            :         }
     415                 :            : 
     416                 :          0 :         return rc;
     417                 :            : }
     418                 :            : 
     419                 :          0 : int mls_setup_user_range(struct context *fromcon, struct user_datum *user,
     420                 :            :                          struct context *usercon)
     421                 :            : {
     422         [ #  # ]:          0 :         if (policydb.mls_enabled) {
     423                 :            :                 struct mls_level *fromcon_sen = &(fromcon->range.level[0]);
     424                 :            :                 struct mls_level *fromcon_clr = &(fromcon->range.level[1]);
     425                 :            :                 struct mls_level *user_low = &(user->range.level[0]);
     426                 :            :                 struct mls_level *user_clr = &(user->range.level[1]);
     427                 :            :                 struct mls_level *user_def = &(user->dfltlevel);
     428                 :            :                 struct mls_level *usercon_sen = &(usercon->range.level[0]);
     429                 :            :                 struct mls_level *usercon_clr = &(usercon->range.level[1]);
     430                 :            : 
     431                 :            :                 /* Honor the user's default level if we can */
     432 [ #  # ][ #  # ]:          0 :                 if (mls_level_between(user_def, fromcon_sen, fromcon_clr))
     433                 :          0 :                         *usercon_sen = *user_def;
     434 [ #  # ][ #  # ]:          0 :                 else if (mls_level_between(fromcon_sen, user_def, user_clr))
     435                 :          0 :                         *usercon_sen = *fromcon_sen;
     436 [ #  # ][ #  # ]:          0 :                 else if (mls_level_between(fromcon_clr, user_low, user_def))
     437                 :          0 :                         *usercon_sen = *user_low;
     438                 :            :                 else
     439                 :            :                         return -EINVAL;
     440                 :            : 
     441                 :            :                 /* Lower the clearance of available contexts
     442                 :            :                    if the clearance of "fromcon" is lower than
     443                 :            :                    that of the user's default clearance (but
     444                 :            :                    only if the "fromcon" clearance dominates
     445                 :            :                    the user's computed sensitivity level) */
     446         [ #  # ]:          0 :                 if (mls_level_dom(user_clr, fromcon_clr))
     447                 :          0 :                         *usercon_clr = *fromcon_clr;
     448         [ #  # ]:          0 :                 else if (mls_level_dom(fromcon_clr, user_clr))
     449                 :          0 :                         *usercon_clr = *user_clr;
     450                 :            :                 else
     451                 :            :                         return -EINVAL;
     452                 :            :         }
     453                 :            : 
     454                 :            :         return 0;
     455                 :            : }
     456                 :            : 
     457                 :            : /*
     458                 :            :  * Convert the MLS fields in the security context
     459                 :            :  * structure `c' from the values specified in the
     460                 :            :  * policy `oldp' to the values specified in the policy `newp'.
     461                 :            :  */
     462                 :          0 : int mls_convert_context(struct policydb *oldp,
     463                 :            :                         struct policydb *newp,
     464                 :            :                         struct context *c)
     465                 :            : {
     466                 :            :         struct level_datum *levdatum;
     467                 :            :         struct cat_datum *catdatum;
     468                 :            :         struct ebitmap bitmap;
     469                 :            :         struct ebitmap_node *node;
     470                 :            :         int l, i;
     471                 :            : 
     472         [ #  # ]:          0 :         if (!policydb.mls_enabled)
     473                 :            :                 return 0;
     474                 :            : 
     475         [ #  # ]:          0 :         for (l = 0; l < 2; l++) {
     476                 :          0 :                 levdatum = hashtab_search(newp->p_levels.table,
     477                 :          0 :                                           sym_name(oldp, SYM_LEVELS,
     478                 :          0 :                                                    c->range.level[l].sens - 1));
     479                 :            : 
     480         [ #  # ]:          0 :                 if (!levdatum)
     481                 :            :                         return -EINVAL;
     482                 :          0 :                 c->range.level[l].sens = levdatum->level->sens;
     483                 :            : 
     484                 :            :                 ebitmap_init(&bitmap);
     485         [ #  # ]:          0 :                 ebitmap_for_each_positive_bit(&c->range.level[l].cat, node, i) {
     486                 :            :                         int rc;
     487                 :            : 
     488                 :          0 :                         catdatum = hashtab_search(newp->p_cats.table,
     489                 :            :                                                   sym_name(oldp, SYM_CATS, i));
     490         [ #  # ]:          0 :                         if (!catdatum)
     491                 :            :                                 return -EINVAL;
     492                 :          0 :                         rc = ebitmap_set_bit(&bitmap, catdatum->value - 1, 1);
     493         [ #  # ]:          0 :                         if (rc)
     494                 :            :                                 return rc;
     495                 :            :                 }
     496                 :          0 :                 ebitmap_destroy(&c->range.level[l].cat);
     497                 :          0 :                 c->range.level[l].cat = bitmap;
     498                 :            :         }
     499                 :            : 
     500                 :            :         return 0;
     501                 :            : }
     502                 :            : 
     503                 :          0 : int mls_compute_sid(struct context *scontext,
     504                 :            :                     struct context *tcontext,
     505                 :            :                     u16 tclass,
     506                 :            :                     u32 specified,
     507                 :            :                     struct context *newcontext,
     508                 :            :                     bool sock)
     509                 :            : {
     510                 :            :         struct range_trans rtr;
     511                 :            :         struct mls_range *r;
     512                 :            :         struct class_datum *cladatum;
     513                 :            :         int default_range = 0;
     514                 :            : 
     515         [ #  # ]:          0 :         if (!policydb.mls_enabled)
     516                 :            :                 return 0;
     517                 :            : 
     518   [ #  #  #  # ]:          0 :         switch (specified) {
     519                 :            :         case AVTAB_TRANSITION:
     520                 :            :                 /* Look for a range transition rule. */
     521                 :          0 :                 rtr.source_type = scontext->type;
     522                 :          0 :                 rtr.target_type = tcontext->type;
     523                 :          0 :                 rtr.target_class = tclass;
     524                 :          0 :                 r = hashtab_search(policydb.range_tr, &rtr);
     525         [ #  # ]:          0 :                 if (r)
     526                 :          0 :                         return mls_range_set(newcontext, r);
     527                 :            : 
     528 [ #  # ][ #  # ]:          0 :                 if (tclass && tclass <= policydb.p_classes.nprim) {
     529                 :          0 :                         cladatum = policydb.class_val_to_struct[tclass - 1];
     530         [ #  # ]:          0 :                         if (cladatum)
     531                 :          0 :                                 default_range = cladatum->default_range;
     532                 :            :                 }
     533                 :            : 
     534   [ #  #  #  #  :          0 :                 switch (default_range) {
                #  #  # ]
     535                 :            :                 case DEFAULT_SOURCE_LOW:
     536                 :          0 :                         return mls_context_cpy_low(newcontext, scontext);
     537                 :            :                 case DEFAULT_SOURCE_HIGH:
     538                 :          0 :                         return mls_context_cpy_high(newcontext, scontext);
     539                 :            :                 case DEFAULT_SOURCE_LOW_HIGH:
     540                 :          0 :                         return mls_context_cpy(newcontext, scontext);
     541                 :            :                 case DEFAULT_TARGET_LOW:
     542                 :          0 :                         return mls_context_cpy_low(newcontext, tcontext);
     543                 :            :                 case DEFAULT_TARGET_HIGH:
     544                 :          0 :                         return mls_context_cpy_high(newcontext, tcontext);
     545                 :            :                 case DEFAULT_TARGET_LOW_HIGH:
     546                 :          0 :                         return mls_context_cpy(newcontext, tcontext);
     547                 :            :                 }
     548                 :            : 
     549                 :            :                 /* Fallthrough */
     550                 :            :         case AVTAB_CHANGE:
     551 [ #  # ][ #  # ]:          0 :                 if ((tclass == policydb.process_class) || (sock == true))
     552                 :            :                         /* Use the process MLS attributes. */
     553                 :          0 :                         return mls_context_cpy(newcontext, scontext);
     554                 :            :                 else
     555                 :            :                         /* Use the process effective MLS attributes. */
     556                 :          0 :                         return mls_context_cpy_low(newcontext, scontext);
     557                 :            :         case AVTAB_MEMBER:
     558                 :            :                 /* Use the process effective MLS attributes. */
     559                 :          0 :                 return mls_context_cpy_low(newcontext, scontext);
     560                 :            : 
     561                 :            :         /* fall through */
     562                 :            :         }
     563                 :            :         return -EINVAL;
     564                 :            : }
     565                 :            : 
     566                 :            : #ifdef CONFIG_NETLABEL
     567                 :            : /**
     568                 :            :  * mls_export_netlbl_lvl - Export the MLS sensitivity levels to NetLabel
     569                 :            :  * @context: the security context
     570                 :            :  * @secattr: the NetLabel security attributes
     571                 :            :  *
     572                 :            :  * Description:
     573                 :            :  * Given the security context copy the low MLS sensitivity level into the
     574                 :            :  * NetLabel MLS sensitivity level field.
     575                 :            :  *
     576                 :            :  */
     577                 :          0 : void mls_export_netlbl_lvl(struct context *context,
     578                 :            :                            struct netlbl_lsm_secattr *secattr)
     579                 :            : {
     580         [ #  # ]:          0 :         if (!policydb.mls_enabled)
     581                 :          0 :                 return;
     582                 :            : 
     583                 :          0 :         secattr->attr.mls.lvl = context->range.level[0].sens - 1;
     584                 :          0 :         secattr->flags |= NETLBL_SECATTR_MLS_LVL;
     585                 :            : }
     586                 :            : 
     587                 :            : /**
     588                 :            :  * mls_import_netlbl_lvl - Import the NetLabel MLS sensitivity levels
     589                 :            :  * @context: the security context
     590                 :            :  * @secattr: the NetLabel security attributes
     591                 :            :  *
     592                 :            :  * Description:
     593                 :            :  * Given the security context and the NetLabel security attributes, copy the
     594                 :            :  * NetLabel MLS sensitivity level into the context.
     595                 :            :  *
     596                 :            :  */
     597                 :          0 : void mls_import_netlbl_lvl(struct context *context,
     598                 :            :                            struct netlbl_lsm_secattr *secattr)
     599                 :            : {
     600         [ #  # ]:          0 :         if (!policydb.mls_enabled)
     601                 :          0 :                 return;
     602                 :            : 
     603                 :          0 :         context->range.level[0].sens = secattr->attr.mls.lvl + 1;
     604                 :          0 :         context->range.level[1].sens = context->range.level[0].sens;
     605                 :            : }
     606                 :            : 
     607                 :            : /**
     608                 :            :  * mls_export_netlbl_cat - Export the MLS categories to NetLabel
     609                 :            :  * @context: the security context
     610                 :            :  * @secattr: the NetLabel security attributes
     611                 :            :  *
     612                 :            :  * Description:
     613                 :            :  * Given the security context copy the low MLS categories into the NetLabel
     614                 :            :  * MLS category field.  Returns zero on success, negative values on failure.
     615                 :            :  *
     616                 :            :  */
     617                 :          0 : int mls_export_netlbl_cat(struct context *context,
     618                 :            :                           struct netlbl_lsm_secattr *secattr)
     619                 :            : {
     620                 :            :         int rc;
     621                 :            : 
     622         [ #  # ]:          0 :         if (!policydb.mls_enabled)
     623                 :            :                 return 0;
     624                 :            : 
     625                 :          0 :         rc = ebitmap_netlbl_export(&context->range.level[0].cat,
     626                 :            :                                    &secattr->attr.mls.cat);
     627 [ #  # ][ #  # ]:          0 :         if (rc == 0 && secattr->attr.mls.cat != NULL)
     628                 :          0 :                 secattr->flags |= NETLBL_SECATTR_MLS_CAT;
     629                 :            : 
     630                 :          0 :         return rc;
     631                 :            : }
     632                 :            : 
     633                 :            : /**
     634                 :            :  * mls_import_netlbl_cat - Import the MLS categories from NetLabel
     635                 :            :  * @context: the security context
     636                 :            :  * @secattr: the NetLabel security attributes
     637                 :            :  *
     638                 :            :  * Description:
     639                 :            :  * Copy the NetLabel security attributes into the SELinux context; since the
     640                 :            :  * NetLabel security attribute only contains a single MLS category use it for
     641                 :            :  * both the low and high categories of the context.  Returns zero on success,
     642                 :            :  * negative values on failure.
     643                 :            :  *
     644                 :            :  */
     645                 :          0 : int mls_import_netlbl_cat(struct context *context,
     646                 :            :                           struct netlbl_lsm_secattr *secattr)
     647                 :            : {
     648                 :            :         int rc;
     649                 :            : 
     650         [ #  # ]:          0 :         if (!policydb.mls_enabled)
     651                 :            :                 return 0;
     652                 :            : 
     653                 :          0 :         rc = ebitmap_netlbl_import(&context->range.level[0].cat,
     654                 :            :                                    secattr->attr.mls.cat);
     655         [ #  # ]:          0 :         if (rc != 0)
     656                 :            :                 goto import_netlbl_cat_failure;
     657                 :            : 
     658                 :          0 :         rc = ebitmap_cpy(&context->range.level[1].cat,
     659                 :            :                          &context->range.level[0].cat);
     660         [ #  # ]:          0 :         if (rc != 0)
     661                 :            :                 goto import_netlbl_cat_failure;
     662                 :            : 
     663                 :            :         return 0;
     664                 :            : 
     665                 :            : import_netlbl_cat_failure:
     666                 :          0 :         ebitmap_destroy(&context->range.level[0].cat);
     667                 :          0 :         ebitmap_destroy(&context->range.level[1].cat);
     668                 :          0 :         return rc;
     669                 :            : }
     670                 :            : #endif /* CONFIG_NETLABEL */

Generated by: LCOV version 1.9