All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Mickaël Salaün" <mic-WFhQfpSGs3bR7s880joybQ@public.gmane.org>
To: Alexei Starovoitov
	<alexei.starovoitov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	Alexei Starovoitov <ast-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>,
	Andy Lutomirski <luto-kltTT9wpgjJwATOyAt5JVQ@public.gmane.org>,
	Daniel Borkmann <daniel-FeC+5ew28dpmcu3hnIyYJQ@public.gmane.org>,
	Daniel Mack <daniel-cYrQPVfZoowdnm+yROfE0A@public.gmane.org>,
	"David S . Miller"
	<davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>,
	James Morris
	<james.l.morris-QHcLZuEGTsvQT0dZR+AlfA@public.gmane.org>,
	Kees Cook <keescook-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>,
	Martin KaFai Lau <kafai-b10kYP2dOMg@public.gmane.org>,
	Tejun Heo <tj-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>,
	cgroups-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Subject: Re: [PATCH v1] cgroup,bpf: Add access check for cgroup_get_from_fd()
Date: Tue, 20 Sep 2016 18:53:35 +0200	[thread overview]
Message-ID: <57E1698F.1090106@digikod.net> (raw)
In-Reply-To: <20160920003007.GB91808-+o4/htvd0TDFYCXBM6kdu7fOX0fSgVTm@public.gmane.org>


[-- Attachment #1.1: Type: text/plain, Size: 3291 bytes --]


On 20/09/2016 02:30, Alexei Starovoitov wrote:
> On Tue, Sep 20, 2016 at 12:49:13AM +0200, Mickaël Salaün wrote:
>> Add security access check for cgroup backed FD. The "cgroup.procs" file
>> of the corresponding cgroup should be readable to identify the cgroup,
>> and writable to prove that the current process can manage this cgroup
>> (e.g. through delegation). This is similar to the check done by
>> cgroup_procs_write_permission().
>>
>> Fixes: 4ed8ec521ed5 ("cgroup: bpf: Add BPF_MAP_TYPE_CGROUP_ARRAY")
> 
> I don't understand what 'fixes' is about.
> Looks like new feature or tightening?
> Since cgroup was opened by the process and it got an fd,
> it had an access, so extra check here looks unnecessary.

It may not be a "fix", but this patch tighten the access control. The
current cgroup_get_from_fd() only rely on the access check done on the
passed FD. However, this FD come from a cgroup directory, not a
"cgroup.procs" (in this directory). The "cgroup.procs" is used for
cgroup delegation by cgroup_procs_write_permission(). Checking
"cgroup.procs" is then more consistent with access checks done by other
part of the cgroup code. Being able to open a cgroup directory only
means that the current process is able to list the cgroup hierarchy, not
necessarily to list the tasks in this cgroups.

A BPF_MAP_TYPE_CGROUP_ARRAY should then only contains cgroups readable
by the process that filled the map. It is currently possible to call
bpf_skb_in_cgroup() and know if a packet come from a task in a cgroup,
whereas the loading process may not be able to list this tasks.

Write access to a cgroup directory means to be able to create
sub-cgroups, not to add or remove tasks from that cgroup. This will be
important for future use like the Daniel Mack's patch (attach an eBPF
program to a cgroup). Indeed, with the current code, a process with
CAP_NET_ADMIN (but without the right to manage a cgroup) would be able
to attach programs to a cgroup. Similar thing goes for Landlock.

