* [PATCH] device_cgroup: do not use rule acceptance function to validate access
@ 2014-04-14 14:47 Aristeu Rozanski
[not found] ` <20140414144736.GS29214-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
0 siblings, 1 reply; 6+ messages in thread
From: Aristeu Rozanski @ 2014-04-14 14:47 UTC (permalink / raw)
To: cgroups-u79uwXL29TY76Z2rM5mHXA; +Cc: Tejun Heo, Li Zefan, Serge Hallyn
may_access() is currently used to validate both new exceptions from children
groups and to check if an access is allowed. This not only makes it hard to
understand and maintain, but it's also incorrect.
It currently allows one to:
# mkdir new_group
# cd new_group
# echo $$ >tasks
# echo "c 1:3 w" >devices.deny
# echo >/dev/null
# echo $?
0
This patch implements the device file access check separately and fixes
the issue.
This is broken since c39a2a3018f8065cb5ea38b0314c1bbedb2cfa0d
After review, this should be considered for stable series.
Signed-off-by: Aristeu Rozanski <aris-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
diff --git a/security/device_cgroup.c b/security/device_cgroup.c
index 8365909..d390d21 100644
--- a/security/device_cgroup.c
+++ b/security/device_cgroup.c
@@ -704,21 +704,35 @@ static int __devcgroup_check_permission(short type, u32 major, u32 minor,
short access)
{
struct dev_cgroup *dev_cgroup;
- struct dev_exception_item ex;
- int rc;
-
- memset(&ex, 0, sizeof(ex));
- ex.type = type;
- ex.major = major;
- ex.minor = minor;
- ex.access = access;
+ struct dev_exception_item *ex;
+ enum devcg_behavior behavior;
+ bool match = false;
rcu_read_lock();
dev_cgroup = task_devcgroup(current);
- rc = may_access(dev_cgroup, &ex, dev_cgroup->behavior);
+ behavior = dev_cgroup->behavior;
+ list_for_each_entry_rcu(ex, &dev_cgroup->exceptions, list) {
+ if (type == DEV_BLOCK && !(ex->type & DEV_BLOCK))
+ continue;
+ if (type == DEV_CHAR && !(ex->type & DEV_CHAR))
+ continue;
+ if (ex->major != ~0 && major != ex->major)
+ continue;
+ if (ex->minor != ~0 && minor != ex->minor)
+ continue;
+ if (access & (~ex->access))
+ continue;
+ match = true;
+ break;
+ }
rcu_read_unlock();
- if (!rc)
+ if (behavior == DEVCG_DEFAULT_ALLOW && match)
+ /* access matches a rule to disallow access */
+ return -EPERM;
+
+ if (behavior == DEVCG_DEFAULT_DENY && !match)
+ /* no exceptions found, default action is to deny access */
return -EPERM;
return 0;
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH] device_cgroup: do not use rule acceptance function to validate access
[not found] ` <20140414144736.GS29214-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
@ 2014-04-14 18:03 ` Tejun Heo
[not found] ` <20140414180323.GC15249-Gd/HAXX7CRxy/B6EtB590w@public.gmane.org>
2014-04-15 15:57 ` Serge Hallyn
1 sibling, 1 reply; 6+ messages in thread
From: Tejun Heo @ 2014-04-14 18:03 UTC (permalink / raw)
To: Aristeu Rozanski; +Cc: cgroups-u79uwXL29TY76Z2rM5mHXA, Li Zefan, Serge Hallyn
Hello,
On Mon, Apr 14, 2014 at 10:47:54AM -0400, Aristeu Rozanski wrote:
> may_access() is currently used to validate both new exceptions from children
> groups and to check if an access is allowed. This not only makes it hard to
> understand and maintain, but it's also incorrect.
>
> It currently allows one to:
>
> # mkdir new_group
> # cd new_group
> # echo $$ >tasks
> # echo "c 1:3 w" >devices.deny
> # echo >/dev/null
> # echo $?
> 0
It'd be nice to explain how this is broken and why the code paths
can't be shared.
> This patch implements the device file access check separately and fixes
> the issue.
>
> This is broken since c39a2a3018f8065cb5ea38b0314c1bbedb2cfa0d
Please use 12-digits-of-SHA1 ("Subject of the patch") format.
> After review, this should be considered for stable series.
>
> Signed-off-by: Aristeu Rozanski <aris-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Can you please cc stable on the next posting?
> - rc = may_access(dev_cgroup, &ex, dev_cgroup->behavior);
> + behavior = dev_cgroup->behavior;
> + list_for_each_entry_rcu(ex, &dev_cgroup->exceptions, list) {
> + if (type == DEV_BLOCK && !(ex->type & DEV_BLOCK))
> + continue;
> + if (type == DEV_CHAR && !(ex->type & DEV_CHAR))
> + continue;
> + if (ex->major != ~0 && major != ex->major)
> + continue;
> + if (ex->minor != ~0 && minor != ex->minor)
> + continue;
> + if (access & (~ex->access))
> + continue;
> + match = true;
> + break;
Can't we at least factor out the above part and share it between the
two functions? Currently, there's a lot of duplication in rather
delicate code and it's not clear where they differ and why.
Thanks.
--
tejun
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] device_cgroup: do not use rule acceptance function to validate access
[not found] ` <20140414180323.GC15249-Gd/HAXX7CRxy/B6EtB590w@public.gmane.org>
@ 2014-04-14 18:16 ` Aristeu Rozanski
[not found] ` <20140414181611.GU29214-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
0 siblings, 1 reply; 6+ messages in thread
From: Aristeu Rozanski @ 2014-04-14 18:16 UTC (permalink / raw)
To: Tejun Heo; +Cc: cgroups-u79uwXL29TY76Z2rM5mHXA, Li Zefan, Serge Hallyn
Hi Tejun,
On Mon, Apr 14, 2014 at 02:03:23PM -0400, Tejun Heo wrote:
> On Mon, Apr 14, 2014 at 10:47:54AM -0400, Aristeu Rozanski wrote:
> > may_access() is currently used to validate both new exceptions from children
> > groups and to check if an access is allowed. This not only makes it hard to
> > understand and maintain, but it's also incorrect.
> >
> > It currently allows one to:
> >
> > # mkdir new_group
> > # cd new_group
> > # echo $$ >tasks
> > # echo "c 1:3 w" >devices.deny
> > # echo >/dev/null
> > # echo $?
> > 0
>
> It'd be nice to explain how this is broken and why the code paths
> can't be shared.
ok
> > This patch implements the device file access check separately and fixes
> > the issue.
> >
> > This is broken since c39a2a3018f8065cb5ea38b0314c1bbedb2cfa0d
>
> Please use 12-digits-of-SHA1 ("Subject of the patch") format.
ok
> > After review, this should be considered for stable series.
> >
> > Signed-off-by: Aristeu Rozanski <aris-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
>
> Can you please cc stable on the next posting?
ok
> > - rc = may_access(dev_cgroup, &ex, dev_cgroup->behavior);
> > + behavior = dev_cgroup->behavior;
> > + list_for_each_entry_rcu(ex, &dev_cgroup->exceptions, list) {
> > + if (type == DEV_BLOCK && !(ex->type & DEV_BLOCK))
> > + continue;
> > + if (type == DEV_CHAR && !(ex->type & DEV_CHAR))
> > + continue;
> > + if (ex->major != ~0 && major != ex->major)
> > + continue;
> > + if (ex->minor != ~0 && minor != ex->minor)
> > + continue;
> > + if (access & (~ex->access))
> > + continue;
> > + match = true;
> > + break;
>
> Can't we at least factor out the above part and share it between the
> two functions?
ok
> Currently, there's a lot of duplication in rather
> delicate code and it's not clear where they differ and why.
Are you referring to the duplication in this patch or other areas too?
--
Aristeu
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] device_cgroup: do not use rule acceptance function to validate access
[not found] ` <20140414181611.GU29214-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
@ 2014-04-14 19:07 ` Tejun Heo
0 siblings, 0 replies; 6+ messages in thread
From: Tejun Heo @ 2014-04-14 19:07 UTC (permalink / raw)
To: Aristeu Rozanski; +Cc: cgroups-u79uwXL29TY76Z2rM5mHXA, Li Zefan, Serge Hallyn
Hey,
On Mon, Apr 14, 2014 at 02:16:12PM -0400, Aristeu Rozanski wrote:
> > Currently, there's a lot of duplication in rather
> > delicate code and it's not clear where they differ and why.
>
> Are you referring to the duplication in this patch or other areas too?
In this patch but if you can reduce duplications in reasonable way in
other areas, that'd also be great. :)
Thanks!
--
tejun
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] device_cgroup: do not use rule acceptance function to validate access
[not found] ` <20140414144736.GS29214-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2014-04-14 18:03 ` Tejun Heo
@ 2014-04-15 15:57 ` Serge Hallyn
2014-04-15 16:53 ` Aristeu Rozanski
1 sibling, 1 reply; 6+ messages in thread
From: Serge Hallyn @ 2014-04-15 15:57 UTC (permalink / raw)
To: Aristeu Rozanski
Cc: cgroups-u79uwXL29TY76Z2rM5mHXA, Tejun Heo, Li Zefan, Serge Hallyn
Quoting Aristeu Rozanski (aris-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org):
> may_access() is currently used to validate both new exceptions from children
> groups and to check if an access is allowed. This not only makes it hard to
> understand and maintain, but it's also incorrect.
Heh, well one might argue that may_access() was more approriate at
__devcgroup_check_permission(), should remain simpler, and parent_has_perm()
should be the wrapper doing the extra bits. That would be easier to
read imo.
In what you have here, you end up duplicating the
list_for_each_entry_rcu. I think you should at least have a common
fn for that.
I don't want to sound pedantic, but since the point of this patch is
that simplicity/ease-of-reading would have prevented the bug ... :)
> It currently allows one to:
>
> # mkdir new_group
> # cd new_group
> # echo $$ >tasks
> # echo "c 1:3 w" >devices.deny
> # echo >/dev/null
> # echo $?
> 0
>
> This patch implements the device file access check separately and fixes
> the issue.
>
> This is broken since c39a2a3018f8065cb5ea38b0314c1bbedb2cfa0d
>
> After review, this should be considered for stable series.
Definately.
> Signed-off-by: Aristeu Rozanski <aris-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
I *think* it's ok, and I appreciate you finding and fixing the bug, but
I don't think the result is as easy to read as it could be, so if you
don't mind I'd like to wait for a new version to ack. If you disagree
with me, let me know and I'll re-read and (presumably) ack.
> diff --git a/security/device_cgroup.c b/security/device_cgroup.c
> index 8365909..d390d21 100644
> --- a/security/device_cgroup.c
> +++ b/security/device_cgroup.c
> @@ -704,21 +704,35 @@ static int __devcgroup_check_permission(short type, u32 major, u32 minor,
> short access)
> {
> struct dev_cgroup *dev_cgroup;
> - struct dev_exception_item ex;
> - int rc;
> -
> - memset(&ex, 0, sizeof(ex));
> - ex.type = type;
> - ex.major = major;
> - ex.minor = minor;
> - ex.access = access;
> + struct dev_exception_item *ex;
> + enum devcg_behavior behavior;
> + bool match = false;
>
> rcu_read_lock();
> dev_cgroup = task_devcgroup(current);
> - rc = may_access(dev_cgroup, &ex, dev_cgroup->behavior);
> + behavior = dev_cgroup->behavior;
> + list_for_each_entry_rcu(ex, &dev_cgroup->exceptions, list) {
> + if (type == DEV_BLOCK && !(ex->type & DEV_BLOCK))
> + continue;
> + if (type == DEV_CHAR && !(ex->type & DEV_CHAR))
> + continue;
> + if (ex->major != ~0 && major != ex->major)
> + continue;
> + if (ex->minor != ~0 && minor != ex->minor)
> + continue;
> + if (access & (~ex->access))
> + continue;
> + match = true;
> + break;
> + }
> rcu_read_unlock();
>
> - if (!rc)
> + if (behavior == DEVCG_DEFAULT_ALLOW && match)
> + /* access matches a rule to disallow access */
> + return -EPERM;
> +
> + if (behavior == DEVCG_DEFAULT_DENY && !match)
> + /* no exceptions found, default action is to deny access */
> return -EPERM;
>
> return 0;
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] device_cgroup: do not use rule acceptance function to validate access
2014-04-15 15:57 ` Serge Hallyn
@ 2014-04-15 16:53 ` Aristeu Rozanski
0 siblings, 0 replies; 6+ messages in thread
From: Aristeu Rozanski @ 2014-04-15 16:53 UTC (permalink / raw)
To: Serge Hallyn
Cc: cgroups-u79uwXL29TY76Z2rM5mHXA, Tejun Heo, Li Zefan, Serge Hallyn
Hi Serge,
On Tue, Apr 15, 2014 at 10:57:52AM -0500, Serge Hallyn wrote:
> Quoting Aristeu Rozanski (aris-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org):
> > may_access() is currently used to validate both new exceptions from children
> > groups and to check if an access is allowed. This not only makes it hard to
> > understand and maintain, but it's also incorrect.
>
> Heh, well one might argue that may_access() was more approriate at
> __devcgroup_check_permission(), should remain simpler, and parent_has_perm()
> should be the wrapper doing the extra bits. That would be easier to
> read imo.
>
> In what you have here, you end up duplicating the
> list_for_each_entry_rcu. I think you should at least have a common
> fn for that.
>
> I don't want to sound pedantic, but since the point of this patch is
> that simplicity/ease-of-reading would have prevented the bug ... :)
Yes, trying to get this right this time. The problem itself isn't
simple, comparing ranges when adding new rules on the child and the
possible difference between the meaning of the exception (is it to
disallow access in that range or to allow?) makes things complicated.
> I *think* it's ok, and I appreciate you finding and fixing the bug, but
> I don't think the result is as easy to read as it could be, so if you
> don't mind I'd like to wait for a new version to ack. If you disagree
> with me, let me know and I'll re-read and (presumably) ack.
Yes, don't worry about it, I'm working on a v2 that will makes things
easier to read. If not, I'll keep working on it until it looks simple
enough.
--
Aristeu
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2014-04-15 16:53 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-04-14 14:47 [PATCH] device_cgroup: do not use rule acceptance function to validate access Aristeu Rozanski
[not found] ` <20140414144736.GS29214-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2014-04-14 18:03 ` Tejun Heo
[not found] ` <20140414180323.GC15249-Gd/HAXX7CRxy/B6EtB590w@public.gmane.org>
2014-04-14 18:16 ` Aristeu Rozanski
[not found] ` <20140414181611.GU29214-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2014-04-14 19:07 ` Tejun Heo
2014-04-15 15:57 ` Serge Hallyn
2014-04-15 16:53 ` Aristeu Rozanski
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).