policy_define.c revision 09c783c9a36cd47216df827c5d2c21ec8cd613e2
1ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue/* 2ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue * Author : Stephen Smalley, <sds@epoch.ncsc.mil> 3ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue */ 4ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue 5ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue/* 6ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue * Updated: Trusted Computer Solutions, Inc. <dgoeddel@trustedcs.com> 7ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue * 8ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue * Support for enhanced MLS infrastructure. 9ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue * 10ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue * Updated: David Caplan, <dac@tresys.com> 11ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue * 12ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue * Added conditional policy language extensions 13ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue * 14ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue * Updated: Joshua Brindle <jbrindle@tresys.com> 15ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue * Karl MacMillan <kmacmillan@mentalrootkit.com> 16ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue * Jason Tang <jtang@tresys.com> 17ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue * 18ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue * Added support for binary policy modules 19ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue * 20ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. 21ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue * Copyright (C) 2003 - 2008 Tresys Technology, LLC 22ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue * Copyright (C) 2007 Red Hat Inc. 23ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue * This program is free software; you can redistribute it and/or modify 24ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue * it under the terms of the GNU General Public License as published by 25ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue * the Free Software Foundation, version 2. 26ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue */ 27ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue 28ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue/* FLASK */ 29ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue 30ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue#include <sys/types.h> 31ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue#include <assert.h> 32ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue#include <stdarg.h> 33ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue#include <stdint.h> 34ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue#include <stdio.h> 35ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue#include <stdlib.h> 36ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue#include <string.h> 37ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue#include <sys/socket.h> 38ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue#include <netinet/in.h> 39ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue#include <arpa/inet.h> 40ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue#include <stdlib.h> 41ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue 42ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue#include <sepol/policydb/expand.h> 43ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue#include <sepol/policydb/policydb.h> 44ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue#include <sepol/policydb/services.h> 45ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue#include <sepol/policydb/conditional.h> 46ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue#include <sepol/policydb/flask.h> 47ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue#include <sepol/policydb/hierarchy.h> 48ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue#include <sepol/policydb/polcaps.h> 49ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue#include "queue.h" 50ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue#include "checkpolicy.h" 51ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue#include "module_compiler.h" 52ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue#include "policy_define.h" 53ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue 54ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghuepolicydb_t *policydbp; 55ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghuequeue_t id_queue = 0; 56ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghueunsigned int pass; 57ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghuechar *curfile = 0; 58ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghueint mlspol = 0; 59ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue 60ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghueextern unsigned long policydb_lineno; 61ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghueextern unsigned long source_lineno; 62ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghueextern unsigned int policydb_errors; 63ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue 64ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghueextern int yywarn(char *msg); 65ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghueextern int yyerror(char *msg); 66ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue 67ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue#define ERRORMSG_LEN 255 68ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghuestatic char errormsg[ERRORMSG_LEN + 1] = {0}; 69ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue 70ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghuestatic int id_has_dot(char *id); 71ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghuestatic int parse_security_context(context_struct_t *c); 72ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue 73ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue/* initialize all of the state variables for the scanner/parser */ 74ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghuevoid init_parser(int pass_number) 75ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue{ 76ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue policydb_lineno = 1; 77ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue source_lineno = 1; 78ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue policydb_errors = 0; 79ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue pass = pass_number; 80ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue} 81ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue 82ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghuevoid yyerror2(char *fmt, ...) 83ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue{ 84ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue va_list ap; 85ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue va_start(ap, fmt); 86ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue vsnprintf(errormsg, ERRORMSG_LEN, fmt, ap); 87ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue yyerror(errormsg); 88ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue va_end(ap); 89ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue} 90ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue 91ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghueint insert_separator(int push) 92ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue{ 93ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue int error; 94ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue 95ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue if (push) 96ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue error = queue_push(id_queue, 0); 97ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue else 98ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue error = queue_insert(id_queue, 0); 99ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue 100ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue if (error) { 101ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue yyerror("queue overflow"); 102ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue return -1; 103ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue } 104ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue return 0; 105ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue} 106ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue 107ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghueint insert_id(char *id, int push) 108ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue{ 109ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue char *newid = 0; 110ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue int error; 111ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue 112ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue newid = (char *)malloc(strlen(id) + 1); 113ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue if (!newid) { 114ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue yyerror("out of memory"); 115ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue return -1; 116ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue } 117ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue strcpy(newid, id); 118ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue if (push) 119ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue error = queue_push(id_queue, (queue_element_t) newid); 120ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue else 121ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue error = queue_insert(id_queue, (queue_element_t) newid); 122ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue 123ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue if (error) { 124ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue yyerror("queue overflow"); 125ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue free(newid); 126ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue return -1; 127ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue } 128ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue return 0; 129ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue} 130ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue 131ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue/* If the identifier has a dot within it and that its first character 132ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue is not a dot then return 1, else return 0. */ 133ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghuestatic int id_has_dot(char *id) 134ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue{ 135ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue if (strchr(id, '.') >= id + 1) { 136ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue return 1; 137ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue } 138ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue return 0; 139ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue} 140ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue 141ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghueint define_class(void) 142ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue{ 143ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue char *id = 0; 144ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue class_datum_t *datum = 0; 145ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue int ret; 146ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue uint32_t value; 147ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue 148ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue if (pass == 2) { 149ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue id = queue_remove(id_queue); 150ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue free(id); 151ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue return 0; 152ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue } 153ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue 154ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue id = (char *)queue_remove(id_queue); 155ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue if (!id) { 156ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue yyerror("no class name for class definition?"); 157ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue return -1; 158ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue } 159ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue datum = (class_datum_t *) malloc(sizeof(class_datum_t)); 160ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue if (!datum) { 161ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue yyerror("out of memory"); 162ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue goto bad; 163ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue } 164ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue memset(datum, 0, sizeof(class_datum_t)); 165ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue ret = declare_symbol(SYM_CLASSES, id, datum, &value, &value); 166ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue switch (ret) { 167ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue case -3:{ 168ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue yyerror("Out of memory!"); 169ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue goto bad; 170ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue } 171ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue case -2:{ 172ab336de91e0468a1352d1a9f5d92f219140e0bd1Jeremy O'Donoghue yyerror2("duplicate declaration of class %s", id); 173 goto bad; 174 } 175 case -1:{ 176 yyerror("could not declare class here"); 177 goto bad; 178 } 179 case 0: 180 case 1:{ 181 break; 182 } 183 default:{ 184 assert(0); /* should never get here */ 185 } 186 } 187 datum->s.value = value; 188 return 0; 189 190 bad: 191 if (id) 192 free(id); 193 if (datum) 194 free(datum); 195 return -1; 196} 197 198int define_permissive(void) 199{ 200 char *type = NULL; 201 struct type_datum *t; 202 int rc = 0; 203 204 type = queue_remove(id_queue); 205 206 if (!type) { 207 yyerror2("forgot to include type in permissive definition?"); 208 rc = -1; 209 goto out; 210 } 211 212 if (pass == 1) 213 goto out; 214 215 if (!is_id_in_scope(SYM_TYPES, type)) { 216 yyerror2("type %s is not within scope", type); 217 rc = -1; 218 goto out; 219 } 220 221 t = hashtab_search(policydbp->p_types.table, type); 222 if (!t) { 223 yyerror2("type is not defined: %s", type); 224 rc = -1; 225 goto out; 226 } 227 228 if (t->flavor == TYPE_ATTRIB) { 229 yyerror2("attributes may not be permissive: %s\n", type); 230 rc = -1; 231 goto out; 232 } 233 234 t->flags |= TYPE_FLAGS_PERMISSIVE; 235 236out: 237 free(type); 238 return rc; 239} 240 241int define_polcap(void) 242{ 243 char *id = 0; 244 int capnum; 245 246 if (pass == 2) { 247 id = queue_remove(id_queue); 248 free(id); 249 return 0; 250 } 251 252 id = (char *)queue_remove(id_queue); 253 if (!id) { 254 yyerror("no capability name for policycap definition?"); 255 goto bad; 256 } 257 258 /* Check for valid cap name -> number mapping */ 259 capnum = sepol_polcap_getnum(id); 260 if (capnum < 0) { 261 yyerror2("invalid policy capability name %s", id); 262 goto bad; 263 } 264 265 /* Store it */ 266 if (ebitmap_set_bit(&policydbp->policycaps, capnum, TRUE)) { 267 yyerror("out of memory"); 268 goto bad; 269 } 270 271 free(id); 272 return 0; 273 274 bad: 275 free(id); 276 return -1; 277} 278 279int define_initial_sid(void) 280{ 281 char *id = 0; 282 ocontext_t *newc = 0, *c, *head; 283 284 if (pass == 2) { 285 id = queue_remove(id_queue); 286 free(id); 287 return 0; 288 } 289 290 id = (char *)queue_remove(id_queue); 291 if (!id) { 292 yyerror("no sid name for SID definition?"); 293 return -1; 294 } 295 newc = (ocontext_t *) malloc(sizeof(ocontext_t)); 296 if (!newc) { 297 yyerror("out of memory"); 298 goto bad; 299 } 300 memset(newc, 0, sizeof(ocontext_t)); 301 newc->u.name = id; 302 context_init(&newc->context[0]); 303 head = policydbp->ocontexts[OCON_ISID]; 304 305 for (c = head; c; c = c->next) { 306 if (!strcmp(newc->u.name, c->u.name)) { 307 yyerror2("duplicate initial SID %s", id); 308 goto bad; 309 } 310 } 311 312 if (head) { 313 newc->sid[0] = head->sid[0] + 1; 314 } else { 315 newc->sid[0] = 1; 316 } 317 newc->next = head; 318 policydbp->ocontexts[OCON_ISID] = newc; 319 320 return 0; 321 322 bad: 323 if (id) 324 free(id); 325 if (newc) 326 free(newc); 327 return -1; 328} 329 330static int read_classes(ebitmap_t *e_classes) 331{ 332 char *id; 333 class_datum_t *cladatum; 334 335 while ((id = queue_remove(id_queue))) { 336 if (!is_id_in_scope(SYM_CLASSES, id)) { 337 yyerror2("class %s is not within scope", id); 338 return -1; 339 } 340 cladatum = hashtab_search(policydbp->p_classes.table, id); 341 if (!cladatum) { 342 yyerror2("unknown class %s", id); 343 return -1; 344 } 345 if (ebitmap_set_bit(e_classes, cladatum->s.value - 1, TRUE)) { 346 yyerror("Out of memory"); 347 return -1; 348 } 349 free(id); 350 } 351 return 0; 352} 353 354int define_default_user(int which) 355{ 356 char *id; 357 class_datum_t *cladatum; 358 359 if (pass == 1) { 360 while ((id = queue_remove(id_queue))) 361 free(id); 362 return 0; 363 } 364 365 while ((id = queue_remove(id_queue))) { 366 if (!is_id_in_scope(SYM_CLASSES, id)) { 367 yyerror2("class %s is not within scope", id); 368 return -1; 369 } 370 cladatum = hashtab_search(policydbp->p_classes.table, id); 371 if (!cladatum) { 372 yyerror2("unknown class %s", id); 373 return -1; 374 } 375 if (cladatum->default_user && cladatum->default_user != which) { 376 yyerror2("conflicting default user information for class %s", id); 377 return -1; 378 } 379 cladatum->default_user = which; 380 free(id); 381 } 382 383 return 0; 384} 385 386int define_default_role(int which) 387{ 388 char *id; 389 class_datum_t *cladatum; 390 391 if (pass == 1) { 392 while ((id = queue_remove(id_queue))) 393 free(id); 394 return 0; 395 } 396 397 while ((id = queue_remove(id_queue))) { 398 if (!is_id_in_scope(SYM_CLASSES, id)) { 399 yyerror2("class %s is not within scope", id); 400 return -1; 401 } 402 cladatum = hashtab_search(policydbp->p_classes.table, id); 403 if (!cladatum) { 404 yyerror2("unknown class %s", id); 405 return -1; 406 } 407 if (cladatum->default_role && cladatum->default_role != which) { 408 yyerror2("conflicting default role information for class %s", id); 409 return -1; 410 } 411 cladatum->default_role = which; 412 free(id); 413 } 414 415 return 0; 416} 417 418int define_default_range(int which) 419{ 420 char *id; 421 class_datum_t *cladatum; 422 423 if (pass == 1) { 424 while ((id = queue_remove(id_queue))) 425 free(id); 426 return 0; 427 } 428 429 while ((id = queue_remove(id_queue))) { 430 if (!is_id_in_scope(SYM_CLASSES, id)) { 431 yyerror2("class %s is not within scope", id); 432 return -1; 433 } 434 cladatum = hashtab_search(policydbp->p_classes.table, id); 435 if (!cladatum) { 436 yyerror2("unknown class %s", id); 437 return -1; 438 } 439 if (cladatum->default_range && cladatum->default_range != which) { 440 yyerror2("conflicting default range information for class %s", id); 441 return -1; 442 } 443 cladatum->default_range = which; 444 free(id); 445 } 446 447 return 0; 448} 449 450int define_common_perms(void) 451{ 452 char *id = 0, *perm = 0; 453 common_datum_t *comdatum = 0; 454 perm_datum_t *perdatum = 0; 455 int ret; 456 457 if (pass == 2) { 458 while ((id = queue_remove(id_queue))) 459 free(id); 460 return 0; 461 } 462 463 id = (char *)queue_remove(id_queue); 464 if (!id) { 465 yyerror("no common name for common perm definition?"); 466 return -1; 467 } 468 comdatum = hashtab_search(policydbp->p_commons.table, id); 469 if (comdatum) { 470 yyerror2("duplicate declaration for common %s\n", id); 471 return -1; 472 } 473 comdatum = (common_datum_t *) malloc(sizeof(common_datum_t)); 474 if (!comdatum) { 475 yyerror("out of memory"); 476 goto bad; 477 } 478 memset(comdatum, 0, sizeof(common_datum_t)); 479 ret = hashtab_insert(policydbp->p_commons.table, 480 (hashtab_key_t) id, (hashtab_datum_t) comdatum); 481 482 if (ret == SEPOL_EEXIST) { 483 yyerror("duplicate common definition"); 484 goto bad; 485 } 486 if (ret == SEPOL_ENOMEM) { 487 yyerror("hash table overflow"); 488 goto bad; 489 } 490 comdatum->s.value = policydbp->p_commons.nprim + 1; 491 if (symtab_init(&comdatum->permissions, PERM_SYMTAB_SIZE)) { 492 yyerror("out of memory"); 493 goto bad; 494 } 495 policydbp->p_commons.nprim++; 496 while ((perm = queue_remove(id_queue))) { 497 perdatum = (perm_datum_t *) malloc(sizeof(perm_datum_t)); 498 if (!perdatum) { 499 yyerror("out of memory"); 500 goto bad_perm; 501 } 502 memset(perdatum, 0, sizeof(perm_datum_t)); 503 perdatum->s.value = comdatum->permissions.nprim + 1; 504 505 if (perdatum->s.value > (sizeof(sepol_access_vector_t) * 8)) { 506 yyerror 507 ("too many permissions to fit in an access vector"); 508 goto bad_perm; 509 } 510 ret = hashtab_insert(comdatum->permissions.table, 511 (hashtab_key_t) perm, 512 (hashtab_datum_t) perdatum); 513 514 if (ret == SEPOL_EEXIST) { 515 yyerror2("duplicate permission %s in common %s", perm, 516 id); 517 goto bad_perm; 518 } 519 if (ret == SEPOL_ENOMEM) { 520 yyerror("hash table overflow"); 521 goto bad_perm; 522 } 523 comdatum->permissions.nprim++; 524 } 525 526 return 0; 527 528 bad: 529 if (id) 530 free(id); 531 if (comdatum) 532 free(comdatum); 533 return -1; 534 535 bad_perm: 536 if (perm) 537 free(perm); 538 if (perdatum) 539 free(perdatum); 540 return -1; 541} 542 543int define_av_perms(int inherits) 544{ 545 char *id; 546 class_datum_t *cladatum; 547 common_datum_t *comdatum; 548 perm_datum_t *perdatum = 0, *perdatum2 = 0; 549 int ret; 550 551 if (pass == 2) { 552 while ((id = queue_remove(id_queue))) 553 free(id); 554 return 0; 555 } 556 557 id = (char *)queue_remove(id_queue); 558 if (!id) { 559 yyerror("no tclass name for av perm definition?"); 560 return -1; 561 } 562 cladatum = (class_datum_t *) hashtab_search(policydbp->p_classes.table, 563 (hashtab_key_t) id); 564 if (!cladatum) { 565 yyerror2("class %s is not defined", id); 566 goto bad; 567 } 568 free(id); 569 570 if (cladatum->comdatum || cladatum->permissions.nprim) { 571 yyerror("duplicate access vector definition"); 572 return -1; 573 } 574 if (symtab_init(&cladatum->permissions, PERM_SYMTAB_SIZE)) { 575 yyerror("out of memory"); 576 return -1; 577 } 578 if (inherits) { 579 id = (char *)queue_remove(id_queue); 580 if (!id) { 581 yyerror 582 ("no inherits name for access vector definition?"); 583 return -1; 584 } 585 comdatum = 586 (common_datum_t *) hashtab_search(policydbp->p_commons. 587 table, 588 (hashtab_key_t) id); 589 590 if (!comdatum) { 591 yyerror2("common %s is not defined", id); 592 goto bad; 593 } 594 cladatum->comkey = id; 595 cladatum->comdatum = comdatum; 596 597 /* 598 * Class-specific permissions start with values 599 * after the last common permission. 600 */ 601 cladatum->permissions.nprim += comdatum->permissions.nprim; 602 } 603 while ((id = queue_remove(id_queue))) { 604 perdatum = (perm_datum_t *) malloc(sizeof(perm_datum_t)); 605 if (!perdatum) { 606 yyerror("out of memory"); 607 goto bad; 608 } 609 memset(perdatum, 0, sizeof(perm_datum_t)); 610 perdatum->s.value = ++cladatum->permissions.nprim; 611 612 if (perdatum->s.value > (sizeof(sepol_access_vector_t) * 8)) { 613 yyerror 614 ("too many permissions to fit in an access vector"); 615 goto bad; 616 } 617 if (inherits) { 618 /* 619 * Class-specific permissions and 620 * common permissions exist in the same 621 * name space. 622 */ 623 perdatum2 = 624 (perm_datum_t *) hashtab_search(cladatum->comdatum-> 625 permissions.table, 626 (hashtab_key_t) id); 627 if (perdatum2) { 628 yyerror2("permission %s conflicts with an " 629 "inherited permission", id); 630 goto bad; 631 } 632 } 633 ret = hashtab_insert(cladatum->permissions.table, 634 (hashtab_key_t) id, 635 (hashtab_datum_t) perdatum); 636 637 if (ret == SEPOL_EEXIST) { 638 yyerror2("duplicate permission %s", id); 639 goto bad; 640 } 641 if (ret == SEPOL_ENOMEM) { 642 yyerror("hash table overflow"); 643 goto bad; 644 } 645 if (add_perm_to_class(perdatum->s.value, cladatum->s.value)) { 646 yyerror("out of memory"); 647 goto bad; 648 } 649 } 650 651 return 0; 652 653 bad: 654 if (id) 655 free(id); 656 if (perdatum) 657 free(perdatum); 658 return -1; 659} 660 661int define_sens(void) 662{ 663 char *id; 664 mls_level_t *level = 0; 665 level_datum_t *datum = 0, *aliasdatum = 0; 666 int ret; 667 uint32_t value; /* dummy variable -- its value is never used */ 668 669 if (!mlspol) { 670 yyerror("sensitivity definition in non-MLS configuration"); 671 return -1; 672 } 673 674 if (pass == 2) { 675 while ((id = queue_remove(id_queue))) 676 free(id); 677 return 0; 678 } 679 680 id = (char *)queue_remove(id_queue); 681 if (!id) { 682 yyerror("no sensitivity name for sensitivity definition?"); 683 return -1; 684 } 685 if (id_has_dot(id)) { 686 yyerror("sensitivity identifiers may not contain periods"); 687 goto bad; 688 } 689 level = (mls_level_t *) malloc(sizeof(mls_level_t)); 690 if (!level) { 691 yyerror("out of memory"); 692 goto bad; 693 } 694 mls_level_init(level); 695 level->sens = 0; /* actual value set in define_dominance */ 696 ebitmap_init(&level->cat); /* actual value set in define_level */ 697 698 datum = (level_datum_t *) malloc(sizeof(level_datum_t)); 699 if (!datum) { 700 yyerror("out of memory"); 701 goto bad; 702 } 703 level_datum_init(datum); 704 datum->isalias = FALSE; 705 datum->level = level; 706 707 ret = declare_symbol(SYM_LEVELS, id, datum, &value, &value); 708 switch (ret) { 709 case -3:{ 710 yyerror("Out of memory!"); 711 goto bad; 712 } 713 case -2:{ 714 yyerror("duplicate declaration of sensitivity level"); 715 goto bad; 716 } 717 case -1:{ 718 yyerror("could not declare sensitivity level here"); 719 goto bad; 720 } 721 case 0: 722 case 1:{ 723 break; 724 } 725 default:{ 726 assert(0); /* should never get here */ 727 } 728 } 729 730 while ((id = queue_remove(id_queue))) { 731 if (id_has_dot(id)) { 732 yyerror("sensitivity aliases may not contain periods"); 733 goto bad_alias; 734 } 735 aliasdatum = (level_datum_t *) malloc(sizeof(level_datum_t)); 736 if (!aliasdatum) { 737 yyerror("out of memory"); 738 goto bad_alias; 739 } 740 level_datum_init(aliasdatum); 741 aliasdatum->isalias = TRUE; 742 aliasdatum->level = level; 743 744 ret = declare_symbol(SYM_LEVELS, id, aliasdatum, NULL, &value); 745 switch (ret) { 746 case -3:{ 747 yyerror("Out of memory!"); 748 goto bad_alias; 749 } 750 case -2:{ 751 yyerror 752 ("duplicate declaration of sensitivity alias"); 753 goto bad_alias; 754 } 755 case -1:{ 756 yyerror 757 ("could not declare sensitivity alias here"); 758 goto bad_alias; 759 } 760 case 0: 761 case 1:{ 762 break; 763 } 764 default:{ 765 assert(0); /* should never get here */ 766 } 767 } 768 } 769 770 return 0; 771 772 bad: 773 if (id) 774 free(id); 775 if (level) 776 free(level); 777 if (datum) { 778 level_datum_destroy(datum); 779 free(datum); 780 } 781 return -1; 782 783 bad_alias: 784 if (id) 785 free(id); 786 if (aliasdatum) { 787 level_datum_destroy(aliasdatum); 788 free(aliasdatum); 789 } 790 return -1; 791} 792 793int define_dominance(void) 794{ 795 level_datum_t *datum; 796 int order; 797 char *id; 798 799 if (!mlspol) { 800 yyerror("dominance definition in non-MLS configuration"); 801 return -1; 802 } 803 804 if (pass == 2) { 805 while ((id = queue_remove(id_queue))) 806 free(id); 807 return 0; 808 } 809 810 order = 0; 811 while ((id = (char *)queue_remove(id_queue))) { 812 datum = 813 (level_datum_t *) hashtab_search(policydbp->p_levels.table, 814 (hashtab_key_t) id); 815 if (!datum) { 816 yyerror2("unknown sensitivity %s used in dominance " 817 "definition", id); 818 free(id); 819 return -1; 820 } 821 if (datum->level->sens != 0) { 822 yyerror2("sensitivity %s occurs multiply in dominance " 823 "definition", id); 824 free(id); 825 return -1; 826 } 827 datum->level->sens = ++order; 828 829 /* no need to keep sensitivity name */ 830 free(id); 831 } 832 833 if (order != policydbp->p_levels.nprim) { 834 yyerror 835 ("all sensitivities must be specified in dominance definition"); 836 return -1; 837 } 838 return 0; 839} 840 841int define_category(void) 842{ 843 char *id; 844 cat_datum_t *datum = 0, *aliasdatum = 0; 845 int ret; 846 uint32_t value; 847 848 if (!mlspol) { 849 yyerror("category definition in non-MLS configuration"); 850 return -1; 851 } 852 853 if (pass == 2) { 854 while ((id = queue_remove(id_queue))) 855 free(id); 856 return 0; 857 } 858 859 id = (char *)queue_remove(id_queue); 860 if (!id) { 861 yyerror("no category name for category definition?"); 862 return -1; 863 } 864 if (id_has_dot(id)) { 865 yyerror("category identifiers may not contain periods"); 866 goto bad; 867 } 868 datum = (cat_datum_t *) malloc(sizeof(cat_datum_t)); 869 if (!datum) { 870 yyerror("out of memory"); 871 goto bad; 872 } 873 cat_datum_init(datum); 874 datum->isalias = FALSE; 875 876 ret = declare_symbol(SYM_CATS, id, datum, &value, &value); 877 switch (ret) { 878 case -3:{ 879 yyerror("Out of memory!"); 880 goto bad; 881 } 882 case -2:{ 883 yyerror("duplicate declaration of category"); 884 goto bad; 885 } 886 case -1:{ 887 yyerror("could not declare category here"); 888 goto bad; 889 } 890 case 0: 891 case 1:{ 892 break; 893 } 894 default:{ 895 assert(0); /* should never get here */ 896 } 897 } 898 datum->s.value = value; 899 900 while ((id = queue_remove(id_queue))) { 901 if (id_has_dot(id)) { 902 yyerror("category aliases may not contain periods"); 903 goto bad_alias; 904 } 905 aliasdatum = (cat_datum_t *) malloc(sizeof(cat_datum_t)); 906 if (!aliasdatum) { 907 yyerror("out of memory"); 908 goto bad_alias; 909 } 910 cat_datum_init(aliasdatum); 911 aliasdatum->isalias = TRUE; 912 aliasdatum->s.value = datum->s.value; 913 914 ret = 915 declare_symbol(SYM_CATS, id, aliasdatum, NULL, 916 &datum->s.value); 917 switch (ret) { 918 case -3:{ 919 yyerror("Out of memory!"); 920 goto bad_alias; 921 } 922 case -2:{ 923 yyerror 924 ("duplicate declaration of category aliases"); 925 goto bad_alias; 926 } 927 case -1:{ 928 yyerror 929 ("could not declare category aliases here"); 930 goto bad_alias; 931 } 932 case 0: 933 case 1:{ 934 break; 935 } 936 default:{ 937 assert(0); /* should never get here */ 938 } 939 } 940 } 941 942 return 0; 943 944 bad: 945 if (id) 946 free(id); 947 if (datum) { 948 cat_datum_destroy(datum); 949 free(datum); 950 } 951 return -1; 952 953 bad_alias: 954 if (id) 955 free(id); 956 if (aliasdatum) { 957 cat_datum_destroy(aliasdatum); 958 free(aliasdatum); 959 } 960 return -1; 961} 962 963static int clone_level(hashtab_key_t key, hashtab_datum_t datum, void *arg) 964{ 965 level_datum_t *levdatum = (level_datum_t *) datum; 966 mls_level_t *level = (mls_level_t *) arg, *newlevel; 967 968 if (levdatum->level == level) { 969 levdatum->defined = 1; 970 if (!levdatum->isalias) 971 return 0; 972 newlevel = (mls_level_t *) malloc(sizeof(mls_level_t)); 973 if (!newlevel) 974 return -1; 975 if (mls_level_cpy(newlevel, level)) { 976 free(newlevel); 977 return -1; 978 } 979 levdatum->level = newlevel; 980 } 981 return 0; 982} 983 984int define_level(void) 985{ 986 char *id; 987 level_datum_t *levdatum; 988 989 if (!mlspol) { 990 yyerror("level definition in non-MLS configuration"); 991 return -1; 992 } 993 994 if (pass == 2) { 995 while ((id = queue_remove(id_queue))) 996 free(id); 997 return 0; 998 } 999 1000 id = (char *)queue_remove(id_queue); 1001 if (!id) { 1002 yyerror("no level name for level definition?"); 1003 return -1; 1004 } 1005 levdatum = (level_datum_t *) hashtab_search(policydbp->p_levels.table, 1006 (hashtab_key_t) id); 1007 if (!levdatum) { 1008 yyerror2("unknown sensitivity %s used in level definition", id); 1009 free(id); 1010 return -1; 1011 } 1012 if (ebitmap_length(&levdatum->level->cat)) { 1013 yyerror2("sensitivity %s used in multiple level definitions", 1014 id); 1015 free(id); 1016 return -1; 1017 } 1018 free(id); 1019 1020 levdatum->defined = 1; 1021 1022 while ((id = queue_remove(id_queue))) { 1023 cat_datum_t *cdatum; 1024 int range_start, range_end, i; 1025 1026 if (id_has_dot(id)) { 1027 char *id_start = id; 1028 char *id_end = strchr(id, '.'); 1029 1030 *(id_end++) = '\0'; 1031 1032 cdatum = 1033 (cat_datum_t *) hashtab_search(policydbp->p_cats. 1034 table, 1035 (hashtab_key_t) 1036 id_start); 1037 if (!cdatum) { 1038 yyerror2("unknown category %s", id_start); 1039 free(id); 1040 return -1; 1041 } 1042 range_start = cdatum->s.value - 1; 1043 cdatum = 1044 (cat_datum_t *) hashtab_search(policydbp->p_cats. 1045 table, 1046 (hashtab_key_t) 1047 id_end); 1048 if (!cdatum) { 1049 yyerror2("unknown category %s", id_end); 1050 free(id); 1051 return -1; 1052 } 1053 range_end = cdatum->s.value - 1; 1054 1055 if (range_end < range_start) { 1056 yyerror2("category range is invalid"); 1057 free(id); 1058 return -1; 1059 } 1060 } else { 1061 cdatum = 1062 (cat_datum_t *) hashtab_search(policydbp->p_cats. 1063 table, 1064 (hashtab_key_t) id); 1065 range_start = range_end = cdatum->s.value - 1; 1066 } 1067 1068 for (i = range_start; i <= range_end; i++) { 1069 if (ebitmap_set_bit(&levdatum->level->cat, i, TRUE)) { 1070 yyerror("out of memory"); 1071 free(id); 1072 return -1; 1073 } 1074 } 1075 1076 free(id); 1077 } 1078 1079 if (hashtab_map 1080 (policydbp->p_levels.table, clone_level, levdatum->level)) { 1081 yyerror("out of memory"); 1082 return -1; 1083 } 1084 1085 return 0; 1086} 1087 1088int define_attrib(void) 1089{ 1090 if (pass == 2) { 1091 free(queue_remove(id_queue)); 1092 return 0; 1093 } 1094 1095 if (declare_type(TRUE, TRUE) == NULL) { 1096 return -1; 1097 } 1098 return 0; 1099} 1100 1101static int add_aliases_to_type(type_datum_t * type) 1102{ 1103 char *id; 1104 type_datum_t *aliasdatum = NULL; 1105 int ret; 1106 while ((id = queue_remove(id_queue))) { 1107 if (id_has_dot(id)) { 1108 free(id); 1109 yyerror 1110 ("type alias identifiers may not contain periods"); 1111 return -1; 1112 } 1113 aliasdatum = (type_datum_t *) malloc(sizeof(type_datum_t)); 1114 if (!aliasdatum) { 1115 free(id); 1116 yyerror("Out of memory!"); 1117 return -1; 1118 } 1119 memset(aliasdatum, 0, sizeof(type_datum_t)); 1120 aliasdatum->s.value = type->s.value; 1121 1122 ret = declare_symbol(SYM_TYPES, id, aliasdatum, 1123 NULL, &aliasdatum->s.value); 1124 switch (ret) { 1125 case -3:{ 1126 yyerror("Out of memory!"); 1127 goto cleanup; 1128 } 1129 case -2:{ 1130 yyerror2("duplicate declaration of alias %s", 1131 id); 1132 goto cleanup; 1133 } 1134 case -1:{ 1135 yyerror("could not declare alias here"); 1136 goto cleanup; 1137 } 1138 case 0: break; 1139 case 1:{ 1140 /* ret == 1 means the alias was required and therefore already 1141 * has a value. Set it up as an alias with a different primary. */ 1142 type_datum_destroy(aliasdatum); 1143 free(aliasdatum); 1144 1145 aliasdatum = hashtab_search(policydbp->symtab[SYM_TYPES].table, id); 1146 assert(aliasdatum); 1147 1148 aliasdatum->primary = type->s.value; 1149 aliasdatum->flavor = TYPE_ALIAS; 1150 1151 break; 1152 } 1153 default:{ 1154 assert(0); /* should never get here */ 1155 } 1156 } 1157 } 1158 return 0; 1159 cleanup: 1160 free(id); 1161 type_datum_destroy(aliasdatum); 1162 free(aliasdatum); 1163 return -1; 1164} 1165 1166int define_typealias(void) 1167{ 1168 char *id; 1169 type_datum_t *t; 1170 1171 if (pass == 2) { 1172 while ((id = queue_remove(id_queue))) 1173 free(id); 1174 return 0; 1175 } 1176 1177 id = (char *)queue_remove(id_queue); 1178 if (!id) { 1179 yyerror("no type name for typealias definition?"); 1180 return -1; 1181 } 1182 1183 if (!is_id_in_scope(SYM_TYPES, id)) { 1184 yyerror2("type %s is not within scope", id); 1185 free(id); 1186 return -1; 1187 } 1188 t = hashtab_search(policydbp->p_types.table, id); 1189 if (!t || t->flavor == TYPE_ATTRIB) { 1190 yyerror2("unknown type %s, or it was already declared as an " 1191 "attribute", id); 1192 free(id); 1193 return -1; 1194 } 1195 return add_aliases_to_type(t); 1196} 1197 1198int define_typeattribute(void) 1199{ 1200 char *id; 1201 type_datum_t *t, *attr; 1202 1203 if (pass == 2) { 1204 while ((id = queue_remove(id_queue))) 1205 free(id); 1206 return 0; 1207 } 1208 1209 id = (char *)queue_remove(id_queue); 1210 if (!id) { 1211 yyerror("no type name for typeattribute definition?"); 1212 return -1; 1213 } 1214 1215 if (!is_id_in_scope(SYM_TYPES, id)) { 1216 yyerror2("type %s is not within scope", id); 1217 free(id); 1218 return -1; 1219 } 1220 t = hashtab_search(policydbp->p_types.table, id); 1221 if (!t || t->flavor == TYPE_ATTRIB) { 1222 yyerror2("unknown type %s", id); 1223 free(id); 1224 return -1; 1225 } 1226 1227 while ((id = queue_remove(id_queue))) { 1228 if (!is_id_in_scope(SYM_TYPES, id)) { 1229 yyerror2("attribute %s is not within scope", id); 1230 free(id); 1231 return -1; 1232 } 1233 attr = hashtab_search(policydbp->p_types.table, id); 1234 if (!attr) { 1235 /* treat it as a fatal error */ 1236 yyerror2("attribute %s is not declared", id); 1237 free(id); 1238 return -1; 1239 } 1240 1241 if (attr->flavor != TYPE_ATTRIB) { 1242 yyerror2("%s is a type, not an attribute", id); 1243 free(id); 1244 return -1; 1245 } 1246 1247 if ((attr = get_local_type(id, attr->s.value, 1)) == NULL) { 1248 yyerror("Out of memory!"); 1249 return -1; 1250 } 1251 1252 if (ebitmap_set_bit(&attr->types, (t->s.value - 1), TRUE)) { 1253 yyerror("out of memory"); 1254 return -1; 1255 } 1256 } 1257 1258 return 0; 1259} 1260 1261static int define_typebounds_helper(char *bounds_id, char *type_id) 1262{ 1263 type_datum_t *bounds, *type; 1264 1265 if (!is_id_in_scope(SYM_TYPES, bounds_id)) { 1266 yyerror2("type %s is not within scope", bounds_id); 1267 return -1; 1268 } 1269 1270 bounds = hashtab_search(policydbp->p_types.table, bounds_id); 1271 if (!bounds || bounds->flavor == TYPE_ATTRIB) { 1272 yyerror2("hoge unknown type %s", bounds_id); 1273 return -1; 1274 } 1275 1276 if (!is_id_in_scope(SYM_TYPES, type_id)) { 1277 yyerror2("type %s is not within scope", type_id); 1278 return -1; 1279 } 1280 1281 type = hashtab_search(policydbp->p_types.table, type_id); 1282 if (!type || type->flavor == TYPE_ATTRIB) { 1283 yyerror2("type %s is not declared", type_id); 1284 return -1; 1285 } 1286 1287 if (type->flavor == TYPE_TYPE && !type->primary) { 1288 type = policydbp->type_val_to_struct[type->s.value - 1]; 1289 } else if (type->flavor == TYPE_ALIAS) { 1290 type = policydbp->type_val_to_struct[type->primary - 1]; 1291 } 1292 1293 if (!type->bounds) 1294 type->bounds = bounds->s.value; 1295 else if (type->bounds != bounds->s.value) { 1296 yyerror2("type %s has inconsistent master {%s,%s}", 1297 type_id, 1298 policydbp->p_type_val_to_name[type->bounds - 1], 1299 policydbp->p_type_val_to_name[bounds->s.value - 1]); 1300 return -1; 1301 } 1302 1303 return 0; 1304} 1305 1306int define_typebounds(void) 1307{ 1308 char *bounds, *id; 1309 1310 if (pass == 1) { 1311 while ((id = queue_remove(id_queue))) 1312 free(id); 1313 return 0; 1314 } 1315 1316 bounds = (char *) queue_remove(id_queue); 1317 if (!bounds) { 1318 yyerror("no type name for typebounds definition?"); 1319 return -1; 1320 } 1321 1322 while ((id = queue_remove(id_queue))) { 1323 if (define_typebounds_helper(bounds, id)) 1324 return -1; 1325 free(id); 1326 } 1327 free(bounds); 1328 1329 return 0; 1330} 1331 1332int define_type(int alias) 1333{ 1334 char *id; 1335 type_datum_t *datum, *attr; 1336 1337 if (pass == 2) { 1338 /* 1339 * If type name contains ".", we have to define boundary 1340 * relationship implicitly to keep compatibility with 1341 * old name based hierarchy. 1342 */ 1343 if ((id = queue_remove(id_queue))) { 1344 char *bounds, *delim; 1345 1346 if ((delim = strrchr(id, '.')) 1347 && (bounds = strdup(id))) { 1348 bounds[(size_t)(delim - id)] = '\0'; 1349 1350 if (define_typebounds_helper(bounds, id)) 1351 return -1; 1352 free(bounds); 1353 } 1354 free(id); 1355 } 1356 1357 if (alias) { 1358 while ((id = queue_remove(id_queue))) 1359 free(id); 1360 } 1361 1362 while ((id = queue_remove(id_queue))) 1363 free(id); 1364 return 0; 1365 } 1366 1367 if ((datum = declare_type(TRUE, FALSE)) == NULL) { 1368 return -1; 1369 } 1370 1371 if (alias) { 1372 if (add_aliases_to_type(datum) == -1) { 1373 return -1; 1374 } 1375 } 1376 1377 while ((id = queue_remove(id_queue))) { 1378 if (!is_id_in_scope(SYM_TYPES, id)) { 1379 yyerror2("attribute %s is not within scope", id); 1380 free(id); 1381 return -1; 1382 } 1383 attr = hashtab_search(policydbp->p_types.table, id); 1384 if (!attr) { 1385 /* treat it as a fatal error */ 1386 yyerror2("attribute %s is not declared", id); 1387 return -1; 1388 } 1389 1390 if (attr->flavor != TYPE_ATTRIB) { 1391 yyerror2("%s is a type, not an attribute", id); 1392 return -1; 1393 } 1394 1395 if ((attr = get_local_type(id, attr->s.value, 1)) == NULL) { 1396 yyerror("Out of memory!"); 1397 return -1; 1398 } 1399 1400 if (ebitmap_set_bit(&attr->types, datum->s.value - 1, TRUE)) { 1401 yyerror("Out of memory"); 1402 return -1; 1403 } 1404 } 1405 1406 return 0; 1407} 1408 1409struct val_to_name { 1410 unsigned int val; 1411 char *name; 1412}; 1413 1414/* Adds a type, given by its textual name, to a typeset. If *add is 1415 0, then add the type to the negative set; otherwise if *add is 1 1416 then add it to the positive side. */ 1417static int set_types(type_set_t * set, char *id, int *add, char starallowed) 1418{ 1419 type_datum_t *t; 1420 1421 if (strcmp(id, "*") == 0) { 1422 if (!starallowed) { 1423 yyerror("* not allowed in this type of rule"); 1424 return -1; 1425 } 1426 /* set TYPE_STAR flag */ 1427 set->flags = TYPE_STAR; 1428 free(id); 1429 *add = 1; 1430 return 0; 1431 } 1432 1433 if (strcmp(id, "~") == 0) { 1434 if (!starallowed) { 1435 yyerror("~ not allowed in this type of rule"); 1436 return -1; 1437 } 1438 /* complement the set */ 1439 set->flags = TYPE_COMP; 1440 free(id); 1441 *add = 1; 1442 return 0; 1443 } 1444 1445 if (strcmp(id, "-") == 0) { 1446 *add = 0; 1447 free(id); 1448 return 0; 1449 } 1450 1451 if (!is_id_in_scope(SYM_TYPES, id)) { 1452 yyerror2("type %s is not within scope", id); 1453 free(id); 1454 return -1; 1455 } 1456 t = hashtab_search(policydbp->p_types.table, id); 1457 if (!t) { 1458 yyerror2("unknown type %s", id); 1459 free(id); 1460 return -1; 1461 } 1462 1463 if (*add == 0) { 1464 if (ebitmap_set_bit(&set->negset, t->s.value - 1, TRUE)) 1465 goto oom; 1466 } else { 1467 if (ebitmap_set_bit(&set->types, t->s.value - 1, TRUE)) 1468 goto oom; 1469 } 1470 free(id); 1471 *add = 1; 1472 return 0; 1473 oom: 1474 yyerror("Out of memory"); 1475 free(id); 1476 return -1; 1477} 1478 1479int define_compute_type_helper(int which, avrule_t ** rule) 1480{ 1481 char *id; 1482 type_datum_t *datum; 1483 ebitmap_t tclasses; 1484 ebitmap_node_t *node; 1485 avrule_t *avrule; 1486 class_perm_node_t *perm; 1487 int i, add = 1; 1488 1489 avrule = malloc(sizeof(avrule_t)); 1490 if (!avrule) { 1491 yyerror("out of memory"); 1492 return -1; 1493 } 1494 avrule_init(avrule); 1495 avrule->specified = which; 1496 avrule->line = policydb_lineno; 1497 1498 while ((id = queue_remove(id_queue))) { 1499 if (set_types(&avrule->stypes, id, &add, 0)) 1500 return -1; 1501 } 1502 add = 1; 1503 while ((id = queue_remove(id_queue))) { 1504 if (set_types(&avrule->ttypes, id, &add, 0)) 1505 return -1; 1506 } 1507 1508 ebitmap_init(&tclasses); 1509 if (read_classes(&tclasses)) 1510 goto bad; 1511 1512 id = (char *)queue_remove(id_queue); 1513 if (!id) { 1514 yyerror("no newtype?"); 1515 goto bad; 1516 } 1517 if (!is_id_in_scope(SYM_TYPES, id)) { 1518 yyerror2("type %s is not within scope", id); 1519 free(id); 1520 goto bad; 1521 } 1522 datum = (type_datum_t *) hashtab_search(policydbp->p_types.table, 1523 (hashtab_key_t) id); 1524 if (!datum || datum->flavor == TYPE_ATTRIB) { 1525 yyerror2("unknown type %s", id); 1526 goto bad; 1527 } 1528 1529 ebitmap_for_each_bit(&tclasses, node, i) { 1530 if (ebitmap_node_get_bit(node, i)) { 1531 perm = malloc(sizeof(class_perm_node_t)); 1532 if (!perm) { 1533 yyerror("out of memory"); 1534 return -1; 1535 } 1536 class_perm_node_init(perm); 1537 perm->class = i + 1; 1538 perm->data = datum->s.value; 1539 perm->next = avrule->perms; 1540 avrule->perms = perm; 1541 } 1542 } 1543 ebitmap_destroy(&tclasses); 1544 1545 *rule = avrule; 1546 return 0; 1547 1548 bad: 1549 avrule_destroy(avrule); 1550 free(avrule); 1551 return -1; 1552} 1553 1554int define_compute_type(int which) 1555{ 1556 char *id; 1557 avrule_t *avrule; 1558 1559 if (pass == 1) { 1560 while ((id = queue_remove(id_queue))) 1561 free(id); 1562 while ((id = queue_remove(id_queue))) 1563 free(id); 1564 while ((id = queue_remove(id_queue))) 1565 free(id); 1566 id = queue_remove(id_queue); 1567 free(id); 1568 return 0; 1569 } 1570 1571 if (define_compute_type_helper(which, &avrule)) 1572 return -1; 1573 1574 append_avrule(avrule); 1575 return 0; 1576} 1577 1578avrule_t *define_cond_compute_type(int which) 1579{ 1580 char *id; 1581 avrule_t *avrule; 1582 1583 if (pass == 1) { 1584 while ((id = queue_remove(id_queue))) 1585 free(id); 1586 while ((id = queue_remove(id_queue))) 1587 free(id); 1588 while ((id = queue_remove(id_queue))) 1589 free(id); 1590 id = queue_remove(id_queue); 1591 free(id); 1592 return (avrule_t *) 1; 1593 } 1594 1595 if (define_compute_type_helper(which, &avrule)) 1596 return COND_ERR; 1597 1598 return avrule; 1599} 1600 1601int define_bool_tunable(int is_tunable) 1602{ 1603 char *id, *bool_value; 1604 cond_bool_datum_t *datum; 1605 int ret; 1606 uint32_t value; 1607 1608 if (pass == 2) { 1609 while ((id = queue_remove(id_queue))) 1610 free(id); 1611 return 0; 1612 } 1613 1614 id = (char *)queue_remove(id_queue); 1615 if (!id) { 1616 yyerror("no identifier for bool definition?"); 1617 return -1; 1618 } 1619 if (id_has_dot(id)) { 1620 free(id); 1621 yyerror("boolean identifiers may not contain periods"); 1622 return -1; 1623 } 1624 datum = (cond_bool_datum_t *) malloc(sizeof(cond_bool_datum_t)); 1625 if (!datum) { 1626 yyerror("out of memory"); 1627 free(id); 1628 return -1; 1629 } 1630 memset(datum, 0, sizeof(cond_bool_datum_t)); 1631 if (is_tunable) 1632 datum->flags |= COND_BOOL_FLAGS_TUNABLE; 1633 ret = declare_symbol(SYM_BOOLS, id, datum, &value, &value); 1634 switch (ret) { 1635 case -3:{ 1636 yyerror("Out of memory!"); 1637 goto cleanup; 1638 } 1639 case -2:{ 1640 yyerror2("duplicate declaration of boolean %s", id); 1641 goto cleanup; 1642 } 1643 case -1:{ 1644 yyerror("could not declare boolean here"); 1645 goto cleanup; 1646 } 1647 case 0: 1648 case 1:{ 1649 break; 1650 } 1651 default:{ 1652 assert(0); /* should never get here */ 1653 } 1654 } 1655 datum->s.value = value; 1656 1657 bool_value = (char *)queue_remove(id_queue); 1658 if (!bool_value) { 1659 yyerror("no default value for bool definition?"); 1660 free(id); 1661 return -1; 1662 } 1663 1664 datum->state = (int)(bool_value[0] == 'T') ? 1 : 0; 1665 return 0; 1666 cleanup: 1667 cond_destroy_bool(id, datum, NULL); 1668 return -1; 1669} 1670 1671avrule_t *define_cond_pol_list(avrule_t * avlist, avrule_t * sl) 1672{ 1673 if (pass == 1) { 1674 /* return something so we get through pass 1 */ 1675 return (avrule_t *) 1; 1676 } 1677 1678 if (sl == NULL) { 1679 /* This is a require block, return previous list */ 1680 return avlist; 1681 } 1682 1683 /* prepend the new avlist to the pre-existing one */ 1684 sl->next = avlist; 1685 return sl; 1686} 1687 1688int define_te_avtab_helper(int which, avrule_t ** rule) 1689{ 1690 char *id; 1691 class_datum_t *cladatum; 1692 perm_datum_t *perdatum = NULL; 1693 class_perm_node_t *perms, *tail = NULL, *cur_perms = NULL; 1694 ebitmap_t tclasses; 1695 ebitmap_node_t *node; 1696 avrule_t *avrule; 1697 unsigned int i; 1698 int add = 1, ret = 0; 1699 int suppress = 0; 1700 1701 avrule = (avrule_t *) malloc(sizeof(avrule_t)); 1702 if (!avrule) { 1703 yyerror("memory error"); 1704 ret = -1; 1705 goto out; 1706 } 1707 avrule_init(avrule); 1708 avrule->specified = which; 1709 avrule->line = policydb_lineno; 1710 1711 while ((id = queue_remove(id_queue))) { 1712 if (set_types 1713 (&avrule->stypes, id, &add, 1714 which == AVRULE_NEVERALLOW ? 1 : 0)) { 1715 ret = -1; 1716 goto out; 1717 } 1718 } 1719 add = 1; 1720 while ((id = queue_remove(id_queue))) { 1721 if (strcmp(id, "self") == 0) { 1722 free(id); 1723 avrule->flags |= RULE_SELF; 1724 continue; 1725 } 1726 if (set_types 1727 (&avrule->ttypes, id, &add, 1728 which == AVRULE_NEVERALLOW ? 1 : 0)) { 1729 ret = -1; 1730 goto out; 1731 } 1732 } 1733 1734 ebitmap_init(&tclasses); 1735 ret = read_classes(&tclasses); 1736 if (ret) 1737 goto out; 1738 1739 perms = NULL; 1740 ebitmap_for_each_bit(&tclasses, node, i) { 1741 if (!ebitmap_node_get_bit(node, i)) 1742 continue; 1743 cur_perms = 1744 (class_perm_node_t *) malloc(sizeof(class_perm_node_t)); 1745 if (!cur_perms) { 1746 yyerror("out of memory"); 1747 ret = -1; 1748 goto out; 1749 } 1750 class_perm_node_init(cur_perms); 1751 cur_perms->class = i + 1; 1752 if (!perms) 1753 perms = cur_perms; 1754 if (tail) 1755 tail->next = cur_perms; 1756 tail = cur_perms; 1757 } 1758 1759 while ((id = queue_remove(id_queue))) { 1760 cur_perms = perms; 1761 ebitmap_for_each_bit(&tclasses, node, i) { 1762 if (!ebitmap_node_get_bit(node, i)) 1763 continue; 1764 cladatum = policydbp->class_val_to_struct[i]; 1765 1766 if (strcmp(id, "*") == 0) { 1767 /* set all permissions in the class */ 1768 cur_perms->data = ~0U; 1769 goto next; 1770 } 1771 1772 if (strcmp(id, "~") == 0) { 1773 /* complement the set */ 1774 if (which == AVRULE_DONTAUDIT) 1775 yywarn("dontaudit rule with a ~?"); 1776 cur_perms->data = ~cur_perms->data; 1777 goto next; 1778 } 1779 1780 perdatum = 1781 hashtab_search(cladatum->permissions.table, id); 1782 if (!perdatum) { 1783 if (cladatum->comdatum) { 1784 perdatum = 1785 hashtab_search(cladatum->comdatum-> 1786 permissions.table, 1787 id); 1788 } 1789 } 1790 if (!perdatum) { 1791 if (!suppress) 1792 yyerror2("permission %s is not defined" 1793 " for class %s", id, 1794 policydbp->p_class_val_to_name[i]); 1795 continue; 1796 } else 1797 if (!is_perm_in_scope 1798 (id, policydbp->p_class_val_to_name[i])) { 1799 if (!suppress) { 1800 yyerror2("permission %s of class %s is" 1801 " not within scope", id, 1802 policydbp->p_class_val_to_name[i]); 1803 } 1804 continue; 1805 } else { 1806 cur_perms->data |= 1U << (perdatum->s.value - 1); 1807 } 1808 next: 1809 cur_perms = cur_perms->next; 1810 } 1811 1812 free(id); 1813 } 1814 1815 ebitmap_destroy(&tclasses); 1816 1817 avrule->perms = perms; 1818 *rule = avrule; 1819 1820 out: 1821 return ret; 1822 1823} 1824 1825avrule_t *define_cond_te_avtab(int which) 1826{ 1827 char *id; 1828 avrule_t *avrule; 1829 int i; 1830 1831 if (pass == 1) { 1832 for (i = 0; i < 4; i++) { 1833 while ((id = queue_remove(id_queue))) 1834 free(id); 1835 } 1836 return (avrule_t *) 1; /* any non-NULL value */ 1837 } 1838 1839 if (define_te_avtab_helper(which, &avrule)) 1840 return COND_ERR; 1841 1842 return avrule; 1843} 1844 1845int define_te_avtab(int which) 1846{ 1847 char *id; 1848 avrule_t *avrule; 1849 int i; 1850 1851 if (pass == 1) { 1852 for (i = 0; i < 4; i++) { 1853 while ((id = queue_remove(id_queue))) 1854 free(id); 1855 } 1856 return 0; 1857 } 1858 1859 if (define_te_avtab_helper(which, &avrule)) 1860 return -1; 1861 1862 /* append this avrule to the end of the current rules list */ 1863 append_avrule(avrule); 1864 return 0; 1865} 1866 1867/* The role-types rule is no longer used to declare regular role or 1868 * role attribute, but solely aimed for declaring role-types associations. 1869 */ 1870int define_role_types(void) 1871{ 1872 role_datum_t *role; 1873 char *id; 1874 int add = 1; 1875 1876 if (pass == 1) { 1877 while ((id = queue_remove(id_queue))) 1878 free(id); 1879 return 0; 1880 } 1881 1882 id = (char *)queue_remove(id_queue); 1883 if (!id) { 1884 yyerror("no role name for role-types rule?"); 1885 return -1; 1886 } 1887 1888 if (!is_id_in_scope(SYM_ROLES, id)) { 1889 yyerror2("role %s is not within scope", id); 1890 free(id); 1891 return -1; 1892 } 1893 1894 role = hashtab_search(policydbp->p_roles.table, id); 1895 if (!role) { 1896 yyerror2("unknown role %s", id); 1897 free(id); 1898 return -1; 1899 } 1900 1901 while ((id = queue_remove(id_queue))) { 1902 if (set_types(&role->types, id, &add, 0)) 1903 return -1; 1904 } 1905 1906 return 0; 1907} 1908 1909int define_attrib_role(void) 1910{ 1911 if (pass == 2) { 1912 free(queue_remove(id_queue)); 1913 return 0; 1914 } 1915 1916 /* Declare a role attribute */ 1917 if (declare_role(TRUE) == NULL) 1918 return -1; 1919 1920 return 0; 1921} 1922 1923int define_role_attr(void) 1924{ 1925 char *id; 1926 role_datum_t *r, *attr; 1927 1928 if (pass == 2) { 1929 while ((id = queue_remove(id_queue))) 1930 free(id); 1931 return 0; 1932 } 1933 1934 /* Declare a regular role */ 1935 if ((r = declare_role(FALSE)) == NULL) 1936 return -1; 1937 1938 while ((id = queue_remove(id_queue))) { 1939 if (!is_id_in_scope(SYM_ROLES, id)) { 1940 yyerror2("attribute %s is not within scope", id); 1941 free(id); 1942 return -1; 1943 } 1944 attr = hashtab_search(policydbp->p_roles.table, id); 1945 if (!attr) { 1946 /* treat it as a fatal error */ 1947 yyerror2("role attribute %s is not declared", id); 1948 free(id); 1949 return -1; 1950 } 1951 1952 if (attr->flavor != ROLE_ATTRIB) { 1953 yyerror2("%s is a regular role, not an attribute", id); 1954 free(id); 1955 return -1; 1956 } 1957 1958 if ((attr = get_local_role(id, attr->s.value, 1)) == NULL) { 1959 yyerror("Out of memory!"); 1960 return -1; 1961 } 1962 1963 if (ebitmap_set_bit(&attr->roles, (r->s.value - 1), TRUE)) { 1964 yyerror("out of memory"); 1965 return -1; 1966 } 1967 } 1968 1969 return 0; 1970} 1971 1972int define_roleattribute(void) 1973{ 1974 char *id; 1975 role_datum_t *r, *attr; 1976 1977 if (pass == 2) { 1978 while ((id = queue_remove(id_queue))) 1979 free(id); 1980 return 0; 1981 } 1982 1983 id = (char *)queue_remove(id_queue); 1984 if (!id) { 1985 yyerror("no role name for roleattribute definition?"); 1986 return -1; 1987 } 1988 1989 if (!is_id_in_scope(SYM_ROLES, id)) { 1990 yyerror2("role %s is not within scope", id); 1991 free(id); 1992 return -1; 1993 } 1994 r = hashtab_search(policydbp->p_roles.table, id); 1995 /* We support adding one role attribute into another */ 1996 if (!r) { 1997 yyerror2("unknown role %s", id); 1998 free(id); 1999 return -1; 2000 } 2001 2002 while ((id = queue_remove(id_queue))) { 2003 if (!is_id_in_scope(SYM_ROLES, id)) { 2004 yyerror2("attribute %s is not within scope", id); 2005 free(id); 2006 return -1; 2007 } 2008 attr = hashtab_search(policydbp->p_roles.table, id); 2009 if (!attr) { 2010 /* treat it as a fatal error */ 2011 yyerror2("role attribute %s is not declared", id); 2012 free(id); 2013 return -1; 2014 } 2015 2016 if (attr->flavor != ROLE_ATTRIB) { 2017 yyerror2("%s is a regular role, not an attribute", id); 2018 free(id); 2019 return -1; 2020 } 2021 2022 if ((attr = get_local_role(id, attr->s.value, 1)) == NULL) { 2023 yyerror("Out of memory!"); 2024 return -1; 2025 } 2026 2027 if (ebitmap_set_bit(&attr->roles, (r->s.value - 1), TRUE)) { 2028 yyerror("out of memory"); 2029 return -1; 2030 } 2031 } 2032 2033 return 0; 2034} 2035 2036role_datum_t *merge_roles_dom(role_datum_t * r1, role_datum_t * r2) 2037{ 2038 role_datum_t *new; 2039 2040 if (pass == 1) { 2041 return (role_datum_t *) 1; /* any non-NULL value */ 2042 } 2043 2044 new = malloc(sizeof(role_datum_t)); 2045 if (!new) { 2046 yyerror("out of memory"); 2047 return NULL; 2048 } 2049 memset(new, 0, sizeof(role_datum_t)); 2050 new->s.value = 0; /* temporary role */ 2051 if (ebitmap_or(&new->dominates, &r1->dominates, &r2->dominates)) { 2052 yyerror("out of memory"); 2053 return NULL; 2054 } 2055 if (ebitmap_or(&new->types.types, &r1->types.types, &r2->types.types)) { 2056 yyerror("out of memory"); 2057 return NULL; 2058 } 2059 if (!r1->s.value) { 2060 /* free intermediate result */ 2061 type_set_destroy(&r1->types); 2062 ebitmap_destroy(&r1->dominates); 2063 free(r1); 2064 } 2065 if (!r2->s.value) { 2066 /* free intermediate result */ 2067 yyerror("right hand role is temporary?"); 2068 type_set_destroy(&r2->types); 2069 ebitmap_destroy(&r2->dominates); 2070 free(r2); 2071 } 2072 return new; 2073} 2074 2075/* This function eliminates the ordering dependency of role dominance rule */ 2076static int dominate_role_recheck(hashtab_key_t key, hashtab_datum_t datum, 2077 void *arg) 2078{ 2079 role_datum_t *rdp = (role_datum_t *) arg; 2080 role_datum_t *rdatum = (role_datum_t *) datum; 2081 ebitmap_node_t *node; 2082 int i; 2083 2084 /* Don't bother to process against self role */ 2085 if (rdatum->s.value == rdp->s.value) 2086 return 0; 2087 2088 /* If a dominating role found */ 2089 if (ebitmap_get_bit(&(rdatum->dominates), rdp->s.value - 1)) { 2090 ebitmap_t types; 2091 ebitmap_init(&types); 2092 if (type_set_expand(&rdp->types, &types, policydbp, 1)) { 2093 ebitmap_destroy(&types); 2094 return -1; 2095 } 2096 /* raise types and dominates from dominated role */ 2097 ebitmap_for_each_bit(&rdp->dominates, node, i) { 2098 if (ebitmap_node_get_bit(node, i)) 2099 if (ebitmap_set_bit 2100 (&rdatum->dominates, i, TRUE)) 2101 goto oom; 2102 } 2103 ebitmap_for_each_bit(&types, node, i) { 2104 if (ebitmap_node_get_bit(node, i)) 2105 if (ebitmap_set_bit 2106 (&rdatum->types.types, i, TRUE)) 2107 goto oom; 2108 } 2109 ebitmap_destroy(&types); 2110 } 2111 2112 /* go through all the roles */ 2113 return 0; 2114 oom: 2115 yyerror("Out of memory"); 2116 return -1; 2117} 2118 2119role_datum_t *define_role_dom(role_datum_t * r) 2120{ 2121 role_datum_t *role; 2122 char *role_id; 2123 ebitmap_node_t *node; 2124 unsigned int i; 2125 int ret; 2126 2127 if (pass == 1) { 2128 role_id = queue_remove(id_queue); 2129 free(role_id); 2130 return (role_datum_t *) 1; /* any non-NULL value */ 2131 } 2132 2133 yywarn("Role dominance has been deprecated"); 2134 2135 role_id = queue_remove(id_queue); 2136 if (!is_id_in_scope(SYM_ROLES, role_id)) { 2137 yyerror2("role %s is not within scope", role_id); 2138 free(role_id); 2139 return NULL; 2140 } 2141 role = (role_datum_t *) hashtab_search(policydbp->p_roles.table, 2142 role_id); 2143 if (!role) { 2144 role = (role_datum_t *) malloc(sizeof(role_datum_t)); 2145 if (!role) { 2146 yyerror("out of memory"); 2147 free(role_id); 2148 return NULL; 2149 } 2150 memset(role, 0, sizeof(role_datum_t)); 2151 ret = 2152 declare_symbol(SYM_ROLES, (hashtab_key_t) role_id, 2153 (hashtab_datum_t) role, &role->s.value, 2154 &role->s.value); 2155 switch (ret) { 2156 case -3:{ 2157 yyerror("Out of memory!"); 2158 goto cleanup; 2159 } 2160 case -2:{ 2161 yyerror2("duplicate declaration of role %s", 2162 role_id); 2163 goto cleanup; 2164 } 2165 case -1:{ 2166 yyerror("could not declare role here"); 2167 goto cleanup; 2168 } 2169 case 0: 2170 case 1:{ 2171 break; 2172 } 2173 default:{ 2174 assert(0); /* should never get here */ 2175 } 2176 } 2177 if (ebitmap_set_bit(&role->dominates, role->s.value - 1, TRUE)) { 2178 yyerror("Out of memory!"); 2179 goto cleanup; 2180 } 2181 } 2182 if (r) { 2183 ebitmap_t types; 2184 ebitmap_init(&types); 2185 ebitmap_for_each_bit(&r->dominates, node, i) { 2186 if (ebitmap_node_get_bit(node, i)) 2187 if (ebitmap_set_bit(&role->dominates, i, TRUE)) 2188 goto oom; 2189 } 2190 if (type_set_expand(&r->types, &types, policydbp, 1)) { 2191 ebitmap_destroy(&types); 2192 return NULL; 2193 } 2194 ebitmap_for_each_bit(&types, node, i) { 2195 if (ebitmap_node_get_bit(node, i)) 2196 if (ebitmap_set_bit 2197 (&role->types.types, i, TRUE)) 2198 goto oom; 2199 } 2200 ebitmap_destroy(&types); 2201 if (!r->s.value) { 2202 /* free intermediate result */ 2203 type_set_destroy(&r->types); 2204 ebitmap_destroy(&r->dominates); 2205 free(r); 2206 } 2207 /* 2208 * Now go through all the roles and escalate this role's 2209 * dominates and types if a role dominates this role. 2210 */ 2211 hashtab_map(policydbp->p_roles.table, 2212 dominate_role_recheck, role); 2213 } 2214 return role; 2215 cleanup: 2216 free(role_id); 2217 role_datum_destroy(role); 2218 free(role); 2219 return NULL; 2220 oom: 2221 yyerror("Out of memory"); 2222 goto cleanup; 2223} 2224 2225static int role_val_to_name_helper(hashtab_key_t key, hashtab_datum_t datum, 2226 void *p) 2227{ 2228 struct val_to_name *v = p; 2229 role_datum_t *roldatum; 2230 2231 roldatum = (role_datum_t *) datum; 2232 2233 if (v->val == roldatum->s.value) { 2234 v->name = key; 2235 return 1; 2236 } 2237 2238 return 0; 2239} 2240 2241static char *role_val_to_name(unsigned int val) 2242{ 2243 struct val_to_name v; 2244 int rc; 2245 2246 v.val = val; 2247 rc = hashtab_map(policydbp->p_roles.table, role_val_to_name_helper, &v); 2248 if (rc) 2249 return v.name; 2250 return NULL; 2251} 2252 2253static int set_roles(role_set_t * set, char *id) 2254{ 2255 role_datum_t *r; 2256 2257 if (strcmp(id, "*") == 0) { 2258 free(id); 2259 yyerror("* is not allowed for role sets"); 2260 return -1; 2261 } 2262 2263 if (strcmp(id, "~") == 0) { 2264 free(id); 2265 yyerror("~ is not allowed for role sets"); 2266 return -1; 2267 } 2268 if (!is_id_in_scope(SYM_ROLES, id)) { 2269 yyerror2("role %s is not within scope", id); 2270 free(id); 2271 return -1; 2272 } 2273 r = hashtab_search(policydbp->p_roles.table, id); 2274 if (!r) { 2275 yyerror2("unknown role %s", id); 2276 free(id); 2277 return -1; 2278 } 2279 2280 if (ebitmap_set_bit(&set->roles, r->s.value - 1, TRUE)) { 2281 yyerror("out of memory"); 2282 free(id); 2283 return -1; 2284 } 2285 free(id); 2286 return 0; 2287} 2288 2289int define_role_trans(int class_specified) 2290{ 2291 char *id; 2292 role_datum_t *role; 2293 role_set_t roles; 2294 type_set_t types; 2295 class_datum_t *cladatum; 2296 ebitmap_t e_types, e_roles, e_classes; 2297 ebitmap_node_t *tnode, *rnode, *cnode; 2298 struct role_trans *tr = NULL; 2299 struct role_trans_rule *rule = NULL; 2300 unsigned int i, j, k; 2301 int add = 1; 2302 2303 if (pass == 1) { 2304 while ((id = queue_remove(id_queue))) 2305 free(id); 2306 while ((id = queue_remove(id_queue))) 2307 free(id); 2308 if (class_specified) 2309 while ((id = queue_remove(id_queue))) 2310 free(id); 2311 id = queue_remove(id_queue); 2312 free(id); 2313 return 0; 2314 } 2315 2316 role_set_init(&roles); 2317 ebitmap_init(&e_roles); 2318 type_set_init(&types); 2319 ebitmap_init(&e_types); 2320 ebitmap_init(&e_classes); 2321 2322 while ((id = queue_remove(id_queue))) { 2323 if (set_roles(&roles, id)) 2324 return -1; 2325 } 2326 add = 1; 2327 while ((id = queue_remove(id_queue))) { 2328 if (set_types(&types, id, &add, 0)) 2329 return -1; 2330 } 2331 2332 if (class_specified) { 2333 if (read_classes(&e_classes)) 2334 return -1; 2335 } else { 2336 cladatum = hashtab_search(policydbp->p_classes.table, 2337 "process"); 2338 if (!cladatum) { 2339 yyerror2("could not find process class for " 2340 "legacy role_transition statement"); 2341 return -1; 2342 } 2343 2344 ebitmap_set_bit(&e_classes, cladatum->s.value - 1, TRUE); 2345 } 2346 2347 id = (char *)queue_remove(id_queue); 2348 if (!id) { 2349 yyerror("no new role in transition definition?"); 2350 goto bad; 2351 } 2352 if (!is_id_in_scope(SYM_ROLES, id)) { 2353 yyerror2("role %s is not within scope", id); 2354 free(id); 2355 goto bad; 2356 } 2357 role = hashtab_search(policydbp->p_roles.table, id); 2358 if (!role) { 2359 yyerror2("unknown role %s used in transition definition", id); 2360 goto bad; 2361 } 2362 2363 if (role->flavor != ROLE_ROLE) { 2364 yyerror2("the new role %s must be a regular role", id); 2365 goto bad; 2366 } 2367 2368 /* This ebitmap business is just to ensure that there are not conflicting role_trans rules */ 2369 if (role_set_expand(&roles, &e_roles, policydbp, NULL, NULL)) 2370 goto bad; 2371 2372 if (type_set_expand(&types, &e_types, policydbp, 1)) 2373 goto bad; 2374 2375 ebitmap_for_each_bit(&e_roles, rnode, i) { 2376 if (!ebitmap_node_get_bit(rnode, i)) 2377 continue; 2378 ebitmap_for_each_bit(&e_types, tnode, j) { 2379 if (!ebitmap_node_get_bit(tnode, j)) 2380 continue; 2381 ebitmap_for_each_bit(&e_classes, cnode, k) { 2382 if (!ebitmap_node_get_bit(cnode, k)) 2383 continue; 2384 for (tr = policydbp->role_tr; tr; 2385 tr = tr->next) { 2386 if (tr->role == (i + 1) && 2387 tr->type == (j + 1) && 2388 tr->tclass == (k + 1)) { 2389 yyerror2("duplicate role " 2390 "transition for " 2391 "(%s,%s,%s)", 2392 role_val_to_name(i+1), 2393 policydbp->p_type_val_to_name[j], 2394 policydbp->p_class_val_to_name[k]); 2395 goto bad; 2396 } 2397 } 2398 2399 tr = malloc(sizeof(struct role_trans)); 2400 if (!tr) { 2401 yyerror("out of memory"); 2402 return -1; 2403 } 2404 memset(tr, 0, sizeof(struct role_trans)); 2405 tr->role = i + 1; 2406 tr->type = j + 1; 2407 tr->tclass = k + 1; 2408 tr->new_role = role->s.value; 2409 tr->next = policydbp->role_tr; 2410 policydbp->role_tr = tr; 2411 } 2412 } 2413 } 2414 /* Now add the real rule */ 2415 rule = malloc(sizeof(struct role_trans_rule)); 2416 if (!rule) { 2417 yyerror("out of memory"); 2418 return -1; 2419 } 2420 memset(rule, 0, sizeof(struct role_trans_rule)); 2421 rule->roles = roles; 2422 rule->types = types; 2423 rule->classes = e_classes; 2424 rule->new_role = role->s.value; 2425 2426 append_role_trans(rule); 2427 2428 ebitmap_destroy(&e_roles); 2429 ebitmap_destroy(&e_types); 2430 2431 return 0; 2432 2433 bad: 2434 return -1; 2435} 2436 2437int define_role_allow(void) 2438{ 2439 char *id; 2440 struct role_allow_rule *ra = 0; 2441 2442 if (pass == 1) { 2443 while ((id = queue_remove(id_queue))) 2444 free(id); 2445 while ((id = queue_remove(id_queue))) 2446 free(id); 2447 return 0; 2448 } 2449 2450 ra = malloc(sizeof(role_allow_rule_t)); 2451 if (!ra) { 2452 yyerror("out of memory"); 2453 return -1; 2454 } 2455 role_allow_rule_init(ra); 2456 2457 while ((id = queue_remove(id_queue))) { 2458 if (set_roles(&ra->roles, id)) 2459 return -1; 2460 } 2461 2462 while ((id = queue_remove(id_queue))) { 2463 if (set_roles(&ra->new_roles, id)) 2464 return -1; 2465 } 2466 2467 append_role_allow(ra); 2468 return 0; 2469} 2470 2471avrule_t *define_cond_filename_trans(void) 2472{ 2473 yyerror("type transitions with a filename not allowed inside " 2474 "conditionals\n"); 2475 return COND_ERR; 2476} 2477 2478int define_filename_trans(void) 2479{ 2480 char *id, *name = NULL; 2481 type_set_t stypes, ttypes; 2482 ebitmap_t e_stypes, e_ttypes; 2483 ebitmap_t e_tclasses; 2484 ebitmap_node_t *snode, *tnode, *cnode; 2485 filename_trans_t *ft; 2486 filename_trans_rule_t *ftr; 2487 type_datum_t *typdatum; 2488 uint32_t otype; 2489 unsigned int c, s, t; 2490 int add; 2491 2492 if (pass == 1) { 2493 /* stype */ 2494 while ((id = queue_remove(id_queue))) 2495 free(id); 2496 /* ttype */ 2497 while ((id = queue_remove(id_queue))) 2498 free(id); 2499 /* tclass */ 2500 while ((id = queue_remove(id_queue))) 2501 free(id); 2502 /* otype */ 2503 id = queue_remove(id_queue); 2504 free(id); 2505 /* name */ 2506 id = queue_remove(id_queue); 2507 free(id); 2508 return 0; 2509 } 2510 2511 2512 add = 1; 2513 type_set_init(&stypes); 2514 while ((id = queue_remove(id_queue))) { 2515 if (set_types(&stypes, id, &add, 0)) 2516 goto bad; 2517 } 2518 2519 add =1; 2520 type_set_init(&ttypes); 2521 while ((id = queue_remove(id_queue))) { 2522 if (set_types(&ttypes, id, &add, 0)) 2523 goto bad; 2524 } 2525 2526 ebitmap_init(&e_tclasses); 2527 if (read_classes(&e_tclasses)) 2528 goto bad; 2529 2530 id = (char *)queue_remove(id_queue); 2531 if (!id) { 2532 yyerror("no otype in transition definition?"); 2533 goto bad; 2534 } 2535 if (!is_id_in_scope(SYM_TYPES, id)) { 2536 yyerror2("type %s is not within scope", id); 2537 free(id); 2538 goto bad; 2539 } 2540 typdatum = hashtab_search(policydbp->p_types.table, id); 2541 if (!typdatum) { 2542 yyerror2("unknown type %s used in transition definition", id); 2543 goto bad; 2544 } 2545 free(id); 2546 otype = typdatum->s.value; 2547 2548 name = queue_remove(id_queue); 2549 if (!name) { 2550 yyerror("no pathname specified in filename_trans definition?"); 2551 goto bad; 2552 } 2553 2554 /* We expand the class set into seperate rules. We expand the types 2555 * just to make sure there are not duplicates. They will get turned 2556 * into seperate rules later */ 2557 ebitmap_init(&e_stypes); 2558 if (type_set_expand(&stypes, &e_stypes, policydbp, 1)) 2559 goto bad; 2560 2561 ebitmap_init(&e_ttypes); 2562 if (type_set_expand(&ttypes, &e_ttypes, policydbp, 1)) 2563 goto bad; 2564 2565 ebitmap_for_each_bit(&e_tclasses, cnode, c) { 2566 if (!ebitmap_node_get_bit(cnode, c)) 2567 continue; 2568 ebitmap_for_each_bit(&e_stypes, snode, s) { 2569 if (!ebitmap_node_get_bit(snode, s)) 2570 continue; 2571 ebitmap_for_each_bit(&e_ttypes, tnode, t) { 2572 if (!ebitmap_node_get_bit(tnode, t)) 2573 continue; 2574 2575 for (ft = policydbp->filename_trans; ft; ft = ft->next) { 2576 if (ft->stype == (s + 1) && 2577 ft->ttype == (t + 1) && 2578 ft->tclass == (c + 1) && 2579 !strcmp(ft->name, name)) { 2580 yyerror2("duplicate filename transition for: filename_trans %s %s %s:%s", 2581 name, 2582 policydbp->p_type_val_to_name[s], 2583 policydbp->p_type_val_to_name[t], 2584 policydbp->p_class_val_to_name[c]); 2585 goto bad; 2586 } 2587 } 2588 2589 ft = malloc(sizeof(*ft)); 2590 if (!ft) { 2591 yyerror("out of memory"); 2592 goto bad; 2593 } 2594 memset(ft, 0, sizeof(*ft)); 2595 2596 ft->next = policydbp->filename_trans; 2597 policydbp->filename_trans = ft; 2598 2599 ft->name = strdup(name); 2600 if (!ft->name) { 2601 yyerror("out of memory"); 2602 goto bad; 2603 } 2604 ft->stype = s + 1; 2605 ft->ttype = t + 1; 2606 ft->tclass = c + 1; 2607 ft->otype = otype; 2608 } 2609 } 2610 2611 /* Now add the real rule since we didn't find any duplicates */ 2612 ftr = malloc(sizeof(*ftr)); 2613 if (!ftr) { 2614 yyerror("out of memory"); 2615 goto bad; 2616 } 2617 filename_trans_rule_init(ftr); 2618 append_filename_trans(ftr); 2619 2620 ftr->name = strdup(name); 2621 ftr->stypes = stypes; 2622 ftr->ttypes = ttypes; 2623 ftr->tclass = c + 1; 2624 ftr->otype = otype; 2625 } 2626 2627 free(name); 2628 ebitmap_destroy(&e_stypes); 2629 ebitmap_destroy(&e_ttypes); 2630 ebitmap_destroy(&e_tclasses); 2631 2632 return 0; 2633 2634bad: 2635 free(name); 2636 return -1; 2637} 2638 2639static constraint_expr_t *constraint_expr_clone(constraint_expr_t * expr) 2640{ 2641 constraint_expr_t *h = NULL, *l = NULL, *e, *newe; 2642 for (e = expr; e; e = e->next) { 2643 newe = malloc(sizeof(*newe)); 2644 if (!newe) 2645 goto oom; 2646 if (constraint_expr_init(newe) == -1) { 2647 free(newe); 2648 goto oom; 2649 } 2650 if (l) 2651 l->next = newe; 2652 else 2653 h = newe; 2654 l = newe; 2655 newe->expr_type = e->expr_type; 2656 newe->attr = e->attr; 2657 newe->op = e->op; 2658 if (newe->expr_type == CEXPR_NAMES) { 2659 if (newe->attr & CEXPR_TYPE) { 2660 if (type_set_cpy 2661 (newe->type_names, e->type_names)) 2662 goto oom; 2663 } else { 2664 if (ebitmap_cpy(&newe->names, &e->names)) 2665 goto oom; 2666 } 2667 } 2668 } 2669 2670 return h; 2671 oom: 2672 e = h; 2673 while (e) { 2674 l = e; 2675 e = e->next; 2676 constraint_expr_destroy(l); 2677 } 2678 return NULL; 2679} 2680 2681int define_constraint(constraint_expr_t * expr) 2682{ 2683 struct constraint_node *node; 2684 char *id; 2685 class_datum_t *cladatum; 2686 perm_datum_t *perdatum; 2687 ebitmap_t classmap; 2688 ebitmap_node_t *enode; 2689 constraint_expr_t *e; 2690 unsigned int i; 2691 int depth; 2692 unsigned char useexpr = 1; 2693 2694 if (pass == 1) { 2695 while ((id = queue_remove(id_queue))) 2696 free(id); 2697 while ((id = queue_remove(id_queue))) 2698 free(id); 2699 return 0; 2700 } 2701 2702 depth = -1; 2703 for (e = expr; e; e = e->next) { 2704 switch (e->expr_type) { 2705 case CEXPR_NOT: 2706 if (depth < 0) { 2707 yyerror("illegal constraint expression"); 2708 return -1; 2709 } 2710 break; 2711 case CEXPR_AND: 2712 case CEXPR_OR: 2713 if (depth < 1) { 2714 yyerror("illegal constraint expression"); 2715 return -1; 2716 } 2717 depth--; 2718 break; 2719 case CEXPR_ATTR: 2720 case CEXPR_NAMES: 2721 if (e->attr & CEXPR_XTARGET) { 2722 yyerror("illegal constraint expression"); 2723 return -1; /* only for validatetrans rules */ 2724 } 2725 if (depth == (CEXPR_MAXDEPTH - 1)) { 2726 yyerror("constraint expression is too deep"); 2727 return -1; 2728 } 2729 depth++; 2730 break; 2731 default: 2732 yyerror("illegal constraint expression"); 2733 return -1; 2734 } 2735 } 2736 if (depth != 0) { 2737 yyerror("illegal constraint expression"); 2738 return -1; 2739 } 2740 2741 ebitmap_init(&classmap); 2742 while ((id = queue_remove(id_queue))) { 2743 if (!is_id_in_scope(SYM_CLASSES, id)) { 2744 yyerror2("class %s is not within scope", id); 2745 free(id); 2746 return -1; 2747 } 2748 cladatum = 2749 (class_datum_t *) hashtab_search(policydbp->p_classes.table, 2750 (hashtab_key_t) id); 2751 if (!cladatum) { 2752 yyerror2("class %s is not defined", id); 2753 ebitmap_destroy(&classmap); 2754 free(id); 2755 return -1; 2756 } 2757 if (ebitmap_set_bit(&classmap, cladatum->s.value - 1, TRUE)) { 2758 yyerror("out of memory"); 2759 ebitmap_destroy(&classmap); 2760 free(id); 2761 return -1; 2762 } 2763 node = malloc(sizeof(struct constraint_node)); 2764 if (!node) { 2765 yyerror("out of memory"); 2766 return -1; 2767 } 2768 memset(node, 0, sizeof(constraint_node_t)); 2769 if (useexpr) { 2770 node->expr = expr; 2771 useexpr = 0; 2772 } else { 2773 node->expr = constraint_expr_clone(expr); 2774 } 2775 if (!node->expr) { 2776 yyerror("out of memory"); 2777 return -1; 2778 } 2779 node->permissions = 0; 2780 2781 node->next = cladatum->constraints; 2782 cladatum->constraints = node; 2783 2784 free(id); 2785 } 2786 2787 while ((id = queue_remove(id_queue))) { 2788 ebitmap_for_each_bit(&classmap, enode, i) { 2789 if (ebitmap_node_get_bit(enode, i)) { 2790 cladatum = policydbp->class_val_to_struct[i]; 2791 node = cladatum->constraints; 2792 2793 perdatum = 2794 (perm_datum_t *) hashtab_search(cladatum-> 2795 permissions. 2796 table, 2797 (hashtab_key_t) 2798 id); 2799 if (!perdatum) { 2800 if (cladatum->comdatum) { 2801 perdatum = 2802 (perm_datum_t *) 2803 hashtab_search(cladatum-> 2804 comdatum-> 2805 permissions. 2806 table, 2807 (hashtab_key_t) 2808 id); 2809 } 2810 if (!perdatum) { 2811 yyerror2("permission %s is not" 2812 " defined", id); 2813 free(id); 2814 ebitmap_destroy(&classmap); 2815 return -1; 2816 } 2817 } 2818 node->permissions |= 2819 (1 << (perdatum->s.value - 1)); 2820 } 2821 } 2822 free(id); 2823 } 2824 2825 ebitmap_destroy(&classmap); 2826 2827 return 0; 2828} 2829 2830int define_validatetrans(constraint_expr_t * expr) 2831{ 2832 struct constraint_node *node; 2833 char *id; 2834 class_datum_t *cladatum; 2835 ebitmap_t classmap; 2836 constraint_expr_t *e; 2837 int depth; 2838 unsigned char useexpr = 1; 2839 2840 if (pass == 1) { 2841 while ((id = queue_remove(id_queue))) 2842 free(id); 2843 return 0; 2844 } 2845 2846 depth = -1; 2847 for (e = expr; e; e = e->next) { 2848 switch (e->expr_type) { 2849 case CEXPR_NOT: 2850 if (depth < 0) { 2851 yyerror("illegal validatetrans expression"); 2852 return -1; 2853 } 2854 break; 2855 case CEXPR_AND: 2856 case CEXPR_OR: 2857 if (depth < 1) { 2858 yyerror("illegal validatetrans expression"); 2859 return -1; 2860 } 2861 depth--; 2862 break; 2863 case CEXPR_ATTR: 2864 case CEXPR_NAMES: 2865 if (depth == (CEXPR_MAXDEPTH - 1)) { 2866 yyerror("validatetrans expression is too deep"); 2867 return -1; 2868 } 2869 depth++; 2870 break; 2871 default: 2872 yyerror("illegal validatetrans expression"); 2873 return -1; 2874 } 2875 } 2876 if (depth != 0) { 2877 yyerror("illegal validatetrans expression"); 2878 return -1; 2879 } 2880 2881 ebitmap_init(&classmap); 2882 while ((id = queue_remove(id_queue))) { 2883 if (!is_id_in_scope(SYM_CLASSES, id)) { 2884 yyerror2("class %s is not within scope", id); 2885 free(id); 2886 return -1; 2887 } 2888 cladatum = 2889 (class_datum_t *) hashtab_search(policydbp->p_classes.table, 2890 (hashtab_key_t) id); 2891 if (!cladatum) { 2892 yyerror2("class %s is not defined", id); 2893 ebitmap_destroy(&classmap); 2894 free(id); 2895 return -1; 2896 } 2897 if (ebitmap_set_bit(&classmap, (cladatum->s.value - 1), TRUE)) { 2898 yyerror("out of memory"); 2899 ebitmap_destroy(&classmap); 2900 free(id); 2901 return -1; 2902 } 2903 2904 node = malloc(sizeof(struct constraint_node)); 2905 if (!node) { 2906 yyerror("out of memory"); 2907 return -1; 2908 } 2909 memset(node, 0, sizeof(constraint_node_t)); 2910 if (useexpr) { 2911 node->expr = expr; 2912 useexpr = 0; 2913 } else { 2914 node->expr = constraint_expr_clone(expr); 2915 } 2916 node->permissions = 0; 2917 2918 node->next = cladatum->validatetrans; 2919 cladatum->validatetrans = node; 2920 2921 free(id); 2922 } 2923 2924 ebitmap_destroy(&classmap); 2925 2926 return 0; 2927} 2928 2929uintptr_t define_cexpr(uint32_t expr_type, uintptr_t arg1, uintptr_t arg2) 2930{ 2931 struct constraint_expr *expr, *e1 = NULL, *e2; 2932 user_datum_t *user; 2933 role_datum_t *role; 2934 ebitmap_t negset; 2935 char *id; 2936 uint32_t val; 2937 int add = 1; 2938 2939 if (pass == 1) { 2940 if (expr_type == CEXPR_NAMES) { 2941 while ((id = queue_remove(id_queue))) 2942 free(id); 2943 } 2944 return 1; /* any non-NULL value */ 2945 } 2946 2947 if ((expr = malloc(sizeof(*expr))) == NULL || 2948 constraint_expr_init(expr) == -1) { 2949 yyerror("out of memory"); 2950 free(expr); 2951 return 0; 2952 } 2953 expr->expr_type = expr_type; 2954 2955 switch (expr_type) { 2956 case CEXPR_NOT: 2957 e1 = NULL; 2958 e2 = (struct constraint_expr *)arg1; 2959 while (e2) { 2960 e1 = e2; 2961 e2 = e2->next; 2962 } 2963 if (!e1 || e1->next) { 2964 yyerror("illegal constraint expression"); 2965 constraint_expr_destroy(expr); 2966 return 0; 2967 } 2968 e1->next = expr; 2969 return arg1; 2970 case CEXPR_AND: 2971 case CEXPR_OR: 2972 e1 = NULL; 2973 e2 = (struct constraint_expr *)arg1; 2974 while (e2) { 2975 e1 = e2; 2976 e2 = e2->next; 2977 } 2978 if (!e1 || e1->next) { 2979 yyerror("illegal constraint expression"); 2980 constraint_expr_destroy(expr); 2981 return 0; 2982 } 2983 e1->next = (struct constraint_expr *)arg2; 2984 2985 e1 = NULL; 2986 e2 = (struct constraint_expr *)arg2; 2987 while (e2) { 2988 e1 = e2; 2989 e2 = e2->next; 2990 } 2991 if (!e1 || e1->next) { 2992 yyerror("illegal constraint expression"); 2993 constraint_expr_destroy(expr); 2994 return 0; 2995 } 2996 e1->next = expr; 2997 return arg1; 2998 case CEXPR_ATTR: 2999 expr->attr = arg1; 3000 expr->op = arg2; 3001 return (uintptr_t) expr; 3002 case CEXPR_NAMES: 3003 add = 1; 3004 expr->attr = arg1; 3005 expr->op = arg2; 3006 ebitmap_init(&negset); 3007 while ((id = (char *)queue_remove(id_queue))) { 3008 if (expr->attr & CEXPR_USER) { 3009 if (!is_id_in_scope(SYM_USERS, id)) { 3010 yyerror2("user %s is not within scope", 3011 id); 3012 constraint_expr_destroy(expr); 3013 return 0; 3014 } 3015 user = 3016 (user_datum_t *) hashtab_search(policydbp-> 3017 p_users. 3018 table, 3019 (hashtab_key_t) 3020 id); 3021 if (!user) { 3022 yyerror2("unknown user %s", id); 3023 constraint_expr_destroy(expr); 3024 return 0; 3025 } 3026 val = user->s.value; 3027 } else if (expr->attr & CEXPR_ROLE) { 3028 if (!is_id_in_scope(SYM_ROLES, id)) { 3029 yyerror2("role %s is not within scope", 3030 id); 3031 constraint_expr_destroy(expr); 3032 return 0; 3033 } 3034 role = 3035 (role_datum_t *) hashtab_search(policydbp-> 3036 p_roles. 3037 table, 3038 (hashtab_key_t) 3039 id); 3040 if (!role) { 3041 yyerror2("unknown role %s", id); 3042 constraint_expr_destroy(expr); 3043 return 0; 3044 } 3045 val = role->s.value; 3046 } else if (expr->attr & CEXPR_TYPE) { 3047 if (set_types(expr->type_names, id, &add, 0)) { 3048 constraint_expr_destroy(expr); 3049 return 0; 3050 } 3051 continue; 3052 } else { 3053 yyerror("invalid constraint expression"); 3054 constraint_expr_destroy(expr); 3055 return 0; 3056 } 3057 if (ebitmap_set_bit(&expr->names, val - 1, TRUE)) { 3058 yyerror("out of memory"); 3059 ebitmap_destroy(&expr->names); 3060 constraint_expr_destroy(expr); 3061 return 0; 3062 } 3063 free(id); 3064 } 3065 ebitmap_destroy(&negset); 3066 return (uintptr_t) expr; 3067 default: 3068 yyerror("invalid constraint expression"); 3069 constraint_expr_destroy(expr); 3070 return 0; 3071 } 3072 3073 yyerror("invalid constraint expression"); 3074 free(expr); 3075 return 0; 3076} 3077 3078int define_conditional(cond_expr_t * expr, avrule_t * t, avrule_t * f) 3079{ 3080 cond_expr_t *e; 3081 int depth; 3082 cond_node_t cn, *cn_old; 3083 3084 /* expression cannot be NULL */ 3085 if (!expr) { 3086 yyerror("illegal conditional expression"); 3087 return -1; 3088 } 3089 if (!t) { 3090 if (!f) { 3091 /* empty is fine, destroy expression and return */ 3092 cond_expr_destroy(expr); 3093 return 0; 3094 } 3095 /* Invert */ 3096 t = f; 3097 f = 0; 3098 expr = define_cond_expr(COND_NOT, expr, 0); 3099 if (!expr) { 3100 yyerror("unable to invert"); 3101 return -1; 3102 } 3103 } 3104 3105 /* verify expression */ 3106 depth = -1; 3107 for (e = expr; e; e = e->next) { 3108 switch (e->expr_type) { 3109 case COND_NOT: 3110 if (depth < 0) { 3111 yyerror 3112 ("illegal conditional expression; Bad NOT"); 3113 return -1; 3114 } 3115 break; 3116 case COND_AND: 3117 case COND_OR: 3118 case COND_XOR: 3119 case COND_EQ: 3120 case COND_NEQ: 3121 if (depth < 1) { 3122 yyerror 3123 ("illegal conditional expression; Bad binary op"); 3124 return -1; 3125 } 3126 depth--; 3127 break; 3128 case COND_BOOL: 3129 if (depth == (COND_EXPR_MAXDEPTH - 1)) { 3130 yyerror 3131 ("conditional expression is like totally too deep"); 3132 return -1; 3133 } 3134 depth++; 3135 break; 3136 default: 3137 yyerror("illegal conditional expression"); 3138 return -1; 3139 } 3140 } 3141 if (depth != 0) { 3142 yyerror("illegal conditional expression"); 3143 return -1; 3144 } 3145 3146 /* use tmp conditional node to partially build new node */ 3147 memset(&cn, 0, sizeof(cn)); 3148 cn.expr = expr; 3149 cn.avtrue_list = t; 3150 cn.avfalse_list = f; 3151 3152 /* normalize/precompute expression */ 3153 if (cond_normalize_expr(policydbp, &cn) < 0) { 3154 yyerror("problem normalizing conditional expression"); 3155 return -1; 3156 } 3157 3158 /* get the existing conditional node, or create a new one */ 3159 cn_old = get_current_cond_list(&cn); 3160 if (!cn_old) { 3161 return -1; 3162 } 3163 3164 append_cond_list(&cn); 3165 3166 /* note that there is no check here for duplicate rules, nor 3167 * check that rule already exists in base -- that will be 3168 * handled during conditional expansion, in expand.c */ 3169 3170 cn.avtrue_list = NULL; 3171 cn.avfalse_list = NULL; 3172 cond_node_destroy(&cn); 3173 3174 return 0; 3175} 3176 3177cond_expr_t *define_cond_expr(uint32_t expr_type, void *arg1, void *arg2) 3178{ 3179 struct cond_expr *expr, *e1 = NULL, *e2; 3180 cond_bool_datum_t *bool_var; 3181 char *id; 3182 3183 /* expressions are handled in the second pass */ 3184 if (pass == 1) { 3185 if (expr_type == COND_BOOL) { 3186 while ((id = queue_remove(id_queue))) { 3187 free(id); 3188 } 3189 } 3190 return (cond_expr_t *) 1; /* any non-NULL value */ 3191 } 3192 3193 /* create a new expression struct */ 3194 expr = malloc(sizeof(struct cond_expr)); 3195 if (!expr) { 3196 yyerror("out of memory"); 3197 return NULL; 3198 } 3199 memset(expr, 0, sizeof(cond_expr_t)); 3200 expr->expr_type = expr_type; 3201 3202 /* create the type asked for */ 3203 switch (expr_type) { 3204 case COND_NOT: 3205 e1 = NULL; 3206 e2 = (struct cond_expr *)arg1; 3207 while (e2) { 3208 e1 = e2; 3209 e2 = e2->next; 3210 } 3211 if (!e1 || e1->next) { 3212 yyerror("illegal conditional NOT expression"); 3213 free(expr); 3214 return NULL; 3215 } 3216 e1->next = expr; 3217 return (struct cond_expr *)arg1; 3218 case COND_AND: 3219 case COND_OR: 3220 case COND_XOR: 3221 case COND_EQ: 3222 case COND_NEQ: 3223 e1 = NULL; 3224 e2 = (struct cond_expr *)arg1; 3225 while (e2) { 3226 e1 = e2; 3227 e2 = e2->next; 3228 } 3229 if (!e1 || e1->next) { 3230 yyerror 3231 ("illegal left side of conditional binary op expression"); 3232 free(expr); 3233 return NULL; 3234 } 3235 e1->next = (struct cond_expr *)arg2; 3236 3237 e1 = NULL; 3238 e2 = (struct cond_expr *)arg2; 3239 while (e2) { 3240 e1 = e2; 3241 e2 = e2->next; 3242 } 3243 if (!e1 || e1->next) { 3244 yyerror 3245 ("illegal right side of conditional binary op expression"); 3246 free(expr); 3247 return NULL; 3248 } 3249 e1->next = expr; 3250 return (struct cond_expr *)arg1; 3251 case COND_BOOL: 3252 id = (char *)queue_remove(id_queue); 3253 if (!id) { 3254 yyerror("bad conditional; expected boolean id"); 3255 free(id); 3256 free(expr); 3257 return NULL; 3258 } 3259 if (!is_id_in_scope(SYM_BOOLS, id)) { 3260 yyerror2("boolean %s is not within scope", id); 3261 free(id); 3262 free(expr); 3263 return NULL; 3264 } 3265 bool_var = 3266 (cond_bool_datum_t *) hashtab_search(policydbp->p_bools. 3267 table, 3268 (hashtab_key_t) id); 3269 if (!bool_var) { 3270 yyerror2("unknown boolean %s in conditional expression", 3271 id); 3272 free(expr); 3273 free(id); 3274 return NULL; 3275 } 3276 expr->bool = bool_var->s.value; 3277 free(id); 3278 return expr; 3279 default: 3280 yyerror("illegal conditional expression"); 3281 return NULL; 3282 } 3283} 3284 3285static int set_user_roles(role_set_t * set, char *id) 3286{ 3287 role_datum_t *r; 3288 unsigned int i; 3289 ebitmap_node_t *node; 3290 3291 if (strcmp(id, "*") == 0) { 3292 free(id); 3293 yyerror("* is not allowed in user declarations"); 3294 return -1; 3295 } 3296 3297 if (strcmp(id, "~") == 0) { 3298 free(id); 3299 yyerror("~ is not allowed in user declarations"); 3300 return -1; 3301 } 3302 3303 if (!is_id_in_scope(SYM_ROLES, id)) { 3304 yyerror2("role %s is not within scope", id); 3305 free(id); 3306 return -1; 3307 } 3308 r = hashtab_search(policydbp->p_roles.table, id); 3309 if (!r) { 3310 yyerror2("unknown role %s", id); 3311 free(id); 3312 return -1; 3313 } 3314 3315 /* set the role and every role it dominates */ 3316 ebitmap_for_each_bit(&r->dominates, node, i) { 3317 if (ebitmap_node_get_bit(node, i)) 3318 if (ebitmap_set_bit(&set->roles, i, TRUE)) 3319 goto oom; 3320 } 3321 free(id); 3322 return 0; 3323 oom: 3324 yyerror("out of memory"); 3325 return -1; 3326} 3327 3328static int parse_categories(char *id, level_datum_t * levdatum, ebitmap_t * cats) 3329{ 3330 cat_datum_t *cdatum; 3331 int range_start, range_end, i; 3332 3333 if (id_has_dot(id)) { 3334 char *id_start = id; 3335 char *id_end = strchr(id, '.'); 3336 3337 *(id_end++) = '\0'; 3338 3339 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table, 3340 (hashtab_key_t) 3341 id_start); 3342 if (!cdatum) { 3343 yyerror2("unknown category %s", id_start); 3344 return -1; 3345 } 3346 range_start = cdatum->s.value - 1; 3347 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table, 3348 (hashtab_key_t) id_end); 3349 if (!cdatum) { 3350 yyerror2("unknown category %s", id_end); 3351 return -1; 3352 } 3353 range_end = cdatum->s.value - 1; 3354 3355 if (range_end < range_start) { 3356 yyerror2("category range is invalid"); 3357 return -1; 3358 } 3359 } else { 3360 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table, 3361 (hashtab_key_t) id); 3362 if (!cdatum) { 3363 yyerror2("unknown category %s", id); 3364 return -1; 3365 } 3366 range_start = range_end = cdatum->s.value - 1; 3367 } 3368 3369 for (i = range_start; i <= range_end; i++) { 3370 if (!ebitmap_get_bit(&levdatum->level->cat, i)) { 3371 uint32_t level_value = levdatum->level->sens - 1; 3372 policydb_index_others(NULL, policydbp, 0); 3373 yyerror2("category %s can not be associated " 3374 "with level %s", 3375 policydbp->p_cat_val_to_name[i], 3376 policydbp->p_sens_val_to_name[level_value]); 3377 return -1; 3378 } 3379 if (ebitmap_set_bit(cats, i, TRUE)) { 3380 yyerror("out of memory"); 3381 return -1; 3382 } 3383 } 3384 3385 return 0; 3386} 3387 3388static int parse_semantic_categories(char *id, level_datum_t * levdatum, 3389 mls_semantic_cat_t ** cats) 3390{ 3391 cat_datum_t *cdatum; 3392 mls_semantic_cat_t *newcat; 3393 unsigned int range_start, range_end; 3394 3395 if (id_has_dot(id)) { 3396 char *id_start = id; 3397 char *id_end = strchr(id, '.'); 3398 3399 *(id_end++) = '\0'; 3400 3401 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table, 3402 (hashtab_key_t) 3403 id_start); 3404 if (!cdatum) { 3405 yyerror2("unknown category %s", id_start); 3406 return -1; 3407 } 3408 range_start = cdatum->s.value; 3409 3410 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table, 3411 (hashtab_key_t) id_end); 3412 if (!cdatum) { 3413 yyerror2("unknown category %s", id_end); 3414 return -1; 3415 } 3416 range_end = cdatum->s.value; 3417 } else { 3418 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table, 3419 (hashtab_key_t) id); 3420 if (!cdatum) { 3421 yyerror2("unknown category %s", id); 3422 return -1; 3423 } 3424 range_start = range_end = cdatum->s.value; 3425 } 3426 3427 newcat = (mls_semantic_cat_t *) malloc(sizeof(mls_semantic_cat_t)); 3428 if (!newcat) { 3429 yyerror("out of memory"); 3430 return -1; 3431 } 3432 3433 mls_semantic_cat_init(newcat); 3434 newcat->next = *cats; 3435 newcat->low = range_start; 3436 newcat->high = range_end; 3437 3438 *cats = newcat; 3439 3440 return 0; 3441} 3442 3443int define_user(void) 3444{ 3445 char *id; 3446 user_datum_t *usrdatum; 3447 level_datum_t *levdatum; 3448 int l; 3449 3450 if (pass == 1) { 3451 while ((id = queue_remove(id_queue))) 3452 free(id); 3453 if (mlspol) { 3454 while ((id = queue_remove(id_queue))) 3455 free(id); 3456 id = queue_remove(id_queue); 3457 free(id); 3458 for (l = 0; l < 2; l++) { 3459 while ((id = queue_remove(id_queue))) { 3460 free(id); 3461 } 3462 id = queue_remove(id_queue); 3463 if (!id) 3464 break; 3465 free(id); 3466 } 3467 } 3468 return 0; 3469 } 3470 3471 if ((usrdatum = declare_user()) == NULL) { 3472 return -1; 3473 } 3474 3475 while ((id = queue_remove(id_queue))) { 3476 if (set_user_roles(&usrdatum->roles, id)) 3477 continue; 3478 } 3479 3480 if (mlspol) { 3481 id = queue_remove(id_queue); 3482 if (!id) { 3483 yyerror("no default level specified for user"); 3484 return -1; 3485 } 3486 3487 levdatum = (level_datum_t *) 3488 hashtab_search(policydbp->p_levels.table, 3489 (hashtab_key_t) id); 3490 if (!levdatum) { 3491 yyerror2("unknown sensitivity %s used in user" 3492 " level definition", id); 3493 free(id); 3494 return -1; 3495 } 3496 free(id); 3497 3498 usrdatum->dfltlevel.sens = levdatum->level->sens; 3499 3500 while ((id = queue_remove(id_queue))) { 3501 if (parse_semantic_categories(id, levdatum, 3502 &usrdatum->dfltlevel.cat)) { 3503 free(id); 3504 return -1; 3505 } 3506 free(id); 3507 } 3508 3509 id = queue_remove(id_queue); 3510 3511 for (l = 0; l < 2; l++) { 3512 levdatum = (level_datum_t *) 3513 hashtab_search(policydbp->p_levels.table, 3514 (hashtab_key_t) id); 3515 if (!levdatum) { 3516 yyerror2("unknown sensitivity %s used in user" 3517 " range definition", id); 3518 free(id); 3519 return -1; 3520 } 3521 free(id); 3522 3523 usrdatum->range.level[l].sens = levdatum->level->sens; 3524 3525 while ((id = queue_remove(id_queue))) { 3526 if (parse_semantic_categories(id, levdatum, 3527 &usrdatum->range.level[l].cat)) { 3528 free(id); 3529 return -1; 3530 } 3531 free(id); 3532 } 3533 3534 id = queue_remove(id_queue); 3535 if (!id) 3536 break; 3537 } 3538 3539 if (l == 0) { 3540 if (mls_semantic_level_cpy(&usrdatum->range.level[1], 3541 &usrdatum->range.level[0])) { 3542 yyerror("out of memory"); 3543 return -1; 3544 } 3545 } 3546 } 3547 return 0; 3548} 3549 3550static int parse_security_context(context_struct_t * c) 3551{ 3552 char *id; 3553 role_datum_t *role; 3554 type_datum_t *typdatum; 3555 user_datum_t *usrdatum; 3556 level_datum_t *levdatum; 3557 int l; 3558 3559 if (pass == 1) { 3560 id = queue_remove(id_queue); 3561 free(id); /* user */ 3562 id = queue_remove(id_queue); 3563 free(id); /* role */ 3564 id = queue_remove(id_queue); 3565 free(id); /* type */ 3566 if (mlspol) { 3567 id = queue_remove(id_queue); 3568 free(id); 3569 for (l = 0; l < 2; l++) { 3570 while ((id = queue_remove(id_queue))) { 3571 free(id); 3572 } 3573 id = queue_remove(id_queue); 3574 if (!id) 3575 break; 3576 free(id); 3577 } 3578 } 3579 return 0; 3580 } 3581 3582 context_init(c); 3583 3584 /* extract the user */ 3585 id = queue_remove(id_queue); 3586 if (!id) { 3587 yyerror("no effective user?"); 3588 goto bad; 3589 } 3590 if (!is_id_in_scope(SYM_USERS, id)) { 3591 yyerror2("user %s is not within scope", id); 3592 free(id); 3593 goto bad; 3594 } 3595 usrdatum = (user_datum_t *) hashtab_search(policydbp->p_users.table, 3596 (hashtab_key_t) id); 3597 if (!usrdatum) { 3598 yyerror2("user %s is not defined", id); 3599 free(id); 3600 goto bad; 3601 } 3602 c->user = usrdatum->s.value; 3603 3604 /* no need to keep the user name */ 3605 free(id); 3606 3607 /* extract the role */ 3608 id = (char *)queue_remove(id_queue); 3609 if (!id) { 3610 yyerror("no role name for sid context definition?"); 3611 return -1; 3612 } 3613 if (!is_id_in_scope(SYM_ROLES, id)) { 3614 yyerror2("role %s is not within scope", id); 3615 free(id); 3616 return -1; 3617 } 3618 role = (role_datum_t *) hashtab_search(policydbp->p_roles.table, 3619 (hashtab_key_t) id); 3620 if (!role) { 3621 yyerror2("role %s is not defined", id); 3622 free(id); 3623 return -1; 3624 } 3625 c->role = role->s.value; 3626 3627 /* no need to keep the role name */ 3628 free(id); 3629 3630 /* extract the type */ 3631 id = (char *)queue_remove(id_queue); 3632 if (!id) { 3633 yyerror("no type name for sid context definition?"); 3634 return -1; 3635 } 3636 if (!is_id_in_scope(SYM_TYPES, id)) { 3637 yyerror2("type %s is not within scope", id); 3638 free(id); 3639 return -1; 3640 } 3641 typdatum = (type_datum_t *) hashtab_search(policydbp->p_types.table, 3642 (hashtab_key_t) id); 3643 if (!typdatum || typdatum->flavor == TYPE_ATTRIB) { 3644 yyerror2("type %s is not defined or is an attribute", id); 3645 free(id); 3646 return -1; 3647 } 3648 c->type = typdatum->s.value; 3649 3650 /* no need to keep the type name */ 3651 free(id); 3652 3653 if (mlspol) { 3654 /* extract the low sensitivity */ 3655 id = (char *)queue_head(id_queue); 3656 if (!id) { 3657 yyerror("no sensitivity name for sid context" 3658 " definition?"); 3659 return -1; 3660 } 3661 3662 id = (char *)queue_remove(id_queue); 3663 for (l = 0; l < 2; l++) { 3664 levdatum = (level_datum_t *) 3665 hashtab_search(policydbp->p_levels.table, 3666 (hashtab_key_t) id); 3667 if (!levdatum) { 3668 yyerror2("Sensitivity %s is not defined", id); 3669 free(id); 3670 return -1; 3671 } 3672 free(id); 3673 c->range.level[l].sens = levdatum->level->sens; 3674 3675 /* extract low category set */ 3676 while ((id = queue_remove(id_queue))) { 3677 if (parse_categories(id, levdatum, 3678 &c->range.level[l].cat)) { 3679 free(id); 3680 return -1; 3681 } 3682 free(id); 3683 } 3684 3685 /* extract high sensitivity */ 3686 id = (char *)queue_remove(id_queue); 3687 if (!id) 3688 break; 3689 } 3690 3691 if (l == 0) { 3692 c->range.level[1].sens = c->range.level[0].sens; 3693 if (ebitmap_cpy(&c->range.level[1].cat, 3694 &c->range.level[0].cat)) { 3695 3696 yyerror("out of memory"); 3697 goto bad; 3698 } 3699 } 3700 } 3701 3702 if (!policydb_context_isvalid(policydbp, c)) { 3703 yyerror("invalid security context"); 3704 goto bad; 3705 } 3706 return 0; 3707 3708 bad: 3709 context_destroy(c); 3710 3711 return -1; 3712} 3713 3714int define_initial_sid_context(void) 3715{ 3716 char *id; 3717 ocontext_t *c, *head; 3718 3719 if (pass == 1) { 3720 id = (char *)queue_remove(id_queue); 3721 free(id); 3722 parse_security_context(NULL); 3723 return 0; 3724 } 3725 3726 id = (char *)queue_remove(id_queue); 3727 if (!id) { 3728 yyerror("no sid name for SID context definition?"); 3729 return -1; 3730 } 3731 head = policydbp->ocontexts[OCON_ISID]; 3732 for (c = head; c; c = c->next) { 3733 if (!strcmp(id, c->u.name)) 3734 break; 3735 } 3736 3737 if (!c) { 3738 yyerror2("SID %s is not defined", id); 3739 free(id); 3740 return -1; 3741 } 3742 if (c->context[0].user) { 3743 yyerror2("The context for SID %s is multiply defined", id); 3744 free(id); 3745 return -1; 3746 } 3747 /* no need to keep the sid name */ 3748 free(id); 3749 3750 if (parse_security_context(&c->context[0])) 3751 return -1; 3752 3753 return 0; 3754} 3755 3756int define_fs_context(unsigned int major, unsigned int minor) 3757{ 3758 ocontext_t *newc, *c, *head; 3759 3760 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) { 3761 yyerror("fscon not supported for target"); 3762 return -1; 3763 } 3764 3765 if (pass == 1) { 3766 parse_security_context(NULL); 3767 parse_security_context(NULL); 3768 return 0; 3769 } 3770 3771 newc = (ocontext_t *) malloc(sizeof(ocontext_t)); 3772 if (!newc) { 3773 yyerror("out of memory"); 3774 return -1; 3775 } 3776 memset(newc, 0, sizeof(ocontext_t)); 3777 3778 newc->u.name = (char *)malloc(6); 3779 if (!newc->u.name) { 3780 yyerror("out of memory"); 3781 free(newc); 3782 return -1; 3783 } 3784 sprintf(newc->u.name, "%02x:%02x", major, minor); 3785 3786 if (parse_security_context(&newc->context[0])) { 3787 free(newc->u.name); 3788 free(newc); 3789 return -1; 3790 } 3791 if (parse_security_context(&newc->context[1])) { 3792 context_destroy(&newc->context[0]); 3793 free(newc->u.name); 3794 free(newc); 3795 return -1; 3796 } 3797 head = policydbp->ocontexts[OCON_FS]; 3798 3799 for (c = head; c; c = c->next) { 3800 if (!strcmp(newc->u.name, c->u.name)) { 3801 yyerror2("duplicate entry for file system %s", 3802 newc->u.name); 3803 context_destroy(&newc->context[0]); 3804 context_destroy(&newc->context[1]); 3805 free(newc->u.name); 3806 free(newc); 3807 return -1; 3808 } 3809 } 3810 3811 newc->next = head; 3812 policydbp->ocontexts[OCON_FS] = newc; 3813 3814 return 0; 3815} 3816 3817int define_pirq_context(unsigned int pirq) 3818{ 3819 ocontext_t *newc, *c, *l, *head; 3820 char *id; 3821 3822 if (policydbp->target_platform != SEPOL_TARGET_XEN) { 3823 yyerror("pirqcon not supported for target"); 3824 return -1; 3825 } 3826 3827 if (pass == 1) { 3828 id = (char *) queue_remove(id_queue); 3829 free(id); 3830 parse_security_context(NULL); 3831 return 0; 3832 } 3833 3834 newc = malloc(sizeof(ocontext_t)); 3835 if (!newc) { 3836 yyerror("out of memory"); 3837 return -1; 3838 } 3839 memset(newc, 0, sizeof(ocontext_t)); 3840 3841 newc->u.pirq = pirq; 3842 3843 if (parse_security_context(&newc->context[0])) { 3844 free(newc); 3845 return -1; 3846 } 3847 3848 head = policydbp->ocontexts[OCON_XEN_PIRQ]; 3849 for (l = NULL, c = head; c; l = c, c = c->next) { 3850 unsigned int pirq2; 3851 3852 pirq2 = c->u.pirq; 3853 if (pirq == pirq2) { 3854 yyerror2("duplicate pirqcon entry for %d ", pirq); 3855 goto bad; 3856 } 3857 } 3858 3859 if (l) 3860 l->next = newc; 3861 else 3862 policydbp->ocontexts[OCON_XEN_PIRQ] = newc; 3863 3864 return 0; 3865 3866bad: 3867 free(newc); 3868 return -1; 3869} 3870 3871int define_iomem_context(unsigned long low, unsigned long high) 3872{ 3873 ocontext_t *newc, *c, *l, *head; 3874 char *id; 3875 3876 if (policydbp->target_platform != SEPOL_TARGET_XEN) { 3877 yyerror("iomemcon not supported for target"); 3878 return -1; 3879 } 3880 3881 if (pass == 1) { 3882 id = (char *)queue_remove(id_queue); 3883 free(id); 3884 parse_security_context(NULL); 3885 return 0; 3886 } 3887 3888 newc = malloc(sizeof(ocontext_t)); 3889 if (!newc) { 3890 yyerror("out of memory"); 3891 return -1; 3892 } 3893 memset(newc, 0, sizeof(ocontext_t)); 3894 3895 newc->u.iomem.low_iomem = low; 3896 newc->u.iomem.high_iomem = high; 3897 3898 if (low > high) { 3899 yyerror2("low memory 0x%x exceeds high memory 0x%x", low, high); 3900 free(newc); 3901 return -1; 3902 } 3903 3904 if (parse_security_context(&newc->context[0])) { 3905 free(newc); 3906 return -1; 3907 } 3908 3909 head = policydbp->ocontexts[OCON_XEN_IOMEM]; 3910 for (l = NULL, c = head; c; l = c, c = c->next) { 3911 unsigned int low2, high2; 3912 3913 low2 = c->u.iomem.low_iomem; 3914 high2 = c->u.iomem.high_iomem; 3915 if (low <= high2 && low2 <= high) { 3916 yyerror2("iomemcon entry for 0x%x-0x%x overlaps with " 3917 "earlier entry 0x%x-0x%x", low, high, 3918 low2, high2); 3919 goto bad; 3920 } 3921 } 3922 3923 if (l) 3924 l->next = newc; 3925 else 3926 policydbp->ocontexts[OCON_XEN_IOMEM] = newc; 3927 3928 return 0; 3929 3930bad: 3931 free(newc); 3932 return -1; 3933} 3934 3935int define_ioport_context(unsigned long low, unsigned long high) 3936{ 3937 ocontext_t *newc, *c, *l, *head; 3938 char *id; 3939 3940 if (policydbp->target_platform != SEPOL_TARGET_XEN) { 3941 yyerror("ioportcon not supported for target"); 3942 return -1; 3943 } 3944 3945 if (pass == 1) { 3946 id = (char *)queue_remove(id_queue); 3947 free(id); 3948 parse_security_context(NULL); 3949 return 0; 3950 } 3951 3952 newc = malloc(sizeof(ocontext_t)); 3953 if (!newc) { 3954 yyerror("out of memory"); 3955 return -1; 3956 } 3957 memset(newc, 0, sizeof(ocontext_t)); 3958 3959 newc->u.ioport.low_ioport = low; 3960 newc->u.ioport.high_ioport = high; 3961 3962 if (low > high) { 3963 yyerror2("low ioport 0x%x exceeds high ioport 0x%x", low, high); 3964 free(newc); 3965 return -1; 3966 } 3967 3968 if (parse_security_context(&newc->context[0])) { 3969 free(newc); 3970 return -1; 3971 } 3972 3973 head = policydbp->ocontexts[OCON_XEN_IOPORT]; 3974 for (l = NULL, c = head; c; l = c, c = c->next) { 3975 unsigned int low2, high2; 3976 3977 low2 = c->u.ioport.low_ioport; 3978 high2 = c->u.ioport.high_ioport; 3979 if (low <= high2 && low2 <= high) { 3980 yyerror2("ioportcon entry for 0x%x-0x%x overlaps with" 3981 "earlier entry 0x%x-0x%x", low, high, 3982 low2, high2); 3983 goto bad; 3984 } 3985 } 3986 3987 if (l) 3988 l->next = newc; 3989 else 3990 policydbp->ocontexts[OCON_XEN_IOPORT] = newc; 3991 3992 return 0; 3993 3994bad: 3995 free(newc); 3996 return -1; 3997} 3998 3999int define_pcidevice_context(unsigned long device) 4000{ 4001 ocontext_t *newc, *c, *l, *head; 4002 char *id; 4003 4004 if (policydbp->target_platform != SEPOL_TARGET_XEN) { 4005 yyerror("pcidevicecon not supported for target"); 4006 return -1; 4007 } 4008 4009 if (pass == 1) { 4010 id = (char *) queue_remove(id_queue); 4011 free(id); 4012 parse_security_context(NULL); 4013 return 0; 4014 } 4015 4016 newc = malloc(sizeof(ocontext_t)); 4017 if (!newc) { 4018 yyerror("out of memory"); 4019 return -1; 4020 } 4021 memset(newc, 0, sizeof(ocontext_t)); 4022 4023 newc->u.device = device; 4024 4025 if (parse_security_context(&newc->context[0])) { 4026 free(newc); 4027 return -1; 4028 } 4029 4030 head = policydbp->ocontexts[OCON_XEN_PCIDEVICE]; 4031 for (l = NULL, c = head; c; l = c, c = c->next) { 4032 unsigned int device2; 4033 4034 device2 = c->u.device; 4035 if (device == device2) { 4036 yyerror2("duplicate pcidevicecon entry for 0x%x ", 4037 device); 4038 goto bad; 4039 } 4040 } 4041 4042 if (l) 4043 l->next = newc; 4044 else 4045 policydbp->ocontexts[OCON_XEN_PCIDEVICE] = newc; 4046 4047 return 0; 4048 4049bad: 4050 free(newc); 4051 return -1; 4052} 4053 4054int define_port_context(unsigned int low, unsigned int high) 4055{ 4056 ocontext_t *newc, *c, *l, *head; 4057 unsigned int protocol; 4058 char *id; 4059 4060 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) { 4061 yyerror("portcon not supported for target"); 4062 return -1; 4063 } 4064 4065 if (pass == 1) { 4066 id = (char *)queue_remove(id_queue); 4067 free(id); 4068 parse_security_context(NULL); 4069 return 0; 4070 } 4071 4072 newc = malloc(sizeof(ocontext_t)); 4073 if (!newc) { 4074 yyerror("out of memory"); 4075 return -1; 4076 } 4077 memset(newc, 0, sizeof(ocontext_t)); 4078 4079 id = (char *)queue_remove(id_queue); 4080 if (!id) { 4081 free(newc); 4082 return -1; 4083 } 4084 if ((strcmp(id, "tcp") == 0) || (strcmp(id, "TCP") == 0)) { 4085 protocol = IPPROTO_TCP; 4086 } else if ((strcmp(id, "udp") == 0) || (strcmp(id, "UDP") == 0)) { 4087 protocol = IPPROTO_UDP; 4088 } else { 4089 yyerror2("unrecognized protocol %s", id); 4090 free(newc); 4091 return -1; 4092 } 4093 4094 newc->u.port.protocol = protocol; 4095 newc->u.port.low_port = low; 4096 newc->u.port.high_port = high; 4097 4098 if (low > high) { 4099 yyerror2("low port %d exceeds high port %d", low, high); 4100 free(newc); 4101 return -1; 4102 } 4103 4104 if (parse_security_context(&newc->context[0])) { 4105 free(newc); 4106 return -1; 4107 } 4108 4109 /* Preserve the matching order specified in the configuration. */ 4110 head = policydbp->ocontexts[OCON_PORT]; 4111 for (l = NULL, c = head; c; l = c, c = c->next) { 4112 unsigned int prot2, low2, high2; 4113 4114 prot2 = c->u.port.protocol; 4115 low2 = c->u.port.low_port; 4116 high2 = c->u.port.high_port; 4117 if (protocol != prot2) 4118 continue; 4119 if (low == low2 && high == high2) { 4120 yyerror2("duplicate portcon entry for %s %d-%d ", id, 4121 low, high); 4122 goto bad; 4123 } 4124 if (low2 <= low && high2 >= high) { 4125 yyerror2("portcon entry for %s %d-%d hidden by earlier " 4126 "entry for %d-%d", id, low, high, low2, high2); 4127 goto bad; 4128 } 4129 } 4130 4131 if (l) 4132 l->next = newc; 4133 else 4134 policydbp->ocontexts[OCON_PORT] = newc; 4135 4136 return 0; 4137 4138 bad: 4139 free(newc); 4140 return -1; 4141} 4142 4143int define_netif_context(void) 4144{ 4145 ocontext_t *newc, *c, *head; 4146 4147 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) { 4148 yyerror("netifcon not supported for target"); 4149 return -1; 4150 } 4151 4152 if (pass == 1) { 4153 free(queue_remove(id_queue)); 4154 parse_security_context(NULL); 4155 parse_security_context(NULL); 4156 return 0; 4157 } 4158 4159 newc = (ocontext_t *) malloc(sizeof(ocontext_t)); 4160 if (!newc) { 4161 yyerror("out of memory"); 4162 return -1; 4163 } 4164 memset(newc, 0, sizeof(ocontext_t)); 4165 4166 newc->u.name = (char *)queue_remove(id_queue); 4167 if (!newc->u.name) { 4168 free(newc); 4169 return -1; 4170 } 4171 if (parse_security_context(&newc->context[0])) { 4172 free(newc->u.name); 4173 free(newc); 4174 return -1; 4175 } 4176 if (parse_security_context(&newc->context[1])) { 4177 context_destroy(&newc->context[0]); 4178 free(newc->u.name); 4179 free(newc); 4180 return -1; 4181 } 4182 head = policydbp->ocontexts[OCON_NETIF]; 4183 4184 for (c = head; c; c = c->next) { 4185 if (!strcmp(newc->u.name, c->u.name)) { 4186 yyerror2("duplicate entry for network interface %s", 4187 newc->u.name); 4188 context_destroy(&newc->context[0]); 4189 context_destroy(&newc->context[1]); 4190 free(newc->u.name); 4191 free(newc); 4192 return -1; 4193 } 4194 } 4195 4196 newc->next = head; 4197 policydbp->ocontexts[OCON_NETIF] = newc; 4198 return 0; 4199} 4200 4201int define_ipv4_node_context() 4202{ 4203 char *id; 4204 int rc = 0; 4205 struct in_addr addr, mask; 4206 ocontext_t *newc, *c, *l, *head; 4207 4208 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) { 4209 yyerror("nodecon not supported for target"); 4210 return -1; 4211 } 4212 4213 if (pass == 1) { 4214 free(queue_remove(id_queue)); 4215 free(queue_remove(id_queue)); 4216 parse_security_context(NULL); 4217 goto out; 4218 } 4219 4220 id = queue_remove(id_queue); 4221 if (!id) { 4222 yyerror("failed to read ipv4 address"); 4223 rc = -1; 4224 goto out; 4225 } 4226 4227 rc = inet_pton(AF_INET, id, &addr); 4228 free(id); 4229 if (rc < 1) { 4230 yyerror("failed to parse ipv4 address"); 4231 if (rc == 0) 4232 rc = -1; 4233 goto out; 4234 } 4235 4236 id = queue_remove(id_queue); 4237 if (!id) { 4238 yyerror("failed to read ipv4 address"); 4239 rc = -1; 4240 goto out; 4241 } 4242 4243 rc = inet_pton(AF_INET, id, &mask); 4244 free(id); 4245 if (rc < 1) { 4246 yyerror("failed to parse ipv4 mask"); 4247 if (rc == 0) 4248 rc = -1; 4249 goto out; 4250 } 4251 4252 newc = malloc(sizeof(ocontext_t)); 4253 if (!newc) { 4254 yyerror("out of memory"); 4255 rc = -1; 4256 goto out; 4257 } 4258 4259 memset(newc, 0, sizeof(ocontext_t)); 4260 newc->u.node.addr = addr.s_addr; 4261 newc->u.node.mask = mask.s_addr; 4262 4263 if (parse_security_context(&newc->context[0])) { 4264 free(newc); 4265 return -1; 4266 } 4267 4268 /* Create order of most specific to least retaining 4269 the order specified in the configuration. */ 4270 head = policydbp->ocontexts[OCON_NODE]; 4271 for (l = NULL, c = head; c; l = c, c = c->next) { 4272 if (newc->u.node.mask > c->u.node.mask) 4273 break; 4274 } 4275 4276 newc->next = c; 4277 4278 if (l) 4279 l->next = newc; 4280 else 4281 policydbp->ocontexts[OCON_NODE] = newc; 4282 rc = 0; 4283out: 4284 return rc; 4285} 4286 4287int define_ipv6_node_context(void) 4288{ 4289 char *id; 4290 int rc = 0; 4291 struct in6_addr addr, mask; 4292 ocontext_t *newc, *c, *l, *head; 4293 4294 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) { 4295 yyerror("nodecon not supported for target"); 4296 return -1; 4297 } 4298 4299 if (pass == 1) { 4300 free(queue_remove(id_queue)); 4301 free(queue_remove(id_queue)); 4302 parse_security_context(NULL); 4303 goto out; 4304 } 4305 4306 id = queue_remove(id_queue); 4307 if (!id) { 4308 yyerror("failed to read ipv6 address"); 4309 rc = -1; 4310 goto out; 4311 } 4312 4313 rc = inet_pton(AF_INET6, id, &addr); 4314 free(id); 4315 if (rc < 1) { 4316 yyerror("failed to parse ipv6 address"); 4317 if (rc == 0) 4318 rc = -1; 4319 goto out; 4320 } 4321 4322 id = queue_remove(id_queue); 4323 if (!id) { 4324 yyerror("failed to read ipv6 address"); 4325 rc = -1; 4326 goto out; 4327 } 4328 4329 rc = inet_pton(AF_INET6, id, &mask); 4330 free(id); 4331 if (rc < 1) { 4332 yyerror("failed to parse ipv6 mask"); 4333 if (rc == 0) 4334 rc = -1; 4335 goto out; 4336 } 4337 4338 newc = malloc(sizeof(ocontext_t)); 4339 if (!newc) { 4340 yyerror("out of memory"); 4341 rc = -1; 4342 goto out; 4343 } 4344 4345 memset(newc, 0, sizeof(ocontext_t)); 4346 memcpy(&newc->u.node6.addr[0], &addr.s6_addr32[0], 16); 4347 memcpy(&newc->u.node6.mask[0], &mask.s6_addr32[0], 16); 4348 4349 if (parse_security_context(&newc->context[0])) { 4350 free(newc); 4351 rc = -1; 4352 goto out; 4353 } 4354 4355 /* Create order of most specific to least retaining 4356 the order specified in the configuration. */ 4357 head = policydbp->ocontexts[OCON_NODE6]; 4358 for (l = NULL, c = head; c; l = c, c = c->next) { 4359 if (memcmp(&newc->u.node6.mask, &c->u.node6.mask, 16) > 0) 4360 break; 4361 } 4362 4363 newc->next = c; 4364 4365 if (l) 4366 l->next = newc; 4367 else 4368 policydbp->ocontexts[OCON_NODE6] = newc; 4369 4370 rc = 0; 4371 out: 4372 return rc; 4373} 4374 4375int define_fs_use(int behavior) 4376{ 4377 ocontext_t *newc, *c, *head; 4378 4379 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) { 4380 yyerror("fsuse not supported for target"); 4381 return -1; 4382 } 4383 4384 if (pass == 1) { 4385 free(queue_remove(id_queue)); 4386 parse_security_context(NULL); 4387 return 0; 4388 } 4389 4390 newc = (ocontext_t *) malloc(sizeof(ocontext_t)); 4391 if (!newc) { 4392 yyerror("out of memory"); 4393 return -1; 4394 } 4395 memset(newc, 0, sizeof(ocontext_t)); 4396 4397 newc->u.name = (char *)queue_remove(id_queue); 4398 if (!newc->u.name) { 4399 free(newc); 4400 return -1; 4401 } 4402 newc->v.behavior = behavior; 4403 if (parse_security_context(&newc->context[0])) { 4404 free(newc->u.name); 4405 free(newc); 4406 return -1; 4407 } 4408 4409 head = policydbp->ocontexts[OCON_FSUSE]; 4410 4411 for (c = head; c; c = c->next) { 4412 if (!strcmp(newc->u.name, c->u.name)) { 4413 yyerror2("duplicate fs_use entry for filesystem type %s", 4414 newc->u.name); 4415 context_destroy(&newc->context[0]); 4416 free(newc->u.name); 4417 free(newc); 4418 return -1; 4419 } 4420 } 4421 4422 newc->next = head; 4423 policydbp->ocontexts[OCON_FSUSE] = newc; 4424 return 0; 4425} 4426 4427int define_genfs_context_helper(char *fstype, int has_type) 4428{ 4429 struct genfs *genfs_p, *genfs, *newgenfs; 4430 ocontext_t *newc, *c, *head, *p; 4431 char *type = NULL; 4432 int len, len2; 4433 4434 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) { 4435 yyerror("genfs not supported for target"); 4436 return -1; 4437 } 4438 4439 if (pass == 1) { 4440 free(fstype); 4441 free(queue_remove(id_queue)); 4442 if (has_type) 4443 free(queue_remove(id_queue)); 4444 parse_security_context(NULL); 4445 return 0; 4446 } 4447 4448 for (genfs_p = NULL, genfs = policydbp->genfs; 4449 genfs; genfs_p = genfs, genfs = genfs->next) { 4450 if (strcmp(fstype, genfs->fstype) <= 0) 4451 break; 4452 } 4453 4454 if (!genfs || strcmp(fstype, genfs->fstype)) { 4455 newgenfs = malloc(sizeof(struct genfs)); 4456 if (!newgenfs) { 4457 yyerror("out of memory"); 4458 return -1; 4459 } 4460 memset(newgenfs, 0, sizeof(struct genfs)); 4461 newgenfs->fstype = fstype; 4462 newgenfs->next = genfs; 4463 if (genfs_p) 4464 genfs_p->next = newgenfs; 4465 else 4466 policydbp->genfs = newgenfs; 4467 genfs = newgenfs; 4468 } 4469 4470 newc = (ocontext_t *) malloc(sizeof(ocontext_t)); 4471 if (!newc) { 4472 yyerror("out of memory"); 4473 return -1; 4474 } 4475 memset(newc, 0, sizeof(ocontext_t)); 4476 4477 newc->u.name = (char *)queue_remove(id_queue); 4478 if (!newc->u.name) 4479 goto fail; 4480 if (has_type) { 4481 type = (char *)queue_remove(id_queue); 4482 if (!type) 4483 goto fail; 4484 if (type[1] != 0) { 4485 yyerror2("invalid type %s", type); 4486 goto fail; 4487 } 4488 switch (type[0]) { 4489 case 'b': 4490 newc->v.sclass = SECCLASS_BLK_FILE; 4491 break; 4492 case 'c': 4493 newc->v.sclass = SECCLASS_CHR_FILE; 4494 break; 4495 case 'd': 4496 newc->v.sclass = SECCLASS_DIR; 4497 break; 4498 case 'p': 4499 newc->v.sclass = SECCLASS_FIFO_FILE; 4500 break; 4501 case 'l': 4502 newc->v.sclass = SECCLASS_LNK_FILE; 4503 break; 4504 case 's': 4505 newc->v.sclass = SECCLASS_SOCK_FILE; 4506 break; 4507 case '-': 4508 newc->v.sclass = SECCLASS_FILE; 4509 break; 4510 default: 4511 yyerror2("invalid type %s", type); 4512 goto fail; 4513 } 4514 } 4515 if (parse_security_context(&newc->context[0])) 4516 goto fail; 4517 4518 head = genfs->head; 4519 4520 for (p = NULL, c = head; c; p = c, c = c->next) { 4521 if (!strcmp(newc->u.name, c->u.name) && 4522 (!newc->v.sclass || !c->v.sclass 4523 || newc->v.sclass == c->v.sclass)) { 4524 yyerror2("duplicate entry for genfs entry (%s, %s)", 4525 fstype, newc->u.name); 4526 goto fail; 4527 } 4528 len = strlen(newc->u.name); 4529 len2 = strlen(c->u.name); 4530 if (len > len2) 4531 break; 4532 } 4533 4534 newc->next = c; 4535 if (p) 4536 p->next = newc; 4537 else 4538 genfs->head = newc; 4539 return 0; 4540 fail: 4541 if (type) 4542 free(type); 4543 context_destroy(&newc->context[0]); 4544 if (fstype) 4545 free(fstype); 4546 if (newc->u.name) 4547 free(newc->u.name); 4548 free(newc); 4549 return -1; 4550} 4551 4552int define_genfs_context(int has_type) 4553{ 4554 return define_genfs_context_helper(queue_remove(id_queue), has_type); 4555} 4556 4557int define_range_trans(int class_specified) 4558{ 4559 char *id; 4560 level_datum_t *levdatum = 0; 4561 class_datum_t *cladatum; 4562 range_trans_rule_t *rule; 4563 int l, add = 1; 4564 4565 if (!mlspol) { 4566 yyerror("range_transition rule in non-MLS configuration"); 4567 return -1; 4568 } 4569 4570 if (pass == 1) { 4571 while ((id = queue_remove(id_queue))) 4572 free(id); 4573 while ((id = queue_remove(id_queue))) 4574 free(id); 4575 if (class_specified) 4576 while ((id = queue_remove(id_queue))) 4577 free(id); 4578 id = queue_remove(id_queue); 4579 free(id); 4580 for (l = 0; l < 2; l++) { 4581 while ((id = queue_remove(id_queue))) { 4582 free(id); 4583 } 4584 id = queue_remove(id_queue); 4585 if (!id) 4586 break; 4587 free(id); 4588 } 4589 return 0; 4590 } 4591 4592 rule = malloc(sizeof(struct range_trans_rule)); 4593 if (!rule) { 4594 yyerror("out of memory"); 4595 return -1; 4596 } 4597 range_trans_rule_init(rule); 4598 4599 while ((id = queue_remove(id_queue))) { 4600 if (set_types(&rule->stypes, id, &add, 0)) 4601 goto out; 4602 } 4603 add = 1; 4604 while ((id = queue_remove(id_queue))) { 4605 if (set_types(&rule->ttypes, id, &add, 0)) 4606 goto out; 4607 } 4608 4609 if (class_specified) { 4610 if (read_classes(&rule->tclasses)) 4611 goto out; 4612 } else { 4613 cladatum = hashtab_search(policydbp->p_classes.table, 4614 "process"); 4615 if (!cladatum) { 4616 yyerror2("could not find process class for " 4617 "legacy range_transition statement"); 4618 goto out; 4619 } 4620 4621 ebitmap_set_bit(&rule->tclasses, cladatum->s.value - 1, TRUE); 4622 } 4623 4624 id = (char *)queue_remove(id_queue); 4625 if (!id) { 4626 yyerror("no range in range_transition definition?"); 4627 goto out; 4628 } 4629 for (l = 0; l < 2; l++) { 4630 levdatum = hashtab_search(policydbp->p_levels.table, id); 4631 if (!levdatum) { 4632 yyerror2("unknown level %s used in range_transition " 4633 "definition", id); 4634 free(id); 4635 goto out; 4636 } 4637 free(id); 4638 4639 rule->trange.level[l].sens = levdatum->level->sens; 4640 4641 while ((id = queue_remove(id_queue))) { 4642 if (parse_semantic_categories(id, levdatum, 4643 &rule->trange.level[l].cat)) { 4644 free(id); 4645 goto out; 4646 } 4647 free(id); 4648 } 4649 4650 id = (char *)queue_remove(id_queue); 4651 if (!id) 4652 break; 4653 } 4654 if (l == 0) { 4655 if (mls_semantic_level_cpy(&rule->trange.level[1], 4656 &rule->trange.level[0])) { 4657 yyerror("out of memory"); 4658 goto out; 4659 } 4660 } 4661 4662 append_range_trans(rule); 4663 return 0; 4664 4665out: 4666 range_trans_rule_destroy(rule); 4667 return -1; 4668} 4669 4670/* FLASK */ 4671