Skip to content

Commit

Permalink
cgroup: Use open-time credentials for process migraton perm checks
Browse files Browse the repository at this point in the history
commit 1756d79 upstream.

cgroup process migration permission checks are performed at write time as
whether a given operation is allowed or not is dependent on the content of
the write - the PID. This currently uses current's credentials which is a
potential security weakness as it may allow scenarios where a less
privileged process tricks a more privileged one into writing into a fd that
it created.

This patch makes both cgroup2 and cgroup1 process migration interfaces to
use the credentials saved at the time of open (file->f_cred) instead of
current's.

Reported-by: "Eric W. Biederman" <ebiederm@xmission.com>
Suggested-by: Linus Torvalds <torvalds@linuxfoundation.org>
Fixes: 187fe84 ("cgroup: require write perm on common ancestor when moving processes on the default hierarchy")
Reviewed-by: Michal Koutný <mkoutny@suse.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
htejun authored and gregkh committed Jan 11, 2022
1 parent 247b624 commit c6ebc35
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 4 deletions.
7 changes: 4 additions & 3 deletions kernel/cgroup/cgroup-v1.c
Expand Up @@ -507,10 +507,11 @@ static ssize_t __cgroup1_procs_write(struct kernfs_open_file *of,
goto out_unlock;

/*
* Even if we're attaching all tasks in the thread group, we only
* need to check permissions on one of them.
* Even if we're attaching all tasks in the thread group, we only need
* to check permissions on one of them. Check permissions using the
* credentials from file open to protect against inherited fd attacks.
*/
cred = current_cred();
cred = of->file->f_cred;
tcred = get_task_cred(task);
if (!uid_eq(cred->euid, GLOBAL_ROOT_UID) &&
!uid_eq(cred->euid, tcred->uid) &&
Expand Down
9 changes: 8 additions & 1 deletion kernel/cgroup/cgroup.c
Expand Up @@ -4892,6 +4892,7 @@ static ssize_t __cgroup_procs_write(struct kernfs_open_file *of, char *buf,
{
struct cgroup *src_cgrp, *dst_cgrp;
struct task_struct *task;
const struct cred *saved_cred;
ssize_t ret;
bool locked;

Expand All @@ -4909,9 +4910,15 @@ static ssize_t __cgroup_procs_write(struct kernfs_open_file *of, char *buf,
src_cgrp = task_cgroup_from_root(task, &cgrp_dfl_root);
spin_unlock_irq(&css_set_lock);

/* process and thread migrations follow same delegation rule */
/*
* Process and thread migrations follow same delegation rule. Check
* permissions using the credentials from file open to protect against
* inherited fd attacks.
*/
saved_cred = override_creds(of->file->f_cred);
ret = cgroup_attach_permissions(src_cgrp, dst_cgrp,
of->file->f_path.dentry->d_sb, threadgroup);
revert_creds(saved_cred);
if (ret)
goto out_finish;

Expand Down

0 comments on commit c6ebc35

Please sign in to comment.