1255e72915d4cbddceb435e13d81601755714e9fSE Android 2255e72915d4cbddceb435e13d81601755714e9fSE Android/* 3255e72915d4cbddceb435e13d81601755714e9fSE Android * Author : Stephen Smalley, <sds@epoch.ncsc.mil> 4255e72915d4cbddceb435e13d81601755714e9fSE Android */ 5255e72915d4cbddceb435e13d81601755714e9fSE Android/* 6255e72915d4cbddceb435e13d81601755714e9fSE Android * Updated: Trusted Computer Solutions, Inc. <dgoeddel@trustedcs.com> 7255e72915d4cbddceb435e13d81601755714e9fSE Android * 8255e72915d4cbddceb435e13d81601755714e9fSE Android * Support for enhanced MLS infrastructure. 9255e72915d4cbddceb435e13d81601755714e9fSE Android * 10255e72915d4cbddceb435e13d81601755714e9fSE Android * Updated: Frank Mayer <mayerf@tresys.com> 11255e72915d4cbddceb435e13d81601755714e9fSE Android * and Karl MacMillan <kmacmillan@tresys.com> 12255e72915d4cbddceb435e13d81601755714e9fSE Android * 13255e72915d4cbddceb435e13d81601755714e9fSE Android * Added conditional policy language extensions 14255e72915d4cbddceb435e13d81601755714e9fSE Android * 15255e72915d4cbddceb435e13d81601755714e9fSE Android * Updated: Red Hat, Inc. James Morris <jmorris@redhat.com> 16255e72915d4cbddceb435e13d81601755714e9fSE Android * 17255e72915d4cbddceb435e13d81601755714e9fSE Android * Fine-grained netlink support 18255e72915d4cbddceb435e13d81601755714e9fSE Android * IPv6 support 19255e72915d4cbddceb435e13d81601755714e9fSE Android * Code cleanup 20255e72915d4cbddceb435e13d81601755714e9fSE Android * 21255e72915d4cbddceb435e13d81601755714e9fSE Android * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. 22255e72915d4cbddceb435e13d81601755714e9fSE Android * Copyright (C) 2003 - 2004 Tresys Technology, LLC 23255e72915d4cbddceb435e13d81601755714e9fSE Android * Copyright (C) 2003 - 2004 Red Hat, Inc. 24255e72915d4cbddceb435e13d81601755714e9fSE Android * 25255e72915d4cbddceb435e13d81601755714e9fSE Android * This library is free software; you can redistribute it and/or 26255e72915d4cbddceb435e13d81601755714e9fSE Android * modify it under the terms of the GNU Lesser General Public 27255e72915d4cbddceb435e13d81601755714e9fSE Android * License as published by the Free Software Foundation; either 28255e72915d4cbddceb435e13d81601755714e9fSE Android * version 2.1 of the License, or (at your option) any later version. 29255e72915d4cbddceb435e13d81601755714e9fSE Android * 30255e72915d4cbddceb435e13d81601755714e9fSE Android * This library is distributed in the hope that it will be useful, 31255e72915d4cbddceb435e13d81601755714e9fSE Android * but WITHOUT ANY WARRANTY; without even the implied warranty of 32255e72915d4cbddceb435e13d81601755714e9fSE Android * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 33255e72915d4cbddceb435e13d81601755714e9fSE Android * Lesser General Public License for more details. 34255e72915d4cbddceb435e13d81601755714e9fSE Android * 35255e72915d4cbddceb435e13d81601755714e9fSE Android * You should have received a copy of the GNU Lesser General Public 36255e72915d4cbddceb435e13d81601755714e9fSE Android * License along with this library; if not, write to the Free Software 37255e72915d4cbddceb435e13d81601755714e9fSE Android * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 38255e72915d4cbddceb435e13d81601755714e9fSE Android */ 39255e72915d4cbddceb435e13d81601755714e9fSE Android 40255e72915d4cbddceb435e13d81601755714e9fSE Android/* FLASK */ 41255e72915d4cbddceb435e13d81601755714e9fSE Android 42255e72915d4cbddceb435e13d81601755714e9fSE Android/* 43255e72915d4cbddceb435e13d81601755714e9fSE Android * Implementation of the security services. 44255e72915d4cbddceb435e13d81601755714e9fSE Android */ 45255e72915d4cbddceb435e13d81601755714e9fSE Android 46dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley/* Initial sizes malloc'd for sepol_compute_av_reason_buffer() support */ 47dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley#define REASON_BUF_SIZE 2048 48dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley#define EXPR_BUF_SIZE 1024 49dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley#define STACK_LEN 32 50dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 51255e72915d4cbddceb435e13d81601755714e9fSE Android#include <stdlib.h> 52255e72915d4cbddceb435e13d81601755714e9fSE Android#include <sys/types.h> 53255e72915d4cbddceb435e13d81601755714e9fSE Android#include <sys/socket.h> 54255e72915d4cbddceb435e13d81601755714e9fSE Android#include <netinet/in.h> 55255e72915d4cbddceb435e13d81601755714e9fSE Android#include <arpa/inet.h> 56255e72915d4cbddceb435e13d81601755714e9fSE Android 57255e72915d4cbddceb435e13d81601755714e9fSE Android#include <sepol/policydb/policydb.h> 58255e72915d4cbddceb435e13d81601755714e9fSE Android#include <sepol/policydb/sidtab.h> 59255e72915d4cbddceb435e13d81601755714e9fSE Android#include <sepol/policydb/services.h> 60255e72915d4cbddceb435e13d81601755714e9fSE Android#include <sepol/policydb/conditional.h> 61255e72915d4cbddceb435e13d81601755714e9fSE Android#include <sepol/policydb/flask.h> 62dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley#include <sepol/policydb/util.h> 63255e72915d4cbddceb435e13d81601755714e9fSE Android 64255e72915d4cbddceb435e13d81601755714e9fSE Android#include "debug.h" 65255e72915d4cbddceb435e13d81601755714e9fSE Android#include "private.h" 66255e72915d4cbddceb435e13d81601755714e9fSE Android#include "context.h" 67255e72915d4cbddceb435e13d81601755714e9fSE Android#include "av_permissions.h" 68255e72915d4cbddceb435e13d81601755714e9fSE Android#include "dso.h" 69255e72915d4cbddceb435e13d81601755714e9fSE Android#include "mls.h" 70255e72915d4cbddceb435e13d81601755714e9fSE Android 71255e72915d4cbddceb435e13d81601755714e9fSE Android#define BUG() do { ERR(NULL, "Badness at %s:%d", __FILE__, __LINE__); } while (0) 72255e72915d4cbddceb435e13d81601755714e9fSE Android#define BUG_ON(x) do { if (x) ERR(NULL, "Badness at %s:%d", __FILE__, __LINE__); } while (0) 73255e72915d4cbddceb435e13d81601755714e9fSE Android 74255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int selinux_enforcing = 1; 75255e72915d4cbddceb435e13d81601755714e9fSE Android 76255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic sidtab_t mysidtab, *sidtab = &mysidtab; 77255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic policydb_t mypolicydb, *policydb = &mypolicydb; 78255e72915d4cbddceb435e13d81601755714e9fSE Android 79dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley/* Used by sepol_compute_av_reason_buffer() to keep track of entries */ 80dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalleystatic int reason_buf_used; 81dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalleystatic int reason_buf_len; 82dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 83dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley/* Stack services for RPN to infix conversion. */ 84dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalleystatic char **stack; 85dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalleystatic int stack_len; 86dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalleystatic int next_stack_entry; 87dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 88dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalleystatic void push(char *expr_ptr) 89dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley{ 90dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley if (next_stack_entry >= stack_len) { 91dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley char **new_stack = stack; 92dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley int new_stack_len; 93dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 94dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley if (stack_len == 0) 95dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley new_stack_len = STACK_LEN; 96dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley else 97dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley new_stack_len = stack_len * 2; 98dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 99dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley new_stack = realloc(stack, new_stack_len * sizeof(*stack)); 100dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley if (!new_stack) { 101dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley ERR(NULL, "unable to allocate stack space"); 102dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley return; 103dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley } 104dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley stack_len = new_stack_len; 105dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley stack = new_stack; 106dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley } 107dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley stack[next_stack_entry] = expr_ptr; 108dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley next_stack_entry++; 109dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley} 110dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 111dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalleystatic char *pop(void) 112dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley{ 113dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley next_stack_entry--; 114dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley if (next_stack_entry < 0) { 115dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley next_stack_entry = 0; 116dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley ERR(NULL, "pop called with no stack entries"); 117dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley return NULL; 118dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley } 119dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley return stack[next_stack_entry]; 120dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley} 121dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley/* End Stack services */ 122dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 123255e72915d4cbddceb435e13d81601755714e9fSE Androidint hidden sepol_set_sidtab(sidtab_t * s) 124255e72915d4cbddceb435e13d81601755714e9fSE Android{ 125255e72915d4cbddceb435e13d81601755714e9fSE Android sidtab = s; 126255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 127255e72915d4cbddceb435e13d81601755714e9fSE Android} 128255e72915d4cbddceb435e13d81601755714e9fSE Android 129255e72915d4cbddceb435e13d81601755714e9fSE Androidint hidden sepol_set_policydb(policydb_t * p) 130255e72915d4cbddceb435e13d81601755714e9fSE Android{ 131255e72915d4cbddceb435e13d81601755714e9fSE Android policydb = p; 132255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 133255e72915d4cbddceb435e13d81601755714e9fSE Android} 134255e72915d4cbddceb435e13d81601755714e9fSE Android 135255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_set_policydb_from_file(FILE * fp) 136255e72915d4cbddceb435e13d81601755714e9fSE Android{ 137255e72915d4cbddceb435e13d81601755714e9fSE Android struct policy_file pf; 138255e72915d4cbddceb435e13d81601755714e9fSE Android 139255e72915d4cbddceb435e13d81601755714e9fSE Android policy_file_init(&pf); 140255e72915d4cbddceb435e13d81601755714e9fSE Android pf.fp = fp; 141255e72915d4cbddceb435e13d81601755714e9fSE Android pf.type = PF_USE_STDIO; 142255e72915d4cbddceb435e13d81601755714e9fSE Android if (mypolicydb.policy_type) 143255e72915d4cbddceb435e13d81601755714e9fSE Android policydb_destroy(&mypolicydb); 144255e72915d4cbddceb435e13d81601755714e9fSE Android if (policydb_init(&mypolicydb)) { 145255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(NULL, "Out of memory!"); 146255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 147255e72915d4cbddceb435e13d81601755714e9fSE Android } 148255e72915d4cbddceb435e13d81601755714e9fSE Android if (policydb_read(&mypolicydb, &pf, 0)) { 149b0e0162a246f2c051427154909c0ecd694cc4805Alice Chu policydb_destroy(&mypolicydb); 150255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(NULL, "can't read binary policy: %s", strerror(errno)); 151255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 152255e72915d4cbddceb435e13d81601755714e9fSE Android } 153255e72915d4cbddceb435e13d81601755714e9fSE Android policydb = &mypolicydb; 154255e72915d4cbddceb435e13d81601755714e9fSE Android return sepol_sidtab_init(sidtab); 155255e72915d4cbddceb435e13d81601755714e9fSE Android} 156255e72915d4cbddceb435e13d81601755714e9fSE Android 157255e72915d4cbddceb435e13d81601755714e9fSE Android/* 158255e72915d4cbddceb435e13d81601755714e9fSE Android * The largest sequence number that has been used when 159255e72915d4cbddceb435e13d81601755714e9fSE Android * providing an access decision to the access vector cache. 160255e72915d4cbddceb435e13d81601755714e9fSE Android * The sequence number only changes when a policy change 161255e72915d4cbddceb435e13d81601755714e9fSE Android * occurs. 162255e72915d4cbddceb435e13d81601755714e9fSE Android */ 163255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic uint32_t latest_granting = 0; 164255e72915d4cbddceb435e13d81601755714e9fSE Android 165255e72915d4cbddceb435e13d81601755714e9fSE Android/* 166dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley * cat_expr_buf adds a string to an expression buffer and handles 167dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley * realloc's if buffer is too small. The array of expression text 168dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley * buffer pointers and its counter are globally defined here as 169dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley * constraint_expr_eval_reason() sets them up and cat_expr_buf 170dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley * updates the e_buf pointer. 171dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley */ 172dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalleystatic int expr_counter; 173dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalleystatic char **expr_list; 174dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalleystatic int expr_buf_used; 175dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalleystatic int expr_buf_len; 176dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 177dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalleystatic void cat_expr_buf(char *e_buf, char *string) 178dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley{ 179dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley int len, new_buf_len; 180dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley char *p, *new_buf = e_buf; 181dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 182dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley while (1) { 183dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley p = e_buf + expr_buf_used; 184dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley len = snprintf(p, expr_buf_len - expr_buf_used, "%s", string); 185dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley if (len < 0 || len >= expr_buf_len - expr_buf_used) { 186dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley new_buf_len = expr_buf_len + EXPR_BUF_SIZE; 187dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley new_buf = realloc(e_buf, new_buf_len); 188dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley if (!new_buf) { 189dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley ERR(NULL, "failed to realloc expr buffer"); 190dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley return; 191dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley } 192dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley /* Update new ptr in expr list and locally + new len */ 193dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley expr_list[expr_counter] = new_buf; 194dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley e_buf = new_buf; 195dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley expr_buf_len = new_buf_len; 196dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley } else { 197dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley expr_buf_used += len; 198dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley return; 199dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley } 200dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley } 201dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley} 202dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 203dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley/* 204dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley * If the POLICY_KERN version is >= POLICYDB_VERSION_CONSTRAINT_NAMES, 205dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley * then for 'types' only, read the types_names->types list as it will 206dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley * contain a list of types and attributes that were defined in the 207dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley * policy source. 208dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley * For user and role plus types (for policy vers < 209dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley * POLICYDB_VERSION_CONSTRAINT_NAMES) just read the e->names list. 210dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley */ 211dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalleystatic void get_name_list(constraint_expr_t *e, int type, 212dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley char *src, char *op, int failed) 213dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley{ 214dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley ebitmap_t *types; 215dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley int rc = 0; 216dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley unsigned int i; 217dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley char tmp_buf[128]; 218dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley int counter = 0; 219dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 220dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley if (policydb->policy_type == POLICY_KERN && 221dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley policydb->policyvers >= POLICYDB_VERSION_CONSTRAINT_NAMES && 222dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley type == CEXPR_TYPE) 223dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley types = &e->type_names->types; 224dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley else 225dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley types = &e->names; 226dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 227dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley /* Find out how many entries */ 228dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley for (i = ebitmap_startbit(types); i < ebitmap_length(types); i++) { 229dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley rc = ebitmap_get_bit(types, i); 230dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley if (rc == 0) 231dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley continue; 232dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley else 233dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley counter++; 234dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley } 235dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley snprintf(tmp_buf, sizeof(tmp_buf), "(%s%s", src, op); 236dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley cat_expr_buf(expr_list[expr_counter], tmp_buf); 237dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 238dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley if (counter == 0) 239dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley cat_expr_buf(expr_list[expr_counter], "<empty_set> "); 240dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley if (counter > 1) 241dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley cat_expr_buf(expr_list[expr_counter], " {"); 242dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley if (counter >= 1) { 243dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley for (i = ebitmap_startbit(types); i < ebitmap_length(types); i++) { 244dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley rc = ebitmap_get_bit(types, i); 245dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley if (rc == 0) 246dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley continue; 247dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 248dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley /* Collect entries */ 249dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley switch (type) { 250dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley case CEXPR_USER: 251dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley snprintf(tmp_buf, sizeof(tmp_buf), " %s", 252dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley policydb->p_user_val_to_name[i]); 253dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley break; 254dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley case CEXPR_ROLE: 255dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley snprintf(tmp_buf, sizeof(tmp_buf), " %s", 256dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley policydb->p_role_val_to_name[i]); 257dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley break; 258dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley case CEXPR_TYPE: 259dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley snprintf(tmp_buf, sizeof(tmp_buf), " %s", 260dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley policydb->p_type_val_to_name[i]); 261dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley break; 262dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley } 263dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley cat_expr_buf(expr_list[expr_counter], tmp_buf); 264dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley } 265dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley } 266dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley if (counter > 1) 267dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley cat_expr_buf(expr_list[expr_counter], " }"); 268dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley if (failed) 269dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley cat_expr_buf(expr_list[expr_counter], " -Fail-) "); 270dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley else 271dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley cat_expr_buf(expr_list[expr_counter], ") "); 272dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 273dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley return; 274dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley} 275dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 276dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalleystatic void msgcat(char *src, char *tgt, char *op, int failed) 277dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley{ 278dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley char tmp_buf[128]; 279dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley if (failed) 280dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley snprintf(tmp_buf, sizeof(tmp_buf), "(%s %s %s -Fail-) ", 281dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley src, op, tgt); 282dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley else 283dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley snprintf(tmp_buf, sizeof(tmp_buf), "(%s %s %s) ", 284dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley src, op, tgt); 285dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley cat_expr_buf(expr_list[expr_counter], tmp_buf); 286dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley} 287dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 288dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley/* Returns a buffer with class, statement type and permissions */ 289dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalleystatic char *get_class_info(sepol_security_class_t tclass, 290dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley constraint_node_t *constraint, 291dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley context_struct_t *xcontext) 292dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley{ 293dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley constraint_expr_t *e; 294dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley int mls, state_num; 295dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 296dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley /* Find if MLS statement or not */ 297dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley mls = 0; 298dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley for (e = constraint->expr; e; e = e->next) { 299dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley if (e->attr >= CEXPR_L1L2) { 300dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley mls = 1; 301dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley break; 302dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley } 303dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley } 304dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 305dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley /* Determine statement type */ 306dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley char *statements[] = { 307dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley "constrain ", /* 0 */ 308dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley "mlsconstrain ", /* 1 */ 309dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley "validatetrans ", /* 2 */ 310dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley "mlsvalidatetrans ", /* 3 */ 311dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 0 }; 312dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 313dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley if (xcontext == NULL) 314dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley state_num = mls + 0; 315dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley else 316dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley state_num = mls + 2; 317dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 318dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley int class_buf_len = 0; 319dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley int new_class_buf_len; 320dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley int len, buf_used; 321dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley char *class_buf = NULL, *p; 322dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley char *new_class_buf = NULL; 323dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 324dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley while (1) { 325dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley new_class_buf_len = class_buf_len + EXPR_BUF_SIZE; 326dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley new_class_buf = realloc(class_buf, new_class_buf_len); 327dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley if (!new_class_buf) 328dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley return NULL; 329dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley class_buf_len = new_class_buf_len; 330dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley class_buf = new_class_buf; 331dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley buf_used = 0; 332dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley p = class_buf; 333dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 334dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley /* Add statement type */ 335dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley len = snprintf(p, class_buf_len - buf_used, "%s", statements[state_num]); 336dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley if (len < 0 || len >= class_buf_len - buf_used) 337dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley continue; 338dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 339dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley /* Add class entry */ 340dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley p += len; 341dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley buf_used += len; 342dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley len = snprintf(p, class_buf_len - buf_used, "%s ", 343dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley policydb->p_class_val_to_name[tclass - 1]); 344dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley if (len < 0 || len >= class_buf_len - buf_used) 345dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley continue; 346dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 347dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley /* Add permission entries */ 348dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley p += len; 349dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley buf_used += len; 350dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley len = snprintf(p, class_buf_len - buf_used, "{%s } (", 351dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley sepol_av_to_string(policydb, tclass, constraint->permissions)); 352dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley if (len < 0 || len >= class_buf_len - buf_used) 353dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley continue; 354dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley break; 355dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley } 356dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley return class_buf; 357dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley} 358dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 359dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley/* 360dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley * Modified version of constraint_expr_eval that will process each 361dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley * constraint as before but adds the information to text buffers that 362dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley * will hold various components. The expression will be in RPN format, 363dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley * therefore there is a stack based RPN to infix converter to produce 364dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley * the final readable constraint. 365dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley * 366dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley * Return the boolean value of a constraint expression 367dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley * when it is applied to the specified source and target 368255e72915d4cbddceb435e13d81601755714e9fSE Android * security contexts. 369255e72915d4cbddceb435e13d81601755714e9fSE Android * 370255e72915d4cbddceb435e13d81601755714e9fSE Android * xcontext is a special beast... It is used by the validatetrans rules 371255e72915d4cbddceb435e13d81601755714e9fSE Android * only. For these rules, scontext is the context before the transition, 372dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley * tcontext is the context after the transition, and xcontext is the 373dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley * context of the process performing the transition. All other callers 374dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley * of constraint_expr_eval_reason should pass in NULL for xcontext. 375dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley * 376dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley * This function will also build a buffer as the constraint is processed 377dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley * for analysis. If this option is not required, then: 378dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley * 'tclass' should be '0' and r_buf MUST be NULL. 379255e72915d4cbddceb435e13d81601755714e9fSE Android */ 380dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalleystatic int constraint_expr_eval_reason(context_struct_t *scontext, 381dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley context_struct_t *tcontext, 382dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley context_struct_t *xcontext, 383dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley sepol_security_class_t tclass, 384dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley constraint_node_t *constraint, 385dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley char **r_buf, 386dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley unsigned int flags) 387255e72915d4cbddceb435e13d81601755714e9fSE Android{ 388255e72915d4cbddceb435e13d81601755714e9fSE Android uint32_t val1, val2; 389255e72915d4cbddceb435e13d81601755714e9fSE Android context_struct_t *c; 390255e72915d4cbddceb435e13d81601755714e9fSE Android role_datum_t *r1, *r2; 391255e72915d4cbddceb435e13d81601755714e9fSE Android mls_level_t *l1, *l2; 392255e72915d4cbddceb435e13d81601755714e9fSE Android constraint_expr_t *e; 393255e72915d4cbddceb435e13d81601755714e9fSE Android int s[CEXPR_MAXDEPTH]; 394255e72915d4cbddceb435e13d81601755714e9fSE Android int sp = -1; 395dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley char tmp_buf[128]; 396dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 397dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley/* 398dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley * Define the s_t_x_num values that make up r1, t2 etc. in text strings 399dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley * Set 1 = source, 2 = target, 3 = xcontext for validatetrans 400dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley */ 401dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley#define SOURCE 1 402dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley#define TARGET 2 403dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley#define XTARGET 3 404dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 405dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley int s_t_x_num = SOURCE; 406dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 407dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley /* Set 0 = fail, u = CEXPR_USER, r = CEXPR_ROLE, t = CEXPR_TYPE */ 408dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley int u_r_t = 0; 409dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 410dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley char *src = NULL; 411dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley char *tgt = NULL; 412dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley int rc = 0, x; 413dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley char *class_buf = NULL; 414dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 415dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley class_buf = get_class_info(tclass, constraint, xcontext); 416dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley if (!class_buf) { 417dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley ERR(NULL, "failed to allocate class buffer"); 418dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley return -ENOMEM; 419dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley } 420dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 421dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley /* Original function but with buffer support */ 422dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley int expr_list_len = 0; 423dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley expr_counter = 0; 424dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley expr_list = NULL; 425dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley for (e = constraint->expr; e; e = e->next) { 426dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley /* Allocate a stack to hold expression buffer entries */ 427dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley if (expr_counter >= expr_list_len) { 428dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley char **new_expr_list = expr_list; 429dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley int new_expr_list_len; 430dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 431dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley if (expr_list_len == 0) 432dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley new_expr_list_len = STACK_LEN; 433dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley else 434dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley new_expr_list_len = expr_list_len * 2; 435dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 436dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley new_expr_list = realloc(expr_list, 437dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley new_expr_list_len * sizeof(*expr_list)); 438dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley if (!new_expr_list) { 439dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley ERR(NULL, "failed to allocate expr buffer stack"); 440dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley rc = -ENOMEM; 441dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley goto out; 442dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley } 443dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley expr_list_len = new_expr_list_len; 444dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley expr_list = new_expr_list; 445dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley } 446dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 447dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley /* 448dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley * malloc a buffer to store each expression text component. If 449dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley * buffer is too small cat_expr_buf() will realloc extra space. 450dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley */ 451dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley expr_buf_len = EXPR_BUF_SIZE; 452dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley expr_list[expr_counter] = malloc(expr_buf_len); 453dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley if (!expr_list[expr_counter]) { 454dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley ERR(NULL, "failed to allocate expr buffer"); 455dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley rc = -ENOMEM; 456dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley goto out; 457dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley } 458dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley expr_buf_used = 0; 459255e72915d4cbddceb435e13d81601755714e9fSE Android 460dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley /* Now process each expression of the constraint */ 461255e72915d4cbddceb435e13d81601755714e9fSE Android switch (e->expr_type) { 462255e72915d4cbddceb435e13d81601755714e9fSE Android case CEXPR_NOT: 463255e72915d4cbddceb435e13d81601755714e9fSE Android BUG_ON(sp < 0); 464255e72915d4cbddceb435e13d81601755714e9fSE Android s[sp] = !s[sp]; 465dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley cat_expr_buf(expr_list[expr_counter], "not"); 466255e72915d4cbddceb435e13d81601755714e9fSE Android break; 467255e72915d4cbddceb435e13d81601755714e9fSE Android case CEXPR_AND: 468255e72915d4cbddceb435e13d81601755714e9fSE Android BUG_ON(sp < 1); 469255e72915d4cbddceb435e13d81601755714e9fSE Android sp--; 470255e72915d4cbddceb435e13d81601755714e9fSE Android s[sp] &= s[sp + 1]; 471dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley cat_expr_buf(expr_list[expr_counter], "and"); 472255e72915d4cbddceb435e13d81601755714e9fSE Android break; 473255e72915d4cbddceb435e13d81601755714e9fSE Android case CEXPR_OR: 474255e72915d4cbddceb435e13d81601755714e9fSE Android BUG_ON(sp < 1); 475255e72915d4cbddceb435e13d81601755714e9fSE Android sp--; 476255e72915d4cbddceb435e13d81601755714e9fSE Android s[sp] |= s[sp + 1]; 477dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley cat_expr_buf(expr_list[expr_counter], "or"); 478255e72915d4cbddceb435e13d81601755714e9fSE Android break; 479255e72915d4cbddceb435e13d81601755714e9fSE Android case CEXPR_ATTR: 480255e72915d4cbddceb435e13d81601755714e9fSE Android if (sp == (CEXPR_MAXDEPTH - 1)) 481dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley goto out; 482dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 483255e72915d4cbddceb435e13d81601755714e9fSE Android switch (e->attr) { 484255e72915d4cbddceb435e13d81601755714e9fSE Android case CEXPR_USER: 485255e72915d4cbddceb435e13d81601755714e9fSE Android val1 = scontext->user; 486255e72915d4cbddceb435e13d81601755714e9fSE Android val2 = tcontext->user; 487dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley free(src); src = strdup("u1"); 488dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley free(tgt); tgt = strdup("u2"); 489255e72915d4cbddceb435e13d81601755714e9fSE Android break; 490255e72915d4cbddceb435e13d81601755714e9fSE Android case CEXPR_TYPE: 491255e72915d4cbddceb435e13d81601755714e9fSE Android val1 = scontext->type; 492255e72915d4cbddceb435e13d81601755714e9fSE Android val2 = tcontext->type; 493dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley free(src); src = strdup("t1"); 494dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley free(tgt); tgt = strdup("t2"); 495255e72915d4cbddceb435e13d81601755714e9fSE Android break; 496255e72915d4cbddceb435e13d81601755714e9fSE Android case CEXPR_ROLE: 497255e72915d4cbddceb435e13d81601755714e9fSE Android val1 = scontext->role; 498255e72915d4cbddceb435e13d81601755714e9fSE Android val2 = tcontext->role; 499255e72915d4cbddceb435e13d81601755714e9fSE Android r1 = policydb->role_val_to_struct[val1 - 1]; 500255e72915d4cbddceb435e13d81601755714e9fSE Android r2 = policydb->role_val_to_struct[val2 - 1]; 501dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley free(src); src = strdup("r1"); 502dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley free(tgt); tgt = strdup("r2"); 503dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 504255e72915d4cbddceb435e13d81601755714e9fSE Android switch (e->op) { 505255e72915d4cbddceb435e13d81601755714e9fSE Android case CEXPR_DOM: 506dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley s[++sp] = ebitmap_get_bit(&r1->dominates, val2 - 1); 507dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley msgcat(src, tgt, "dom", s[sp] == 0); 508dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley expr_counter++; 509255e72915d4cbddceb435e13d81601755714e9fSE Android continue; 510255e72915d4cbddceb435e13d81601755714e9fSE Android case CEXPR_DOMBY: 511dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley s[++sp] = ebitmap_get_bit(&r2->dominates, val1 - 1); 512dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley msgcat(src, tgt, "domby", s[sp] == 0); 513dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley expr_counter++; 514255e72915d4cbddceb435e13d81601755714e9fSE Android continue; 515255e72915d4cbddceb435e13d81601755714e9fSE Android case CEXPR_INCOMP: 516dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley s[++sp] = (!ebitmap_get_bit(&r1->dominates, val2 - 1) 517dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley && !ebitmap_get_bit(&r2->dominates, val1 - 1)); 518dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley msgcat(src, tgt, "incomp", s[sp] == 0); 519dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley expr_counter++; 520255e72915d4cbddceb435e13d81601755714e9fSE Android continue; 521255e72915d4cbddceb435e13d81601755714e9fSE Android default: 522255e72915d4cbddceb435e13d81601755714e9fSE Android break; 523255e72915d4cbddceb435e13d81601755714e9fSE Android } 524255e72915d4cbddceb435e13d81601755714e9fSE Android break; 525255e72915d4cbddceb435e13d81601755714e9fSE Android case CEXPR_L1L2: 526255e72915d4cbddceb435e13d81601755714e9fSE Android l1 = &(scontext->range.level[0]); 527255e72915d4cbddceb435e13d81601755714e9fSE Android l2 = &(tcontext->range.level[0]); 528dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley free(src); src = strdup("l1"); 529dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley free(tgt); tgt = strdup("l2"); 530255e72915d4cbddceb435e13d81601755714e9fSE Android goto mls_ops; 531255e72915d4cbddceb435e13d81601755714e9fSE Android case CEXPR_L1H2: 532255e72915d4cbddceb435e13d81601755714e9fSE Android l1 = &(scontext->range.level[0]); 533255e72915d4cbddceb435e13d81601755714e9fSE Android l2 = &(tcontext->range.level[1]); 534dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley free(src); src = strdup("l1"); 535dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley free(tgt); tgt = strdup("h2"); 536255e72915d4cbddceb435e13d81601755714e9fSE Android goto mls_ops; 537255e72915d4cbddceb435e13d81601755714e9fSE Android case CEXPR_H1L2: 538255e72915d4cbddceb435e13d81601755714e9fSE Android l1 = &(scontext->range.level[1]); 539255e72915d4cbddceb435e13d81601755714e9fSE Android l2 = &(tcontext->range.level[0]); 540dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley free(src); src = strdup("h1"); 541dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley free(tgt); tgt = strdup("l2"); 542255e72915d4cbddceb435e13d81601755714e9fSE Android goto mls_ops; 543255e72915d4cbddceb435e13d81601755714e9fSE Android case CEXPR_H1H2: 544255e72915d4cbddceb435e13d81601755714e9fSE Android l1 = &(scontext->range.level[1]); 545255e72915d4cbddceb435e13d81601755714e9fSE Android l2 = &(tcontext->range.level[1]); 546dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley free(src); src = strdup("h1"); 547dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley free(tgt); tgt = strdup("h2"); 548255e72915d4cbddceb435e13d81601755714e9fSE Android goto mls_ops; 549255e72915d4cbddceb435e13d81601755714e9fSE Android case CEXPR_L1H1: 550255e72915d4cbddceb435e13d81601755714e9fSE Android l1 = &(scontext->range.level[0]); 551255e72915d4cbddceb435e13d81601755714e9fSE Android l2 = &(scontext->range.level[1]); 552dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley free(src); src = strdup("l1"); 553dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley free(tgt); tgt = strdup("h1"); 554255e72915d4cbddceb435e13d81601755714e9fSE Android goto mls_ops; 555255e72915d4cbddceb435e13d81601755714e9fSE Android case CEXPR_L2H2: 556255e72915d4cbddceb435e13d81601755714e9fSE Android l1 = &(tcontext->range.level[0]); 557255e72915d4cbddceb435e13d81601755714e9fSE Android l2 = &(tcontext->range.level[1]); 558dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley free(src); src = strdup("l2"); 559dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley free(tgt); tgt = strdup("h2"); 560dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalleymls_ops: 561255e72915d4cbddceb435e13d81601755714e9fSE Android switch (e->op) { 562255e72915d4cbddceb435e13d81601755714e9fSE Android case CEXPR_EQ: 563255e72915d4cbddceb435e13d81601755714e9fSE Android s[++sp] = mls_level_eq(l1, l2); 564dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley msgcat(src, tgt, "eq", s[sp] == 0); 565dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley expr_counter++; 566255e72915d4cbddceb435e13d81601755714e9fSE Android continue; 567255e72915d4cbddceb435e13d81601755714e9fSE Android case CEXPR_NEQ: 568255e72915d4cbddceb435e13d81601755714e9fSE Android s[++sp] = !mls_level_eq(l1, l2); 569dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley msgcat(src, tgt, "!=", s[sp] == 0); 570dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley expr_counter++; 571255e72915d4cbddceb435e13d81601755714e9fSE Android continue; 572255e72915d4cbddceb435e13d81601755714e9fSE Android case CEXPR_DOM: 573255e72915d4cbddceb435e13d81601755714e9fSE Android s[++sp] = mls_level_dom(l1, l2); 574dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley msgcat(src, tgt, "dom", s[sp] == 0); 575dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley expr_counter++; 576255e72915d4cbddceb435e13d81601755714e9fSE Android continue; 577255e72915d4cbddceb435e13d81601755714e9fSE Android case CEXPR_DOMBY: 578255e72915d4cbddceb435e13d81601755714e9fSE Android s[++sp] = mls_level_dom(l2, l1); 579dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley msgcat(src, tgt, "domby", s[sp] == 0); 580dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley expr_counter++; 581255e72915d4cbddceb435e13d81601755714e9fSE Android continue; 582255e72915d4cbddceb435e13d81601755714e9fSE Android case CEXPR_INCOMP: 583255e72915d4cbddceb435e13d81601755714e9fSE Android s[++sp] = mls_level_incomp(l2, l1); 584dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley msgcat(src, tgt, "incomp", s[sp] == 0); 585dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley expr_counter++; 586255e72915d4cbddceb435e13d81601755714e9fSE Android continue; 587255e72915d4cbddceb435e13d81601755714e9fSE Android default: 588255e72915d4cbddceb435e13d81601755714e9fSE Android BUG(); 589dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley goto out; 590255e72915d4cbddceb435e13d81601755714e9fSE Android } 591255e72915d4cbddceb435e13d81601755714e9fSE Android break; 592255e72915d4cbddceb435e13d81601755714e9fSE Android default: 593255e72915d4cbddceb435e13d81601755714e9fSE Android BUG(); 594dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley goto out; 595255e72915d4cbddceb435e13d81601755714e9fSE Android } 596255e72915d4cbddceb435e13d81601755714e9fSE Android 597255e72915d4cbddceb435e13d81601755714e9fSE Android switch (e->op) { 598255e72915d4cbddceb435e13d81601755714e9fSE Android case CEXPR_EQ: 599255e72915d4cbddceb435e13d81601755714e9fSE Android s[++sp] = (val1 == val2); 600dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley msgcat(src, tgt, "==", s[sp] == 0); 601255e72915d4cbddceb435e13d81601755714e9fSE Android break; 602255e72915d4cbddceb435e13d81601755714e9fSE Android case CEXPR_NEQ: 603255e72915d4cbddceb435e13d81601755714e9fSE Android s[++sp] = (val1 != val2); 604dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley msgcat(src, tgt, "!=", s[sp] == 0); 605255e72915d4cbddceb435e13d81601755714e9fSE Android break; 606255e72915d4cbddceb435e13d81601755714e9fSE Android default: 607255e72915d4cbddceb435e13d81601755714e9fSE Android BUG(); 608dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley goto out; 609255e72915d4cbddceb435e13d81601755714e9fSE Android } 610255e72915d4cbddceb435e13d81601755714e9fSE Android break; 611255e72915d4cbddceb435e13d81601755714e9fSE Android case CEXPR_NAMES: 612255e72915d4cbddceb435e13d81601755714e9fSE Android if (sp == (CEXPR_MAXDEPTH - 1)) 613dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley goto out; 614dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley s_t_x_num = SOURCE; 615255e72915d4cbddceb435e13d81601755714e9fSE Android c = scontext; 616dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley if (e->attr & CEXPR_TARGET) { 617dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley s_t_x_num = TARGET; 618255e72915d4cbddceb435e13d81601755714e9fSE Android c = tcontext; 619dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley } else if (e->attr & CEXPR_XTARGET) { 620dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley s_t_x_num = XTARGET; 621255e72915d4cbddceb435e13d81601755714e9fSE Android c = xcontext; 622255e72915d4cbddceb435e13d81601755714e9fSE Android } 623dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley if (!c) { 624dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley BUG(); 625dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley goto out; 626dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley } 627dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley if (e->attr & CEXPR_USER) { 628dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley u_r_t = CEXPR_USER; 629255e72915d4cbddceb435e13d81601755714e9fSE Android val1 = c->user; 630dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley snprintf(tmp_buf, sizeof(tmp_buf), "u%d ", s_t_x_num); 631dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley free(src); src = strdup(tmp_buf); 632dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley } else if (e->attr & CEXPR_ROLE) { 633dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley u_r_t = CEXPR_ROLE; 634255e72915d4cbddceb435e13d81601755714e9fSE Android val1 = c->role; 635dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley snprintf(tmp_buf, sizeof(tmp_buf), "r%d ", s_t_x_num); 636dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley free(src); src = strdup(tmp_buf); 637dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley } else if (e->attr & CEXPR_TYPE) { 638dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley u_r_t = CEXPR_TYPE; 639255e72915d4cbddceb435e13d81601755714e9fSE Android val1 = c->type; 640dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley snprintf(tmp_buf, sizeof(tmp_buf), "t%d ", s_t_x_num); 641dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley free(src); src = strdup(tmp_buf); 642dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley } else { 643255e72915d4cbddceb435e13d81601755714e9fSE Android BUG(); 644dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley goto out; 645255e72915d4cbddceb435e13d81601755714e9fSE Android } 646255e72915d4cbddceb435e13d81601755714e9fSE Android 647255e72915d4cbddceb435e13d81601755714e9fSE Android switch (e->op) { 648255e72915d4cbddceb435e13d81601755714e9fSE Android case CEXPR_EQ: 649255e72915d4cbddceb435e13d81601755714e9fSE Android s[++sp] = ebitmap_get_bit(&e->names, val1 - 1); 650dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley get_name_list(e, u_r_t, src, "==", s[sp] == 0); 651255e72915d4cbddceb435e13d81601755714e9fSE Android break; 652dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 653255e72915d4cbddceb435e13d81601755714e9fSE Android case CEXPR_NEQ: 654255e72915d4cbddceb435e13d81601755714e9fSE Android s[++sp] = !ebitmap_get_bit(&e->names, val1 - 1); 655dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley get_name_list(e, u_r_t, src, "!=", s[sp] == 0); 656255e72915d4cbddceb435e13d81601755714e9fSE Android break; 657255e72915d4cbddceb435e13d81601755714e9fSE Android default: 658255e72915d4cbddceb435e13d81601755714e9fSE Android BUG(); 659dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley goto out; 660255e72915d4cbddceb435e13d81601755714e9fSE Android } 661255e72915d4cbddceb435e13d81601755714e9fSE Android break; 662255e72915d4cbddceb435e13d81601755714e9fSE Android default: 663255e72915d4cbddceb435e13d81601755714e9fSE Android BUG(); 664dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley goto out; 665255e72915d4cbddceb435e13d81601755714e9fSE Android } 666dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley expr_counter++; 667255e72915d4cbddceb435e13d81601755714e9fSE Android } 668255e72915d4cbddceb435e13d81601755714e9fSE Android 669dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley /* 670dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley * At this point each expression of the constraint is in 671dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley * expr_list[n+1] and in RPN format. Now convert to 'infix' 672dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley */ 673dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 674dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley /* 675dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley * Save expr count but zero expr_counter to detect if 676dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley * 'BUG(); goto out;' was called as we need to release any used 677dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley * expr_list malloc's. Normally they are released by the RPN to 678dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley * infix code. 679dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley */ 680dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley int expr_count = expr_counter; 681dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley expr_counter = 0; 682dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 683dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley /* 684dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley * The array of expression answer buffer pointers and counter. 685dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley * Generate the same number of answer buffer entries as expression 686dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley * buffers (as there will never be more). 687dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley */ 688dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley char **answer_list; 689dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley int answer_counter = 0; 690dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 691dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley answer_list = malloc(expr_count * sizeof(*answer_list)); 692dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley if (!answer_list) { 693dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley ERR(NULL, "failed to allocate answer stack"); 694dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley rc = -ENOMEM; 695dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley goto out; 696dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley } 697dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 698dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley /* The pop operands */ 699dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley char *a; 700dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley char *b; 701dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley int a_len, b_len; 702dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 703dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley /* Convert constraint from RPN to infix notation. */ 704dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley for (x = 0; x != expr_count; x++) { 705dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley if (strncmp(expr_list[x], "and", 3) == 0 || strncmp(expr_list[x], 706dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley "or", 2) == 0) { 707dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley b = pop(); 708dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley b_len = strlen(b); 709dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley a = pop(); 710dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley a_len = strlen(a); 711dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 712dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley /* get a buffer to hold the answer */ 713dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley answer_list[answer_counter] = malloc(a_len + b_len + 8); 714dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley if (!answer_list[answer_counter]) { 715dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley ERR(NULL, "failed to allocate answer buffer"); 716dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley rc = -ENOMEM; 717dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley goto out; 718dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley } 719dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley memset(answer_list[answer_counter], '\0', a_len + b_len + 8); 720dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 721dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley sprintf(answer_list[answer_counter], "%s %s %s", a, 722dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley expr_list[x], b); 723dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley push(answer_list[answer_counter++]); 724dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley free(a); 725dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley free(b); 726dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley } else if (strncmp(expr_list[x], "not", 3) == 0) { 727dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley b = pop(); 728dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley b_len = strlen(b); 729dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 730dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley answer_list[answer_counter] = malloc(b_len + 8); 731dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley if (!answer_list[answer_counter]) { 732dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley ERR(NULL, "failed to allocate answer buffer"); 733dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley rc = -ENOMEM; 734dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley goto out; 735dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley } 736dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley memset(answer_list[answer_counter], '\0', b_len + 8); 737dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 738dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley if (strncmp(b, "not", 3) == 0) 739dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley sprintf(answer_list[answer_counter], "%s (%s)", 740dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley expr_list[x], b); 741dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley else 742dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley sprintf(answer_list[answer_counter], "%s%s", 743dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley expr_list[x], b); 744dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley push(answer_list[answer_counter++]); 745dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley free(b); 746dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley } else { 747dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley push(expr_list[x]); 748dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley } 749dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley } 750dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley /* Get the final answer from tos and build constraint text */ 751dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley a = pop(); 752dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 753dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley /* Constraint calculation: rc = 0 is denied, rc = 1 is granted */ 754dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley sprintf(tmp_buf, "Constraint %s\n", s[0] ? "GRANTED" : "DENIED"); 755dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 756dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley int len, new_buf_len; 757dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley char *p, **new_buf = r_buf; 758dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley /* 759dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley * These contain the constraint components that are added to the 760dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley * callers reason buffer. 761dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley */ 762dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley char *buffers[] = { class_buf, a, "); ", tmp_buf, 0 }; 763dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 764dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley /* 765dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley * This will add the constraints to the callers reason buffer (who is 766dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley * responsible for freeing the memory). It will handle any realloc's 767dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley * should the buffer be too short. 768dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley * The reason_buf_used and reason_buf_len counters are defined 769dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley * globally as multiple constraints can be in the buffer. 770dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley */ 771dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 772dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley if (r_buf && ((s[0] == 0) || ((s[0] == 1 && 773dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley (flags & SHOW_GRANTED) == SHOW_GRANTED)))) { 774dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley for (x = 0; buffers[x] != NULL; x++) { 775dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley while (1) { 776dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley p = *r_buf + reason_buf_used; 777dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley len = snprintf(p, reason_buf_len - reason_buf_used, 778dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley "%s", buffers[x]); 779dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley if (len < 0 || len >= reason_buf_len - reason_buf_used) { 780dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley new_buf_len = reason_buf_len + REASON_BUF_SIZE; 781dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley *new_buf = realloc(*r_buf, new_buf_len); 782dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley if (!new_buf) { 783dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley ERR(NULL, "failed to realloc reason buffer"); 784dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley goto out1; 785dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley } 786dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley **r_buf = **new_buf; 787dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley reason_buf_len = new_buf_len; 788dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley continue; 789dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley } else { 790dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley reason_buf_used += len; 791dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley break; 792dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley } 793dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley } 794dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley } 795dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley } 796dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 797dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalleyout1: 798dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley rc = s[0]; 799dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley free(a); 800dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 801dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalleyout: 802dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley free(class_buf); 803dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley free(src); 804dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley free(tgt); 805dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 806dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley if (expr_counter) { 807dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley for (x = 0; expr_list[x] != NULL; x++) 808dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley free(expr_list[x]); 809dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley } 810dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley return rc; 811255e72915d4cbddceb435e13d81601755714e9fSE Android} 812255e72915d4cbddceb435e13d81601755714e9fSE Android 813255e72915d4cbddceb435e13d81601755714e9fSE Android/* 814255e72915d4cbddceb435e13d81601755714e9fSE Android * Compute access vectors based on a context structure pair for 815255e72915d4cbddceb435e13d81601755714e9fSE Android * the permissions in a particular class. 816255e72915d4cbddceb435e13d81601755714e9fSE Android */ 817255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int context_struct_compute_av(context_struct_t * scontext, 818255e72915d4cbddceb435e13d81601755714e9fSE Android context_struct_t * tcontext, 819255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_security_class_t tclass, 820255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_access_vector_t requested, 821255e72915d4cbddceb435e13d81601755714e9fSE Android struct sepol_av_decision *avd, 822dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley unsigned int *reason, 823dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley char **r_buf, 824dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley unsigned int flags) 825255e72915d4cbddceb435e13d81601755714e9fSE Android{ 826255e72915d4cbddceb435e13d81601755714e9fSE Android constraint_node_t *constraint; 827255e72915d4cbddceb435e13d81601755714e9fSE Android struct role_allow *ra; 828255e72915d4cbddceb435e13d81601755714e9fSE Android avtab_key_t avkey; 829255e72915d4cbddceb435e13d81601755714e9fSE Android class_datum_t *tclass_datum; 830255e72915d4cbddceb435e13d81601755714e9fSE Android avtab_ptr_t node; 831255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_t *sattr, *tattr; 832255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_node_t *snode, *tnode; 833255e72915d4cbddceb435e13d81601755714e9fSE Android unsigned int i, j; 834255e72915d4cbddceb435e13d81601755714e9fSE Android 835255e72915d4cbddceb435e13d81601755714e9fSE Android if (!tclass || tclass > policydb->p_classes.nprim) { 836255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(NULL, "unrecognized class %d", tclass); 837255e72915d4cbddceb435e13d81601755714e9fSE Android return -EINVAL; 838255e72915d4cbddceb435e13d81601755714e9fSE Android } 839255e72915d4cbddceb435e13d81601755714e9fSE Android tclass_datum = policydb->class_val_to_struct[tclass - 1]; 840255e72915d4cbddceb435e13d81601755714e9fSE Android 841255e72915d4cbddceb435e13d81601755714e9fSE Android /* 842255e72915d4cbddceb435e13d81601755714e9fSE Android * Initialize the access vectors to the default values. 843255e72915d4cbddceb435e13d81601755714e9fSE Android */ 844255e72915d4cbddceb435e13d81601755714e9fSE Android avd->allowed = 0; 845255e72915d4cbddceb435e13d81601755714e9fSE Android avd->decided = 0xffffffff; 846255e72915d4cbddceb435e13d81601755714e9fSE Android avd->auditallow = 0; 847255e72915d4cbddceb435e13d81601755714e9fSE Android avd->auditdeny = 0xffffffff; 848255e72915d4cbddceb435e13d81601755714e9fSE Android avd->seqno = latest_granting; 849255e72915d4cbddceb435e13d81601755714e9fSE Android *reason = 0; 850255e72915d4cbddceb435e13d81601755714e9fSE Android 851255e72915d4cbddceb435e13d81601755714e9fSE Android /* 852255e72915d4cbddceb435e13d81601755714e9fSE Android * If a specific type enforcement rule was defined for 853255e72915d4cbddceb435e13d81601755714e9fSE Android * this permission check, then use it. 854255e72915d4cbddceb435e13d81601755714e9fSE Android */ 855255e72915d4cbddceb435e13d81601755714e9fSE Android avkey.target_class = tclass; 856255e72915d4cbddceb435e13d81601755714e9fSE Android avkey.specified = AVTAB_AV; 857255e72915d4cbddceb435e13d81601755714e9fSE Android sattr = &policydb->type_attr_map[scontext->type - 1]; 858255e72915d4cbddceb435e13d81601755714e9fSE Android tattr = &policydb->type_attr_map[tcontext->type - 1]; 859255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_for_each_bit(sattr, snode, i) { 860255e72915d4cbddceb435e13d81601755714e9fSE Android if (!ebitmap_node_get_bit(snode, i)) 861255e72915d4cbddceb435e13d81601755714e9fSE Android continue; 862255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_for_each_bit(tattr, tnode, j) { 863255e72915d4cbddceb435e13d81601755714e9fSE Android if (!ebitmap_node_get_bit(tnode, j)) 864255e72915d4cbddceb435e13d81601755714e9fSE Android continue; 865255e72915d4cbddceb435e13d81601755714e9fSE Android avkey.source_type = i + 1; 866255e72915d4cbddceb435e13d81601755714e9fSE Android avkey.target_type = j + 1; 867255e72915d4cbddceb435e13d81601755714e9fSE Android for (node = 868255e72915d4cbddceb435e13d81601755714e9fSE Android avtab_search_node(&policydb->te_avtab, &avkey); 869255e72915d4cbddceb435e13d81601755714e9fSE Android node != NULL; 870255e72915d4cbddceb435e13d81601755714e9fSE Android node = 871255e72915d4cbddceb435e13d81601755714e9fSE Android avtab_search_node_next(node, avkey.specified)) { 872255e72915d4cbddceb435e13d81601755714e9fSE Android if (node->key.specified == AVTAB_ALLOWED) 873255e72915d4cbddceb435e13d81601755714e9fSE Android avd->allowed |= node->datum.data; 874255e72915d4cbddceb435e13d81601755714e9fSE Android else if (node->key.specified == 875255e72915d4cbddceb435e13d81601755714e9fSE Android AVTAB_AUDITALLOW) 876255e72915d4cbddceb435e13d81601755714e9fSE Android avd->auditallow |= node->datum.data; 877255e72915d4cbddceb435e13d81601755714e9fSE Android else if (node->key.specified == AVTAB_AUDITDENY) 878255e72915d4cbddceb435e13d81601755714e9fSE Android avd->auditdeny &= node->datum.data; 879255e72915d4cbddceb435e13d81601755714e9fSE Android } 880255e72915d4cbddceb435e13d81601755714e9fSE Android 881255e72915d4cbddceb435e13d81601755714e9fSE Android /* Check conditional av table for additional permissions */ 882255e72915d4cbddceb435e13d81601755714e9fSE Android cond_compute_av(&policydb->te_cond_avtab, &avkey, avd); 883255e72915d4cbddceb435e13d81601755714e9fSE Android 884255e72915d4cbddceb435e13d81601755714e9fSE Android } 885255e72915d4cbddceb435e13d81601755714e9fSE Android } 886255e72915d4cbddceb435e13d81601755714e9fSE Android 887255e72915d4cbddceb435e13d81601755714e9fSE Android if (requested & ~avd->allowed) { 888255e72915d4cbddceb435e13d81601755714e9fSE Android *reason |= SEPOL_COMPUTEAV_TE; 889255e72915d4cbddceb435e13d81601755714e9fSE Android requested &= avd->allowed; 890255e72915d4cbddceb435e13d81601755714e9fSE Android } 891255e72915d4cbddceb435e13d81601755714e9fSE Android 892255e72915d4cbddceb435e13d81601755714e9fSE Android /* 893255e72915d4cbddceb435e13d81601755714e9fSE Android * Remove any permissions prohibited by a constraint (this includes 894255e72915d4cbddceb435e13d81601755714e9fSE Android * the MLS policy). 895255e72915d4cbddceb435e13d81601755714e9fSE Android */ 896255e72915d4cbddceb435e13d81601755714e9fSE Android constraint = tclass_datum->constraints; 897255e72915d4cbddceb435e13d81601755714e9fSE Android while (constraint) { 898255e72915d4cbddceb435e13d81601755714e9fSE Android if ((constraint->permissions & (avd->allowed)) && 899dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley !constraint_expr_eval_reason(scontext, tcontext, NULL, 900dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley tclass, constraint, r_buf, flags)) { 901255e72915d4cbddceb435e13d81601755714e9fSE Android avd->allowed = 902255e72915d4cbddceb435e13d81601755714e9fSE Android (avd->allowed) & ~(constraint->permissions); 903255e72915d4cbddceb435e13d81601755714e9fSE Android } 904255e72915d4cbddceb435e13d81601755714e9fSE Android constraint = constraint->next; 905255e72915d4cbddceb435e13d81601755714e9fSE Android } 906255e72915d4cbddceb435e13d81601755714e9fSE Android 907255e72915d4cbddceb435e13d81601755714e9fSE Android if (requested & ~avd->allowed) { 908255e72915d4cbddceb435e13d81601755714e9fSE Android *reason |= SEPOL_COMPUTEAV_CONS; 909255e72915d4cbddceb435e13d81601755714e9fSE Android requested &= avd->allowed; 910255e72915d4cbddceb435e13d81601755714e9fSE Android } 911255e72915d4cbddceb435e13d81601755714e9fSE Android 912255e72915d4cbddceb435e13d81601755714e9fSE Android /* 913255e72915d4cbddceb435e13d81601755714e9fSE Android * If checking process transition permission and the 914255e72915d4cbddceb435e13d81601755714e9fSE Android * role is changing, then check the (current_role, new_role) 915255e72915d4cbddceb435e13d81601755714e9fSE Android * pair. 916255e72915d4cbddceb435e13d81601755714e9fSE Android */ 917255e72915d4cbddceb435e13d81601755714e9fSE Android if (tclass == SECCLASS_PROCESS && 918255e72915d4cbddceb435e13d81601755714e9fSE Android (avd->allowed & (PROCESS__TRANSITION | PROCESS__DYNTRANSITION)) && 919255e72915d4cbddceb435e13d81601755714e9fSE Android scontext->role != tcontext->role) { 920255e72915d4cbddceb435e13d81601755714e9fSE Android for (ra = policydb->role_allow; ra; ra = ra->next) { 921255e72915d4cbddceb435e13d81601755714e9fSE Android if (scontext->role == ra->role && 922255e72915d4cbddceb435e13d81601755714e9fSE Android tcontext->role == ra->new_role) 923255e72915d4cbddceb435e13d81601755714e9fSE Android break; 924255e72915d4cbddceb435e13d81601755714e9fSE Android } 925255e72915d4cbddceb435e13d81601755714e9fSE Android if (!ra) 926255e72915d4cbddceb435e13d81601755714e9fSE Android avd->allowed = (avd->allowed) & ~(PROCESS__TRANSITION | 927255e72915d4cbddceb435e13d81601755714e9fSE Android PROCESS__DYNTRANSITION); 928255e72915d4cbddceb435e13d81601755714e9fSE Android } 929255e72915d4cbddceb435e13d81601755714e9fSE Android 930255e72915d4cbddceb435e13d81601755714e9fSE Android if (requested & ~avd->allowed) { 931255e72915d4cbddceb435e13d81601755714e9fSE Android *reason |= SEPOL_COMPUTEAV_RBAC; 932255e72915d4cbddceb435e13d81601755714e9fSE Android requested &= avd->allowed; 933255e72915d4cbddceb435e13d81601755714e9fSE Android } 934255e72915d4cbddceb435e13d81601755714e9fSE Android 935255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 936255e72915d4cbddceb435e13d81601755714e9fSE Android} 937255e72915d4cbddceb435e13d81601755714e9fSE Android 938255e72915d4cbddceb435e13d81601755714e9fSE Androidint hidden sepol_validate_transition(sepol_security_id_t oldsid, 939255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_security_id_t newsid, 940255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_security_id_t tasksid, 941255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_security_class_t tclass) 942255e72915d4cbddceb435e13d81601755714e9fSE Android{ 943255e72915d4cbddceb435e13d81601755714e9fSE Android context_struct_t *ocontext; 944255e72915d4cbddceb435e13d81601755714e9fSE Android context_struct_t *ncontext; 945255e72915d4cbddceb435e13d81601755714e9fSE Android context_struct_t *tcontext; 946255e72915d4cbddceb435e13d81601755714e9fSE Android class_datum_t *tclass_datum; 947255e72915d4cbddceb435e13d81601755714e9fSE Android constraint_node_t *constraint; 948255e72915d4cbddceb435e13d81601755714e9fSE Android 949255e72915d4cbddceb435e13d81601755714e9fSE Android if (!tclass || tclass > policydb->p_classes.nprim) { 950255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(NULL, "unrecognized class %d", tclass); 951255e72915d4cbddceb435e13d81601755714e9fSE Android return -EINVAL; 952255e72915d4cbddceb435e13d81601755714e9fSE Android } 953255e72915d4cbddceb435e13d81601755714e9fSE Android tclass_datum = policydb->class_val_to_struct[tclass - 1]; 954255e72915d4cbddceb435e13d81601755714e9fSE Android 955255e72915d4cbddceb435e13d81601755714e9fSE Android ocontext = sepol_sidtab_search(sidtab, oldsid); 956255e72915d4cbddceb435e13d81601755714e9fSE Android if (!ocontext) { 957255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(NULL, "unrecognized SID %d", oldsid); 958255e72915d4cbddceb435e13d81601755714e9fSE Android return -EINVAL; 959255e72915d4cbddceb435e13d81601755714e9fSE Android } 960255e72915d4cbddceb435e13d81601755714e9fSE Android 961255e72915d4cbddceb435e13d81601755714e9fSE Android ncontext = sepol_sidtab_search(sidtab, newsid); 962255e72915d4cbddceb435e13d81601755714e9fSE Android if (!ncontext) { 963255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(NULL, "unrecognized SID %d", newsid); 964255e72915d4cbddceb435e13d81601755714e9fSE Android return -EINVAL; 965255e72915d4cbddceb435e13d81601755714e9fSE Android } 966255e72915d4cbddceb435e13d81601755714e9fSE Android 967255e72915d4cbddceb435e13d81601755714e9fSE Android tcontext = sepol_sidtab_search(sidtab, tasksid); 968255e72915d4cbddceb435e13d81601755714e9fSE Android if (!tcontext) { 969255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(NULL, "unrecognized SID %d", tasksid); 970255e72915d4cbddceb435e13d81601755714e9fSE Android return -EINVAL; 971255e72915d4cbddceb435e13d81601755714e9fSE Android } 972255e72915d4cbddceb435e13d81601755714e9fSE Android 973255e72915d4cbddceb435e13d81601755714e9fSE Android constraint = tclass_datum->validatetrans; 974255e72915d4cbddceb435e13d81601755714e9fSE Android while (constraint) { 975dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley if (!constraint_expr_eval_reason(ocontext, ncontext, tcontext, 976dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 0, constraint, NULL, 0)) { 977255e72915d4cbddceb435e13d81601755714e9fSE Android return -EPERM; 978255e72915d4cbddceb435e13d81601755714e9fSE Android } 979255e72915d4cbddceb435e13d81601755714e9fSE Android constraint = constraint->next; 980255e72915d4cbddceb435e13d81601755714e9fSE Android } 981255e72915d4cbddceb435e13d81601755714e9fSE Android 982255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 983255e72915d4cbddceb435e13d81601755714e9fSE Android} 984255e72915d4cbddceb435e13d81601755714e9fSE Android 985255e72915d4cbddceb435e13d81601755714e9fSE Androidint hidden sepol_compute_av_reason(sepol_security_id_t ssid, 986255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_security_id_t tsid, 987255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_security_class_t tclass, 988255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_access_vector_t requested, 989255e72915d4cbddceb435e13d81601755714e9fSE Android struct sepol_av_decision *avd, 990255e72915d4cbddceb435e13d81601755714e9fSE Android unsigned int *reason) 991255e72915d4cbddceb435e13d81601755714e9fSE Android{ 992255e72915d4cbddceb435e13d81601755714e9fSE Android context_struct_t *scontext = 0, *tcontext = 0; 993255e72915d4cbddceb435e13d81601755714e9fSE Android int rc = 0; 994255e72915d4cbddceb435e13d81601755714e9fSE Android 995255e72915d4cbddceb435e13d81601755714e9fSE Android scontext = sepol_sidtab_search(sidtab, ssid); 996255e72915d4cbddceb435e13d81601755714e9fSE Android if (!scontext) { 997255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(NULL, "unrecognized SID %d", ssid); 998255e72915d4cbddceb435e13d81601755714e9fSE Android rc = -EINVAL; 999255e72915d4cbddceb435e13d81601755714e9fSE Android goto out; 1000255e72915d4cbddceb435e13d81601755714e9fSE Android } 1001255e72915d4cbddceb435e13d81601755714e9fSE Android tcontext = sepol_sidtab_search(sidtab, tsid); 1002255e72915d4cbddceb435e13d81601755714e9fSE Android if (!tcontext) { 1003255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(NULL, "unrecognized SID %d", tsid); 1004255e72915d4cbddceb435e13d81601755714e9fSE Android rc = -EINVAL; 1005255e72915d4cbddceb435e13d81601755714e9fSE Android goto out; 1006255e72915d4cbddceb435e13d81601755714e9fSE Android } 1007255e72915d4cbddceb435e13d81601755714e9fSE Android 1008255e72915d4cbddceb435e13d81601755714e9fSE Android rc = context_struct_compute_av(scontext, tcontext, tclass, 1009dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley requested, avd, reason, NULL, 0); 1010255e72915d4cbddceb435e13d81601755714e9fSE Android out: 1011255e72915d4cbddceb435e13d81601755714e9fSE Android return rc; 1012255e72915d4cbddceb435e13d81601755714e9fSE Android} 1013255e72915d4cbddceb435e13d81601755714e9fSE Android 1014dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley/* 1015dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley * sepol_compute_av_reason_buffer - the reason buffer is malloc'd to 1016dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley * REASON_BUF_SIZE. If the buffer size is exceeded, then it is realloc'd 1017dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley * in the constraint_expr_eval_reason() function. 1018dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley */ 1019dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalleyint hidden sepol_compute_av_reason_buffer(sepol_security_id_t ssid, 1020dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley sepol_security_id_t tsid, 1021dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley sepol_security_class_t tclass, 1022dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley sepol_access_vector_t requested, 1023dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley struct sepol_av_decision *avd, 1024dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley unsigned int *reason, 1025dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley char **reason_buf, 1026dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley unsigned int flags) 1027dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley{ 1028dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley context_struct_t *scontext = 0, *tcontext = 0; 1029dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley int rc = 0; 1030dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 1031dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley scontext = sepol_sidtab_search(sidtab, ssid); 1032dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley if (!scontext) { 1033dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley ERR(NULL, "unrecognized SID %d", ssid); 1034dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley rc = -EINVAL; 1035dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley goto out; 1036dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley } 1037dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley tcontext = sepol_sidtab_search(sidtab, tsid); 1038dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley if (!tcontext) { 1039dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley ERR(NULL, "unrecognized SID %d", tsid); 1040dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley rc = -EINVAL; 1041dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley goto out; 1042dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley } 1043dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 1044dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley /* 1045dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley * Set the buffer to NULL as constraints may not be processed. 1046dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley * If a buffer is required, then the routines in 1047dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley * constraint_expr_eval_reason will realloc in REASON_BUF_SIZE 1048dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley * chunks (as it gets called for each constraint processed). 1049dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley * We just make sure these start from zero. 1050dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley */ 1051dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley *reason_buf = NULL; 1052dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley reason_buf_used = 0; 1053dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley reason_buf_len = 0; 1054dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 1055dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley rc = context_struct_compute_av(scontext, tcontext, tclass, 1056dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley requested, avd, reason, reason_buf, flags); 1057dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalleyout: 1058dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley return rc; 1059dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley} 1060dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 1061255e72915d4cbddceb435e13d81601755714e9fSE Androidint hidden sepol_compute_av(sepol_security_id_t ssid, 1062255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_security_id_t tsid, 1063255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_security_class_t tclass, 1064255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_access_vector_t requested, 1065255e72915d4cbddceb435e13d81601755714e9fSE Android struct sepol_av_decision *avd) 1066255e72915d4cbddceb435e13d81601755714e9fSE Android{ 1067255e72915d4cbddceb435e13d81601755714e9fSE Android unsigned int reason = 0; 1068255e72915d4cbddceb435e13d81601755714e9fSE Android return sepol_compute_av_reason(ssid, tsid, tclass, requested, avd, 1069255e72915d4cbddceb435e13d81601755714e9fSE Android &reason); 1070255e72915d4cbddceb435e13d81601755714e9fSE Android} 1071255e72915d4cbddceb435e13d81601755714e9fSE Android 1072255e72915d4cbddceb435e13d81601755714e9fSE Android/* 1073dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley * Return a class ID associated with the class string specified by 1074dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley * class_name. 1075dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley */ 1076dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalleyint hidden sepol_string_to_security_class(const char *class_name, 1077dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley sepol_security_class_t *tclass) 1078dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley{ 1079dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley char *class = NULL; 1080dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley sepol_security_class_t id; 1081dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 1082dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley for (id = 1;; id++) { 1083dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley class = policydb->p_class_val_to_name[id - 1]; 1084dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley if (class == NULL) { 1085dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley ERR(NULL, "could not convert %s to class id", class_name); 1086dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley return STATUS_ERR; 1087dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley } 1088dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley if ((strcmp(class, class_name)) == 0) { 1089dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley *tclass = id; 1090dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley return STATUS_SUCCESS; 1091dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley } 1092dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley } 1093dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley} 1094dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 1095dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley/* 1096dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley * Return access vector bit associated with the class ID and permission 1097dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley * string. 1098dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley */ 1099dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalleyint hidden sepol_string_to_av_perm(sepol_security_class_t tclass, 1100dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley const char *perm_name, 1101dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley sepol_access_vector_t *av) 1102dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley{ 1103dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley class_datum_t *tclass_datum; 1104dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley perm_datum_t *perm_datum; 1105dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 1106dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley if (!tclass || tclass > policydb->p_classes.nprim) { 1107dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley ERR(NULL, "unrecognized class %d", tclass); 1108dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley return -EINVAL; 1109dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley } 1110dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley tclass_datum = policydb->class_val_to_struct[tclass - 1]; 1111dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 1112dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley /* Check for unique perms then the common ones (if any) */ 1113dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley perm_datum = (perm_datum_t *) 1114dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley hashtab_search(tclass_datum->permissions.table, 1115dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley (hashtab_key_t)perm_name); 1116dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley if (perm_datum != NULL) { 1117dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley *av = 0x1 << (perm_datum->s.value - 1); 1118dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley return STATUS_SUCCESS; 1119dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley } 1120dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 1121dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley if (tclass_datum->comdatum == NULL) 1122dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley goto out; 1123dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 1124dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley perm_datum = (perm_datum_t *) 1125dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley hashtab_search(tclass_datum->comdatum->permissions.table, 1126dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley (hashtab_key_t)perm_name); 1127dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 1128dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley if (perm_datum != NULL) { 1129dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley *av = 0x1 << (perm_datum->s.value - 1); 1130dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley return STATUS_SUCCESS; 1131dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley } 1132dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalleyout: 1133dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley ERR(NULL, "could not convert %s to av bit", perm_name); 1134dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley return STATUS_ERR; 1135dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley} 1136dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 1137dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley/* 1138255e72915d4cbddceb435e13d81601755714e9fSE Android * Write the security context string representation of 1139255e72915d4cbddceb435e13d81601755714e9fSE Android * the context associated with `sid' into a dynamically 1140255e72915d4cbddceb435e13d81601755714e9fSE Android * allocated string of the correct size. Set `*scontext' 1141255e72915d4cbddceb435e13d81601755714e9fSE Android * to point to this string and set `*scontext_len' to 1142255e72915d4cbddceb435e13d81601755714e9fSE Android * the length of the string. 1143255e72915d4cbddceb435e13d81601755714e9fSE Android */ 1144255e72915d4cbddceb435e13d81601755714e9fSE Androidint hidden sepol_sid_to_context(sepol_security_id_t sid, 1145255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_security_context_t * scontext, 1146255e72915d4cbddceb435e13d81601755714e9fSE Android size_t * scontext_len) 1147255e72915d4cbddceb435e13d81601755714e9fSE Android{ 1148255e72915d4cbddceb435e13d81601755714e9fSE Android context_struct_t *context; 1149255e72915d4cbddceb435e13d81601755714e9fSE Android int rc = 0; 1150255e72915d4cbddceb435e13d81601755714e9fSE Android 1151255e72915d4cbddceb435e13d81601755714e9fSE Android context = sepol_sidtab_search(sidtab, sid); 1152255e72915d4cbddceb435e13d81601755714e9fSE Android if (!context) { 1153255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(NULL, "unrecognized SID %d", sid); 1154255e72915d4cbddceb435e13d81601755714e9fSE Android rc = -EINVAL; 1155255e72915d4cbddceb435e13d81601755714e9fSE Android goto out; 1156255e72915d4cbddceb435e13d81601755714e9fSE Android } 1157255e72915d4cbddceb435e13d81601755714e9fSE Android rc = context_to_string(NULL, policydb, context, scontext, scontext_len); 1158255e72915d4cbddceb435e13d81601755714e9fSE Android out: 1159255e72915d4cbddceb435e13d81601755714e9fSE Android return rc; 1160255e72915d4cbddceb435e13d81601755714e9fSE Android 1161255e72915d4cbddceb435e13d81601755714e9fSE Android} 1162255e72915d4cbddceb435e13d81601755714e9fSE Android 1163255e72915d4cbddceb435e13d81601755714e9fSE Android/* 1164255e72915d4cbddceb435e13d81601755714e9fSE Android * Return a SID associated with the security context that 1165255e72915d4cbddceb435e13d81601755714e9fSE Android * has the string representation specified by `scontext'. 1166255e72915d4cbddceb435e13d81601755714e9fSE Android */ 1167255e72915d4cbddceb435e13d81601755714e9fSE Androidint hidden sepol_context_to_sid(const sepol_security_context_t scontext, 1168255e72915d4cbddceb435e13d81601755714e9fSE Android size_t scontext_len, sepol_security_id_t * sid) 1169255e72915d4cbddceb435e13d81601755714e9fSE Android{ 1170255e72915d4cbddceb435e13d81601755714e9fSE Android 1171255e72915d4cbddceb435e13d81601755714e9fSE Android context_struct_t *context = NULL; 1172255e72915d4cbddceb435e13d81601755714e9fSE Android 1173255e72915d4cbddceb435e13d81601755714e9fSE Android /* First, create the context */ 1174255e72915d4cbddceb435e13d81601755714e9fSE Android if (context_from_string(NULL, policydb, &context, 1175255e72915d4cbddceb435e13d81601755714e9fSE Android scontext, scontext_len) < 0) 1176255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 1177255e72915d4cbddceb435e13d81601755714e9fSE Android 1178255e72915d4cbddceb435e13d81601755714e9fSE Android /* Obtain the new sid */ 1179255e72915d4cbddceb435e13d81601755714e9fSE Android if (sid && (sepol_sidtab_context_to_sid(sidtab, context, sid) < 0)) 1180255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 1181255e72915d4cbddceb435e13d81601755714e9fSE Android 1182255e72915d4cbddceb435e13d81601755714e9fSE Android context_destroy(context); 1183255e72915d4cbddceb435e13d81601755714e9fSE Android free(context); 1184255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_SUCCESS; 1185255e72915d4cbddceb435e13d81601755714e9fSE Android 1186255e72915d4cbddceb435e13d81601755714e9fSE Android err: 1187255e72915d4cbddceb435e13d81601755714e9fSE Android if (context) { 1188255e72915d4cbddceb435e13d81601755714e9fSE Android context_destroy(context); 1189255e72915d4cbddceb435e13d81601755714e9fSE Android free(context); 1190255e72915d4cbddceb435e13d81601755714e9fSE Android } 1191255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(NULL, "could not convert %s to sid", scontext); 1192255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_ERR; 1193255e72915d4cbddceb435e13d81601755714e9fSE Android} 1194255e72915d4cbddceb435e13d81601755714e9fSE Android 1195255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic inline int compute_sid_handle_invalid_context(context_struct_t * 1196255e72915d4cbddceb435e13d81601755714e9fSE Android scontext, 1197255e72915d4cbddceb435e13d81601755714e9fSE Android context_struct_t * 1198255e72915d4cbddceb435e13d81601755714e9fSE Android tcontext, 1199255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_security_class_t 1200255e72915d4cbddceb435e13d81601755714e9fSE Android tclass, 1201255e72915d4cbddceb435e13d81601755714e9fSE Android context_struct_t * 1202255e72915d4cbddceb435e13d81601755714e9fSE Android newcontext) 1203255e72915d4cbddceb435e13d81601755714e9fSE Android{ 1204255e72915d4cbddceb435e13d81601755714e9fSE Android if (selinux_enforcing) { 1205255e72915d4cbddceb435e13d81601755714e9fSE Android return -EACCES; 1206255e72915d4cbddceb435e13d81601755714e9fSE Android } else { 1207255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_security_context_t s, t, n; 1208255e72915d4cbddceb435e13d81601755714e9fSE Android size_t slen, tlen, nlen; 1209255e72915d4cbddceb435e13d81601755714e9fSE Android 1210255e72915d4cbddceb435e13d81601755714e9fSE Android context_to_string(NULL, policydb, scontext, &s, &slen); 1211255e72915d4cbddceb435e13d81601755714e9fSE Android context_to_string(NULL, policydb, tcontext, &t, &tlen); 1212255e72915d4cbddceb435e13d81601755714e9fSE Android context_to_string(NULL, policydb, newcontext, &n, &nlen); 1213255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(NULL, "invalid context %s for " 1214255e72915d4cbddceb435e13d81601755714e9fSE Android "scontext=%s tcontext=%s tclass=%s", 1215255e72915d4cbddceb435e13d81601755714e9fSE Android n, s, t, policydb->p_class_val_to_name[tclass - 1]); 1216255e72915d4cbddceb435e13d81601755714e9fSE Android free(s); 1217255e72915d4cbddceb435e13d81601755714e9fSE Android free(t); 1218255e72915d4cbddceb435e13d81601755714e9fSE Android free(n); 1219255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 1220255e72915d4cbddceb435e13d81601755714e9fSE Android } 1221255e72915d4cbddceb435e13d81601755714e9fSE Android} 1222255e72915d4cbddceb435e13d81601755714e9fSE Android 1223255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int sepol_compute_sid(sepol_security_id_t ssid, 1224255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_security_id_t tsid, 1225255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_security_class_t tclass, 1226255e72915d4cbddceb435e13d81601755714e9fSE Android uint32_t specified, sepol_security_id_t * out_sid) 1227255e72915d4cbddceb435e13d81601755714e9fSE Android{ 1228255e72915d4cbddceb435e13d81601755714e9fSE Android context_struct_t *scontext = 0, *tcontext = 0, newcontext; 1229255e72915d4cbddceb435e13d81601755714e9fSE Android struct role_trans *roletr = 0; 1230255e72915d4cbddceb435e13d81601755714e9fSE Android avtab_key_t avkey; 1231255e72915d4cbddceb435e13d81601755714e9fSE Android avtab_datum_t *avdatum; 1232255e72915d4cbddceb435e13d81601755714e9fSE Android avtab_ptr_t node; 1233255e72915d4cbddceb435e13d81601755714e9fSE Android int rc = 0; 1234255e72915d4cbddceb435e13d81601755714e9fSE Android 1235255e72915d4cbddceb435e13d81601755714e9fSE Android scontext = sepol_sidtab_search(sidtab, ssid); 1236255e72915d4cbddceb435e13d81601755714e9fSE Android if (!scontext) { 1237255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(NULL, "unrecognized SID %d", ssid); 1238255e72915d4cbddceb435e13d81601755714e9fSE Android rc = -EINVAL; 1239255e72915d4cbddceb435e13d81601755714e9fSE Android goto out; 1240255e72915d4cbddceb435e13d81601755714e9fSE Android } 1241255e72915d4cbddceb435e13d81601755714e9fSE Android tcontext = sepol_sidtab_search(sidtab, tsid); 1242255e72915d4cbddceb435e13d81601755714e9fSE Android if (!tcontext) { 1243255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(NULL, "unrecognized SID %d", tsid); 1244255e72915d4cbddceb435e13d81601755714e9fSE Android rc = -EINVAL; 1245255e72915d4cbddceb435e13d81601755714e9fSE Android goto out; 1246255e72915d4cbddceb435e13d81601755714e9fSE Android } 1247255e72915d4cbddceb435e13d81601755714e9fSE Android 1248255e72915d4cbddceb435e13d81601755714e9fSE Android context_init(&newcontext); 1249255e72915d4cbddceb435e13d81601755714e9fSE Android 1250255e72915d4cbddceb435e13d81601755714e9fSE Android /* Set the user identity. */ 1251255e72915d4cbddceb435e13d81601755714e9fSE Android switch (specified) { 1252255e72915d4cbddceb435e13d81601755714e9fSE Android case AVTAB_TRANSITION: 1253255e72915d4cbddceb435e13d81601755714e9fSE Android case AVTAB_CHANGE: 1254255e72915d4cbddceb435e13d81601755714e9fSE Android /* Use the process user identity. */ 1255255e72915d4cbddceb435e13d81601755714e9fSE Android newcontext.user = scontext->user; 1256255e72915d4cbddceb435e13d81601755714e9fSE Android break; 1257255e72915d4cbddceb435e13d81601755714e9fSE Android case AVTAB_MEMBER: 1258255e72915d4cbddceb435e13d81601755714e9fSE Android /* Use the related object owner. */ 1259255e72915d4cbddceb435e13d81601755714e9fSE Android newcontext.user = tcontext->user; 1260255e72915d4cbddceb435e13d81601755714e9fSE Android break; 1261255e72915d4cbddceb435e13d81601755714e9fSE Android } 1262255e72915d4cbddceb435e13d81601755714e9fSE Android 1263255e72915d4cbddceb435e13d81601755714e9fSE Android /* Set the role and type to default values. */ 1264255e72915d4cbddceb435e13d81601755714e9fSE Android switch (tclass) { 1265255e72915d4cbddceb435e13d81601755714e9fSE Android case SECCLASS_PROCESS: 1266255e72915d4cbddceb435e13d81601755714e9fSE Android /* Use the current role and type of process. */ 1267255e72915d4cbddceb435e13d81601755714e9fSE Android newcontext.role = scontext->role; 1268255e72915d4cbddceb435e13d81601755714e9fSE Android newcontext.type = scontext->type; 1269255e72915d4cbddceb435e13d81601755714e9fSE Android break; 1270255e72915d4cbddceb435e13d81601755714e9fSE Android default: 1271255e72915d4cbddceb435e13d81601755714e9fSE Android /* Use the well-defined object role. */ 1272255e72915d4cbddceb435e13d81601755714e9fSE Android newcontext.role = OBJECT_R_VAL; 1273255e72915d4cbddceb435e13d81601755714e9fSE Android /* Use the type of the related object. */ 1274255e72915d4cbddceb435e13d81601755714e9fSE Android newcontext.type = tcontext->type; 1275255e72915d4cbddceb435e13d81601755714e9fSE Android } 1276255e72915d4cbddceb435e13d81601755714e9fSE Android 1277255e72915d4cbddceb435e13d81601755714e9fSE Android /* Look for a type transition/member/change rule. */ 1278255e72915d4cbddceb435e13d81601755714e9fSE Android avkey.source_type = scontext->type; 1279255e72915d4cbddceb435e13d81601755714e9fSE Android avkey.target_type = tcontext->type; 1280255e72915d4cbddceb435e13d81601755714e9fSE Android avkey.target_class = tclass; 1281255e72915d4cbddceb435e13d81601755714e9fSE Android avkey.specified = specified; 1282255e72915d4cbddceb435e13d81601755714e9fSE Android avdatum = avtab_search(&policydb->te_avtab, &avkey); 1283255e72915d4cbddceb435e13d81601755714e9fSE Android 1284255e72915d4cbddceb435e13d81601755714e9fSE Android /* If no permanent rule, also check for enabled conditional rules */ 1285255e72915d4cbddceb435e13d81601755714e9fSE Android if (!avdatum) { 1286255e72915d4cbddceb435e13d81601755714e9fSE Android node = avtab_search_node(&policydb->te_cond_avtab, &avkey); 1287255e72915d4cbddceb435e13d81601755714e9fSE Android for (; node != NULL; 1288255e72915d4cbddceb435e13d81601755714e9fSE Android node = avtab_search_node_next(node, specified)) { 1289255e72915d4cbddceb435e13d81601755714e9fSE Android if (node->key.specified & AVTAB_ENABLED) { 1290255e72915d4cbddceb435e13d81601755714e9fSE Android avdatum = &node->datum; 1291255e72915d4cbddceb435e13d81601755714e9fSE Android break; 1292255e72915d4cbddceb435e13d81601755714e9fSE Android } 1293255e72915d4cbddceb435e13d81601755714e9fSE Android } 1294255e72915d4cbddceb435e13d81601755714e9fSE Android } 1295255e72915d4cbddceb435e13d81601755714e9fSE Android 1296255e72915d4cbddceb435e13d81601755714e9fSE Android if (avdatum) { 1297255e72915d4cbddceb435e13d81601755714e9fSE Android /* Use the type from the type transition/member/change rule. */ 1298255e72915d4cbddceb435e13d81601755714e9fSE Android newcontext.type = avdatum->data; 1299255e72915d4cbddceb435e13d81601755714e9fSE Android } 1300255e72915d4cbddceb435e13d81601755714e9fSE Android 1301255e72915d4cbddceb435e13d81601755714e9fSE Android /* Check for class-specific changes. */ 1302255e72915d4cbddceb435e13d81601755714e9fSE Android switch (tclass) { 1303255e72915d4cbddceb435e13d81601755714e9fSE Android case SECCLASS_PROCESS: 1304255e72915d4cbddceb435e13d81601755714e9fSE Android if (specified & AVTAB_TRANSITION) { 1305255e72915d4cbddceb435e13d81601755714e9fSE Android /* Look for a role transition rule. */ 1306255e72915d4cbddceb435e13d81601755714e9fSE Android for (roletr = policydb->role_tr; roletr; 1307255e72915d4cbddceb435e13d81601755714e9fSE Android roletr = roletr->next) { 1308255e72915d4cbddceb435e13d81601755714e9fSE Android if (roletr->role == scontext->role && 1309255e72915d4cbddceb435e13d81601755714e9fSE Android roletr->type == tcontext->type) { 1310255e72915d4cbddceb435e13d81601755714e9fSE Android /* Use the role transition rule. */ 1311255e72915d4cbddceb435e13d81601755714e9fSE Android newcontext.role = roletr->new_role; 1312255e72915d4cbddceb435e13d81601755714e9fSE Android break; 1313255e72915d4cbddceb435e13d81601755714e9fSE Android } 1314255e72915d4cbddceb435e13d81601755714e9fSE Android } 1315255e72915d4cbddceb435e13d81601755714e9fSE Android } 1316255e72915d4cbddceb435e13d81601755714e9fSE Android break; 1317255e72915d4cbddceb435e13d81601755714e9fSE Android default: 1318255e72915d4cbddceb435e13d81601755714e9fSE Android break; 1319255e72915d4cbddceb435e13d81601755714e9fSE Android } 1320255e72915d4cbddceb435e13d81601755714e9fSE Android 1321255e72915d4cbddceb435e13d81601755714e9fSE Android /* Set the MLS attributes. 1322255e72915d4cbddceb435e13d81601755714e9fSE Android This is done last because it may allocate memory. */ 1323255e72915d4cbddceb435e13d81601755714e9fSE Android rc = mls_compute_sid(policydb, scontext, tcontext, tclass, specified, 1324255e72915d4cbddceb435e13d81601755714e9fSE Android &newcontext); 1325255e72915d4cbddceb435e13d81601755714e9fSE Android if (rc) 1326255e72915d4cbddceb435e13d81601755714e9fSE Android goto out; 1327255e72915d4cbddceb435e13d81601755714e9fSE Android 1328255e72915d4cbddceb435e13d81601755714e9fSE Android /* Check the validity of the context. */ 1329255e72915d4cbddceb435e13d81601755714e9fSE Android if (!policydb_context_isvalid(policydb, &newcontext)) { 1330255e72915d4cbddceb435e13d81601755714e9fSE Android rc = compute_sid_handle_invalid_context(scontext, 1331255e72915d4cbddceb435e13d81601755714e9fSE Android tcontext, 1332255e72915d4cbddceb435e13d81601755714e9fSE Android tclass, &newcontext); 1333255e72915d4cbddceb435e13d81601755714e9fSE Android if (rc) 1334255e72915d4cbddceb435e13d81601755714e9fSE Android goto out; 1335255e72915d4cbddceb435e13d81601755714e9fSE Android } 1336255e72915d4cbddceb435e13d81601755714e9fSE Android /* Obtain the sid for the context. */ 1337255e72915d4cbddceb435e13d81601755714e9fSE Android rc = sepol_sidtab_context_to_sid(sidtab, &newcontext, out_sid); 1338255e72915d4cbddceb435e13d81601755714e9fSE Android out: 1339255e72915d4cbddceb435e13d81601755714e9fSE Android context_destroy(&newcontext); 1340255e72915d4cbddceb435e13d81601755714e9fSE Android return rc; 1341255e72915d4cbddceb435e13d81601755714e9fSE Android} 1342255e72915d4cbddceb435e13d81601755714e9fSE Android 1343255e72915d4cbddceb435e13d81601755714e9fSE Android/* 1344255e72915d4cbddceb435e13d81601755714e9fSE Android * Compute a SID to use for labeling a new object in the 1345255e72915d4cbddceb435e13d81601755714e9fSE Android * class `tclass' based on a SID pair. 1346255e72915d4cbddceb435e13d81601755714e9fSE Android */ 1347255e72915d4cbddceb435e13d81601755714e9fSE Androidint hidden sepol_transition_sid(sepol_security_id_t ssid, 1348255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_security_id_t tsid, 1349255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_security_class_t tclass, 1350255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_security_id_t * out_sid) 1351255e72915d4cbddceb435e13d81601755714e9fSE Android{ 1352255e72915d4cbddceb435e13d81601755714e9fSE Android return sepol_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION, out_sid); 1353255e72915d4cbddceb435e13d81601755714e9fSE Android} 1354255e72915d4cbddceb435e13d81601755714e9fSE Android 1355255e72915d4cbddceb435e13d81601755714e9fSE Android/* 1356255e72915d4cbddceb435e13d81601755714e9fSE Android * Compute a SID to use when selecting a member of a 1357255e72915d4cbddceb435e13d81601755714e9fSE Android * polyinstantiated object of class `tclass' based on 1358255e72915d4cbddceb435e13d81601755714e9fSE Android * a SID pair. 1359255e72915d4cbddceb435e13d81601755714e9fSE Android */ 1360255e72915d4cbddceb435e13d81601755714e9fSE Androidint hidden sepol_member_sid(sepol_security_id_t ssid, 1361255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_security_id_t tsid, 1362255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_security_class_t tclass, 1363255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_security_id_t * out_sid) 1364255e72915d4cbddceb435e13d81601755714e9fSE Android{ 1365255e72915d4cbddceb435e13d81601755714e9fSE Android return sepol_compute_sid(ssid, tsid, tclass, AVTAB_MEMBER, out_sid); 1366255e72915d4cbddceb435e13d81601755714e9fSE Android} 1367255e72915d4cbddceb435e13d81601755714e9fSE Android 1368255e72915d4cbddceb435e13d81601755714e9fSE Android/* 1369255e72915d4cbddceb435e13d81601755714e9fSE Android * Compute a SID to use for relabeling an object in the 1370255e72915d4cbddceb435e13d81601755714e9fSE Android * class `tclass' based on a SID pair. 1371255e72915d4cbddceb435e13d81601755714e9fSE Android */ 1372255e72915d4cbddceb435e13d81601755714e9fSE Androidint hidden sepol_change_sid(sepol_security_id_t ssid, 1373255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_security_id_t tsid, 1374255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_security_class_t tclass, 1375255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_security_id_t * out_sid) 1376255e72915d4cbddceb435e13d81601755714e9fSE Android{ 1377255e72915d4cbddceb435e13d81601755714e9fSE Android return sepol_compute_sid(ssid, tsid, tclass, AVTAB_CHANGE, out_sid); 1378255e72915d4cbddceb435e13d81601755714e9fSE Android} 1379255e72915d4cbddceb435e13d81601755714e9fSE Android 1380255e72915d4cbddceb435e13d81601755714e9fSE Android/* 1381255e72915d4cbddceb435e13d81601755714e9fSE Android * Verify that each permission that is defined under the 1382255e72915d4cbddceb435e13d81601755714e9fSE Android * existing policy is still defined with the same value 1383255e72915d4cbddceb435e13d81601755714e9fSE Android * in the new policy. 1384255e72915d4cbddceb435e13d81601755714e9fSE Android */ 1385255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int validate_perm(hashtab_key_t key, hashtab_datum_t datum, void *p) 1386255e72915d4cbddceb435e13d81601755714e9fSE Android{ 1387255e72915d4cbddceb435e13d81601755714e9fSE Android hashtab_t h; 1388255e72915d4cbddceb435e13d81601755714e9fSE Android perm_datum_t *perdatum, *perdatum2; 1389255e72915d4cbddceb435e13d81601755714e9fSE Android 1390255e72915d4cbddceb435e13d81601755714e9fSE Android h = (hashtab_t) p; 1391255e72915d4cbddceb435e13d81601755714e9fSE Android perdatum = (perm_datum_t *) datum; 1392255e72915d4cbddceb435e13d81601755714e9fSE Android 1393255e72915d4cbddceb435e13d81601755714e9fSE Android perdatum2 = (perm_datum_t *) hashtab_search(h, key); 1394255e72915d4cbddceb435e13d81601755714e9fSE Android if (!perdatum2) { 1395255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(NULL, "permission %s disappeared", key); 1396255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1397255e72915d4cbddceb435e13d81601755714e9fSE Android } 1398255e72915d4cbddceb435e13d81601755714e9fSE Android if (perdatum->s.value != perdatum2->s.value) { 1399255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(NULL, "the value of permissions %s changed", key); 1400255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1401255e72915d4cbddceb435e13d81601755714e9fSE Android } 1402255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 1403255e72915d4cbddceb435e13d81601755714e9fSE Android} 1404255e72915d4cbddceb435e13d81601755714e9fSE Android 1405255e72915d4cbddceb435e13d81601755714e9fSE Android/* 1406255e72915d4cbddceb435e13d81601755714e9fSE Android * Verify that each class that is defined under the 1407255e72915d4cbddceb435e13d81601755714e9fSE Android * existing policy is still defined with the same 1408255e72915d4cbddceb435e13d81601755714e9fSE Android * attributes in the new policy. 1409255e72915d4cbddceb435e13d81601755714e9fSE Android */ 1410255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int validate_class(hashtab_key_t key, hashtab_datum_t datum, void *p) 1411255e72915d4cbddceb435e13d81601755714e9fSE Android{ 1412255e72915d4cbddceb435e13d81601755714e9fSE Android policydb_t *newp; 1413255e72915d4cbddceb435e13d81601755714e9fSE Android class_datum_t *cladatum, *cladatum2; 1414255e72915d4cbddceb435e13d81601755714e9fSE Android 1415255e72915d4cbddceb435e13d81601755714e9fSE Android newp = (policydb_t *) p; 1416255e72915d4cbddceb435e13d81601755714e9fSE Android cladatum = (class_datum_t *) datum; 1417255e72915d4cbddceb435e13d81601755714e9fSE Android 1418255e72915d4cbddceb435e13d81601755714e9fSE Android cladatum2 = 1419255e72915d4cbddceb435e13d81601755714e9fSE Android (class_datum_t *) hashtab_search(newp->p_classes.table, key); 1420255e72915d4cbddceb435e13d81601755714e9fSE Android if (!cladatum2) { 1421255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(NULL, "class %s disappeared", key); 1422255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1423255e72915d4cbddceb435e13d81601755714e9fSE Android } 1424255e72915d4cbddceb435e13d81601755714e9fSE Android if (cladatum->s.value != cladatum2->s.value) { 1425255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(NULL, "the value of class %s changed", key); 1426255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1427255e72915d4cbddceb435e13d81601755714e9fSE Android } 1428255e72915d4cbddceb435e13d81601755714e9fSE Android if ((cladatum->comdatum && !cladatum2->comdatum) || 1429255e72915d4cbddceb435e13d81601755714e9fSE Android (!cladatum->comdatum && cladatum2->comdatum)) { 1430255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(NULL, "the inherits clause for the access " 1431255e72915d4cbddceb435e13d81601755714e9fSE Android "vector definition for class %s changed", key); 1432255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1433255e72915d4cbddceb435e13d81601755714e9fSE Android } 1434255e72915d4cbddceb435e13d81601755714e9fSE Android if (cladatum->comdatum) { 1435255e72915d4cbddceb435e13d81601755714e9fSE Android if (hashtab_map 1436255e72915d4cbddceb435e13d81601755714e9fSE Android (cladatum->comdatum->permissions.table, validate_perm, 1437255e72915d4cbddceb435e13d81601755714e9fSE Android cladatum2->comdatum->permissions.table)) { 1438255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(NULL, 1439255e72915d4cbddceb435e13d81601755714e9fSE Android " in the access vector definition " 1440255e72915d4cbddceb435e13d81601755714e9fSE Android "for class %s\n", key); 1441255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1442255e72915d4cbddceb435e13d81601755714e9fSE Android } 1443255e72915d4cbddceb435e13d81601755714e9fSE Android } 1444255e72915d4cbddceb435e13d81601755714e9fSE Android if (hashtab_map(cladatum->permissions.table, validate_perm, 1445255e72915d4cbddceb435e13d81601755714e9fSE Android cladatum2->permissions.table)) { 1446255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(NULL, " in access vector definition for class %s", key); 1447255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1448255e72915d4cbddceb435e13d81601755714e9fSE Android } 1449255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 1450255e72915d4cbddceb435e13d81601755714e9fSE Android} 1451255e72915d4cbddceb435e13d81601755714e9fSE Android 1452255e72915d4cbddceb435e13d81601755714e9fSE Android/* Clone the SID into the new SID table. */ 1453255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int clone_sid(sepol_security_id_t sid, 1454255e72915d4cbddceb435e13d81601755714e9fSE Android context_struct_t * context, void *arg) 1455255e72915d4cbddceb435e13d81601755714e9fSE Android{ 1456255e72915d4cbddceb435e13d81601755714e9fSE Android sidtab_t *s = arg; 1457255e72915d4cbddceb435e13d81601755714e9fSE Android 1458255e72915d4cbddceb435e13d81601755714e9fSE Android return sepol_sidtab_insert(s, sid, context); 1459255e72915d4cbddceb435e13d81601755714e9fSE Android} 1460255e72915d4cbddceb435e13d81601755714e9fSE Android 1461255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic inline int convert_context_handle_invalid_context(context_struct_t * 1462255e72915d4cbddceb435e13d81601755714e9fSE Android context) 1463255e72915d4cbddceb435e13d81601755714e9fSE Android{ 1464255e72915d4cbddceb435e13d81601755714e9fSE Android if (selinux_enforcing) { 1465255e72915d4cbddceb435e13d81601755714e9fSE Android return -EINVAL; 1466255e72915d4cbddceb435e13d81601755714e9fSE Android } else { 1467255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_security_context_t s; 1468255e72915d4cbddceb435e13d81601755714e9fSE Android size_t len; 1469255e72915d4cbddceb435e13d81601755714e9fSE Android 1470255e72915d4cbddceb435e13d81601755714e9fSE Android context_to_string(NULL, policydb, context, &s, &len); 1471255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(NULL, "context %s is invalid", s); 1472255e72915d4cbddceb435e13d81601755714e9fSE Android free(s); 1473255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 1474255e72915d4cbddceb435e13d81601755714e9fSE Android } 1475255e72915d4cbddceb435e13d81601755714e9fSE Android} 1476255e72915d4cbddceb435e13d81601755714e9fSE Android 1477255e72915d4cbddceb435e13d81601755714e9fSE Androidtypedef struct { 1478255e72915d4cbddceb435e13d81601755714e9fSE Android policydb_t *oldp; 1479255e72915d4cbddceb435e13d81601755714e9fSE Android policydb_t *newp; 1480255e72915d4cbddceb435e13d81601755714e9fSE Android} convert_context_args_t; 1481255e72915d4cbddceb435e13d81601755714e9fSE Android 1482255e72915d4cbddceb435e13d81601755714e9fSE Android/* 1483255e72915d4cbddceb435e13d81601755714e9fSE Android * Convert the values in the security context 1484255e72915d4cbddceb435e13d81601755714e9fSE Android * structure `c' from the values specified 1485255e72915d4cbddceb435e13d81601755714e9fSE Android * in the policy `p->oldp' to the values specified 1486255e72915d4cbddceb435e13d81601755714e9fSE Android * in the policy `p->newp'. Verify that the 1487255e72915d4cbddceb435e13d81601755714e9fSE Android * context is valid under the new policy. 1488255e72915d4cbddceb435e13d81601755714e9fSE Android */ 1489255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int convert_context(sepol_security_id_t key __attribute__ ((unused)), 1490255e72915d4cbddceb435e13d81601755714e9fSE Android context_struct_t * c, void *p) 1491255e72915d4cbddceb435e13d81601755714e9fSE Android{ 1492255e72915d4cbddceb435e13d81601755714e9fSE Android convert_context_args_t *args; 1493255e72915d4cbddceb435e13d81601755714e9fSE Android context_struct_t oldc; 1494255e72915d4cbddceb435e13d81601755714e9fSE Android role_datum_t *role; 1495255e72915d4cbddceb435e13d81601755714e9fSE Android type_datum_t *typdatum; 1496255e72915d4cbddceb435e13d81601755714e9fSE Android user_datum_t *usrdatum; 1497255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_security_context_t s; 1498255e72915d4cbddceb435e13d81601755714e9fSE Android size_t len; 1499255e72915d4cbddceb435e13d81601755714e9fSE Android int rc = -EINVAL; 1500255e72915d4cbddceb435e13d81601755714e9fSE Android 1501255e72915d4cbddceb435e13d81601755714e9fSE Android args = (convert_context_args_t *) p; 1502255e72915d4cbddceb435e13d81601755714e9fSE Android 1503255e72915d4cbddceb435e13d81601755714e9fSE Android if (context_cpy(&oldc, c)) 1504255e72915d4cbddceb435e13d81601755714e9fSE Android return -ENOMEM; 1505255e72915d4cbddceb435e13d81601755714e9fSE Android 1506255e72915d4cbddceb435e13d81601755714e9fSE Android /* Convert the user. */ 1507255e72915d4cbddceb435e13d81601755714e9fSE Android usrdatum = (user_datum_t *) hashtab_search(args->newp->p_users.table, 1508255e72915d4cbddceb435e13d81601755714e9fSE Android args->oldp-> 1509255e72915d4cbddceb435e13d81601755714e9fSE Android p_user_val_to_name[c->user - 1510255e72915d4cbddceb435e13d81601755714e9fSE Android 1]); 1511255e72915d4cbddceb435e13d81601755714e9fSE Android 1512255e72915d4cbddceb435e13d81601755714e9fSE Android if (!usrdatum) { 1513255e72915d4cbddceb435e13d81601755714e9fSE Android goto bad; 1514255e72915d4cbddceb435e13d81601755714e9fSE Android } 1515255e72915d4cbddceb435e13d81601755714e9fSE Android c->user = usrdatum->s.value; 1516255e72915d4cbddceb435e13d81601755714e9fSE Android 1517255e72915d4cbddceb435e13d81601755714e9fSE Android /* Convert the role. */ 1518255e72915d4cbddceb435e13d81601755714e9fSE Android role = (role_datum_t *) hashtab_search(args->newp->p_roles.table, 1519255e72915d4cbddceb435e13d81601755714e9fSE Android args->oldp-> 1520255e72915d4cbddceb435e13d81601755714e9fSE Android p_role_val_to_name[c->role - 1]); 1521255e72915d4cbddceb435e13d81601755714e9fSE Android if (!role) { 1522255e72915d4cbddceb435e13d81601755714e9fSE Android goto bad; 1523255e72915d4cbddceb435e13d81601755714e9fSE Android } 1524255e72915d4cbddceb435e13d81601755714e9fSE Android c->role = role->s.value; 1525255e72915d4cbddceb435e13d81601755714e9fSE Android 1526255e72915d4cbddceb435e13d81601755714e9fSE Android /* Convert the type. */ 1527255e72915d4cbddceb435e13d81601755714e9fSE Android typdatum = (type_datum_t *) 1528255e72915d4cbddceb435e13d81601755714e9fSE Android hashtab_search(args->newp->p_types.table, 1529255e72915d4cbddceb435e13d81601755714e9fSE Android args->oldp->p_type_val_to_name[c->type - 1]); 1530255e72915d4cbddceb435e13d81601755714e9fSE Android if (!typdatum) { 1531255e72915d4cbddceb435e13d81601755714e9fSE Android goto bad; 1532255e72915d4cbddceb435e13d81601755714e9fSE Android } 1533255e72915d4cbddceb435e13d81601755714e9fSE Android c->type = typdatum->s.value; 1534255e72915d4cbddceb435e13d81601755714e9fSE Android 1535255e72915d4cbddceb435e13d81601755714e9fSE Android rc = mls_convert_context(args->oldp, args->newp, c); 1536255e72915d4cbddceb435e13d81601755714e9fSE Android if (rc) 1537255e72915d4cbddceb435e13d81601755714e9fSE Android goto bad; 1538255e72915d4cbddceb435e13d81601755714e9fSE Android 1539255e72915d4cbddceb435e13d81601755714e9fSE Android /* Check the validity of the new context. */ 1540255e72915d4cbddceb435e13d81601755714e9fSE Android if (!policydb_context_isvalid(args->newp, c)) { 1541255e72915d4cbddceb435e13d81601755714e9fSE Android rc = convert_context_handle_invalid_context(&oldc); 1542255e72915d4cbddceb435e13d81601755714e9fSE Android if (rc) 1543255e72915d4cbddceb435e13d81601755714e9fSE Android goto bad; 1544255e72915d4cbddceb435e13d81601755714e9fSE Android } 1545255e72915d4cbddceb435e13d81601755714e9fSE Android 1546255e72915d4cbddceb435e13d81601755714e9fSE Android context_destroy(&oldc); 1547255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 1548255e72915d4cbddceb435e13d81601755714e9fSE Android 1549255e72915d4cbddceb435e13d81601755714e9fSE Android bad: 1550255e72915d4cbddceb435e13d81601755714e9fSE Android context_to_string(NULL, policydb, &oldc, &s, &len); 1551255e72915d4cbddceb435e13d81601755714e9fSE Android context_destroy(&oldc); 1552255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(NULL, "invalidating context %s", s); 1553255e72915d4cbddceb435e13d81601755714e9fSE Android free(s); 1554255e72915d4cbddceb435e13d81601755714e9fSE Android return rc; 1555255e72915d4cbddceb435e13d81601755714e9fSE Android} 1556255e72915d4cbddceb435e13d81601755714e9fSE Android 1557255e72915d4cbddceb435e13d81601755714e9fSE Android/* Reading from a policy "file". */ 1558255e72915d4cbddceb435e13d81601755714e9fSE Androidint hidden next_entry(void *buf, struct policy_file *fp, size_t bytes) 1559255e72915d4cbddceb435e13d81601755714e9fSE Android{ 1560255e72915d4cbddceb435e13d81601755714e9fSE Android size_t nread; 1561255e72915d4cbddceb435e13d81601755714e9fSE Android 1562255e72915d4cbddceb435e13d81601755714e9fSE Android switch (fp->type) { 1563255e72915d4cbddceb435e13d81601755714e9fSE Android case PF_USE_STDIO: 1564255e72915d4cbddceb435e13d81601755714e9fSE Android nread = fread(buf, bytes, 1, fp->fp); 1565255e72915d4cbddceb435e13d81601755714e9fSE Android 1566255e72915d4cbddceb435e13d81601755714e9fSE Android if (nread != 1) 1567255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1568255e72915d4cbddceb435e13d81601755714e9fSE Android break; 1569255e72915d4cbddceb435e13d81601755714e9fSE Android case PF_USE_MEMORY: 1570255e72915d4cbddceb435e13d81601755714e9fSE Android if (bytes > fp->len) 1571255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1572255e72915d4cbddceb435e13d81601755714e9fSE Android memcpy(buf, fp->data, bytes); 1573255e72915d4cbddceb435e13d81601755714e9fSE Android fp->data += bytes; 1574255e72915d4cbddceb435e13d81601755714e9fSE Android fp->len -= bytes; 1575255e72915d4cbddceb435e13d81601755714e9fSE Android break; 1576255e72915d4cbddceb435e13d81601755714e9fSE Android default: 1577255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1578255e72915d4cbddceb435e13d81601755714e9fSE Android } 1579255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 1580255e72915d4cbddceb435e13d81601755714e9fSE Android} 1581255e72915d4cbddceb435e13d81601755714e9fSE Android 1582255e72915d4cbddceb435e13d81601755714e9fSE Androidsize_t hidden put_entry(const void *ptr, size_t size, size_t n, 1583255e72915d4cbddceb435e13d81601755714e9fSE Android struct policy_file *fp) 1584255e72915d4cbddceb435e13d81601755714e9fSE Android{ 1585255e72915d4cbddceb435e13d81601755714e9fSE Android size_t bytes = size * n; 1586255e72915d4cbddceb435e13d81601755714e9fSE Android 1587255e72915d4cbddceb435e13d81601755714e9fSE Android switch (fp->type) { 1588255e72915d4cbddceb435e13d81601755714e9fSE Android case PF_USE_STDIO: 1589255e72915d4cbddceb435e13d81601755714e9fSE Android return fwrite(ptr, size, n, fp->fp); 1590255e72915d4cbddceb435e13d81601755714e9fSE Android case PF_USE_MEMORY: 1591255e72915d4cbddceb435e13d81601755714e9fSE Android if (bytes > fp->len) { 1592255e72915d4cbddceb435e13d81601755714e9fSE Android errno = ENOSPC; 1593255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 1594255e72915d4cbddceb435e13d81601755714e9fSE Android } 1595255e72915d4cbddceb435e13d81601755714e9fSE Android 1596255e72915d4cbddceb435e13d81601755714e9fSE Android memcpy(fp->data, ptr, bytes); 1597255e72915d4cbddceb435e13d81601755714e9fSE Android fp->data += bytes; 1598255e72915d4cbddceb435e13d81601755714e9fSE Android fp->len -= bytes; 1599255e72915d4cbddceb435e13d81601755714e9fSE Android return n; 1600255e72915d4cbddceb435e13d81601755714e9fSE Android case PF_LEN: 1601255e72915d4cbddceb435e13d81601755714e9fSE Android fp->len += bytes; 1602255e72915d4cbddceb435e13d81601755714e9fSE Android return n; 1603255e72915d4cbddceb435e13d81601755714e9fSE Android default: 1604255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 1605255e72915d4cbddceb435e13d81601755714e9fSE Android } 1606255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 1607255e72915d4cbddceb435e13d81601755714e9fSE Android} 1608255e72915d4cbddceb435e13d81601755714e9fSE Android 1609255e72915d4cbddceb435e13d81601755714e9fSE Android/* 1610255e72915d4cbddceb435e13d81601755714e9fSE Android * Read a new set of configuration data from 1611255e72915d4cbddceb435e13d81601755714e9fSE Android * a policy database binary representation file. 1612255e72915d4cbddceb435e13d81601755714e9fSE Android * 1613255e72915d4cbddceb435e13d81601755714e9fSE Android * Verify that each class that is defined under the 1614255e72915d4cbddceb435e13d81601755714e9fSE Android * existing policy is still defined with the same 1615255e72915d4cbddceb435e13d81601755714e9fSE Android * attributes in the new policy. 1616255e72915d4cbddceb435e13d81601755714e9fSE Android * 1617255e72915d4cbddceb435e13d81601755714e9fSE Android * Convert the context structures in the SID table to the 1618255e72915d4cbddceb435e13d81601755714e9fSE Android * new representation and verify that all entries 1619255e72915d4cbddceb435e13d81601755714e9fSE Android * in the SID table are valid under the new policy. 1620255e72915d4cbddceb435e13d81601755714e9fSE Android * 1621255e72915d4cbddceb435e13d81601755714e9fSE Android * Change the active policy database to use the new 1622255e72915d4cbddceb435e13d81601755714e9fSE Android * configuration data. 1623255e72915d4cbddceb435e13d81601755714e9fSE Android * 1624255e72915d4cbddceb435e13d81601755714e9fSE Android * Reset the access vector cache. 1625255e72915d4cbddceb435e13d81601755714e9fSE Android */ 1626255e72915d4cbddceb435e13d81601755714e9fSE Androidint hidden sepol_load_policy(void *data, size_t len) 1627255e72915d4cbddceb435e13d81601755714e9fSE Android{ 1628255e72915d4cbddceb435e13d81601755714e9fSE Android policydb_t oldpolicydb, newpolicydb; 1629255e72915d4cbddceb435e13d81601755714e9fSE Android sidtab_t oldsidtab, newsidtab; 1630255e72915d4cbddceb435e13d81601755714e9fSE Android convert_context_args_t args; 1631255e72915d4cbddceb435e13d81601755714e9fSE Android int rc = 0; 1632255e72915d4cbddceb435e13d81601755714e9fSE Android struct policy_file file, *fp; 1633255e72915d4cbddceb435e13d81601755714e9fSE Android 1634255e72915d4cbddceb435e13d81601755714e9fSE Android policy_file_init(&file); 1635255e72915d4cbddceb435e13d81601755714e9fSE Android file.type = PF_USE_MEMORY; 1636255e72915d4cbddceb435e13d81601755714e9fSE Android file.data = data; 1637255e72915d4cbddceb435e13d81601755714e9fSE Android file.len = len; 1638255e72915d4cbddceb435e13d81601755714e9fSE Android fp = &file; 1639255e72915d4cbddceb435e13d81601755714e9fSE Android 1640255e72915d4cbddceb435e13d81601755714e9fSE Android if (policydb_init(&newpolicydb)) 1641255e72915d4cbddceb435e13d81601755714e9fSE Android return -ENOMEM; 1642255e72915d4cbddceb435e13d81601755714e9fSE Android 1643255e72915d4cbddceb435e13d81601755714e9fSE Android if (policydb_read(&newpolicydb, fp, 1)) { 1644dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley policydb_destroy(&mypolicydb); 1645255e72915d4cbddceb435e13d81601755714e9fSE Android return -EINVAL; 1646255e72915d4cbddceb435e13d81601755714e9fSE Android } 1647255e72915d4cbddceb435e13d81601755714e9fSE Android 1648255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_sidtab_init(&newsidtab); 1649255e72915d4cbddceb435e13d81601755714e9fSE Android 1650255e72915d4cbddceb435e13d81601755714e9fSE Android /* Verify that the existing classes did not change. */ 1651255e72915d4cbddceb435e13d81601755714e9fSE Android if (hashtab_map 1652255e72915d4cbddceb435e13d81601755714e9fSE Android (policydb->p_classes.table, validate_class, &newpolicydb)) { 1653255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(NULL, "the definition of an existing class changed"); 1654255e72915d4cbddceb435e13d81601755714e9fSE Android rc = -EINVAL; 1655255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 1656255e72915d4cbddceb435e13d81601755714e9fSE Android } 1657255e72915d4cbddceb435e13d81601755714e9fSE Android 1658255e72915d4cbddceb435e13d81601755714e9fSE Android /* Clone the SID table. */ 1659255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_sidtab_shutdown(sidtab); 1660255e72915d4cbddceb435e13d81601755714e9fSE Android if (sepol_sidtab_map(sidtab, clone_sid, &newsidtab)) { 1661255e72915d4cbddceb435e13d81601755714e9fSE Android rc = -ENOMEM; 1662255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 1663255e72915d4cbddceb435e13d81601755714e9fSE Android } 1664255e72915d4cbddceb435e13d81601755714e9fSE Android 1665255e72915d4cbddceb435e13d81601755714e9fSE Android /* Convert the internal representations of contexts 1666255e72915d4cbddceb435e13d81601755714e9fSE Android in the new SID table and remove invalid SIDs. */ 1667255e72915d4cbddceb435e13d81601755714e9fSE Android args.oldp = policydb; 1668255e72915d4cbddceb435e13d81601755714e9fSE Android args.newp = &newpolicydb; 1669255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_sidtab_map_remove_on_error(&newsidtab, convert_context, &args); 1670255e72915d4cbddceb435e13d81601755714e9fSE Android 1671255e72915d4cbddceb435e13d81601755714e9fSE Android /* Save the old policydb and SID table to free later. */ 1672255e72915d4cbddceb435e13d81601755714e9fSE Android memcpy(&oldpolicydb, policydb, sizeof *policydb); 1673255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_sidtab_set(&oldsidtab, sidtab); 1674255e72915d4cbddceb435e13d81601755714e9fSE Android 1675255e72915d4cbddceb435e13d81601755714e9fSE Android /* Install the new policydb and SID table. */ 1676255e72915d4cbddceb435e13d81601755714e9fSE Android memcpy(policydb, &newpolicydb, sizeof *policydb); 1677255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_sidtab_set(sidtab, &newsidtab); 1678255e72915d4cbddceb435e13d81601755714e9fSE Android 1679255e72915d4cbddceb435e13d81601755714e9fSE Android /* Free the old policydb and SID table. */ 1680255e72915d4cbddceb435e13d81601755714e9fSE Android policydb_destroy(&oldpolicydb); 1681255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_sidtab_destroy(&oldsidtab); 1682255e72915d4cbddceb435e13d81601755714e9fSE Android 1683255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 1684255e72915d4cbddceb435e13d81601755714e9fSE Android 1685255e72915d4cbddceb435e13d81601755714e9fSE Android err: 1686255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_sidtab_destroy(&newsidtab); 1687255e72915d4cbddceb435e13d81601755714e9fSE Android policydb_destroy(&newpolicydb); 1688255e72915d4cbddceb435e13d81601755714e9fSE Android return rc; 1689255e72915d4cbddceb435e13d81601755714e9fSE Android 1690255e72915d4cbddceb435e13d81601755714e9fSE Android} 1691255e72915d4cbddceb435e13d81601755714e9fSE Android 1692255e72915d4cbddceb435e13d81601755714e9fSE Android/* 1693255e72915d4cbddceb435e13d81601755714e9fSE Android * Return the SIDs to use for an unlabeled file system 1694255e72915d4cbddceb435e13d81601755714e9fSE Android * that is being mounted from the device with the 1695255e72915d4cbddceb435e13d81601755714e9fSE Android * the kdevname `name'. The `fs_sid' SID is returned for 1696255e72915d4cbddceb435e13d81601755714e9fSE Android * the file system and the `file_sid' SID is returned 1697255e72915d4cbddceb435e13d81601755714e9fSE Android * for all files within that file system. 1698255e72915d4cbddceb435e13d81601755714e9fSE Android */ 1699255e72915d4cbddceb435e13d81601755714e9fSE Androidint hidden sepol_fs_sid(char *name, 1700255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_security_id_t * fs_sid, 1701255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_security_id_t * file_sid) 1702255e72915d4cbddceb435e13d81601755714e9fSE Android{ 1703255e72915d4cbddceb435e13d81601755714e9fSE Android int rc = 0; 1704255e72915d4cbddceb435e13d81601755714e9fSE Android ocontext_t *c; 1705255e72915d4cbddceb435e13d81601755714e9fSE Android 1706255e72915d4cbddceb435e13d81601755714e9fSE Android c = policydb->ocontexts[OCON_FS]; 1707255e72915d4cbddceb435e13d81601755714e9fSE Android while (c) { 1708255e72915d4cbddceb435e13d81601755714e9fSE Android if (strcmp(c->u.name, name) == 0) 1709255e72915d4cbddceb435e13d81601755714e9fSE Android break; 1710255e72915d4cbddceb435e13d81601755714e9fSE Android c = c->next; 1711255e72915d4cbddceb435e13d81601755714e9fSE Android } 1712255e72915d4cbddceb435e13d81601755714e9fSE Android 1713255e72915d4cbddceb435e13d81601755714e9fSE Android if (c) { 1714255e72915d4cbddceb435e13d81601755714e9fSE Android if (!c->sid[0] || !c->sid[1]) { 1715255e72915d4cbddceb435e13d81601755714e9fSE Android rc = sepol_sidtab_context_to_sid(sidtab, 1716255e72915d4cbddceb435e13d81601755714e9fSE Android &c->context[0], 1717255e72915d4cbddceb435e13d81601755714e9fSE Android &c->sid[0]); 1718255e72915d4cbddceb435e13d81601755714e9fSE Android if (rc) 1719255e72915d4cbddceb435e13d81601755714e9fSE Android goto out; 1720255e72915d4cbddceb435e13d81601755714e9fSE Android rc = sepol_sidtab_context_to_sid(sidtab, 1721255e72915d4cbddceb435e13d81601755714e9fSE Android &c->context[1], 1722255e72915d4cbddceb435e13d81601755714e9fSE Android &c->sid[1]); 1723255e72915d4cbddceb435e13d81601755714e9fSE Android if (rc) 1724255e72915d4cbddceb435e13d81601755714e9fSE Android goto out; 1725255e72915d4cbddceb435e13d81601755714e9fSE Android } 1726255e72915d4cbddceb435e13d81601755714e9fSE Android *fs_sid = c->sid[0]; 1727255e72915d4cbddceb435e13d81601755714e9fSE Android *file_sid = c->sid[1]; 1728255e72915d4cbddceb435e13d81601755714e9fSE Android } else { 1729255e72915d4cbddceb435e13d81601755714e9fSE Android *fs_sid = SECINITSID_FS; 1730255e72915d4cbddceb435e13d81601755714e9fSE Android *file_sid = SECINITSID_FILE; 1731255e72915d4cbddceb435e13d81601755714e9fSE Android } 1732255e72915d4cbddceb435e13d81601755714e9fSE Android 1733255e72915d4cbddceb435e13d81601755714e9fSE Android out: 1734255e72915d4cbddceb435e13d81601755714e9fSE Android return rc; 1735255e72915d4cbddceb435e13d81601755714e9fSE Android} 1736255e72915d4cbddceb435e13d81601755714e9fSE Android 1737255e72915d4cbddceb435e13d81601755714e9fSE Android/* 1738255e72915d4cbddceb435e13d81601755714e9fSE Android * Return the SID of the port specified by 1739255e72915d4cbddceb435e13d81601755714e9fSE Android * `domain', `type', `protocol', and `port'. 1740255e72915d4cbddceb435e13d81601755714e9fSE Android */ 1741255e72915d4cbddceb435e13d81601755714e9fSE Androidint hidden sepol_port_sid(uint16_t domain __attribute__ ((unused)), 1742255e72915d4cbddceb435e13d81601755714e9fSE Android uint16_t type __attribute__ ((unused)), 1743255e72915d4cbddceb435e13d81601755714e9fSE Android uint8_t protocol, 1744255e72915d4cbddceb435e13d81601755714e9fSE Android uint16_t port, sepol_security_id_t * out_sid) 1745255e72915d4cbddceb435e13d81601755714e9fSE Android{ 1746255e72915d4cbddceb435e13d81601755714e9fSE Android ocontext_t *c; 1747255e72915d4cbddceb435e13d81601755714e9fSE Android int rc = 0; 1748255e72915d4cbddceb435e13d81601755714e9fSE Android 1749255e72915d4cbddceb435e13d81601755714e9fSE Android c = policydb->ocontexts[OCON_PORT]; 1750255e72915d4cbddceb435e13d81601755714e9fSE Android while (c) { 1751255e72915d4cbddceb435e13d81601755714e9fSE Android if (c->u.port.protocol == protocol && 1752255e72915d4cbddceb435e13d81601755714e9fSE Android c->u.port.low_port <= port && c->u.port.high_port >= port) 1753255e72915d4cbddceb435e13d81601755714e9fSE Android break; 1754255e72915d4cbddceb435e13d81601755714e9fSE Android c = c->next; 1755255e72915d4cbddceb435e13d81601755714e9fSE Android } 1756255e72915d4cbddceb435e13d81601755714e9fSE Android 1757255e72915d4cbddceb435e13d81601755714e9fSE Android if (c) { 1758255e72915d4cbddceb435e13d81601755714e9fSE Android if (!c->sid[0]) { 1759255e72915d4cbddceb435e13d81601755714e9fSE Android rc = sepol_sidtab_context_to_sid(sidtab, 1760255e72915d4cbddceb435e13d81601755714e9fSE Android &c->context[0], 1761255e72915d4cbddceb435e13d81601755714e9fSE Android &c->sid[0]); 1762255e72915d4cbddceb435e13d81601755714e9fSE Android if (rc) 1763255e72915d4cbddceb435e13d81601755714e9fSE Android goto out; 1764255e72915d4cbddceb435e13d81601755714e9fSE Android } 1765255e72915d4cbddceb435e13d81601755714e9fSE Android *out_sid = c->sid[0]; 1766255e72915d4cbddceb435e13d81601755714e9fSE Android } else { 1767255e72915d4cbddceb435e13d81601755714e9fSE Android *out_sid = SECINITSID_PORT; 1768255e72915d4cbddceb435e13d81601755714e9fSE Android } 1769255e72915d4cbddceb435e13d81601755714e9fSE Android 1770255e72915d4cbddceb435e13d81601755714e9fSE Android out: 1771255e72915d4cbddceb435e13d81601755714e9fSE Android return rc; 1772255e72915d4cbddceb435e13d81601755714e9fSE Android} 1773255e72915d4cbddceb435e13d81601755714e9fSE Android 1774255e72915d4cbddceb435e13d81601755714e9fSE Android/* 1775255e72915d4cbddceb435e13d81601755714e9fSE Android * Return the SIDs to use for a network interface 1776255e72915d4cbddceb435e13d81601755714e9fSE Android * with the name `name'. The `if_sid' SID is returned for 1777255e72915d4cbddceb435e13d81601755714e9fSE Android * the interface and the `msg_sid' SID is returned as 1778255e72915d4cbddceb435e13d81601755714e9fSE Android * the default SID for messages received on the 1779255e72915d4cbddceb435e13d81601755714e9fSE Android * interface. 1780255e72915d4cbddceb435e13d81601755714e9fSE Android */ 1781255e72915d4cbddceb435e13d81601755714e9fSE Androidint hidden sepol_netif_sid(char *name, 1782255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_security_id_t * if_sid, 1783255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_security_id_t * msg_sid) 1784255e72915d4cbddceb435e13d81601755714e9fSE Android{ 1785255e72915d4cbddceb435e13d81601755714e9fSE Android int rc = 0; 1786255e72915d4cbddceb435e13d81601755714e9fSE Android ocontext_t *c; 1787255e72915d4cbddceb435e13d81601755714e9fSE Android 1788255e72915d4cbddceb435e13d81601755714e9fSE Android c = policydb->ocontexts[OCON_NETIF]; 1789255e72915d4cbddceb435e13d81601755714e9fSE Android while (c) { 1790255e72915d4cbddceb435e13d81601755714e9fSE Android if (strcmp(name, c->u.name) == 0) 1791255e72915d4cbddceb435e13d81601755714e9fSE Android break; 1792255e72915d4cbddceb435e13d81601755714e9fSE Android c = c->next; 1793255e72915d4cbddceb435e13d81601755714e9fSE Android } 1794255e72915d4cbddceb435e13d81601755714e9fSE Android 1795255e72915d4cbddceb435e13d81601755714e9fSE Android if (c) { 1796255e72915d4cbddceb435e13d81601755714e9fSE Android if (!c->sid[0] || !c->sid[1]) { 1797255e72915d4cbddceb435e13d81601755714e9fSE Android rc = sepol_sidtab_context_to_sid(sidtab, 1798255e72915d4cbddceb435e13d81601755714e9fSE Android &c->context[0], 1799255e72915d4cbddceb435e13d81601755714e9fSE Android &c->sid[0]); 1800255e72915d4cbddceb435e13d81601755714e9fSE Android if (rc) 1801255e72915d4cbddceb435e13d81601755714e9fSE Android goto out; 1802255e72915d4cbddceb435e13d81601755714e9fSE Android rc = sepol_sidtab_context_to_sid(sidtab, 1803255e72915d4cbddceb435e13d81601755714e9fSE Android &c->context[1], 1804255e72915d4cbddceb435e13d81601755714e9fSE Android &c->sid[1]); 1805255e72915d4cbddceb435e13d81601755714e9fSE Android if (rc) 1806255e72915d4cbddceb435e13d81601755714e9fSE Android goto out; 1807255e72915d4cbddceb435e13d81601755714e9fSE Android } 1808255e72915d4cbddceb435e13d81601755714e9fSE Android *if_sid = c->sid[0]; 1809255e72915d4cbddceb435e13d81601755714e9fSE Android *msg_sid = c->sid[1]; 1810255e72915d4cbddceb435e13d81601755714e9fSE Android } else { 1811255e72915d4cbddceb435e13d81601755714e9fSE Android *if_sid = SECINITSID_NETIF; 1812255e72915d4cbddceb435e13d81601755714e9fSE Android *msg_sid = SECINITSID_NETMSG; 1813255e72915d4cbddceb435e13d81601755714e9fSE Android } 1814255e72915d4cbddceb435e13d81601755714e9fSE Android 1815255e72915d4cbddceb435e13d81601755714e9fSE Android out: 1816255e72915d4cbddceb435e13d81601755714e9fSE Android return rc; 1817255e72915d4cbddceb435e13d81601755714e9fSE Android} 1818255e72915d4cbddceb435e13d81601755714e9fSE Android 1819255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int match_ipv6_addrmask(uint32_t * input, uint32_t * addr, 1820255e72915d4cbddceb435e13d81601755714e9fSE Android uint32_t * mask) 1821255e72915d4cbddceb435e13d81601755714e9fSE Android{ 1822255e72915d4cbddceb435e13d81601755714e9fSE Android int i, fail = 0; 1823255e72915d4cbddceb435e13d81601755714e9fSE Android 1824255e72915d4cbddceb435e13d81601755714e9fSE Android for (i = 0; i < 4; i++) 1825255e72915d4cbddceb435e13d81601755714e9fSE Android if (addr[i] != (input[i] & mask[i])) { 1826255e72915d4cbddceb435e13d81601755714e9fSE Android fail = 1; 1827255e72915d4cbddceb435e13d81601755714e9fSE Android break; 1828255e72915d4cbddceb435e13d81601755714e9fSE Android } 1829255e72915d4cbddceb435e13d81601755714e9fSE Android 1830255e72915d4cbddceb435e13d81601755714e9fSE Android return !fail; 1831255e72915d4cbddceb435e13d81601755714e9fSE Android} 1832255e72915d4cbddceb435e13d81601755714e9fSE Android 1833255e72915d4cbddceb435e13d81601755714e9fSE Android/* 1834255e72915d4cbddceb435e13d81601755714e9fSE Android * Return the SID of the node specified by the address 1835255e72915d4cbddceb435e13d81601755714e9fSE Android * `addrp' where `addrlen' is the length of the address 1836255e72915d4cbddceb435e13d81601755714e9fSE Android * in bytes and `domain' is the communications domain or 1837255e72915d4cbddceb435e13d81601755714e9fSE Android * address family in which the address should be interpreted. 1838255e72915d4cbddceb435e13d81601755714e9fSE Android */ 1839255e72915d4cbddceb435e13d81601755714e9fSE Androidint hidden sepol_node_sid(uint16_t domain, 1840255e72915d4cbddceb435e13d81601755714e9fSE Android void *addrp, 1841255e72915d4cbddceb435e13d81601755714e9fSE Android size_t addrlen, sepol_security_id_t * out_sid) 1842255e72915d4cbddceb435e13d81601755714e9fSE Android{ 1843255e72915d4cbddceb435e13d81601755714e9fSE Android int rc = 0; 1844255e72915d4cbddceb435e13d81601755714e9fSE Android ocontext_t *c; 1845255e72915d4cbddceb435e13d81601755714e9fSE Android 1846255e72915d4cbddceb435e13d81601755714e9fSE Android switch (domain) { 1847255e72915d4cbddceb435e13d81601755714e9fSE Android case AF_INET:{ 1848255e72915d4cbddceb435e13d81601755714e9fSE Android uint32_t addr; 1849255e72915d4cbddceb435e13d81601755714e9fSE Android 1850255e72915d4cbddceb435e13d81601755714e9fSE Android if (addrlen != sizeof(uint32_t)) { 1851255e72915d4cbddceb435e13d81601755714e9fSE Android rc = -EINVAL; 1852255e72915d4cbddceb435e13d81601755714e9fSE Android goto out; 1853255e72915d4cbddceb435e13d81601755714e9fSE Android } 1854255e72915d4cbddceb435e13d81601755714e9fSE Android 1855255e72915d4cbddceb435e13d81601755714e9fSE Android addr = *((uint32_t *) addrp); 1856255e72915d4cbddceb435e13d81601755714e9fSE Android 1857255e72915d4cbddceb435e13d81601755714e9fSE Android c = policydb->ocontexts[OCON_NODE]; 1858255e72915d4cbddceb435e13d81601755714e9fSE Android while (c) { 1859255e72915d4cbddceb435e13d81601755714e9fSE Android if (c->u.node.addr == (addr & c->u.node.mask)) 1860255e72915d4cbddceb435e13d81601755714e9fSE Android break; 1861255e72915d4cbddceb435e13d81601755714e9fSE Android c = c->next; 1862255e72915d4cbddceb435e13d81601755714e9fSE Android } 1863255e72915d4cbddceb435e13d81601755714e9fSE Android break; 1864255e72915d4cbddceb435e13d81601755714e9fSE Android } 1865255e72915d4cbddceb435e13d81601755714e9fSE Android 1866255e72915d4cbddceb435e13d81601755714e9fSE Android case AF_INET6: 1867255e72915d4cbddceb435e13d81601755714e9fSE Android if (addrlen != sizeof(uint64_t) * 2) { 1868255e72915d4cbddceb435e13d81601755714e9fSE Android rc = -EINVAL; 1869255e72915d4cbddceb435e13d81601755714e9fSE Android goto out; 1870255e72915d4cbddceb435e13d81601755714e9fSE Android } 1871255e72915d4cbddceb435e13d81601755714e9fSE Android 1872255e72915d4cbddceb435e13d81601755714e9fSE Android c = policydb->ocontexts[OCON_NODE6]; 1873255e72915d4cbddceb435e13d81601755714e9fSE Android while (c) { 1874255e72915d4cbddceb435e13d81601755714e9fSE Android if (match_ipv6_addrmask(addrp, c->u.node6.addr, 1875255e72915d4cbddceb435e13d81601755714e9fSE Android c->u.node6.mask)) 1876255e72915d4cbddceb435e13d81601755714e9fSE Android break; 1877255e72915d4cbddceb435e13d81601755714e9fSE Android c = c->next; 1878255e72915d4cbddceb435e13d81601755714e9fSE Android } 1879255e72915d4cbddceb435e13d81601755714e9fSE Android break; 1880255e72915d4cbddceb435e13d81601755714e9fSE Android 1881255e72915d4cbddceb435e13d81601755714e9fSE Android default: 1882255e72915d4cbddceb435e13d81601755714e9fSE Android *out_sid = SECINITSID_NODE; 1883255e72915d4cbddceb435e13d81601755714e9fSE Android goto out; 1884255e72915d4cbddceb435e13d81601755714e9fSE Android } 1885255e72915d4cbddceb435e13d81601755714e9fSE Android 1886255e72915d4cbddceb435e13d81601755714e9fSE Android if (c) { 1887255e72915d4cbddceb435e13d81601755714e9fSE Android if (!c->sid[0]) { 1888255e72915d4cbddceb435e13d81601755714e9fSE Android rc = sepol_sidtab_context_to_sid(sidtab, 1889255e72915d4cbddceb435e13d81601755714e9fSE Android &c->context[0], 1890255e72915d4cbddceb435e13d81601755714e9fSE Android &c->sid[0]); 1891255e72915d4cbddceb435e13d81601755714e9fSE Android if (rc) 1892255e72915d4cbddceb435e13d81601755714e9fSE Android goto out; 1893255e72915d4cbddceb435e13d81601755714e9fSE Android } 1894255e72915d4cbddceb435e13d81601755714e9fSE Android *out_sid = c->sid[0]; 1895255e72915d4cbddceb435e13d81601755714e9fSE Android } else { 1896255e72915d4cbddceb435e13d81601755714e9fSE Android *out_sid = SECINITSID_NODE; 1897255e72915d4cbddceb435e13d81601755714e9fSE Android } 1898255e72915d4cbddceb435e13d81601755714e9fSE Android 1899255e72915d4cbddceb435e13d81601755714e9fSE Android out: 1900255e72915d4cbddceb435e13d81601755714e9fSE Android return rc; 1901255e72915d4cbddceb435e13d81601755714e9fSE Android} 1902255e72915d4cbddceb435e13d81601755714e9fSE Android 1903255e72915d4cbddceb435e13d81601755714e9fSE Android/* 1904255e72915d4cbddceb435e13d81601755714e9fSE Android * Generate the set of SIDs for legal security contexts 1905255e72915d4cbddceb435e13d81601755714e9fSE Android * for a given user that can be reached by `fromsid'. 1906255e72915d4cbddceb435e13d81601755714e9fSE Android * Set `*sids' to point to a dynamically allocated 1907255e72915d4cbddceb435e13d81601755714e9fSE Android * array containing the set of SIDs. Set `*nel' to the 1908255e72915d4cbddceb435e13d81601755714e9fSE Android * number of elements in the array. 1909255e72915d4cbddceb435e13d81601755714e9fSE Android */ 1910255e72915d4cbddceb435e13d81601755714e9fSE Android#define SIDS_NEL 25 1911255e72915d4cbddceb435e13d81601755714e9fSE Android 1912255e72915d4cbddceb435e13d81601755714e9fSE Androidint hidden sepol_get_user_sids(sepol_security_id_t fromsid, 1913255e72915d4cbddceb435e13d81601755714e9fSE Android char *username, 1914255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_security_id_t ** sids, uint32_t * nel) 1915255e72915d4cbddceb435e13d81601755714e9fSE Android{ 1916255e72915d4cbddceb435e13d81601755714e9fSE Android context_struct_t *fromcon, usercon; 1917255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_security_id_t *mysids, *mysids2, sid; 1918255e72915d4cbddceb435e13d81601755714e9fSE Android uint32_t mynel = 0, maxnel = SIDS_NEL; 1919255e72915d4cbddceb435e13d81601755714e9fSE Android user_datum_t *user; 1920255e72915d4cbddceb435e13d81601755714e9fSE Android role_datum_t *role; 1921255e72915d4cbddceb435e13d81601755714e9fSE Android struct sepol_av_decision avd; 1922255e72915d4cbddceb435e13d81601755714e9fSE Android int rc = 0; 1923255e72915d4cbddceb435e13d81601755714e9fSE Android unsigned int i, j, reason; 1924255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_node_t *rnode, *tnode; 1925255e72915d4cbddceb435e13d81601755714e9fSE Android 1926255e72915d4cbddceb435e13d81601755714e9fSE Android fromcon = sepol_sidtab_search(sidtab, fromsid); 1927255e72915d4cbddceb435e13d81601755714e9fSE Android if (!fromcon) { 1928255e72915d4cbddceb435e13d81601755714e9fSE Android rc = -EINVAL; 1929255e72915d4cbddceb435e13d81601755714e9fSE Android goto out; 1930255e72915d4cbddceb435e13d81601755714e9fSE Android } 1931255e72915d4cbddceb435e13d81601755714e9fSE Android 1932255e72915d4cbddceb435e13d81601755714e9fSE Android user = (user_datum_t *) hashtab_search(policydb->p_users.table, 1933255e72915d4cbddceb435e13d81601755714e9fSE Android username); 1934255e72915d4cbddceb435e13d81601755714e9fSE Android if (!user) { 1935255e72915d4cbddceb435e13d81601755714e9fSE Android rc = -EINVAL; 1936255e72915d4cbddceb435e13d81601755714e9fSE Android goto out; 1937255e72915d4cbddceb435e13d81601755714e9fSE Android } 1938255e72915d4cbddceb435e13d81601755714e9fSE Android usercon.user = user->s.value; 1939255e72915d4cbddceb435e13d81601755714e9fSE Android 1940255e72915d4cbddceb435e13d81601755714e9fSE Android mysids = malloc(maxnel * sizeof(sepol_security_id_t)); 1941255e72915d4cbddceb435e13d81601755714e9fSE Android if (!mysids) { 1942255e72915d4cbddceb435e13d81601755714e9fSE Android rc = -ENOMEM; 1943255e72915d4cbddceb435e13d81601755714e9fSE Android goto out; 1944255e72915d4cbddceb435e13d81601755714e9fSE Android } 1945255e72915d4cbddceb435e13d81601755714e9fSE Android memset(mysids, 0, maxnel * sizeof(sepol_security_id_t)); 1946255e72915d4cbddceb435e13d81601755714e9fSE Android 1947255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_for_each_bit(&user->roles.roles, rnode, i) { 1948255e72915d4cbddceb435e13d81601755714e9fSE Android if (!ebitmap_node_get_bit(rnode, i)) 1949255e72915d4cbddceb435e13d81601755714e9fSE Android continue; 1950255e72915d4cbddceb435e13d81601755714e9fSE Android role = policydb->role_val_to_struct[i]; 1951255e72915d4cbddceb435e13d81601755714e9fSE Android usercon.role = i + 1; 1952255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_for_each_bit(&role->types.types, tnode, j) { 1953255e72915d4cbddceb435e13d81601755714e9fSE Android if (!ebitmap_node_get_bit(tnode, j)) 1954255e72915d4cbddceb435e13d81601755714e9fSE Android continue; 1955255e72915d4cbddceb435e13d81601755714e9fSE Android usercon.type = j + 1; 1956255e72915d4cbddceb435e13d81601755714e9fSE Android if (usercon.type == fromcon->type) 1957255e72915d4cbddceb435e13d81601755714e9fSE Android continue; 1958255e72915d4cbddceb435e13d81601755714e9fSE Android 1959255e72915d4cbddceb435e13d81601755714e9fSE Android if (mls_setup_user_range 1960255e72915d4cbddceb435e13d81601755714e9fSE Android (fromcon, user, &usercon, policydb->mls)) 1961255e72915d4cbddceb435e13d81601755714e9fSE Android continue; 1962255e72915d4cbddceb435e13d81601755714e9fSE Android 1963255e72915d4cbddceb435e13d81601755714e9fSE Android rc = context_struct_compute_av(fromcon, &usercon, 1964255e72915d4cbddceb435e13d81601755714e9fSE Android SECCLASS_PROCESS, 1965255e72915d4cbddceb435e13d81601755714e9fSE Android PROCESS__TRANSITION, 1966dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley &avd, &reason, NULL, 0); 1967255e72915d4cbddceb435e13d81601755714e9fSE Android if (rc || !(avd.allowed & PROCESS__TRANSITION)) 1968255e72915d4cbddceb435e13d81601755714e9fSE Android continue; 1969255e72915d4cbddceb435e13d81601755714e9fSE Android rc = sepol_sidtab_context_to_sid(sidtab, &usercon, 1970255e72915d4cbddceb435e13d81601755714e9fSE Android &sid); 1971255e72915d4cbddceb435e13d81601755714e9fSE Android if (rc) { 1972255e72915d4cbddceb435e13d81601755714e9fSE Android free(mysids); 1973255e72915d4cbddceb435e13d81601755714e9fSE Android goto out; 1974255e72915d4cbddceb435e13d81601755714e9fSE Android } 1975255e72915d4cbddceb435e13d81601755714e9fSE Android if (mynel < maxnel) { 1976255e72915d4cbddceb435e13d81601755714e9fSE Android mysids[mynel++] = sid; 1977255e72915d4cbddceb435e13d81601755714e9fSE Android } else { 1978255e72915d4cbddceb435e13d81601755714e9fSE Android maxnel += SIDS_NEL; 1979255e72915d4cbddceb435e13d81601755714e9fSE Android mysids2 = 1980255e72915d4cbddceb435e13d81601755714e9fSE Android malloc(maxnel * 1981255e72915d4cbddceb435e13d81601755714e9fSE Android sizeof(sepol_security_id_t)); 1982255e72915d4cbddceb435e13d81601755714e9fSE Android 1983255e72915d4cbddceb435e13d81601755714e9fSE Android if (!mysids2) { 1984255e72915d4cbddceb435e13d81601755714e9fSE Android rc = -ENOMEM; 1985255e72915d4cbddceb435e13d81601755714e9fSE Android free(mysids); 1986255e72915d4cbddceb435e13d81601755714e9fSE Android goto out; 1987255e72915d4cbddceb435e13d81601755714e9fSE Android } 1988255e72915d4cbddceb435e13d81601755714e9fSE Android memset(mysids2, 0, 1989255e72915d4cbddceb435e13d81601755714e9fSE Android maxnel * sizeof(sepol_security_id_t)); 1990255e72915d4cbddceb435e13d81601755714e9fSE Android memcpy(mysids2, mysids, 1991255e72915d4cbddceb435e13d81601755714e9fSE Android mynel * sizeof(sepol_security_id_t)); 1992255e72915d4cbddceb435e13d81601755714e9fSE Android free(mysids); 1993255e72915d4cbddceb435e13d81601755714e9fSE Android mysids = mysids2; 1994255e72915d4cbddceb435e13d81601755714e9fSE Android mysids[mynel++] = sid; 1995255e72915d4cbddceb435e13d81601755714e9fSE Android } 1996255e72915d4cbddceb435e13d81601755714e9fSE Android } 1997255e72915d4cbddceb435e13d81601755714e9fSE Android } 1998255e72915d4cbddceb435e13d81601755714e9fSE Android 1999255e72915d4cbddceb435e13d81601755714e9fSE Android *sids = mysids; 2000255e72915d4cbddceb435e13d81601755714e9fSE Android *nel = mynel; 2001255e72915d4cbddceb435e13d81601755714e9fSE Android 2002255e72915d4cbddceb435e13d81601755714e9fSE Android out: 2003255e72915d4cbddceb435e13d81601755714e9fSE Android return rc; 2004255e72915d4cbddceb435e13d81601755714e9fSE Android} 2005255e72915d4cbddceb435e13d81601755714e9fSE Android 2006255e72915d4cbddceb435e13d81601755714e9fSE Android/* 2007255e72915d4cbddceb435e13d81601755714e9fSE Android * Return the SID to use for a file in a filesystem 2008255e72915d4cbddceb435e13d81601755714e9fSE Android * that cannot support a persistent label mapping or use another 2009255e72915d4cbddceb435e13d81601755714e9fSE Android * fixed labeling behavior like transition SIDs or task SIDs. 2010255e72915d4cbddceb435e13d81601755714e9fSE Android */ 2011255e72915d4cbddceb435e13d81601755714e9fSE Androidint hidden sepol_genfs_sid(const char *fstype, 2012255e72915d4cbddceb435e13d81601755714e9fSE Android char *path, 2013255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_security_class_t sclass, 2014255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_security_id_t * sid) 2015255e72915d4cbddceb435e13d81601755714e9fSE Android{ 2016255e72915d4cbddceb435e13d81601755714e9fSE Android size_t len; 2017255e72915d4cbddceb435e13d81601755714e9fSE Android genfs_t *genfs; 2018255e72915d4cbddceb435e13d81601755714e9fSE Android ocontext_t *c; 2019255e72915d4cbddceb435e13d81601755714e9fSE Android int rc = 0, cmp = 0; 2020255e72915d4cbddceb435e13d81601755714e9fSE Android 2021255e72915d4cbddceb435e13d81601755714e9fSE Android for (genfs = policydb->genfs; genfs; genfs = genfs->next) { 2022255e72915d4cbddceb435e13d81601755714e9fSE Android cmp = strcmp(fstype, genfs->fstype); 2023255e72915d4cbddceb435e13d81601755714e9fSE Android if (cmp <= 0) 2024255e72915d4cbddceb435e13d81601755714e9fSE Android break; 2025255e72915d4cbddceb435e13d81601755714e9fSE Android } 2026255e72915d4cbddceb435e13d81601755714e9fSE Android 2027255e72915d4cbddceb435e13d81601755714e9fSE Android if (!genfs || cmp) { 2028255e72915d4cbddceb435e13d81601755714e9fSE Android *sid = SECINITSID_UNLABELED; 2029255e72915d4cbddceb435e13d81601755714e9fSE Android rc = -ENOENT; 2030255e72915d4cbddceb435e13d81601755714e9fSE Android goto out; 2031255e72915d4cbddceb435e13d81601755714e9fSE Android } 2032255e72915d4cbddceb435e13d81601755714e9fSE Android 2033255e72915d4cbddceb435e13d81601755714e9fSE Android for (c = genfs->head; c; c = c->next) { 2034255e72915d4cbddceb435e13d81601755714e9fSE Android len = strlen(c->u.name); 2035255e72915d4cbddceb435e13d81601755714e9fSE Android if ((!c->v.sclass || sclass == c->v.sclass) && 2036255e72915d4cbddceb435e13d81601755714e9fSE Android (strncmp(c->u.name, path, len) == 0)) 2037255e72915d4cbddceb435e13d81601755714e9fSE Android break; 2038255e72915d4cbddceb435e13d81601755714e9fSE Android } 2039255e72915d4cbddceb435e13d81601755714e9fSE Android 2040255e72915d4cbddceb435e13d81601755714e9fSE Android if (!c) { 2041255e72915d4cbddceb435e13d81601755714e9fSE Android *sid = SECINITSID_UNLABELED; 2042255e72915d4cbddceb435e13d81601755714e9fSE Android rc = -ENOENT; 2043255e72915d4cbddceb435e13d81601755714e9fSE Android goto out; 2044255e72915d4cbddceb435e13d81601755714e9fSE Android } 2045255e72915d4cbddceb435e13d81601755714e9fSE Android 2046255e72915d4cbddceb435e13d81601755714e9fSE Android if (!c->sid[0]) { 2047255e72915d4cbddceb435e13d81601755714e9fSE Android rc = sepol_sidtab_context_to_sid(sidtab, 2048255e72915d4cbddceb435e13d81601755714e9fSE Android &c->context[0], &c->sid[0]); 2049255e72915d4cbddceb435e13d81601755714e9fSE Android if (rc) 2050255e72915d4cbddceb435e13d81601755714e9fSE Android goto out; 2051255e72915d4cbddceb435e13d81601755714e9fSE Android } 2052255e72915d4cbddceb435e13d81601755714e9fSE Android 2053255e72915d4cbddceb435e13d81601755714e9fSE Android *sid = c->sid[0]; 2054255e72915d4cbddceb435e13d81601755714e9fSE Android out: 2055255e72915d4cbddceb435e13d81601755714e9fSE Android return rc; 2056255e72915d4cbddceb435e13d81601755714e9fSE Android} 2057255e72915d4cbddceb435e13d81601755714e9fSE Android 2058255e72915d4cbddceb435e13d81601755714e9fSE Androidint hidden sepol_fs_use(const char *fstype, 2059255e72915d4cbddceb435e13d81601755714e9fSE Android unsigned int *behavior, sepol_security_id_t * sid) 2060255e72915d4cbddceb435e13d81601755714e9fSE Android{ 2061255e72915d4cbddceb435e13d81601755714e9fSE Android int rc = 0; 2062255e72915d4cbddceb435e13d81601755714e9fSE Android ocontext_t *c; 2063255e72915d4cbddceb435e13d81601755714e9fSE Android 2064255e72915d4cbddceb435e13d81601755714e9fSE Android c = policydb->ocontexts[OCON_FSUSE]; 2065255e72915d4cbddceb435e13d81601755714e9fSE Android while (c) { 2066255e72915d4cbddceb435e13d81601755714e9fSE Android if (strcmp(fstype, c->u.name) == 0) 2067255e72915d4cbddceb435e13d81601755714e9fSE Android break; 2068255e72915d4cbddceb435e13d81601755714e9fSE Android c = c->next; 2069255e72915d4cbddceb435e13d81601755714e9fSE Android } 2070255e72915d4cbddceb435e13d81601755714e9fSE Android 2071255e72915d4cbddceb435e13d81601755714e9fSE Android if (c) { 2072255e72915d4cbddceb435e13d81601755714e9fSE Android *behavior = c->v.behavior; 2073255e72915d4cbddceb435e13d81601755714e9fSE Android if (!c->sid[0]) { 2074255e72915d4cbddceb435e13d81601755714e9fSE Android rc = sepol_sidtab_context_to_sid(sidtab, 2075255e72915d4cbddceb435e13d81601755714e9fSE Android &c->context[0], 2076255e72915d4cbddceb435e13d81601755714e9fSE Android &c->sid[0]); 2077255e72915d4cbddceb435e13d81601755714e9fSE Android if (rc) 2078255e72915d4cbddceb435e13d81601755714e9fSE Android goto out; 2079255e72915d4cbddceb435e13d81601755714e9fSE Android } 2080255e72915d4cbddceb435e13d81601755714e9fSE Android *sid = c->sid[0]; 2081255e72915d4cbddceb435e13d81601755714e9fSE Android } else { 2082255e72915d4cbddceb435e13d81601755714e9fSE Android rc = sepol_genfs_sid(fstype, "/", SECCLASS_DIR, sid); 2083255e72915d4cbddceb435e13d81601755714e9fSE Android if (rc) { 2084255e72915d4cbddceb435e13d81601755714e9fSE Android *behavior = SECURITY_FS_USE_NONE; 2085255e72915d4cbddceb435e13d81601755714e9fSE Android rc = 0; 2086255e72915d4cbddceb435e13d81601755714e9fSE Android } else { 2087255e72915d4cbddceb435e13d81601755714e9fSE Android *behavior = SECURITY_FS_USE_GENFS; 2088255e72915d4cbddceb435e13d81601755714e9fSE Android } 2089255e72915d4cbddceb435e13d81601755714e9fSE Android } 2090255e72915d4cbddceb435e13d81601755714e9fSE Android 2091255e72915d4cbddceb435e13d81601755714e9fSE Android out: 2092255e72915d4cbddceb435e13d81601755714e9fSE Android return rc; 2093255e72915d4cbddceb435e13d81601755714e9fSE Android} 2094255e72915d4cbddceb435e13d81601755714e9fSE Android 2095255e72915d4cbddceb435e13d81601755714e9fSE Android/* FLASK */ 2096