diff options
-rw-r--r-- | security/selinux/ss/services.c | 43 |
1 files changed, 39 insertions, 4 deletions
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 0e5c3a422a8e..cf27b3ee1a95 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c | |||
@@ -525,14 +525,16 @@ static void type_attribute_bounds_av(struct context *scontext, | |||
525 | u16 tclass, | 525 | u16 tclass, |
526 | struct av_decision *avd) | 526 | struct av_decision *avd) |
527 | { | 527 | { |
528 | struct context lo_scontext; | ||
529 | struct context lo_tcontext; | ||
530 | struct av_decision lo_avd; | ||
528 | struct type_datum *source | 531 | struct type_datum *source |
529 | = policydb.type_val_to_struct[scontext->type - 1]; | 532 | = policydb.type_val_to_struct[scontext->type - 1]; |
533 | struct type_datum *target | ||
534 | = policydb.type_val_to_struct[tcontext->type - 1]; | ||
535 | u32 masked = 0; | ||
530 | 536 | ||
531 | if (source->bounds) { | 537 | if (source->bounds) { |
532 | struct context lo_scontext; | ||
533 | struct av_decision lo_avd; | ||
534 | u32 masked; | ||
535 | |||
536 | memset(&lo_avd, 0, sizeof(lo_avd)); | 538 | memset(&lo_avd, 0, sizeof(lo_avd)); |
537 | 539 | ||
538 | memcpy(&lo_scontext, scontext, sizeof(lo_scontext)); | 540 | memcpy(&lo_scontext, scontext, sizeof(lo_scontext)); |
@@ -545,7 +547,40 @@ static void type_attribute_bounds_av(struct context *scontext, | |||
545 | if ((lo_avd.allowed & avd->allowed) == avd->allowed) | 547 | if ((lo_avd.allowed & avd->allowed) == avd->allowed) |
546 | return; /* no masked permission */ | 548 | return; /* no masked permission */ |
547 | masked = ~lo_avd.allowed & avd->allowed; | 549 | masked = ~lo_avd.allowed & avd->allowed; |
550 | } | ||
551 | |||
552 | if (target->bounds) { | ||
553 | memset(&lo_avd, 0, sizeof(lo_avd)); | ||
554 | |||
555 | memcpy(&lo_tcontext, tcontext, sizeof(lo_tcontext)); | ||
556 | lo_tcontext.type = target->bounds; | ||
557 | |||
558 | context_struct_compute_av(scontext, | ||
559 | &lo_tcontext, | ||
560 | tclass, | ||
561 | &lo_avd); | ||
562 | if ((lo_avd.allowed & avd->allowed) == avd->allowed) | ||
563 | return; /* no masked permission */ | ||
564 | masked = ~lo_avd.allowed & avd->allowed; | ||
565 | } | ||
566 | |||
567 | if (source->bounds && target->bounds) { | ||
568 | memset(&lo_avd, 0, sizeof(lo_avd)); | ||
569 | /* | ||
570 | * lo_scontext and lo_tcontext are already | ||
571 | * set up. | ||
572 | */ | ||
573 | |||
574 | context_struct_compute_av(&lo_scontext, | ||
575 | &lo_tcontext, | ||
576 | tclass, | ||
577 | &lo_avd); | ||
578 | if ((lo_avd.allowed & avd->allowed) == avd->allowed) | ||
579 | return; /* no masked permission */ | ||
580 | masked = ~lo_avd.allowed & avd->allowed; | ||
581 | } | ||
548 | 582 | ||
583 | if (masked) { | ||
549 | /* mask violated permissions */ | 584 | /* mask violated permissions */ |
550 | avd->allowed &= ~masked; | 585 | avd->allowed &= ~masked; |
551 | 586 | ||