1255e72915d4cbddceb435e13d81601755714e9fSE Android/* Author : Stephen Smalley, <sds@epoch.ncsc.mil> */ 2255e72915d4cbddceb435e13d81601755714e9fSE Android/* 3255e72915d4cbddceb435e13d81601755714e9fSE Android * Updated: Trusted Computer Solutions, Inc. <dgoeddel@trustedcs.com> 4255e72915d4cbddceb435e13d81601755714e9fSE Android * 5255e72915d4cbddceb435e13d81601755714e9fSE Android * Support for enhanced MLS infrastructure. 6255e72915d4cbddceb435e13d81601755714e9fSE Android * 7255e72915d4cbddceb435e13d81601755714e9fSE Android * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. 8255e72915d4cbddceb435e13d81601755714e9fSE Android * 9255e72915d4cbddceb435e13d81601755714e9fSE Android * This library is free software; you can redistribute it and/or 10255e72915d4cbddceb435e13d81601755714e9fSE Android * modify it under the terms of the GNU Lesser General Public 11255e72915d4cbddceb435e13d81601755714e9fSE Android * License as published by the Free Software Foundation; either 12255e72915d4cbddceb435e13d81601755714e9fSE Android * version 2.1 of the License, or (at your option) any later version. 13255e72915d4cbddceb435e13d81601755714e9fSE Android * 14255e72915d4cbddceb435e13d81601755714e9fSE Android * This library is distributed in the hope that it will be useful, 15255e72915d4cbddceb435e13d81601755714e9fSE Android * but WITHOUT ANY WARRANTY; without even the implied warranty of 16255e72915d4cbddceb435e13d81601755714e9fSE Android * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17255e72915d4cbddceb435e13d81601755714e9fSE Android * Lesser General Public License for more details. 18255e72915d4cbddceb435e13d81601755714e9fSE Android * 19255e72915d4cbddceb435e13d81601755714e9fSE Android * You should have received a copy of the GNU Lesser General Public 20255e72915d4cbddceb435e13d81601755714e9fSE Android * License along with this library; if not, write to the Free Software 21255e72915d4cbddceb435e13d81601755714e9fSE Android * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 22255e72915d4cbddceb435e13d81601755714e9fSE Android */ 23255e72915d4cbddceb435e13d81601755714e9fSE Android 24255e72915d4cbddceb435e13d81601755714e9fSE Android/* FLASK */ 25255e72915d4cbddceb435e13d81601755714e9fSE Android 26255e72915d4cbddceb435e13d81601755714e9fSE Android/* 27255e72915d4cbddceb435e13d81601755714e9fSE Android * Implementation of the multi-level security (MLS) policy. 28255e72915d4cbddceb435e13d81601755714e9fSE Android */ 29255e72915d4cbddceb435e13d81601755714e9fSE Android 30255e72915d4cbddceb435e13d81601755714e9fSE Android#include <sepol/policydb/policydb.h> 31255e72915d4cbddceb435e13d81601755714e9fSE Android#include <sepol/policydb/services.h> 32255e72915d4cbddceb435e13d81601755714e9fSE Android#include <sepol/policydb/flask.h> 33255e72915d4cbddceb435e13d81601755714e9fSE Android#include <sepol/policydb/context.h> 34255e72915d4cbddceb435e13d81601755714e9fSE Android 35255e72915d4cbddceb435e13d81601755714e9fSE Android#include <stdlib.h> 36255e72915d4cbddceb435e13d81601755714e9fSE Android 37255e72915d4cbddceb435e13d81601755714e9fSE Android#include "handle.h" 38255e72915d4cbddceb435e13d81601755714e9fSE Android#include "debug.h" 39255e72915d4cbddceb435e13d81601755714e9fSE Android#include "private.h" 40255e72915d4cbddceb435e13d81601755714e9fSE Android#include "mls.h" 41255e72915d4cbddceb435e13d81601755714e9fSE Android 42255e72915d4cbddceb435e13d81601755714e9fSE Androidint mls_to_string(sepol_handle_t * handle, 43255e72915d4cbddceb435e13d81601755714e9fSE Android const policydb_t * policydb, 44255e72915d4cbddceb435e13d81601755714e9fSE Android const context_struct_t * mls, char **str) 45255e72915d4cbddceb435e13d81601755714e9fSE Android{ 46255e72915d4cbddceb435e13d81601755714e9fSE Android 47255e72915d4cbddceb435e13d81601755714e9fSE Android char *ptr = NULL, *ptr2 = NULL; 48255e72915d4cbddceb435e13d81601755714e9fSE Android 49255e72915d4cbddceb435e13d81601755714e9fSE Android /* Temporary buffer - length + NULL terminator */ 50255e72915d4cbddceb435e13d81601755714e9fSE Android int len = mls_compute_context_len(policydb, mls) + 1; 51255e72915d4cbddceb435e13d81601755714e9fSE Android 52255e72915d4cbddceb435e13d81601755714e9fSE Android ptr = (char *)malloc(len); 53255e72915d4cbddceb435e13d81601755714e9fSE Android if (ptr == NULL) 54255e72915d4cbddceb435e13d81601755714e9fSE Android goto omem; 55255e72915d4cbddceb435e13d81601755714e9fSE Android 56255e72915d4cbddceb435e13d81601755714e9fSE Android /* Final string w/ ':' cut off */ 57255e72915d4cbddceb435e13d81601755714e9fSE Android ptr2 = (char *)malloc(len - 1); 58255e72915d4cbddceb435e13d81601755714e9fSE Android if (ptr2 == NULL) 59255e72915d4cbddceb435e13d81601755714e9fSE Android goto omem; 60255e72915d4cbddceb435e13d81601755714e9fSE Android 61255e72915d4cbddceb435e13d81601755714e9fSE Android mls_sid_to_context(policydb, mls, &ptr); 62255e72915d4cbddceb435e13d81601755714e9fSE Android ptr -= len - 1; 63255e72915d4cbddceb435e13d81601755714e9fSE Android strcpy(ptr2, ptr + 1); 64255e72915d4cbddceb435e13d81601755714e9fSE Android 65255e72915d4cbddceb435e13d81601755714e9fSE Android free(ptr); 66255e72915d4cbddceb435e13d81601755714e9fSE Android *str = ptr2; 67255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_SUCCESS; 68255e72915d4cbddceb435e13d81601755714e9fSE Android 69255e72915d4cbddceb435e13d81601755714e9fSE Android omem: 70255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "out of memory, could not convert mls context to string"); 71255e72915d4cbddceb435e13d81601755714e9fSE Android 72255e72915d4cbddceb435e13d81601755714e9fSE Android free(ptr); 73255e72915d4cbddceb435e13d81601755714e9fSE Android free(ptr2); 74255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_ERR; 75255e72915d4cbddceb435e13d81601755714e9fSE Android 76255e72915d4cbddceb435e13d81601755714e9fSE Android} 77255e72915d4cbddceb435e13d81601755714e9fSE Android 78255e72915d4cbddceb435e13d81601755714e9fSE Androidint mls_from_string(sepol_handle_t * handle, 79255e72915d4cbddceb435e13d81601755714e9fSE Android const policydb_t * policydb, 80255e72915d4cbddceb435e13d81601755714e9fSE Android const char *str, context_struct_t * mls) 81255e72915d4cbddceb435e13d81601755714e9fSE Android{ 82255e72915d4cbddceb435e13d81601755714e9fSE Android 83255e72915d4cbddceb435e13d81601755714e9fSE Android char *tmp = strdup(str); 84255e72915d4cbddceb435e13d81601755714e9fSE Android char *tmp_cp = tmp; 85255e72915d4cbddceb435e13d81601755714e9fSE Android if (!tmp) 86255e72915d4cbddceb435e13d81601755714e9fSE Android goto omem; 87255e72915d4cbddceb435e13d81601755714e9fSE Android 88255e72915d4cbddceb435e13d81601755714e9fSE Android if (mls_context_to_sid(policydb, '$', &tmp_cp, mls) < 0) { 89255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "invalid MLS context %s", str); 90255e72915d4cbddceb435e13d81601755714e9fSE Android free(tmp); 91255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 92255e72915d4cbddceb435e13d81601755714e9fSE Android } 93255e72915d4cbddceb435e13d81601755714e9fSE Android 94255e72915d4cbddceb435e13d81601755714e9fSE Android free(tmp); 95255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_SUCCESS; 96255e72915d4cbddceb435e13d81601755714e9fSE Android 97255e72915d4cbddceb435e13d81601755714e9fSE Android omem: 98255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "out of memory"); 99255e72915d4cbddceb435e13d81601755714e9fSE Android 100255e72915d4cbddceb435e13d81601755714e9fSE Android err: 101255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "could not construct mls context structure"); 102255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_ERR; 103255e72915d4cbddceb435e13d81601755714e9fSE Android} 104255e72915d4cbddceb435e13d81601755714e9fSE Android 105255e72915d4cbddceb435e13d81601755714e9fSE Android/* 106255e72915d4cbddceb435e13d81601755714e9fSE Android * Return the length in bytes for the MLS fields of the 107255e72915d4cbddceb435e13d81601755714e9fSE Android * security context string representation of `context'. 108255e72915d4cbddceb435e13d81601755714e9fSE Android */ 109255e72915d4cbddceb435e13d81601755714e9fSE Androidint mls_compute_context_len(const policydb_t * policydb, 110255e72915d4cbddceb435e13d81601755714e9fSE Android const context_struct_t * context) 111255e72915d4cbddceb435e13d81601755714e9fSE Android{ 112255e72915d4cbddceb435e13d81601755714e9fSE Android 113255e72915d4cbddceb435e13d81601755714e9fSE Android unsigned int i, l, len, range; 114255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_node_t *cnode; 115255e72915d4cbddceb435e13d81601755714e9fSE Android 116255e72915d4cbddceb435e13d81601755714e9fSE Android if (!policydb->mls) 117255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 118255e72915d4cbddceb435e13d81601755714e9fSE Android 119255e72915d4cbddceb435e13d81601755714e9fSE Android len = 1; /* for the beginning ":" */ 120255e72915d4cbddceb435e13d81601755714e9fSE Android for (l = 0; l < 2; l++) { 121255e72915d4cbddceb435e13d81601755714e9fSE Android range = 0; 122255e72915d4cbddceb435e13d81601755714e9fSE Android len += 123255e72915d4cbddceb435e13d81601755714e9fSE Android strlen(policydb-> 124255e72915d4cbddceb435e13d81601755714e9fSE Android p_sens_val_to_name[context->range.level[l].sens - 125255e72915d4cbddceb435e13d81601755714e9fSE Android 1]); 126255e72915d4cbddceb435e13d81601755714e9fSE Android 127255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_for_each_bit(&context->range.level[l].cat, cnode, i) { 128255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_node_get_bit(cnode, i)) { 129255e72915d4cbddceb435e13d81601755714e9fSE Android if (range) { 130255e72915d4cbddceb435e13d81601755714e9fSE Android range++; 131255e72915d4cbddceb435e13d81601755714e9fSE Android continue; 132255e72915d4cbddceb435e13d81601755714e9fSE Android } 133255e72915d4cbddceb435e13d81601755714e9fSE Android 134255e72915d4cbddceb435e13d81601755714e9fSE Android len += 135255e72915d4cbddceb435e13d81601755714e9fSE Android strlen(policydb->p_cat_val_to_name[i]) + 1; 136255e72915d4cbddceb435e13d81601755714e9fSE Android range++; 137255e72915d4cbddceb435e13d81601755714e9fSE Android } else { 138255e72915d4cbddceb435e13d81601755714e9fSE Android if (range > 1) 139255e72915d4cbddceb435e13d81601755714e9fSE Android len += 140255e72915d4cbddceb435e13d81601755714e9fSE Android strlen(policydb-> 141255e72915d4cbddceb435e13d81601755714e9fSE Android p_cat_val_to_name[i - 1]) + 142255e72915d4cbddceb435e13d81601755714e9fSE Android 1; 143255e72915d4cbddceb435e13d81601755714e9fSE Android range = 0; 144255e72915d4cbddceb435e13d81601755714e9fSE Android } 145255e72915d4cbddceb435e13d81601755714e9fSE Android } 146255e72915d4cbddceb435e13d81601755714e9fSE Android /* Handle case where last category is the end of range */ 147255e72915d4cbddceb435e13d81601755714e9fSE Android if (range > 1) 148255e72915d4cbddceb435e13d81601755714e9fSE Android len += strlen(policydb->p_cat_val_to_name[i - 1]) + 1; 149255e72915d4cbddceb435e13d81601755714e9fSE Android 150255e72915d4cbddceb435e13d81601755714e9fSE Android if (l == 0) { 151255e72915d4cbddceb435e13d81601755714e9fSE Android if (mls_level_eq(&context->range.level[0], 152255e72915d4cbddceb435e13d81601755714e9fSE Android &context->range.level[1])) 153255e72915d4cbddceb435e13d81601755714e9fSE Android break; 154255e72915d4cbddceb435e13d81601755714e9fSE Android else 155255e72915d4cbddceb435e13d81601755714e9fSE Android len++; 156255e72915d4cbddceb435e13d81601755714e9fSE Android } 157255e72915d4cbddceb435e13d81601755714e9fSE Android } 158255e72915d4cbddceb435e13d81601755714e9fSE Android 159255e72915d4cbddceb435e13d81601755714e9fSE Android return len; 160255e72915d4cbddceb435e13d81601755714e9fSE Android} 161255e72915d4cbddceb435e13d81601755714e9fSE Android 162255e72915d4cbddceb435e13d81601755714e9fSE Android/* 163255e72915d4cbddceb435e13d81601755714e9fSE Android * Write the security context string representation of 164255e72915d4cbddceb435e13d81601755714e9fSE Android * the MLS fields of `context' into the string `*scontext'. 165255e72915d4cbddceb435e13d81601755714e9fSE Android * Update `*scontext' to point to the end of the MLS fields. 166255e72915d4cbddceb435e13d81601755714e9fSE Android */ 167255e72915d4cbddceb435e13d81601755714e9fSE Androidvoid mls_sid_to_context(const policydb_t * policydb, 168255e72915d4cbddceb435e13d81601755714e9fSE Android const context_struct_t * context, char **scontext) 169255e72915d4cbddceb435e13d81601755714e9fSE Android{ 170255e72915d4cbddceb435e13d81601755714e9fSE Android 171255e72915d4cbddceb435e13d81601755714e9fSE Android char *scontextp; 172255e72915d4cbddceb435e13d81601755714e9fSE Android unsigned int i, l, range, wrote_sep; 173255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_node_t *cnode; 174255e72915d4cbddceb435e13d81601755714e9fSE Android 175255e72915d4cbddceb435e13d81601755714e9fSE Android if (!policydb->mls) 176255e72915d4cbddceb435e13d81601755714e9fSE Android return; 177255e72915d4cbddceb435e13d81601755714e9fSE Android 178255e72915d4cbddceb435e13d81601755714e9fSE Android scontextp = *scontext; 179255e72915d4cbddceb435e13d81601755714e9fSE Android 180255e72915d4cbddceb435e13d81601755714e9fSE Android *scontextp = ':'; 181255e72915d4cbddceb435e13d81601755714e9fSE Android scontextp++; 182255e72915d4cbddceb435e13d81601755714e9fSE Android 183255e72915d4cbddceb435e13d81601755714e9fSE Android for (l = 0; l < 2; l++) { 184255e72915d4cbddceb435e13d81601755714e9fSE Android range = 0; 185255e72915d4cbddceb435e13d81601755714e9fSE Android wrote_sep = 0; 186255e72915d4cbddceb435e13d81601755714e9fSE Android strcpy(scontextp, 187255e72915d4cbddceb435e13d81601755714e9fSE Android policydb->p_sens_val_to_name[context->range.level[l]. 188255e72915d4cbddceb435e13d81601755714e9fSE Android sens - 1]); 189255e72915d4cbddceb435e13d81601755714e9fSE Android scontextp += 190255e72915d4cbddceb435e13d81601755714e9fSE Android strlen(policydb-> 191255e72915d4cbddceb435e13d81601755714e9fSE Android p_sens_val_to_name[context->range.level[l].sens - 192255e72915d4cbddceb435e13d81601755714e9fSE Android 1]); 193255e72915d4cbddceb435e13d81601755714e9fSE Android /* categories */ 194255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_for_each_bit(&context->range.level[l].cat, cnode, i) { 195255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_node_get_bit(cnode, i)) { 196255e72915d4cbddceb435e13d81601755714e9fSE Android if (range) { 197255e72915d4cbddceb435e13d81601755714e9fSE Android range++; 198255e72915d4cbddceb435e13d81601755714e9fSE Android continue; 199255e72915d4cbddceb435e13d81601755714e9fSE Android } 200255e72915d4cbddceb435e13d81601755714e9fSE Android 201255e72915d4cbddceb435e13d81601755714e9fSE Android if (!wrote_sep) { 202255e72915d4cbddceb435e13d81601755714e9fSE Android *scontextp++ = ':'; 203255e72915d4cbddceb435e13d81601755714e9fSE Android wrote_sep = 1; 204255e72915d4cbddceb435e13d81601755714e9fSE Android } else 205255e72915d4cbddceb435e13d81601755714e9fSE Android *scontextp++ = ','; 206255e72915d4cbddceb435e13d81601755714e9fSE Android strcpy(scontextp, 207255e72915d4cbddceb435e13d81601755714e9fSE Android policydb->p_cat_val_to_name[i]); 208255e72915d4cbddceb435e13d81601755714e9fSE Android scontextp += 209255e72915d4cbddceb435e13d81601755714e9fSE Android strlen(policydb->p_cat_val_to_name[i]); 210255e72915d4cbddceb435e13d81601755714e9fSE Android range++; 211255e72915d4cbddceb435e13d81601755714e9fSE Android } else { 212255e72915d4cbddceb435e13d81601755714e9fSE Android if (range > 1) { 213255e72915d4cbddceb435e13d81601755714e9fSE Android if (range > 2) 214255e72915d4cbddceb435e13d81601755714e9fSE Android *scontextp++ = '.'; 215255e72915d4cbddceb435e13d81601755714e9fSE Android else 216255e72915d4cbddceb435e13d81601755714e9fSE Android *scontextp++ = ','; 217255e72915d4cbddceb435e13d81601755714e9fSE Android 218255e72915d4cbddceb435e13d81601755714e9fSE Android strcpy(scontextp, 219255e72915d4cbddceb435e13d81601755714e9fSE Android policydb->p_cat_val_to_name[i - 220255e72915d4cbddceb435e13d81601755714e9fSE Android 1]); 221255e72915d4cbddceb435e13d81601755714e9fSE Android scontextp += 222255e72915d4cbddceb435e13d81601755714e9fSE Android strlen(policydb-> 223255e72915d4cbddceb435e13d81601755714e9fSE Android p_cat_val_to_name[i - 1]); 224255e72915d4cbddceb435e13d81601755714e9fSE Android } 225255e72915d4cbddceb435e13d81601755714e9fSE Android range = 0; 226255e72915d4cbddceb435e13d81601755714e9fSE Android } 227255e72915d4cbddceb435e13d81601755714e9fSE Android } 228255e72915d4cbddceb435e13d81601755714e9fSE Android /* Handle case where last category is the end of range */ 229255e72915d4cbddceb435e13d81601755714e9fSE Android if (range > 1) { 230255e72915d4cbddceb435e13d81601755714e9fSE Android if (range > 2) 231255e72915d4cbddceb435e13d81601755714e9fSE Android *scontextp++ = '.'; 232255e72915d4cbddceb435e13d81601755714e9fSE Android else 233255e72915d4cbddceb435e13d81601755714e9fSE Android *scontextp++ = ','; 234255e72915d4cbddceb435e13d81601755714e9fSE Android 235255e72915d4cbddceb435e13d81601755714e9fSE Android strcpy(scontextp, policydb->p_cat_val_to_name[i - 1]); 236255e72915d4cbddceb435e13d81601755714e9fSE Android scontextp += strlen(policydb->p_cat_val_to_name[i - 1]); 237255e72915d4cbddceb435e13d81601755714e9fSE Android } 238255e72915d4cbddceb435e13d81601755714e9fSE Android 239255e72915d4cbddceb435e13d81601755714e9fSE Android if (l == 0) { 240255e72915d4cbddceb435e13d81601755714e9fSE Android if (mls_level_eq(&context->range.level[0], 241255e72915d4cbddceb435e13d81601755714e9fSE Android &context->range.level[1])) 242255e72915d4cbddceb435e13d81601755714e9fSE Android break; 243255e72915d4cbddceb435e13d81601755714e9fSE Android else { 244255e72915d4cbddceb435e13d81601755714e9fSE Android *scontextp = '-'; 245255e72915d4cbddceb435e13d81601755714e9fSE Android scontextp++; 246255e72915d4cbddceb435e13d81601755714e9fSE Android } 247255e72915d4cbddceb435e13d81601755714e9fSE Android } 248255e72915d4cbddceb435e13d81601755714e9fSE Android } 249255e72915d4cbddceb435e13d81601755714e9fSE Android 250255e72915d4cbddceb435e13d81601755714e9fSE Android *scontext = scontextp; 251255e72915d4cbddceb435e13d81601755714e9fSE Android return; 252255e72915d4cbddceb435e13d81601755714e9fSE Android} 253255e72915d4cbddceb435e13d81601755714e9fSE Android 254255e72915d4cbddceb435e13d81601755714e9fSE Android/* 255255e72915d4cbddceb435e13d81601755714e9fSE Android * Return 1 if the MLS fields in the security context 256255e72915d4cbddceb435e13d81601755714e9fSE Android * structure `c' are valid. Return 0 otherwise. 257255e72915d4cbddceb435e13d81601755714e9fSE Android */ 258255e72915d4cbddceb435e13d81601755714e9fSE Androidint mls_context_isvalid(const policydb_t * p, const context_struct_t * c) 259255e72915d4cbddceb435e13d81601755714e9fSE Android{ 260255e72915d4cbddceb435e13d81601755714e9fSE Android 261255e72915d4cbddceb435e13d81601755714e9fSE Android level_datum_t *levdatum; 262255e72915d4cbddceb435e13d81601755714e9fSE Android user_datum_t *usrdatum; 263255e72915d4cbddceb435e13d81601755714e9fSE Android unsigned int i, l; 264255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_node_t *cnode; 265255e72915d4cbddceb435e13d81601755714e9fSE Android 266255e72915d4cbddceb435e13d81601755714e9fSE Android if (!p->mls) 267255e72915d4cbddceb435e13d81601755714e9fSE Android return 1; 268255e72915d4cbddceb435e13d81601755714e9fSE Android 269255e72915d4cbddceb435e13d81601755714e9fSE Android /* 270255e72915d4cbddceb435e13d81601755714e9fSE Android * MLS range validity checks: high must dominate low, low level must 271255e72915d4cbddceb435e13d81601755714e9fSE Android * be valid (category set <-> sensitivity check), and high level must 272255e72915d4cbddceb435e13d81601755714e9fSE Android * be valid (category set <-> sensitivity check) 273255e72915d4cbddceb435e13d81601755714e9fSE Android */ 274255e72915d4cbddceb435e13d81601755714e9fSE Android if (!mls_level_dom(&c->range.level[1], &c->range.level[0])) 275255e72915d4cbddceb435e13d81601755714e9fSE Android /* High does not dominate low. */ 276255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 277255e72915d4cbddceb435e13d81601755714e9fSE Android 278255e72915d4cbddceb435e13d81601755714e9fSE Android for (l = 0; l < 2; l++) { 279255e72915d4cbddceb435e13d81601755714e9fSE Android if (!c->range.level[l].sens 280255e72915d4cbddceb435e13d81601755714e9fSE Android || c->range.level[l].sens > p->p_levels.nprim) 281255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 282255e72915d4cbddceb435e13d81601755714e9fSE Android levdatum = (level_datum_t *) hashtab_search(p->p_levels.table, 283255e72915d4cbddceb435e13d81601755714e9fSE Android p-> 284255e72915d4cbddceb435e13d81601755714e9fSE Android p_sens_val_to_name 285255e72915d4cbddceb435e13d81601755714e9fSE Android [c->range.level[l]. 286255e72915d4cbddceb435e13d81601755714e9fSE Android sens - 1]); 287255e72915d4cbddceb435e13d81601755714e9fSE Android if (!levdatum) 288255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 289255e72915d4cbddceb435e13d81601755714e9fSE Android 290255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_for_each_bit(&c->range.level[l].cat, cnode, i) { 291255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_node_get_bit(cnode, i)) { 292255e72915d4cbddceb435e13d81601755714e9fSE Android if (i > p->p_cats.nprim) 293255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 294255e72915d4cbddceb435e13d81601755714e9fSE Android if (!ebitmap_get_bit(&levdatum->level->cat, i)) 295255e72915d4cbddceb435e13d81601755714e9fSE Android /* 296255e72915d4cbddceb435e13d81601755714e9fSE Android * Category may not be associated with 297255e72915d4cbddceb435e13d81601755714e9fSE Android * sensitivity in low level. 298255e72915d4cbddceb435e13d81601755714e9fSE Android */ 299255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 300255e72915d4cbddceb435e13d81601755714e9fSE Android } 301255e72915d4cbddceb435e13d81601755714e9fSE Android } 302255e72915d4cbddceb435e13d81601755714e9fSE Android } 303255e72915d4cbddceb435e13d81601755714e9fSE Android 304255e72915d4cbddceb435e13d81601755714e9fSE Android if (c->role == OBJECT_R_VAL) 305255e72915d4cbddceb435e13d81601755714e9fSE Android return 1; 306255e72915d4cbddceb435e13d81601755714e9fSE Android 307255e72915d4cbddceb435e13d81601755714e9fSE Android /* 308255e72915d4cbddceb435e13d81601755714e9fSE Android * User must be authorized for the MLS range. 309255e72915d4cbddceb435e13d81601755714e9fSE Android */ 310255e72915d4cbddceb435e13d81601755714e9fSE Android if (!c->user || c->user > p->p_users.nprim) 311255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 312255e72915d4cbddceb435e13d81601755714e9fSE Android usrdatum = p->user_val_to_struct[c->user - 1]; 313255e72915d4cbddceb435e13d81601755714e9fSE Android if (!mls_range_contains(usrdatum->exp_range, c->range)) 314255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; /* user may not be associated with range */ 315255e72915d4cbddceb435e13d81601755714e9fSE Android 316255e72915d4cbddceb435e13d81601755714e9fSE Android return 1; 317255e72915d4cbddceb435e13d81601755714e9fSE Android} 318255e72915d4cbddceb435e13d81601755714e9fSE Android 319255e72915d4cbddceb435e13d81601755714e9fSE Android/* 320255e72915d4cbddceb435e13d81601755714e9fSE Android * Set the MLS fields in the security context structure 321255e72915d4cbddceb435e13d81601755714e9fSE Android * `context' based on the string representation in 322255e72915d4cbddceb435e13d81601755714e9fSE Android * the string `*scontext'. Update `*scontext' to 323255e72915d4cbddceb435e13d81601755714e9fSE Android * point to the end of the string representation of 324255e72915d4cbddceb435e13d81601755714e9fSE Android * the MLS fields. 325255e72915d4cbddceb435e13d81601755714e9fSE Android * 326255e72915d4cbddceb435e13d81601755714e9fSE Android * This function modifies the string in place, inserting 327255e72915d4cbddceb435e13d81601755714e9fSE Android * NULL characters to terminate the MLS fields. 328255e72915d4cbddceb435e13d81601755714e9fSE Android */ 329255e72915d4cbddceb435e13d81601755714e9fSE Androidint mls_context_to_sid(const policydb_t * policydb, 330255e72915d4cbddceb435e13d81601755714e9fSE Android char oldc, char **scontext, context_struct_t * context) 331255e72915d4cbddceb435e13d81601755714e9fSE Android{ 332255e72915d4cbddceb435e13d81601755714e9fSE Android 333255e72915d4cbddceb435e13d81601755714e9fSE Android char delim; 334255e72915d4cbddceb435e13d81601755714e9fSE Android char *scontextp, *p, *rngptr; 335255e72915d4cbddceb435e13d81601755714e9fSE Android level_datum_t *levdatum; 336255e72915d4cbddceb435e13d81601755714e9fSE Android cat_datum_t *catdatum, *rngdatum; 337255e72915d4cbddceb435e13d81601755714e9fSE Android unsigned int l; 338255e72915d4cbddceb435e13d81601755714e9fSE Android 339255e72915d4cbddceb435e13d81601755714e9fSE Android if (!policydb->mls) 340255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 341255e72915d4cbddceb435e13d81601755714e9fSE Android 342255e72915d4cbddceb435e13d81601755714e9fSE Android /* No MLS component to the security context */ 343255e72915d4cbddceb435e13d81601755714e9fSE Android if (!oldc) 344255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 345255e72915d4cbddceb435e13d81601755714e9fSE Android 346255e72915d4cbddceb435e13d81601755714e9fSE Android /* Extract low sensitivity. */ 347255e72915d4cbddceb435e13d81601755714e9fSE Android scontextp = p = *scontext; 348255e72915d4cbddceb435e13d81601755714e9fSE Android while (*p && *p != ':' && *p != '-') 349255e72915d4cbddceb435e13d81601755714e9fSE Android p++; 350255e72915d4cbddceb435e13d81601755714e9fSE Android 351255e72915d4cbddceb435e13d81601755714e9fSE Android delim = *p; 352255e72915d4cbddceb435e13d81601755714e9fSE Android if (delim != 0) 353255e72915d4cbddceb435e13d81601755714e9fSE Android *p++ = 0; 354255e72915d4cbddceb435e13d81601755714e9fSE Android 355255e72915d4cbddceb435e13d81601755714e9fSE Android for (l = 0; l < 2; l++) { 356255e72915d4cbddceb435e13d81601755714e9fSE Android levdatum = 357255e72915d4cbddceb435e13d81601755714e9fSE Android (level_datum_t *) hashtab_search(policydb->p_levels.table, 358255e72915d4cbddceb435e13d81601755714e9fSE Android (hashtab_key_t) scontextp); 359255e72915d4cbddceb435e13d81601755714e9fSE Android 360255e72915d4cbddceb435e13d81601755714e9fSE Android if (!levdatum) 361255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 362255e72915d4cbddceb435e13d81601755714e9fSE Android 363255e72915d4cbddceb435e13d81601755714e9fSE Android context->range.level[l].sens = levdatum->level->sens; 364255e72915d4cbddceb435e13d81601755714e9fSE Android 365255e72915d4cbddceb435e13d81601755714e9fSE Android if (delim == ':') { 366255e72915d4cbddceb435e13d81601755714e9fSE Android /* Extract category set. */ 367255e72915d4cbddceb435e13d81601755714e9fSE Android while (1) { 368255e72915d4cbddceb435e13d81601755714e9fSE Android scontextp = p; 369255e72915d4cbddceb435e13d81601755714e9fSE Android while (*p && *p != ',' && *p != '-') 370255e72915d4cbddceb435e13d81601755714e9fSE Android p++; 371255e72915d4cbddceb435e13d81601755714e9fSE Android delim = *p; 372255e72915d4cbddceb435e13d81601755714e9fSE Android if (delim != 0) 373255e72915d4cbddceb435e13d81601755714e9fSE Android *p++ = 0; 374255e72915d4cbddceb435e13d81601755714e9fSE Android 375255e72915d4cbddceb435e13d81601755714e9fSE Android /* Separate into range if exists */ 376255e72915d4cbddceb435e13d81601755714e9fSE Android if ((rngptr = strchr(scontextp, '.')) != NULL) { 377255e72915d4cbddceb435e13d81601755714e9fSE Android /* Remove '.' */ 378255e72915d4cbddceb435e13d81601755714e9fSE Android *rngptr++ = 0; 379255e72915d4cbddceb435e13d81601755714e9fSE Android } 380255e72915d4cbddceb435e13d81601755714e9fSE Android 381255e72915d4cbddceb435e13d81601755714e9fSE Android catdatum = 382255e72915d4cbddceb435e13d81601755714e9fSE Android (cat_datum_t *) hashtab_search(policydb-> 383255e72915d4cbddceb435e13d81601755714e9fSE Android p_cats.table, 384255e72915d4cbddceb435e13d81601755714e9fSE Android (hashtab_key_t) 385255e72915d4cbddceb435e13d81601755714e9fSE Android scontextp); 386255e72915d4cbddceb435e13d81601755714e9fSE Android if (!catdatum) 387255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 388255e72915d4cbddceb435e13d81601755714e9fSE Android 389255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_set_bit 390255e72915d4cbddceb435e13d81601755714e9fSE Android (&context->range.level[l].cat, 391255e72915d4cbddceb435e13d81601755714e9fSE Android catdatum->s.value - 1, 1)) 392255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 393255e72915d4cbddceb435e13d81601755714e9fSE Android 394255e72915d4cbddceb435e13d81601755714e9fSE Android /* If range, set all categories in range */ 395255e72915d4cbddceb435e13d81601755714e9fSE Android if (rngptr) { 396255e72915d4cbddceb435e13d81601755714e9fSE Android unsigned int i; 397255e72915d4cbddceb435e13d81601755714e9fSE Android 398255e72915d4cbddceb435e13d81601755714e9fSE Android rngdatum = (cat_datum_t *) 399255e72915d4cbddceb435e13d81601755714e9fSE Android hashtab_search(policydb->p_cats. 400255e72915d4cbddceb435e13d81601755714e9fSE Android table, 401255e72915d4cbddceb435e13d81601755714e9fSE Android (hashtab_key_t) 402255e72915d4cbddceb435e13d81601755714e9fSE Android rngptr); 403255e72915d4cbddceb435e13d81601755714e9fSE Android if (!rngdatum) 404255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 405255e72915d4cbddceb435e13d81601755714e9fSE Android 406255e72915d4cbddceb435e13d81601755714e9fSE Android if (catdatum->s.value >= 407255e72915d4cbddceb435e13d81601755714e9fSE Android rngdatum->s.value) 408255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 409255e72915d4cbddceb435e13d81601755714e9fSE Android 410255e72915d4cbddceb435e13d81601755714e9fSE Android for (i = catdatum->s.value; 411255e72915d4cbddceb435e13d81601755714e9fSE Android i < rngdatum->s.value; i++) { 412255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_set_bit 413255e72915d4cbddceb435e13d81601755714e9fSE Android (&context->range.level[l]. 414255e72915d4cbddceb435e13d81601755714e9fSE Android cat, i, 1)) 415255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 416255e72915d4cbddceb435e13d81601755714e9fSE Android } 417255e72915d4cbddceb435e13d81601755714e9fSE Android } 418255e72915d4cbddceb435e13d81601755714e9fSE Android 419255e72915d4cbddceb435e13d81601755714e9fSE Android if (delim != ',') 420255e72915d4cbddceb435e13d81601755714e9fSE Android break; 421255e72915d4cbddceb435e13d81601755714e9fSE Android } 422255e72915d4cbddceb435e13d81601755714e9fSE Android } 423255e72915d4cbddceb435e13d81601755714e9fSE Android if (delim == '-') { 424255e72915d4cbddceb435e13d81601755714e9fSE Android /* Extract high sensitivity. */ 425255e72915d4cbddceb435e13d81601755714e9fSE Android scontextp = p; 426255e72915d4cbddceb435e13d81601755714e9fSE Android while (*p && *p != ':') 427255e72915d4cbddceb435e13d81601755714e9fSE Android p++; 428255e72915d4cbddceb435e13d81601755714e9fSE Android 429255e72915d4cbddceb435e13d81601755714e9fSE Android delim = *p; 430255e72915d4cbddceb435e13d81601755714e9fSE Android if (delim != 0) 431255e72915d4cbddceb435e13d81601755714e9fSE Android *p++ = 0; 432255e72915d4cbddceb435e13d81601755714e9fSE Android } else 433255e72915d4cbddceb435e13d81601755714e9fSE Android break; 434255e72915d4cbddceb435e13d81601755714e9fSE Android } 435255e72915d4cbddceb435e13d81601755714e9fSE Android 436255e72915d4cbddceb435e13d81601755714e9fSE Android /* High level is missing, copy low level */ 437255e72915d4cbddceb435e13d81601755714e9fSE Android if (l == 0) { 438255e72915d4cbddceb435e13d81601755714e9fSE Android if (mls_level_cpy(&context->range.level[1], 439255e72915d4cbddceb435e13d81601755714e9fSE Android &context->range.level[0]) < 0) 440255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 441255e72915d4cbddceb435e13d81601755714e9fSE Android } 442255e72915d4cbddceb435e13d81601755714e9fSE Android *scontext = ++p; 443255e72915d4cbddceb435e13d81601755714e9fSE Android 444255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_SUCCESS; 445255e72915d4cbddceb435e13d81601755714e9fSE Android 446255e72915d4cbddceb435e13d81601755714e9fSE Android err: 447255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_ERR; 448255e72915d4cbddceb435e13d81601755714e9fSE Android} 449255e72915d4cbddceb435e13d81601755714e9fSE Android 450255e72915d4cbddceb435e13d81601755714e9fSE Android/* 451255e72915d4cbddceb435e13d81601755714e9fSE Android * Copies the MLS range from `src' into `dst'. 452255e72915d4cbddceb435e13d81601755714e9fSE Android */ 453255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic inline int mls_copy_context(context_struct_t * dst, 454255e72915d4cbddceb435e13d81601755714e9fSE Android context_struct_t * src) 455255e72915d4cbddceb435e13d81601755714e9fSE Android{ 456255e72915d4cbddceb435e13d81601755714e9fSE Android int l, rc = 0; 457255e72915d4cbddceb435e13d81601755714e9fSE Android 458255e72915d4cbddceb435e13d81601755714e9fSE Android /* Copy the MLS range from the source context */ 459255e72915d4cbddceb435e13d81601755714e9fSE Android for (l = 0; l < 2; l++) { 460255e72915d4cbddceb435e13d81601755714e9fSE Android dst->range.level[l].sens = src->range.level[l].sens; 461255e72915d4cbddceb435e13d81601755714e9fSE Android rc = ebitmap_cpy(&dst->range.level[l].cat, 462255e72915d4cbddceb435e13d81601755714e9fSE Android &src->range.level[l].cat); 463255e72915d4cbddceb435e13d81601755714e9fSE Android if (rc) 464255e72915d4cbddceb435e13d81601755714e9fSE Android break; 465255e72915d4cbddceb435e13d81601755714e9fSE Android } 466255e72915d4cbddceb435e13d81601755714e9fSE Android 467255e72915d4cbddceb435e13d81601755714e9fSE Android return rc; 468255e72915d4cbddceb435e13d81601755714e9fSE Android} 469255e72915d4cbddceb435e13d81601755714e9fSE Android 470255e72915d4cbddceb435e13d81601755714e9fSE Android/* 471255e72915d4cbddceb435e13d81601755714e9fSE Android * Copies the effective MLS range from `src' into `dst'. 472255e72915d4cbddceb435e13d81601755714e9fSE Android */ 473255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic inline int mls_scopy_context(context_struct_t * dst, 474255e72915d4cbddceb435e13d81601755714e9fSE Android context_struct_t * src) 475255e72915d4cbddceb435e13d81601755714e9fSE Android{ 476255e72915d4cbddceb435e13d81601755714e9fSE Android int l, rc = 0; 477255e72915d4cbddceb435e13d81601755714e9fSE Android 478255e72915d4cbddceb435e13d81601755714e9fSE Android /* Copy the MLS range from the source context */ 479255e72915d4cbddceb435e13d81601755714e9fSE Android for (l = 0; l < 2; l++) { 480255e72915d4cbddceb435e13d81601755714e9fSE Android dst->range.level[l].sens = src->range.level[0].sens; 481255e72915d4cbddceb435e13d81601755714e9fSE Android rc = ebitmap_cpy(&dst->range.level[l].cat, 482255e72915d4cbddceb435e13d81601755714e9fSE Android &src->range.level[0].cat); 483255e72915d4cbddceb435e13d81601755714e9fSE Android if (rc) 484255e72915d4cbddceb435e13d81601755714e9fSE Android break; 485255e72915d4cbddceb435e13d81601755714e9fSE Android } 486255e72915d4cbddceb435e13d81601755714e9fSE Android 487255e72915d4cbddceb435e13d81601755714e9fSE Android return rc; 488255e72915d4cbddceb435e13d81601755714e9fSE Android} 489255e72915d4cbddceb435e13d81601755714e9fSE Android 490255e72915d4cbddceb435e13d81601755714e9fSE Android/* 491255e72915d4cbddceb435e13d81601755714e9fSE Android * Copies the MLS range `range' into `context'. 492255e72915d4cbddceb435e13d81601755714e9fSE Android */ 493255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic inline int mls_range_set(context_struct_t * context, mls_range_t * range) 494255e72915d4cbddceb435e13d81601755714e9fSE Android{ 495255e72915d4cbddceb435e13d81601755714e9fSE Android int l, rc = 0; 496255e72915d4cbddceb435e13d81601755714e9fSE Android 497255e72915d4cbddceb435e13d81601755714e9fSE Android /* Copy the MLS range into the context */ 498255e72915d4cbddceb435e13d81601755714e9fSE Android for (l = 0; l < 2; l++) { 499255e72915d4cbddceb435e13d81601755714e9fSE Android context->range.level[l].sens = range->level[l].sens; 500255e72915d4cbddceb435e13d81601755714e9fSE Android rc = ebitmap_cpy(&context->range.level[l].cat, 501255e72915d4cbddceb435e13d81601755714e9fSE Android &range->level[l].cat); 502255e72915d4cbddceb435e13d81601755714e9fSE Android if (rc) 503255e72915d4cbddceb435e13d81601755714e9fSE Android break; 504255e72915d4cbddceb435e13d81601755714e9fSE Android } 505255e72915d4cbddceb435e13d81601755714e9fSE Android 506255e72915d4cbddceb435e13d81601755714e9fSE Android return rc; 507255e72915d4cbddceb435e13d81601755714e9fSE Android} 508255e72915d4cbddceb435e13d81601755714e9fSE Android 509255e72915d4cbddceb435e13d81601755714e9fSE Androidint mls_setup_user_range(context_struct_t * fromcon, user_datum_t * user, 510255e72915d4cbddceb435e13d81601755714e9fSE Android context_struct_t * usercon, int mls) 511255e72915d4cbddceb435e13d81601755714e9fSE Android{ 512255e72915d4cbddceb435e13d81601755714e9fSE Android if (mls) { 513255e72915d4cbddceb435e13d81601755714e9fSE Android mls_level_t *fromcon_sen = &(fromcon->range.level[0]); 514255e72915d4cbddceb435e13d81601755714e9fSE Android mls_level_t *fromcon_clr = &(fromcon->range.level[1]); 515255e72915d4cbddceb435e13d81601755714e9fSE Android mls_level_t *user_low = &(user->exp_range.level[0]); 516255e72915d4cbddceb435e13d81601755714e9fSE Android mls_level_t *user_clr = &(user->exp_range.level[1]); 517255e72915d4cbddceb435e13d81601755714e9fSE Android mls_level_t *user_def = &(user->exp_dfltlevel); 518255e72915d4cbddceb435e13d81601755714e9fSE Android mls_level_t *usercon_sen = &(usercon->range.level[0]); 519255e72915d4cbddceb435e13d81601755714e9fSE Android mls_level_t *usercon_clr = &(usercon->range.level[1]); 520255e72915d4cbddceb435e13d81601755714e9fSE Android 521255e72915d4cbddceb435e13d81601755714e9fSE Android /* Honor the user's default level if we can */ 522255e72915d4cbddceb435e13d81601755714e9fSE Android if (mls_level_between(user_def, fromcon_sen, fromcon_clr)) { 523255e72915d4cbddceb435e13d81601755714e9fSE Android *usercon_sen = *user_def; 524255e72915d4cbddceb435e13d81601755714e9fSE Android } else if (mls_level_between(fromcon_sen, user_def, user_clr)) { 525255e72915d4cbddceb435e13d81601755714e9fSE Android *usercon_sen = *fromcon_sen; 526255e72915d4cbddceb435e13d81601755714e9fSE Android } else if (mls_level_between(fromcon_clr, user_low, user_def)) { 527255e72915d4cbddceb435e13d81601755714e9fSE Android *usercon_sen = *user_low; 528255e72915d4cbddceb435e13d81601755714e9fSE Android } else 529255e72915d4cbddceb435e13d81601755714e9fSE Android return -EINVAL; 530255e72915d4cbddceb435e13d81601755714e9fSE Android 531255e72915d4cbddceb435e13d81601755714e9fSE Android /* Lower the clearance of available contexts 532255e72915d4cbddceb435e13d81601755714e9fSE Android if the clearance of "fromcon" is lower than 533255e72915d4cbddceb435e13d81601755714e9fSE Android that of the user's default clearance (but 534255e72915d4cbddceb435e13d81601755714e9fSE Android only if the "fromcon" clearance dominates 535255e72915d4cbddceb435e13d81601755714e9fSE Android the user's computed sensitivity level) */ 536255e72915d4cbddceb435e13d81601755714e9fSE Android if (mls_level_dom(user_clr, fromcon_clr)) { 537255e72915d4cbddceb435e13d81601755714e9fSE Android *usercon_clr = *fromcon_clr; 538255e72915d4cbddceb435e13d81601755714e9fSE Android } else if (mls_level_dom(fromcon_clr, user_clr)) { 539255e72915d4cbddceb435e13d81601755714e9fSE Android *usercon_clr = *user_clr; 540255e72915d4cbddceb435e13d81601755714e9fSE Android } else 541255e72915d4cbddceb435e13d81601755714e9fSE Android return -EINVAL; 542255e72915d4cbddceb435e13d81601755714e9fSE Android } 543255e72915d4cbddceb435e13d81601755714e9fSE Android 544255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 545255e72915d4cbddceb435e13d81601755714e9fSE Android} 546255e72915d4cbddceb435e13d81601755714e9fSE Android 547255e72915d4cbddceb435e13d81601755714e9fSE Android/* 548255e72915d4cbddceb435e13d81601755714e9fSE Android * Convert the MLS fields in the security context 549255e72915d4cbddceb435e13d81601755714e9fSE Android * structure `c' from the values specified in the 550255e72915d4cbddceb435e13d81601755714e9fSE Android * policy `oldp' to the values specified in the policy `newp'. 551255e72915d4cbddceb435e13d81601755714e9fSE Android */ 552255e72915d4cbddceb435e13d81601755714e9fSE Androidint mls_convert_context(policydb_t * oldp, 553255e72915d4cbddceb435e13d81601755714e9fSE Android policydb_t * newp, context_struct_t * c) 554255e72915d4cbddceb435e13d81601755714e9fSE Android{ 555255e72915d4cbddceb435e13d81601755714e9fSE Android level_datum_t *levdatum; 556255e72915d4cbddceb435e13d81601755714e9fSE Android cat_datum_t *catdatum; 557255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_t bitmap; 558255e72915d4cbddceb435e13d81601755714e9fSE Android unsigned int l, i; 559255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_node_t *cnode; 560255e72915d4cbddceb435e13d81601755714e9fSE Android 561255e72915d4cbddceb435e13d81601755714e9fSE Android if (!oldp->mls) 562255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 563255e72915d4cbddceb435e13d81601755714e9fSE Android 564255e72915d4cbddceb435e13d81601755714e9fSE Android for (l = 0; l < 2; l++) { 565255e72915d4cbddceb435e13d81601755714e9fSE Android levdatum = 566255e72915d4cbddceb435e13d81601755714e9fSE Android (level_datum_t *) hashtab_search(newp->p_levels.table, 567255e72915d4cbddceb435e13d81601755714e9fSE Android oldp-> 568255e72915d4cbddceb435e13d81601755714e9fSE Android p_sens_val_to_name[c-> 569255e72915d4cbddceb435e13d81601755714e9fSE Android range. 570255e72915d4cbddceb435e13d81601755714e9fSE Android level 571255e72915d4cbddceb435e13d81601755714e9fSE Android [l]. 572255e72915d4cbddceb435e13d81601755714e9fSE Android sens - 573255e72915d4cbddceb435e13d81601755714e9fSE Android 1]); 574255e72915d4cbddceb435e13d81601755714e9fSE Android 575255e72915d4cbddceb435e13d81601755714e9fSE Android if (!levdatum) 576255e72915d4cbddceb435e13d81601755714e9fSE Android return -EINVAL; 577255e72915d4cbddceb435e13d81601755714e9fSE Android c->range.level[l].sens = levdatum->level->sens; 578255e72915d4cbddceb435e13d81601755714e9fSE Android 579255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_init(&bitmap); 580255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_for_each_bit(&c->range.level[l].cat, cnode, i) { 581255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_node_get_bit(cnode, i)) { 582255e72915d4cbddceb435e13d81601755714e9fSE Android int rc; 583255e72915d4cbddceb435e13d81601755714e9fSE Android 584255e72915d4cbddceb435e13d81601755714e9fSE Android catdatum = 585255e72915d4cbddceb435e13d81601755714e9fSE Android (cat_datum_t *) hashtab_search(newp->p_cats. 586255e72915d4cbddceb435e13d81601755714e9fSE Android table, 587255e72915d4cbddceb435e13d81601755714e9fSE Android oldp-> 588255e72915d4cbddceb435e13d81601755714e9fSE Android p_cat_val_to_name 589255e72915d4cbddceb435e13d81601755714e9fSE Android [i]); 590255e72915d4cbddceb435e13d81601755714e9fSE Android if (!catdatum) 591255e72915d4cbddceb435e13d81601755714e9fSE Android return -EINVAL; 592255e72915d4cbddceb435e13d81601755714e9fSE Android rc = ebitmap_set_bit(&bitmap, 593255e72915d4cbddceb435e13d81601755714e9fSE Android catdatum->s.value - 1, 1); 594255e72915d4cbddceb435e13d81601755714e9fSE Android if (rc) 595255e72915d4cbddceb435e13d81601755714e9fSE Android return rc; 596255e72915d4cbddceb435e13d81601755714e9fSE Android } 597255e72915d4cbddceb435e13d81601755714e9fSE Android } 598255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_destroy(&c->range.level[l].cat); 599255e72915d4cbddceb435e13d81601755714e9fSE Android c->range.level[l].cat = bitmap; 600255e72915d4cbddceb435e13d81601755714e9fSE Android } 601255e72915d4cbddceb435e13d81601755714e9fSE Android 602255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 603255e72915d4cbddceb435e13d81601755714e9fSE Android} 604255e72915d4cbddceb435e13d81601755714e9fSE Android 605255e72915d4cbddceb435e13d81601755714e9fSE Androidint mls_compute_sid(policydb_t * policydb, 606255e72915d4cbddceb435e13d81601755714e9fSE Android context_struct_t * scontext, 607255e72915d4cbddceb435e13d81601755714e9fSE Android context_struct_t * tcontext, 608255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_security_class_t tclass, 609255e72915d4cbddceb435e13d81601755714e9fSE Android uint32_t specified, context_struct_t * newcontext) 610255e72915d4cbddceb435e13d81601755714e9fSE Android{ 611255e72915d4cbddceb435e13d81601755714e9fSE Android range_trans_t *rtr; 612255e72915d4cbddceb435e13d81601755714e9fSE Android if (!policydb->mls) 613255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 614255e72915d4cbddceb435e13d81601755714e9fSE Android 615255e72915d4cbddceb435e13d81601755714e9fSE Android switch (specified) { 616255e72915d4cbddceb435e13d81601755714e9fSE Android case AVTAB_TRANSITION: 617255e72915d4cbddceb435e13d81601755714e9fSE Android /* Look for a range transition rule. */ 618255e72915d4cbddceb435e13d81601755714e9fSE Android for (rtr = policydb->range_tr; rtr; rtr = rtr->next) { 619255e72915d4cbddceb435e13d81601755714e9fSE Android if (rtr->source_type == scontext->type && 620255e72915d4cbddceb435e13d81601755714e9fSE Android rtr->target_type == tcontext->type && 621255e72915d4cbddceb435e13d81601755714e9fSE Android rtr->target_class == tclass) { 622255e72915d4cbddceb435e13d81601755714e9fSE Android /* Set the range from the rule */ 623255e72915d4cbddceb435e13d81601755714e9fSE Android return mls_range_set(newcontext, 624255e72915d4cbddceb435e13d81601755714e9fSE Android &rtr->target_range); 625255e72915d4cbddceb435e13d81601755714e9fSE Android } 626255e72915d4cbddceb435e13d81601755714e9fSE Android } 627255e72915d4cbddceb435e13d81601755714e9fSE Android /* Fallthrough */ 628255e72915d4cbddceb435e13d81601755714e9fSE Android case AVTAB_CHANGE: 629255e72915d4cbddceb435e13d81601755714e9fSE Android if (tclass == SECCLASS_PROCESS) 630255e72915d4cbddceb435e13d81601755714e9fSE Android /* Use the process MLS attributes. */ 631255e72915d4cbddceb435e13d81601755714e9fSE Android return mls_copy_context(newcontext, scontext); 632255e72915d4cbddceb435e13d81601755714e9fSE Android else 633255e72915d4cbddceb435e13d81601755714e9fSE Android /* Use the process effective MLS attributes. */ 634255e72915d4cbddceb435e13d81601755714e9fSE Android return mls_scopy_context(newcontext, scontext); 635255e72915d4cbddceb435e13d81601755714e9fSE Android case AVTAB_MEMBER: 636255e72915d4cbddceb435e13d81601755714e9fSE Android /* Only polyinstantiate the MLS attributes if 637255e72915d4cbddceb435e13d81601755714e9fSE Android the type is being polyinstantiated */ 638255e72915d4cbddceb435e13d81601755714e9fSE Android if (newcontext->type != tcontext->type) { 639255e72915d4cbddceb435e13d81601755714e9fSE Android /* Use the process effective MLS attributes. */ 640255e72915d4cbddceb435e13d81601755714e9fSE Android return mls_scopy_context(newcontext, scontext); 641255e72915d4cbddceb435e13d81601755714e9fSE Android } else { 642255e72915d4cbddceb435e13d81601755714e9fSE Android /* Use the related object MLS attributes. */ 643255e72915d4cbddceb435e13d81601755714e9fSE Android return mls_copy_context(newcontext, tcontext); 644255e72915d4cbddceb435e13d81601755714e9fSE Android } 645255e72915d4cbddceb435e13d81601755714e9fSE Android default: 646255e72915d4cbddceb435e13d81601755714e9fSE Android return -EINVAL; 647255e72915d4cbddceb435e13d81601755714e9fSE Android } 648255e72915d4cbddceb435e13d81601755714e9fSE Android return -EINVAL; 649255e72915d4cbddceb435e13d81601755714e9fSE Android} 650255e72915d4cbddceb435e13d81601755714e9fSE Android 651255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_mls_contains(sepol_handle_t * handle, 652255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_policydb_t * policydb, 653255e72915d4cbddceb435e13d81601755714e9fSE Android const char *mls1, const char *mls2, int *response) 654255e72915d4cbddceb435e13d81601755714e9fSE Android{ 655255e72915d4cbddceb435e13d81601755714e9fSE Android 656255e72915d4cbddceb435e13d81601755714e9fSE Android context_struct_t *ctx1 = NULL, *ctx2 = NULL; 657255e72915d4cbddceb435e13d81601755714e9fSE Android ctx1 = malloc(sizeof(context_struct_t)); 658255e72915d4cbddceb435e13d81601755714e9fSE Android ctx2 = malloc(sizeof(context_struct_t)); 659255e72915d4cbddceb435e13d81601755714e9fSE Android if (ctx1 == NULL || ctx2 == NULL) 660255e72915d4cbddceb435e13d81601755714e9fSE Android goto omem; 661255e72915d4cbddceb435e13d81601755714e9fSE Android context_init(ctx1); 662255e72915d4cbddceb435e13d81601755714e9fSE Android context_init(ctx2); 663255e72915d4cbddceb435e13d81601755714e9fSE Android 664255e72915d4cbddceb435e13d81601755714e9fSE Android if (mls_from_string(handle, &policydb->p, mls1, ctx1) < 0) 665255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 666255e72915d4cbddceb435e13d81601755714e9fSE Android 667255e72915d4cbddceb435e13d81601755714e9fSE Android if (mls_from_string(handle, &policydb->p, mls2, ctx2) < 0) 668255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 669255e72915d4cbddceb435e13d81601755714e9fSE Android 670255e72915d4cbddceb435e13d81601755714e9fSE Android *response = mls_range_contains(ctx1->range, ctx2->range); 671255e72915d4cbddceb435e13d81601755714e9fSE Android context_destroy(ctx1); 672255e72915d4cbddceb435e13d81601755714e9fSE Android context_destroy(ctx2); 673255e72915d4cbddceb435e13d81601755714e9fSE Android free(ctx1); 674255e72915d4cbddceb435e13d81601755714e9fSE Android free(ctx2); 675255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_SUCCESS; 676255e72915d4cbddceb435e13d81601755714e9fSE Android 677255e72915d4cbddceb435e13d81601755714e9fSE Android omem: 678255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "out of memory"); 679255e72915d4cbddceb435e13d81601755714e9fSE Android 680255e72915d4cbddceb435e13d81601755714e9fSE Android err: 681255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "could not check if mls context %s contains %s", 682255e72915d4cbddceb435e13d81601755714e9fSE Android mls1, mls2); 683255e72915d4cbddceb435e13d81601755714e9fSE Android context_destroy(ctx1); 684255e72915d4cbddceb435e13d81601755714e9fSE Android context_destroy(ctx2); 685255e72915d4cbddceb435e13d81601755714e9fSE Android free(ctx1); 686255e72915d4cbddceb435e13d81601755714e9fSE Android free(ctx2); 687255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_ERR; 688255e72915d4cbddceb435e13d81601755714e9fSE Android} 689255e72915d4cbddceb435e13d81601755714e9fSE Android 690255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_mls_check(sepol_handle_t * handle, 691255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_policydb_t * policydb, const char *mls) 692255e72915d4cbddceb435e13d81601755714e9fSE Android{ 693255e72915d4cbddceb435e13d81601755714e9fSE Android 694255e72915d4cbddceb435e13d81601755714e9fSE Android int ret; 695255e72915d4cbddceb435e13d81601755714e9fSE Android context_struct_t *con = malloc(sizeof(context_struct_t)); 696255e72915d4cbddceb435e13d81601755714e9fSE Android if (!con) { 697255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "out of memory, could not check if " 698255e72915d4cbddceb435e13d81601755714e9fSE Android "mls context %s is valid", mls); 699255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_ERR; 700255e72915d4cbddceb435e13d81601755714e9fSE Android } 701255e72915d4cbddceb435e13d81601755714e9fSE Android context_init(con); 702255e72915d4cbddceb435e13d81601755714e9fSE Android 703255e72915d4cbddceb435e13d81601755714e9fSE Android ret = mls_from_string(handle, &policydb->p, mls, con); 704255e72915d4cbddceb435e13d81601755714e9fSE Android context_destroy(con); 705255e72915d4cbddceb435e13d81601755714e9fSE Android free(con); 706255e72915d4cbddceb435e13d81601755714e9fSE Android return ret; 707255e72915d4cbddceb435e13d81601755714e9fSE Android} 708255e72915d4cbddceb435e13d81601755714e9fSE Android 709255e72915d4cbddceb435e13d81601755714e9fSE Androidvoid mls_semantic_cat_init(mls_semantic_cat_t * c) 710255e72915d4cbddceb435e13d81601755714e9fSE Android{ 711255e72915d4cbddceb435e13d81601755714e9fSE Android memset(c, 0, sizeof(mls_semantic_cat_t)); 712255e72915d4cbddceb435e13d81601755714e9fSE Android} 713255e72915d4cbddceb435e13d81601755714e9fSE Android 714255e72915d4cbddceb435e13d81601755714e9fSE Androidvoid mls_semantic_cat_destroy(mls_semantic_cat_t * c __attribute__ ((unused))) 715255e72915d4cbddceb435e13d81601755714e9fSE Android{ 716255e72915d4cbddceb435e13d81601755714e9fSE Android /* it's currently a simple struct - really nothing to destroy */ 717255e72915d4cbddceb435e13d81601755714e9fSE Android return; 718255e72915d4cbddceb435e13d81601755714e9fSE Android} 719255e72915d4cbddceb435e13d81601755714e9fSE Android 720255e72915d4cbddceb435e13d81601755714e9fSE Androidvoid mls_semantic_level_init(mls_semantic_level_t * l) 721255e72915d4cbddceb435e13d81601755714e9fSE Android{ 722255e72915d4cbddceb435e13d81601755714e9fSE Android memset(l, 0, sizeof(mls_semantic_level_t)); 723255e72915d4cbddceb435e13d81601755714e9fSE Android} 724255e72915d4cbddceb435e13d81601755714e9fSE Android 725255e72915d4cbddceb435e13d81601755714e9fSE Androidvoid mls_semantic_level_destroy(mls_semantic_level_t * l) 726255e72915d4cbddceb435e13d81601755714e9fSE Android{ 727255e72915d4cbddceb435e13d81601755714e9fSE Android mls_semantic_cat_t *cur, *next; 728255e72915d4cbddceb435e13d81601755714e9fSE Android 729255e72915d4cbddceb435e13d81601755714e9fSE Android if (l == NULL) 730255e72915d4cbddceb435e13d81601755714e9fSE Android return; 731255e72915d4cbddceb435e13d81601755714e9fSE Android 732255e72915d4cbddceb435e13d81601755714e9fSE Android next = l->cat; 733255e72915d4cbddceb435e13d81601755714e9fSE Android while (next) { 734255e72915d4cbddceb435e13d81601755714e9fSE Android cur = next; 735255e72915d4cbddceb435e13d81601755714e9fSE Android next = cur->next; 736255e72915d4cbddceb435e13d81601755714e9fSE Android mls_semantic_cat_destroy(cur); 737255e72915d4cbddceb435e13d81601755714e9fSE Android free(cur); 738255e72915d4cbddceb435e13d81601755714e9fSE Android } 739255e72915d4cbddceb435e13d81601755714e9fSE Android} 740255e72915d4cbddceb435e13d81601755714e9fSE Android 741255e72915d4cbddceb435e13d81601755714e9fSE Androidint mls_semantic_level_cpy(mls_semantic_level_t * dst, 742255e72915d4cbddceb435e13d81601755714e9fSE Android mls_semantic_level_t * src) 743255e72915d4cbddceb435e13d81601755714e9fSE Android{ 744255e72915d4cbddceb435e13d81601755714e9fSE Android mls_semantic_cat_t *cat, *newcat, *lnewcat = NULL; 745255e72915d4cbddceb435e13d81601755714e9fSE Android 746255e72915d4cbddceb435e13d81601755714e9fSE Android mls_semantic_level_init(dst); 747255e72915d4cbddceb435e13d81601755714e9fSE Android dst->sens = src->sens; 748255e72915d4cbddceb435e13d81601755714e9fSE Android cat = src->cat; 749255e72915d4cbddceb435e13d81601755714e9fSE Android while (cat) { 750255e72915d4cbddceb435e13d81601755714e9fSE Android newcat = 751255e72915d4cbddceb435e13d81601755714e9fSE Android (mls_semantic_cat_t *) malloc(sizeof(mls_semantic_cat_t)); 752255e72915d4cbddceb435e13d81601755714e9fSE Android if (!newcat) 753255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 754255e72915d4cbddceb435e13d81601755714e9fSE Android 755255e72915d4cbddceb435e13d81601755714e9fSE Android mls_semantic_cat_init(newcat); 756255e72915d4cbddceb435e13d81601755714e9fSE Android if (lnewcat) 757255e72915d4cbddceb435e13d81601755714e9fSE Android lnewcat->next = newcat; 758255e72915d4cbddceb435e13d81601755714e9fSE Android else 759255e72915d4cbddceb435e13d81601755714e9fSE Android dst->cat = newcat; 760255e72915d4cbddceb435e13d81601755714e9fSE Android 761255e72915d4cbddceb435e13d81601755714e9fSE Android newcat->low = cat->low; 762255e72915d4cbddceb435e13d81601755714e9fSE Android newcat->high = cat->high; 763255e72915d4cbddceb435e13d81601755714e9fSE Android 764255e72915d4cbddceb435e13d81601755714e9fSE Android lnewcat = newcat; 765255e72915d4cbddceb435e13d81601755714e9fSE Android cat = cat->next; 766255e72915d4cbddceb435e13d81601755714e9fSE Android } 767255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 768255e72915d4cbddceb435e13d81601755714e9fSE Android 769255e72915d4cbddceb435e13d81601755714e9fSE Android err: 770255e72915d4cbddceb435e13d81601755714e9fSE Android mls_semantic_level_destroy(dst); 771255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 772255e72915d4cbddceb435e13d81601755714e9fSE Android} 773255e72915d4cbddceb435e13d81601755714e9fSE Android 774255e72915d4cbddceb435e13d81601755714e9fSE Androidvoid mls_semantic_range_init(mls_semantic_range_t * r) 775255e72915d4cbddceb435e13d81601755714e9fSE Android{ 776255e72915d4cbddceb435e13d81601755714e9fSE Android mls_semantic_level_init(&r->level[0]); 777255e72915d4cbddceb435e13d81601755714e9fSE Android mls_semantic_level_init(&r->level[1]); 778255e72915d4cbddceb435e13d81601755714e9fSE Android} 779255e72915d4cbddceb435e13d81601755714e9fSE Android 780255e72915d4cbddceb435e13d81601755714e9fSE Androidvoid mls_semantic_range_destroy(mls_semantic_range_t * r) 781255e72915d4cbddceb435e13d81601755714e9fSE Android{ 782255e72915d4cbddceb435e13d81601755714e9fSE Android mls_semantic_level_destroy(&r->level[0]); 783255e72915d4cbddceb435e13d81601755714e9fSE Android mls_semantic_level_destroy(&r->level[1]); 784255e72915d4cbddceb435e13d81601755714e9fSE Android} 785255e72915d4cbddceb435e13d81601755714e9fSE Android 786255e72915d4cbddceb435e13d81601755714e9fSE Androidint mls_semantic_range_cpy(mls_semantic_range_t * dst, 787255e72915d4cbddceb435e13d81601755714e9fSE Android mls_semantic_range_t * src) 788255e72915d4cbddceb435e13d81601755714e9fSE Android{ 789255e72915d4cbddceb435e13d81601755714e9fSE Android if (mls_semantic_level_cpy(&dst->level[0], &src->level[0]) < 0) 790255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 791255e72915d4cbddceb435e13d81601755714e9fSE Android 792255e72915d4cbddceb435e13d81601755714e9fSE Android if (mls_semantic_level_cpy(&dst->level[1], &src->level[1]) < 0) { 793255e72915d4cbddceb435e13d81601755714e9fSE Android mls_semantic_level_destroy(&dst->level[0]); 794255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 795255e72915d4cbddceb435e13d81601755714e9fSE Android } 796255e72915d4cbddceb435e13d81601755714e9fSE Android 797255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 798255e72915d4cbddceb435e13d81601755714e9fSE Android} 799