Skip to content

Commit

Permalink
device_cgroup: Cleanup cgroup eBPF device filter code
Browse files Browse the repository at this point in the history
Original cgroup v2 eBPF code for filtering device access made it
possible to compile with CONFIG_CGROUP_DEVICE=n and still use the eBPF
filtering. Change
commit 4b7d4d4 ("device_cgroup: Export devcgroup_check_permission")
reverted this, making it required to set it to y.

Since the device filtering (and all the docs) for cgroup v2 is no longer
a "device controller" like it was in v1, someone might compile their
kernel with CONFIG_CGROUP_DEVICE=n. Then (for linux 5.5+) the eBPF
filter will not be invoked, and all processes will be allowed access
to all devices, no matter what the eBPF filter says.

Signed-off-by: Odin Ugedal <[email protected]>
Acked-by: Roman Gushchin <[email protected]>
Signed-off-by: Tejun Heo <[email protected]>
  • Loading branch information
odinuge authored and htejun committed Apr 13, 2020
1 parent 772b314 commit eec8fd0
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 14 deletions.
2 changes: 1 addition & 1 deletion drivers/gpu/drm/amd/amdkfd/kfd_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -1050,7 +1050,7 @@ void kfd_dec_compute_active(struct kfd_dev *dev);
/* Check with device cgroup if @kfd device is accessible */
static inline int kfd_devcgroup_check_permission(struct kfd_dev *kfd)
{
#if defined(CONFIG_CGROUP_DEVICE)
#if defined(CONFIG_CGROUP_DEVICE) || defined(CONFIG_CGROUP_BPF)
struct drm_device *ddev = kfd->ddev;

return devcgroup_check_permission(DEVCG_DEV_CHAR, ddev->driver->major,
Expand Down
14 changes: 5 additions & 9 deletions include/linux/device_cgroup.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
#include <linux/fs.h>
#include <linux/bpf-cgroup.h>

#define DEVCG_ACC_MKNOD 1
#define DEVCG_ACC_READ 2
Expand All @@ -11,16 +10,10 @@
#define DEVCG_DEV_CHAR 2
#define DEVCG_DEV_ALL 4 /* this represents all devices */

#ifdef CONFIG_CGROUP_DEVICE
int devcgroup_check_permission(short type, u32 major, u32 minor,
short access);
#else
static inline int devcgroup_check_permission(short type, u32 major, u32 minor,
short access)
{ return 0; }
#endif

#if defined(CONFIG_CGROUP_DEVICE) || defined(CONFIG_CGROUP_BPF)
int devcgroup_check_permission(short type, u32 major, u32 minor,
short access);
static inline int devcgroup_inode_permission(struct inode *inode, int mask)
{
short type, access = 0;
Expand Down Expand Up @@ -61,6 +54,9 @@ static inline int devcgroup_inode_mknod(int mode, dev_t dev)
}

#else
static inline int devcgroup_check_permission(short type, u32 major, u32 minor,
short access)
{ return 0; }
static inline int devcgroup_inode_permission(struct inode *inode, int mask)
{ return 0; }
static inline int devcgroup_inode_mknod(int mode, dev_t dev)
Expand Down
2 changes: 1 addition & 1 deletion security/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ obj-$(CONFIG_SECURITY_YAMA) += yama/
obj-$(CONFIG_SECURITY_LOADPIN) += loadpin/
obj-$(CONFIG_SECURITY_SAFESETID) += safesetid/
obj-$(CONFIG_SECURITY_LOCKDOWN_LSM) += lockdown/
obj-$(CONFIG_CGROUP_DEVICE) += device_cgroup.o
obj-$(CONFIG_CGROUPS) += device_cgroup.o
obj-$(CONFIG_BPF_LSM) += bpf/

# Object integrity file lists
Expand Down
19 changes: 16 additions & 3 deletions security/device_cgroup.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
#include <linux/rcupdate.h>
#include <linux/mutex.h>

#ifdef CONFIG_CGROUP_DEVICE

static DEFINE_MUTEX(devcgroup_mutex);

enum devcg_behavior {
Expand Down Expand Up @@ -792,7 +794,7 @@ struct cgroup_subsys devices_cgrp_subsys = {
};

/**
* __devcgroup_check_permission - checks if an inode operation is permitted
* devcgroup_legacy_check_permission - checks if an inode operation is permitted
* @dev_cgroup: the dev cgroup to be tested against
* @type: device type
* @major: device major number
Expand All @@ -801,7 +803,7 @@ struct cgroup_subsys devices_cgrp_subsys = {
*
* returns 0 on success, -EPERM case the operation is not permitted
*/
static int __devcgroup_check_permission(short type, u32 major, u32 minor,
static int devcgroup_legacy_check_permission(short type, u32 major, u32 minor,
short access)
{
struct dev_cgroup *dev_cgroup;
Expand All @@ -825,13 +827,24 @@ static int __devcgroup_check_permission(short type, u32 major, u32 minor,
return 0;
}

#endif /* CONFIG_CGROUP_DEVICE */

#if defined(CONFIG_CGROUP_DEVICE) || defined(CONFIG_CGROUP_BPF)

int devcgroup_check_permission(short type, u32 major, u32 minor, short access)
{
int rc = BPF_CGROUP_RUN_PROG_DEVICE_CGROUP(type, major, minor, access);

if (rc)
return -EPERM;

return __devcgroup_check_permission(type, major, minor, access);
#ifdef CONFIG_CGROUP_DEVICE
return devcgroup_legacy_check_permission(type, major, minor, access);

#else /* CONFIG_CGROUP_DEVICE */
return 0;

#endif /* CONFIG_CGROUP_DEVICE */
}
EXPORT_SYMBOL(devcgroup_check_permission);
#endif /* defined(CONFIG_CGROUP_DEVICE) || defined(CONFIG_CGROUP_BPF) */

0 comments on commit eec8fd0

Please sign in to comment.