aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/ss/conditional.c
diff options
context:
space:
mode:
authorJeff Vander Stoep <jeffv@google.com>2015-07-10 17:19:56 -0400
committerPaul Moore <pmoore@redhat.com>2015-07-13 13:31:58 -0400
commitfa1aa143ac4a682c7f5fd52a3cf05f5a6fe44a0a (patch)
tree3f53aa6f35af83370aa7cd7bc25a2f6a2b6b8bbd /security/selinux/ss/conditional.c
parent671a2781ff01abf4fdc8904881fc3abd3a8279af (diff)
selinux: extended permissions for ioctls
Add extended permissions logic to selinux. Extended permissions provides additional permissions in 256 bit increments. Extend the generic ioctl permission check to use the extended permissions for per-command filtering. Source/target/class sets including the ioctl permission may additionally include a set of commands. Example: allowxperm <source> <target>:<class> ioctl unpriv_app_socket_cmds auditallowxperm <source> <target>:<class> ioctl priv_gpu_cmds Where unpriv_app_socket_cmds and priv_gpu_cmds are macros representing commonly granted sets of ioctl commands. When ioctl commands are omitted only the permissions are checked. This feature is intended to provide finer granularity for the ioctl permission that may be too imprecise. For example, the same driver may use ioctls to provide important and benign functionality such as driver version or socket type as well as dangerous capabilities such as debugging features, read/write/execute to physical memory or access to sensitive data. Per-command filtering provides a mechanism to reduce the attack surface of the kernel, and limit applications to the subset of commands required. The format of the policy binary has been modified to include ioctl commands, and the policy version number has been incremented to POLICYDB_VERSION_XPERMS_IOCTL=30 to account for the format change. The extended permissions logic is deliberately generic to allow components to be reused e.g. netlink filters Signed-off-by: Jeff Vander Stoep <jeffv@google.com> Acked-by: Nick Kralevich <nnk@google.com> Signed-off-by: Paul Moore <pmoore@redhat.com>
Diffstat (limited to 'security/selinux/ss/conditional.c')
-rw-r--r--security/selinux/ss/conditional.c32
1 files changed, 27 insertions, 5 deletions
diff --git a/security/selinux/ss/conditional.c b/security/selinux/ss/conditional.c
index 62c6773be0b7..18643bf9894d 100644
--- a/security/selinux/ss/conditional.c
+++ b/security/selinux/ss/conditional.c
@@ -15,6 +15,7 @@
15 15
16#include "security.h" 16#include "security.h"
17#include "conditional.h" 17#include "conditional.h"
18#include "services.h"
18 19
19/* 20/*
20 * cond_evaluate_expr evaluates a conditional expr 21 * cond_evaluate_expr evaluates a conditional expr
@@ -612,21 +613,39 @@ int cond_write_list(struct policydb *p, struct cond_node *list, void *fp)
612 613
613 return 0; 614 return 0;
614} 615}
616
617void cond_compute_xperms(struct avtab *ctab, struct avtab_key *key,
618 struct extended_perms_decision *xpermd)
619{
620 struct avtab_node *node;
621
622 if (!ctab || !key || !xpermd)
623 return;
624
625 for (node = avtab_search_node(ctab, key); node;
626 node = avtab_search_node_next(node, key->specified)) {
627 if (node->key.specified & AVTAB_ENABLED)
628 services_compute_xperms_decision(xpermd, node);
629 }
630 return;
631
632}
615/* Determine whether additional permissions are granted by the conditional 633/* Determine whether additional permissions are granted by the conditional
616 * av table, and if so, add them to the result 634 * av table, and if so, add them to the result
617 */ 635 */
618void cond_compute_av(struct avtab *ctab, struct avtab_key *key, struct av_decision *avd) 636void cond_compute_av(struct avtab *ctab, struct avtab_key *key,
637 struct av_decision *avd, struct extended_perms *xperms)
619{ 638{
620 struct avtab_node *node; 639 struct avtab_node *node;
621 640
622 if (!ctab || !key || !avd) 641 if (!ctab || !key || !avd || !xperms)
623 return; 642 return;
624 643
625 for (node = avtab_search_node(ctab, key); node; 644 for (node = avtab_search_node(ctab, key); node;
626 node = avtab_search_node_next(node, key->specified)) { 645 node = avtab_search_node_next(node, key->specified)) {
627 if ((u16)(AVTAB_ALLOWED|AVTAB_ENABLED) == 646 if ((u16)(AVTAB_ALLOWED|AVTAB_ENABLED) ==
628 (node->key.specified & (AVTAB_ALLOWED|AVTAB_ENABLED))) 647 (node->key.specified & (AVTAB_ALLOWED|AVTAB_ENABLED)))
629 avd->allowed |= node->datum.data; 648 avd->allowed |= node->datum.u.data;
630 if ((u16)(AVTAB_AUDITDENY|AVTAB_ENABLED) == 649 if ((u16)(AVTAB_AUDITDENY|AVTAB_ENABLED) ==
631 (node->key.specified & (AVTAB_AUDITDENY|AVTAB_ENABLED))) 650 (node->key.specified & (AVTAB_AUDITDENY|AVTAB_ENABLED)))
632 /* Since a '0' in an auditdeny mask represents a 651 /* Since a '0' in an auditdeny mask represents a
@@ -634,10 +653,13 @@ void cond_compute_av(struct avtab *ctab, struct avtab_key *key, struct av_decisi
634 * the '&' operand to ensure that all '0's in the mask 653 * the '&' operand to ensure that all '0's in the mask
635 * are retained (much unlike the allow and auditallow cases). 654 * are retained (much unlike the allow and auditallow cases).
636 */ 655 */
637 avd->auditdeny &= node->datum.data; 656 avd->auditdeny &= node->datum.u.data;
638 if ((u16)(AVTAB_AUDITALLOW|AVTAB_ENABLED) == 657 if ((u16)(AVTAB_AUDITALLOW|AVTAB_ENABLED) ==
639 (node->key.specified & (AVTAB_AUDITALLOW|AVTAB_ENABLED))) 658 (node->key.specified & (AVTAB_AUDITALLOW|AVTAB_ENABLED)))
640 avd->auditallow |= node->datum.data; 659 avd->auditallow |= node->datum.u.data;
660 if ((node->key.specified & AVTAB_ENABLED) &&
661 (node->key.specified & AVTAB_XPERMS))
662 services_compute_xperms_drivers(xperms, node);
641 } 663 }
642 return; 664 return;
643} 665}