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 | ||