> 
>> -struct cgroup *cgroup_get_from_fd(int fd)
>> +struct cgroup *cgroup_get_from_fd(int fd, int access_mask)
>>  {
>>  	struct cgroup_subsys_state *css;
>>  	struct cgroup *cgrp;
>>  	struct file *f;
>> +	struct inode *inode;
>> +	int ret;
>>  
>>  	f = fget_raw(fd);
>>  	if (!f)
>>  		return ERR_PTR(-EBADF);
>>  
>>  	css = css_tryget_online_from_dir(f->f_path.dentry, NULL);
>> -	fput(f);
> 
> why move it down?

Because it is used by kernfs_get_inode().

> 
>> -	if (IS_ERR(css))
>> -		return ERR_CAST(css);
>> +	if (IS_ERR(css)) {
>> +		ret = PTR_ERR(css);
>> +		goto put_f;
>> +	}
>>  
>>  	cgrp = css->cgroup;
>>  	if (!cgroup_on_dfl(cgrp)) {
>> -		cgroup_put(cgrp);
>> -		return ERR_PTR(-EBADF);
>> +		ret = -EBADF;
>> +		goto put_cgrp;
>> +	}
>> +
>> +	ret = -ENOMEM;
>> +	inode = kernfs_get_inode(f->f_path.dentry->d_sb, cgrp->procs_file.kn);
>> +	if (inode) {
>> +		ret = inode_permission(inode, access_mask);
>> +		iput(inode);
>>  	}
>> +	if (ret)
>> +		goto put_cgrp;
>>  
>> +	fput(f);
>>  	return cgrp;
>> +
>> +put_cgrp:
>> +	cgroup_put(cgrp);
>> +put_f:
>> +	fput(f);
>> +	return ERR_PTR(ret);
>>  }
>>  EXPORT_SYMBOL_GPL(cgroup_get_from_fd);
>>  
>> -- 
>> 2.9.3
>>
> 


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 455 bytes --]

WARNING: multiple messages have this Message-ID (diff)
From: "Mickaël Salaün" <mic@digikod.net>
To: Alexei Starovoitov <alexei.starovoitov@gmail.com>
Cc: linux-kernel@vger.kernel.org, Alexei Starovoitov <ast@kernel.org>,
	Andy Lutomirski <luto@amacapital.net>,
	Daniel Borkmann <daniel@iogearbox.net>,
	Daniel Mack <daniel@zonque.org>,
	"David S . Miller" <davem@davemloft.net>,
	James Morris <james.l.morris@oracle.com>,
	Kees Cook <keescook@chromium.org>,
	Martin KaFai Lau <kafai@fb.com>, Tejun Heo <tj@kernel.org>,
	cgroups@vger.kernel.org
Subject: Re: [PATCH v1] cgroup,bpf: Add access check for cgroup_get_from_fd()
Date: Tue, 20 Sep 2016 18:53:35 +0200	[thread overview]
Message-ID: <57E1698F.1090106@digikod.net> (raw)
In-Reply-To: <20160920003007.GB91808@ast-mbp.thefacebook.com>


[-- Attachment #1.1: Type: text/plain, Size: 3291 bytes --]


On 20/09/2016 02:30, Alexei Starovoitov wrote:
> On Tue, Sep 20, 2016 at 12:49:13AM +0200, Mickaël Salaün wrote:
>> Add security access check for cgroup backed FD. The "cgroup.procs" file
>> of the corresponding cgroup should be readable to identify the cgroup,
>> and writable to prove that the current process can manage this cgroup
>> (e.g. through delegation). This is similar to the check done by
>> cgroup_procs_write_permission().
>>
>> Fixes: 4ed8ec521ed5 ("cgroup: bpf: Add BPF_MAP_TYPE_CGROUP_ARRAY")
> 
> I don't understand what 'fixes' is about.
> Looks like new feature or tightening?
> Since cgroup was opened by the process and it got an fd,
> it had an access, so extra check here looks unnecessary.

It may not be a "fix", but this patch tighten the access control. The
current cgroup_get_from_fd() only rely on the access check done on the
passed FD. However, this FD come from a cgroup directory, not a
"cgroup.procs" (in this directory). The "cgroup.procs" is used for
cgroup delegation by cgroup_procs_write_permission(). Checking
"cgroup.procs" is then more consistent with access checks done by other
part of the cgroup code. Being able to open a cgroup directory only
means that the current process is able to list the cgroup hierarchy, not
necessarily to list the tasks in this cgroups.

A BPF_MAP_TYPE_CGROUP_ARRAY should then only contains cgroups readable
by the process that filled the map. It is currently possible to call
bpf_skb_in_cgroup() and know if a packet come from a task in a cgroup,
whereas the loading process may not be able to list this tasks.

Write access to a cgroup directory means to be able to create
sub-cgroups, not to add or remove tasks from that cgroup. This will be
important for future use like the Daniel Mack's patch (attach an eBPF
program to a cgroup). Indeed, with the current code, a process with
CAP_NET_ADMIN (but without the right to manage a cgroup) would be able
to attach programs to a cgroup. Similar thing goes for Landlock.

