| .. | .. |
|---|
| 81 | 81 | return -ENOMEM; |
|---|
| 82 | 82 | } |
|---|
| 83 | 83 | |
|---|
| 84 | +static void dev_exceptions_move(struct list_head *dest, struct list_head *orig) |
|---|
| 85 | +{ |
|---|
| 86 | + struct dev_exception_item *ex, *tmp; |
|---|
| 87 | + |
|---|
| 88 | + lockdep_assert_held(&devcgroup_mutex); |
|---|
| 89 | + |
|---|
| 90 | + list_for_each_entry_safe(ex, tmp, orig, list) { |
|---|
| 91 | + list_move_tail(&ex->list, dest); |
|---|
| 92 | + } |
|---|
| 93 | +} |
|---|
| 94 | + |
|---|
| 84 | 95 | /* |
|---|
| 85 | 96 | * called under devcgroup_mutex |
|---|
| 86 | 97 | */ |
|---|
| .. | .. |
|---|
| 603 | 614 | int count, rc = 0; |
|---|
| 604 | 615 | struct dev_exception_item ex; |
|---|
| 605 | 616 | struct dev_cgroup *parent = css_to_devcgroup(devcgroup->css.parent); |
|---|
| 617 | + struct dev_cgroup tmp_devcgrp; |
|---|
| 606 | 618 | |
|---|
| 607 | 619 | if (!capable(CAP_SYS_ADMIN)) |
|---|
| 608 | 620 | return -EPERM; |
|---|
| 609 | 621 | |
|---|
| 610 | 622 | memset(&ex, 0, sizeof(ex)); |
|---|
| 623 | + memset(&tmp_devcgrp, 0, sizeof(tmp_devcgrp)); |
|---|
| 611 | 624 | b = buffer; |
|---|
| 612 | 625 | |
|---|
| 613 | 626 | switch (*b) { |
|---|
| .. | .. |
|---|
| 619 | 632 | |
|---|
| 620 | 633 | if (!may_allow_all(parent)) |
|---|
| 621 | 634 | return -EPERM; |
|---|
| 622 | | - dev_exception_clean(devcgroup); |
|---|
| 623 | | - devcgroup->behavior = DEVCG_DEFAULT_ALLOW; |
|---|
| 624 | | - if (!parent) |
|---|
| 635 | + if (!parent) { |
|---|
| 636 | + devcgroup->behavior = DEVCG_DEFAULT_ALLOW; |
|---|
| 637 | + dev_exception_clean(devcgroup); |
|---|
| 625 | 638 | break; |
|---|
| 639 | + } |
|---|
| 626 | 640 | |
|---|
| 627 | | - rc = dev_exceptions_copy(&devcgroup->exceptions, |
|---|
| 628 | | - &parent->exceptions); |
|---|
| 641 | + INIT_LIST_HEAD(&tmp_devcgrp.exceptions); |
|---|
| 642 | + rc = dev_exceptions_copy(&tmp_devcgrp.exceptions, |
|---|
| 643 | + &devcgroup->exceptions); |
|---|
| 629 | 644 | if (rc) |
|---|
| 630 | 645 | return rc; |
|---|
| 646 | + dev_exception_clean(devcgroup); |
|---|
| 647 | + rc = dev_exceptions_copy(&devcgroup->exceptions, |
|---|
| 648 | + &parent->exceptions); |
|---|
| 649 | + if (rc) { |
|---|
| 650 | + dev_exceptions_move(&devcgroup->exceptions, |
|---|
| 651 | + &tmp_devcgrp.exceptions); |
|---|
| 652 | + return rc; |
|---|
| 653 | + } |
|---|
| 654 | + devcgroup->behavior = DEVCG_DEFAULT_ALLOW; |
|---|
| 655 | + dev_exception_clean(&tmp_devcgrp); |
|---|
| 631 | 656 | break; |
|---|
| 632 | 657 | case DEVCG_DENY: |
|---|
| 633 | 658 | if (css_has_online_children(&devcgroup->css)) |
|---|