diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 8f39d91eabc9..2f99eaa910af 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -2210,6 +2210,40 @@ static int selinux_dma_buf_charge_task(const struct cred *from, const struct cre
SECCLASS_DMA_BUF, DMA_BUF__CHARGE_TASK, NULL);
}
+#ifdef CONFIG_CGROUPS
+static int selinux_dma_buf_charge_cgroup(const struct cred *cred, struct cgroup *cgrp)
+{
+ u32 cgrp_sid, clen;
+ int rc;
+ char *context;
+
+ rc = kernfs_xattr_get(cgrp->kn, XATTR_NAME_SELINUX, NULL, 0);
+ if (rc == -ENODATA)
+ return 0;
+ else if (rc < 0)
+ return rc;
+
+ clen = (u32)rc;
+ context = kmalloc(clen, GFP_KERNEL);
+ if (!context)
+ return -ENOMEM;
+
+ rc = kernfs_xattr_get(cgrp->kn, XATTR_NAME_SELINUX, context, clen);
+ if (rc < 0) {
+ kfree(context);
+ return rc;
+ }
+
+ rc = security_context_to_sid(context, rc, &cgrp_sid, GFP_KERNEL);
+ kfree(context);
+ if (rc)
+ return rc;
+
+ return avc_has_perm(cred_sid(cred), cgrp_sid,
+ SECCLASS_DMA_BUF, DMA_BUF__CHARGE_CGROUP, NULL);
+}
+#endif
+
static int selinux_quotactl(int cmds, int type, int id, const struct super_block *sb)
{
const struct cred *cred = current_cred();@@ -7681,6 +7715,9 @@ static struct security_hook_list selinux_hooks[] __ro_after_init = {
LSM_HOOK_INIT(capset, selinux_capset),
LSM_HOOK_INIT(capable, selinux_capable),
LSM_HOOK_INIT(dma_buf_charge_task, selinux_dma_buf_charge_task),
+#ifdef CONFIG_CGROUPS
+ LSM_HOOK_INIT(dma_buf_charge_cgroup, selinux_dma_buf_charge_cgroup),
+#endif
LSM_HOOK_INIT(quotactl, selinux_quotactl),
LSM_HOOK_INIT(quota_on, selinux_quota_on),
LSM_HOOK_INIT(syslog, selinux_syslog),diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h
index b4ebedc6e424..90d1e04c3d27 100644
--- a/security/selinux/include/classmap.h
+++ b/security/selinux/include/classmap.h
@@ -181,7 +181,7 @@ const struct security_class_mapping secclass_map[] = {
{ "user_namespace", { "create", NULL } },
{ "memfd_file",
{ COMMON_FILE_PERMS, "execute_no_trans", "entrypoint", NULL } },
- { "dma_buf", { "charge_task", NULL } },
+ { "dma_buf", { "charge_task", "charge_cgroup", NULL } },
/* last one */ { NULL, {} }
};
--
2.55.0