diff mbox

[v3,3/6] cgroup: Introduce cgroup_permission()

Message ID 20180306234700.6562-4-matthew.d.roper@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Matt Roper March 6, 2018, 11:46 p.m. UTC
Non-controller kernel subsystems may base access restrictions for
cgroup-related syscalls/ioctls on a process' access to the cgroup.
Let's make it easy for other parts of the kernel to check these cgroup
permissions.

Cc: Tejun Heo <tj@kernel.org>
Cc: cgroups@vger.kernel.org
Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
---
 include/linux/cgroup.h |  1 +
 kernel/cgroup/cgroup.c | 42 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 43 insertions(+)

Comments

Tejun Heo March 13, 2018, 8:43 p.m. UTC | #1
On Tue, Mar 06, 2018 at 03:46:57PM -0800, Matt Roper wrote:
> Non-controller kernel subsystems may base access restrictions for
> cgroup-related syscalls/ioctls on a process' access to the cgroup.
> Let's make it easy for other parts of the kernel to check these cgroup
> permissions.

I'm not sure about pulling in cgroup perms this way because cgroup
access perms have more to it than the file and directory permissions.
Can't this be restricted to root or some CAP?

Thanks.
diff mbox

Patch

diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
index b1ea2064f247..dd1d1d9813e8 100644
--- a/include/linux/cgroup.h
+++ b/include/linux/cgroup.h
@@ -100,6 +100,7 @@  struct cgroup_subsys_state *css_tryget_online_from_dir(struct dentry *dentry,
 
 struct cgroup *cgroup_get_from_path(const char *path);
 struct cgroup *cgroup_get_from_fd(int fd);
+int cgroup_permission(int fd, int mask);
 
 int cgroup_attach_task_all(struct task_struct *from, struct task_struct *);
 int cgroup_transfer_tasks(struct cgroup *to, struct cgroup *from);
diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c
index 9e576dc8b566..52d68b226867 100644
--- a/kernel/cgroup/cgroup.c
+++ b/kernel/cgroup/cgroup.c
@@ -5781,6 +5781,48 @@  struct cgroup *cgroup_get_from_fd(int fd)
 }
 EXPORT_SYMBOL_GPL(cgroup_get_from_fd);
 
+/**
+ * cgroup_permission - check cgroup fd permissions
+ * @fd: fd obtained by open(cgroup)
+ * @mask: Right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC)
+ *
+ * Check for read/write/execute permissions on a cgroup.
+ */
+int cgroup_permission(int fd, int mask)
+{
+	struct file *f;
+	struct inode *inode;
+	struct cgroup_subsys_state *css;
+	int ret;
+
+	f = fget_raw(fd);
+	if (!f)
+		return -EBADF;
+
+	css = css_tryget_online_from_dir(f->f_path.dentry, NULL);
+	if (IS_ERR(css)) {
+		ret = PTR_ERR(css);
+		goto out_file;
+	}
+
+	inode = kernfs_get_inode(f->f_path.dentry->d_sb, css->cgroup->kn);
+	if (!inode) {
+		ret = -ENOMEM;
+		goto out_cgroup;
+	}
+
+	ret = inode_permission(inode, mask);
+	iput(inode);
+
+out_cgroup:
+	cgroup_put(css->cgroup);
+out_file:
+	fput(f);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(cgroup_permission);
+
 /*
  * sock->sk_cgrp_data handling.  For more info, see sock_cgroup_data
  * definition in cgroup-defs.h.