Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
conditional.c
Go to the documentation of this file.
1 /* Authors: Karl MacMillan <[email protected]>
2  * Frank Mayer <[email protected]>
3  *
4  * Copyright (C) 2003 - 2004 Tresys Technology, LLC
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, version 2.
8  */
9 
10 #include <linux/kernel.h>
11 #include <linux/errno.h>
12 #include <linux/string.h>
13 #include <linux/spinlock.h>
14 #include <linux/slab.h>
15 
16 #include "security.h"
17 #include "conditional.h"
18 
19 /*
20  * cond_evaluate_expr evaluates a conditional expr
21  * in reverse polish notation. It returns true (1), false (0),
22  * or undefined (-1). Undefined occurs when the expression
23  * exceeds the stack depth of COND_EXPR_MAXDEPTH.
24  */
25 static int cond_evaluate_expr(struct policydb *p, struct cond_expr *expr)
26 {
27 
28  struct cond_expr *cur;
29  int s[COND_EXPR_MAXDEPTH];
30  int sp = -1;
31 
32  for (cur = expr; cur; cur = cur->next) {
33  switch (cur->expr_type) {
34  case COND_BOOL:
35  if (sp == (COND_EXPR_MAXDEPTH - 1))
36  return -1;
37  sp++;
38  s[sp] = p->bool_val_to_struct[cur->bool - 1]->state;
39  break;
40  case COND_NOT:
41  if (sp < 0)
42  return -1;
43  s[sp] = !s[sp];
44  break;
45  case COND_OR:
46  if (sp < 1)
47  return -1;
48  sp--;
49  s[sp] |= s[sp + 1];
50  break;
51  case COND_AND:
52  if (sp < 1)
53  return -1;
54  sp--;
55  s[sp] &= s[sp + 1];
56  break;
57  case COND_XOR:
58  if (sp < 1)
59  return -1;
60  sp--;
61  s[sp] ^= s[sp + 1];
62  break;
63  case COND_EQ:
64  if (sp < 1)
65  return -1;
66  sp--;
67  s[sp] = (s[sp] == s[sp + 1]);
68  break;
69  case COND_NEQ:
70  if (sp < 1)
71  return -1;
72  sp--;
73  s[sp] = (s[sp] != s[sp + 1]);
74  break;
75  default:
76  return -1;
77  }
78  }
79  return s[0];
80 }
81 
82 /*
83  * evaluate_cond_node evaluates the conditional stored in
84  * a struct cond_node and if the result is different than the
85  * current state of the node it sets the rules in the true/false
86  * list appropriately. If the result of the expression is undefined
87  * all of the rules are disabled for safety.
88  */
89 int evaluate_cond_node(struct policydb *p, struct cond_node *node)
90 {
91  int new_state;
92  struct cond_av_list *cur;
93 
94  new_state = cond_evaluate_expr(p, node->expr);
95  if (new_state != node->cur_state) {
96  node->cur_state = new_state;
97  if (new_state == -1)
98  printk(KERN_ERR "SELinux: expression result was undefined - disabling all rules.\n");
99  /* turn the rules on or off */
100  for (cur = node->true_list; cur; cur = cur->next) {
101  if (new_state <= 0)
102  cur->node->key.specified &= ~AVTAB_ENABLED;
103  else
104  cur->node->key.specified |= AVTAB_ENABLED;
105  }
106 
107  for (cur = node->false_list; cur; cur = cur->next) {
108  /* -1 or 1 */
109  if (new_state)
110  cur->node->key.specified &= ~AVTAB_ENABLED;
111  else
112  cur->node->key.specified |= AVTAB_ENABLED;
113  }
114  }
115  return 0;
116 }
117 
119 {
120  int rc;
121 
123  p->cond_list = NULL;
124 
125  rc = avtab_init(&p->te_cond_avtab);
126  if (rc)
127  return rc;
128 
129  return 0;
130 }
131 
132 static void cond_av_list_destroy(struct cond_av_list *list)
133 {
134  struct cond_av_list *cur, *next;
135  for (cur = list; cur; cur = next) {
136  next = cur->next;
137  /* the avtab_ptr_t node is destroy by the avtab */
138  kfree(cur);
139  }
140 }
141 
142 static void cond_node_destroy(struct cond_node *node)
143 {
144  struct cond_expr *cur_expr, *next_expr;
145 
146  for (cur_expr = node->expr; cur_expr; cur_expr = next_expr) {
147  next_expr = cur_expr->next;
148  kfree(cur_expr);
149  }
150  cond_av_list_destroy(node->true_list);
151  cond_av_list_destroy(node->false_list);
152  kfree(node);
153 }
154 
155 static void cond_list_destroy(struct cond_node *list)
156 {
157  struct cond_node *next, *cur;
158 
159  if (list == NULL)
160  return;
161 
162  for (cur = list; cur; cur = next) {
163  next = cur->next;
164  cond_node_destroy(cur);
165  }
166 }
167 
169 {
172  cond_list_destroy(p->cond_list);
173 }
174 
176 {
178  p->bool_val_to_struct =
179  kmalloc(p->p_bools.nprim * sizeof(struct cond_bool_datum *), GFP_KERNEL);
180  if (!p->bool_val_to_struct)
181  return -ENOMEM;
182  return 0;
183 }
184 
185 int cond_destroy_bool(void *key, void *datum, void *p)
186 {
187  kfree(key);
188  kfree(datum);
189  return 0;
190 }
191 
192 int cond_index_bool(void *key, void *datum, void *datap)
193 {
194  struct policydb *p;
195  struct cond_bool_datum *booldatum;
196  struct flex_array *fa;
197 
198  booldatum = datum;
199  p = datap;
200 
201  if (!booldatum->value || booldatum->value > p->p_bools.nprim)
202  return -EINVAL;
203 
204  fa = p->sym_val_to_name[SYM_BOOLS];
205  if (flex_array_put_ptr(fa, booldatum->value - 1, key,
207  BUG();
208  p->bool_val_to_struct[booldatum->value - 1] = booldatum;
209 
210  return 0;
211 }
212 
213 static int bool_isvalid(struct cond_bool_datum *b)
214 {
215  if (!(b->state == 0 || b->state == 1))
216  return 0;
217  return 1;
218 }
219 
220 int cond_read_bool(struct policydb *p, struct hashtab *h, void *fp)
221 {
222  char *key = NULL;
223  struct cond_bool_datum *booldatum;
224  __le32 buf[3];
225  u32 len;
226  int rc;
227 
228  booldatum = kzalloc(sizeof(struct cond_bool_datum), GFP_KERNEL);
229  if (!booldatum)
230  return -ENOMEM;
231 
232  rc = next_entry(buf, fp, sizeof buf);
233  if (rc)
234  goto err;
235 
236  booldatum->value = le32_to_cpu(buf[0]);
237  booldatum->state = le32_to_cpu(buf[1]);
238 
239  rc = -EINVAL;
240  if (!bool_isvalid(booldatum))
241  goto err;
242 
243  len = le32_to_cpu(buf[2]);
244 
245  rc = -ENOMEM;
246  key = kmalloc(len + 1, GFP_KERNEL);
247  if (!key)
248  goto err;
249  rc = next_entry(key, fp, len);
250  if (rc)
251  goto err;
252  key[len] = '\0';
253  rc = hashtab_insert(h, key, booldatum);
254  if (rc)
255  goto err;
256 
257  return 0;
258 err:
259  cond_destroy_bool(key, booldatum, NULL);
260  return rc;
261 }
262 
264  struct policydb *p;
268 };
269 
270 static int cond_insertf(struct avtab *a, struct avtab_key *k, struct avtab_datum *d, void *ptr)
271 {
272  struct cond_insertf_data *data = ptr;
273  struct policydb *p = data->p;
274  struct cond_av_list *other = data->other, *list, *cur;
275  struct avtab_node *node_ptr;
276  u8 found;
277  int rc = -EINVAL;
278 
279  /*
280  * For type rules we have to make certain there aren't any
281  * conflicting rules by searching the te_avtab and the
282  * cond_te_avtab.
283  */
284  if (k->specified & AVTAB_TYPE) {
285  if (avtab_search(&p->te_avtab, k)) {
286  printk(KERN_ERR "SELinux: type rule already exists outside of a conditional.\n");
287  goto err;
288  }
289  /*
290  * If we are reading the false list other will be a pointer to
291  * the true list. We can have duplicate entries if there is only
292  * 1 other entry and it is in our true list.
293  *
294  * If we are reading the true list (other == NULL) there shouldn't
295  * be any other entries.
296  */
297  if (other) {
298  node_ptr = avtab_search_node(&p->te_cond_avtab, k);
299  if (node_ptr) {
300  if (avtab_search_node_next(node_ptr, k->specified)) {
301  printk(KERN_ERR "SELinux: too many conflicting type rules.\n");
302  goto err;
303  }
304  found = 0;
305  for (cur = other; cur; cur = cur->next) {
306  if (cur->node == node_ptr) {
307  found = 1;
308  break;
309  }
310  }
311  if (!found) {
312  printk(KERN_ERR "SELinux: conflicting type rules.\n");
313  goto err;
314  }
315  }
316  } else {
317  if (avtab_search(&p->te_cond_avtab, k)) {
318  printk(KERN_ERR "SELinux: conflicting type rules when adding type rule for true.\n");
319  goto err;
320  }
321  }
322  }
323 
324  node_ptr = avtab_insert_nonunique(&p->te_cond_avtab, k, d);
325  if (!node_ptr) {
326  printk(KERN_ERR "SELinux: could not insert rule.\n");
327  rc = -ENOMEM;
328  goto err;
329  }
330 
331  list = kzalloc(sizeof(struct cond_av_list), GFP_KERNEL);
332  if (!list) {
333  rc = -ENOMEM;
334  goto err;
335  }
336 
337  list->node = node_ptr;
338  if (!data->head)
339  data->head = list;
340  else
341  data->tail->next = list;
342  data->tail = list;
343  return 0;
344 
345 err:
346  cond_av_list_destroy(data->head);
347  data->head = NULL;
348  return rc;
349 }
350 
351 static int cond_read_av_list(struct policydb *p, void *fp, struct cond_av_list **ret_list, struct cond_av_list *other)
352 {
353  int i, rc;
354  __le32 buf[1];
355  u32 len;
356  struct cond_insertf_data data;
357 
358  *ret_list = NULL;
359 
360  len = 0;
361  rc = next_entry(buf, fp, sizeof(u32));
362  if (rc)
363  return rc;
364 
365  len = le32_to_cpu(buf[0]);
366  if (len == 0)
367  return 0;
368 
369  data.p = p;
370  data.other = other;
371  data.head = NULL;
372  data.tail = NULL;
373  for (i = 0; i < len; i++) {
374  rc = avtab_read_item(&p->te_cond_avtab, fp, p, cond_insertf,
375  &data);
376  if (rc)
377  return rc;
378  }
379 
380  *ret_list = data.head;
381  return 0;
382 }
383 
384 static int expr_isvalid(struct policydb *p, struct cond_expr *expr)
385 {
386  if (expr->expr_type <= 0 || expr->expr_type > COND_LAST) {
387  printk(KERN_ERR "SELinux: conditional expressions uses unknown operator.\n");
388  return 0;
389  }
390 
391  if (expr->bool > p->p_bools.nprim) {
392  printk(KERN_ERR "SELinux: conditional expressions uses unknown bool.\n");
393  return 0;
394  }
395  return 1;
396 }
397 
398 static int cond_read_node(struct policydb *p, struct cond_node *node, void *fp)
399 {
400  __le32 buf[2];
401  u32 len, i;
402  int rc;
403  struct cond_expr *expr = NULL, *last = NULL;
404 
405  rc = next_entry(buf, fp, sizeof(u32));
406  if (rc)
407  return rc;
408 
409  node->cur_state = le32_to_cpu(buf[0]);
410 
411  len = 0;
412  rc = next_entry(buf, fp, sizeof(u32));
413  if (rc)
414  return rc;
415 
416  /* expr */
417  len = le32_to_cpu(buf[0]);
418 
419  for (i = 0; i < len; i++) {
420  rc = next_entry(buf, fp, sizeof(u32) * 2);
421  if (rc)
422  goto err;
423 
424  rc = -ENOMEM;
425  expr = kzalloc(sizeof(struct cond_expr), GFP_KERNEL);
426  if (!expr)
427  goto err;
428 
429  expr->expr_type = le32_to_cpu(buf[0]);
430  expr->bool = le32_to_cpu(buf[1]);
431 
432  if (!expr_isvalid(p, expr)) {
433  rc = -EINVAL;
434  kfree(expr);
435  goto err;
436  }
437 
438  if (i == 0)
439  node->expr = expr;
440  else
441  last->next = expr;
442  last = expr;
443  }
444 
445  rc = cond_read_av_list(p, fp, &node->true_list, NULL);
446  if (rc)
447  goto err;
448  rc = cond_read_av_list(p, fp, &node->false_list, node->true_list);
449  if (rc)
450  goto err;
451  return 0;
452 err:
453  cond_node_destroy(node);
454  return rc;
455 }
456 
457 int cond_read_list(struct policydb *p, void *fp)
458 {
459  struct cond_node *node, *last = NULL;
460  __le32 buf[1];
461  u32 i, len;
462  int rc;
463 
464  rc = next_entry(buf, fp, sizeof buf);
465  if (rc)
466  return rc;
467 
468  len = le32_to_cpu(buf[0]);
469 
470  rc = avtab_alloc(&(p->te_cond_avtab), p->te_avtab.nel);
471  if (rc)
472  goto err;
473 
474  for (i = 0; i < len; i++) {
475  rc = -ENOMEM;
476  node = kzalloc(sizeof(struct cond_node), GFP_KERNEL);
477  if (!node)
478  goto err;
479 
480  rc = cond_read_node(p, node, fp);
481  if (rc)
482  goto err;
483 
484  if (i == 0)
485  p->cond_list = node;
486  else
487  last->next = node;
488  last = node;
489  }
490  return 0;
491 err:
492  cond_list_destroy(p->cond_list);
493  p->cond_list = NULL;
494  return rc;
495 }
496 
497 int cond_write_bool(void *vkey, void *datum, void *ptr)
498 {
499  char *key = vkey;
500  struct cond_bool_datum *booldatum = datum;
501  struct policy_data *pd = ptr;
502  void *fp = pd->fp;
503  __le32 buf[3];
504  u32 len;
505  int rc;
506 
507  len = strlen(key);
508  buf[0] = cpu_to_le32(booldatum->value);
509  buf[1] = cpu_to_le32(booldatum->state);
510  buf[2] = cpu_to_le32(len);
511  rc = put_entry(buf, sizeof(u32), 3, fp);
512  if (rc)
513  return rc;
514  rc = put_entry(key, 1, len, fp);
515  if (rc)
516  return rc;
517  return 0;
518 }
519 
520 /*
521  * cond_write_cond_av_list doesn't write out the av_list nodes.
522  * Instead it writes out the key/value pairs from the avtab. This
523  * is necessary because there is no way to uniquely identifying rules
524  * in the avtab so it is not possible to associate individual rules
525  * in the avtab with a conditional without saving them as part of
526  * the conditional. This means that the avtab with the conditional
527  * rules will not be saved but will be rebuilt on policy load.
528  */
529 static int cond_write_av_list(struct policydb *p,
530  struct cond_av_list *list, struct policy_file *fp)
531 {
532  __le32 buf[1];
533  struct cond_av_list *cur_list;
534  u32 len;
535  int rc;
536 
537  len = 0;
538  for (cur_list = list; cur_list != NULL; cur_list = cur_list->next)
539  len++;
540 
541  buf[0] = cpu_to_le32(len);
542  rc = put_entry(buf, sizeof(u32), 1, fp);
543  if (rc)
544  return rc;
545 
546  if (len == 0)
547  return 0;
548 
549  for (cur_list = list; cur_list != NULL; cur_list = cur_list->next) {
550  rc = avtab_write_item(p, cur_list->node, fp);
551  if (rc)
552  return rc;
553  }
554 
555  return 0;
556 }
557 
558 static int cond_write_node(struct policydb *p, struct cond_node *node,
559  struct policy_file *fp)
560 {
561  struct cond_expr *cur_expr;
562  __le32 buf[2];
563  int rc;
564  u32 len = 0;
565 
566  buf[0] = cpu_to_le32(node->cur_state);
567  rc = put_entry(buf, sizeof(u32), 1, fp);
568  if (rc)
569  return rc;
570 
571  for (cur_expr = node->expr; cur_expr != NULL; cur_expr = cur_expr->next)
572  len++;
573 
574  buf[0] = cpu_to_le32(len);
575  rc = put_entry(buf, sizeof(u32), 1, fp);
576  if (rc)
577  return rc;
578 
579  for (cur_expr = node->expr; cur_expr != NULL; cur_expr = cur_expr->next) {
580  buf[0] = cpu_to_le32(cur_expr->expr_type);
581  buf[1] = cpu_to_le32(cur_expr->bool);
582  rc = put_entry(buf, sizeof(u32), 2, fp);
583  if (rc)
584  return rc;
585  }
586 
587  rc = cond_write_av_list(p, node->true_list, fp);
588  if (rc)
589  return rc;
590  rc = cond_write_av_list(p, node->false_list, fp);
591  if (rc)
592  return rc;
593 
594  return 0;
595 }
596 
597 int cond_write_list(struct policydb *p, struct cond_node *list, void *fp)
598 {
599  struct cond_node *cur;
600  u32 len;
601  __le32 buf[1];
602  int rc;
603 
604  len = 0;
605  for (cur = list; cur != NULL; cur = cur->next)
606  len++;
607  buf[0] = cpu_to_le32(len);
608  rc = put_entry(buf, sizeof(u32), 1, fp);
609  if (rc)
610  return rc;
611 
612  for (cur = list; cur != NULL; cur = cur->next) {
613  rc = cond_write_node(p, cur, fp);
614  if (rc)
615  return rc;
616  }
617 
618  return 0;
619 }
620 /* Determine whether additional permissions are granted by the conditional
621  * av table, and if so, add them to the result
622  */
623 void cond_compute_av(struct avtab *ctab, struct avtab_key *key, struct av_decision *avd)
624 {
625  struct avtab_node *node;
626 
627  if (!ctab || !key || !avd)
628  return;
629 
630  for (node = avtab_search_node(ctab, key); node;
631  node = avtab_search_node_next(node, key->specified)) {
633  (node->key.specified & (AVTAB_ALLOWED|AVTAB_ENABLED)))
634  avd->allowed |= node->datum.data;
636  (node->key.specified & (AVTAB_AUDITDENY|AVTAB_ENABLED)))
637  /* Since a '0' in an auditdeny mask represents a
638  * permission we do NOT want to audit (dontaudit), we use
639  * the '&' operand to ensure that all '0's in the mask
640  * are retained (much unlike the allow and auditallow cases).
641  */
642  avd->auditdeny &= node->datum.data;
644  (node->key.specified & (AVTAB_AUDITALLOW|AVTAB_ENABLED)))
645  avd->auditallow |= node->datum.data;
646  }
647  return;
648 }