Messages in this thread | | | Date | Mon, 7 Nov 2022 13:56:30 -0500 | From | Aristeu Rozanski <> | Subject | Re: [PATCH] device_cgroup: Roll back to original exceptions after copy failure |
| |
On Tue, Oct 25, 2022 at 07:31:01PM +0800, Wang Weiyang wrote: > When add the 'a *:* rwm' entry to devcgroup A's whitelist, at first A's > exceptions will be cleaned and A's behavior is changed to > DEVCG_DEFAULT_ALLOW. Then parent's exceptions will be copyed to A's > whitelist. If copy failure occurs, just return leaving A to grant > permissions to all devices. And A may grant more permissions than > parent. > > Backup A's whitelist and recover original exceptions after copy > failure. > > Fixes: 4cef7299b478 ("device_cgroup: add proper checking when changing default behavior") > Signed-off-by: Wang Weiyang <wangweiyang2@huawei.com> > --- > security/device_cgroup.c | 33 +++++++++++++++++++++++++++++---- > 1 file changed, 29 insertions(+), 4 deletions(-) > > diff --git a/security/device_cgroup.c b/security/device_cgroup.c > index a9f8c63a96d1..bef2b9285fb3 100644 > --- a/security/device_cgroup.c > +++ b/security/device_cgroup.c > @@ -82,6 +82,17 @@ static int dev_exceptions_copy(struct list_head *dest, struct list_head *orig) > return -ENOMEM; > } > > +static void dev_exceptions_move(struct list_head *dest, struct list_head *orig) > +{ > + struct dev_exception_item *ex, *tmp; > + > + lockdep_assert_held(&devcgroup_mutex); > + > + list_for_each_entry_safe(ex, tmp, orig, list) { > + list_move_tail(&ex->list, dest); > + } > +} > + > /* > * called under devcgroup_mutex > */ > @@ -604,11 +615,13 @@ static int devcgroup_update_access(struct dev_cgroup *devcgroup, > int count, rc = 0; > struct dev_exception_item ex; > struct dev_cgroup *parent = css_to_devcgroup(devcgroup->css.parent); > + struct dev_cgroup tmp_devcgrp; > > if (!capable(CAP_SYS_ADMIN)) > return -EPERM; > > memset(&ex, 0, sizeof(ex)); > + memset(&tmp_devcgrp, 0, sizeof(tmp_devcgrp)); > b = buffer; > > switch (*b) { > @@ -620,15 +633,27 @@ static int devcgroup_update_access(struct dev_cgroup *devcgroup, > > if (!may_allow_all(parent)) > return -EPERM; > - dev_exception_clean(devcgroup); > - devcgroup->behavior = DEVCG_DEFAULT_ALLOW; > - if (!parent) > + if (!parent) { > + devcgroup->behavior = DEVCG_DEFAULT_ALLOW; > + dev_exception_clean(devcgroup); > break; > + } > > + INIT_LIST_HEAD(&tmp_devcgrp.exceptions); > + rc = dev_exceptions_copy(&tmp_devcgrp.exceptions, > + &devcgroup->exceptions); > + if (rc) > + return rc; > + dev_exception_clean(devcgroup); > rc = dev_exceptions_copy(&devcgroup->exceptions, > &parent->exceptions); > - if (rc) > + if (rc) { > + dev_exceptions_move(&devcgroup->exceptions, > + &tmp_devcgrp.exceptions); > return rc; > + } > + devcgroup->behavior = DEVCG_DEFAULT_ALLOW; > + dev_exception_clean(&tmp_devcgrp); > break; > case DEVCG_DENY: > if (css_has_online_children(&devcgroup->css))
Reviewed-by: Aristeu Rozanski <aris@redhat.com>
-- Aristeu
| |