> 
>> -struct cgroup *cgroup_get_from_fd(int fd)
>> +struct cgroup *cgroup_get_from_fd(int fd, int access_mask)
>>  {
>>  	struct cgroup_subsys_state *css;
>>  	struct cgroup *cgrp;
>>  	struct file *f;
>> +	struct inode *inode;
>> +	int ret;
>>  
>>  	f = fget_raw(fd);
>>  	if (!f)
>>  		return ERR_PTR(-EBADF);
>>  
>>  	css = css_tryget_online_from_dir(f->f_path.dentry, NULL);
>> -	fput(f);
> 
> why move it down?

Because it is used by kernfs_get_inode().

> 
>> -	if (IS_ERR(css))
>> -		return ERR_CAST(css);
>> +	if (IS_ERR(css)) {
>> +		ret = PTR_ERR(css);
>> +		goto put_f;
>> +	}
>>  
>>  	cgrp = css->cgroup;
>>  	if (!cgroup_on_dfl(cgrp)) {
>> -		cgroup_put(cgrp);
>> -		return ERR_PTR(-EBADF);
>> +		ret = -EBADF;
>> +		goto put_cgrp;
>> +	}
>> +
>> +	ret = -ENOMEM;
>> +	inode = kernfs_get_inode(f->f_path.dentry->d_sb, cgrp->procs_file.kn);
>> +	if (inode) {
>> +		ret = inode_permission(inode, access_mask);
>> +		iput(inode);
>>  	}
>> +	if (ret)
>> +		goto put_cgrp;
>>  
>> +	fput(f);
>>  	return cgrp;
>> +
>> +put_cgrp:
>> +	cgroup_put(cgrp);
>> +put_f:
>> +	fput(f);
>> +	return ERR_PTR(ret);
>>  }
>>  EXPORT_SYMBOL_GPL(cgroup_get_from_fd);
>>  
>> -- 
>> 2.9.3
>>
> 


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 455 bytes --]

  parent reply	other threads:[~2016-09-20 16:53 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-09-19 22:49 [PATCH v1] cgroup,bpf: Add access check for cgroup_get_from_fd() Mickaël Salaün
2016-09-19 22:49 ` Mickaël Salaün
     [not found] ` <20160919224913.24808-1-mic-WFhQfpSGs3bR7s880joybQ@public.gmane.org>
2016-09-20  0:30   ` Alexei Starovoitov
2016-09-20  0:30     ` Alexei Starovoitov
     [not found]     ` <20160920003007.GB91808-+o4/htvd0TDFYCXBM6kdu7fOX0fSgVTm@public.gmane.org>
2016-09-20 16:53       ` Mickaël Salaün [this message]
2016-09-20 16:53         ` Mickaël Salaün
2016-09-20 16:58         ` Tejun Heo
2016-09-20 13:53   ` Tejun Heo
2016-09-20 13:53     ` Tejun Heo

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=57E1698F.1090106@digikod.net \
    --to=mic-wfhqfpsgs3br7s880joybq@public.gmane.org \
    --cc=alexei.starovoitov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
    --cc=ast-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org \
    --cc=cgroups-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=daniel-FeC+5ew28dpmcu3hnIyYJQ@public.gmane.org \
    --cc=daniel-cYrQPVfZoowdnm+yROfE0A@public.gmane.org \
    --cc=davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org \
    --cc=james.l.morris-QHcLZuEGTsvQT0dZR+AlfA@public.gmane.org \
    --cc=kafai-b10kYP2dOMg@public.gmane.org \
    --cc=keescook-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org \
    --cc=linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=luto-kltTT9wpgjJwATOyAt5JVQ@public.gmane.org \
    --cc=tj-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.