summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/device_cgroup.h61
-rw-r--r--security/device_cgroup.c47
2 files changed, 59 insertions, 49 deletions
diff --git a/include/linux/device_cgroup.h b/include/linux/device_cgroup.h
index cdbc344a92e4..2d93d7ecd479 100644
--- a/include/linux/device_cgroup.h
+++ b/include/linux/device_cgroup.h
@@ -1,17 +1,70 @@
1/* SPDX-License-Identifier: GPL-2.0 */ 1/* SPDX-License-Identifier: GPL-2.0 */
2#include <linux/fs.h> 2#include <linux/fs.h>
3 3
4#define DEVCG_ACC_MKNOD 1
5#define DEVCG_ACC_READ 2
6#define DEVCG_ACC_WRITE 4
7#define DEVCG_ACC_MASK (DEVCG_ACC_MKNOD | DEVCG_ACC_READ | DEVCG_ACC_WRITE)
8
9#define DEVCG_DEV_BLOCK 1
10#define DEVCG_DEV_CHAR 2
11#define DEVCG_DEV_ALL 4 /* this represents all devices */
12
13#ifdef CONFIG_CGROUP_DEVICE
14extern int __devcgroup_check_permission(short type, u32 major, u32 minor,
15 short access);
16#else
17static inline int __devcgroup_check_permission(short type, u32 major, u32 minor,
18 short access)
19{ return 0; }
20#endif
21
4#ifdef CONFIG_CGROUP_DEVICE 22#ifdef CONFIG_CGROUP_DEVICE
5extern int __devcgroup_inode_permission(struct inode *inode, int mask); 23static inline int devcgroup_check_permission(short type, u32 major, u32 minor,
6extern int devcgroup_inode_mknod(int mode, dev_t dev); 24 short access)
25{
26 return __devcgroup_check_permission(type, major, minor, access);
27}
28
7static inline int devcgroup_inode_permission(struct inode *inode, int mask) 29static inline int devcgroup_inode_permission(struct inode *inode, int mask)
8{ 30{
31 short type, access = 0;
32
9 if (likely(!inode->i_rdev)) 33 if (likely(!inode->i_rdev))
10 return 0; 34 return 0;
11 if (!S_ISBLK(inode->i_mode) && !S_ISCHR(inode->i_mode)) 35
36 if (S_ISBLK(inode->i_mode))
37 type = DEVCG_DEV_BLOCK;
38 else if (S_ISCHR(inode->i_mode))
39 type = DEVCG_DEV_CHAR;
40 else
12 return 0; 41 return 0;
13 return __devcgroup_inode_permission(inode, mask); 42
43 if (mask & MAY_WRITE)
44 access |= DEVCG_ACC_WRITE;
45 if (mask & MAY_READ)
46 access |= DEVCG_ACC_READ;
47
48 return devcgroup_check_permission(type, imajor(inode), iminor(inode),
49 access);
14} 50}
51
52static inline int devcgroup_inode_mknod(int mode, dev_t dev)
53{
54 short type;
55
56 if (!S_ISBLK(mode) && !S_ISCHR(mode))
57 return 0;
58
59 if (S_ISBLK(mode))
60 type = DEVCG_DEV_BLOCK;
61 else
62 type = DEVCG_DEV_CHAR;
63
64 return devcgroup_check_permission(type, MAJOR(dev), MINOR(dev),
65 DEVCG_ACC_MKNOD);
66}
67
15#else 68#else
16static inline int devcgroup_inode_permission(struct inode *inode, int mask) 69static inline int devcgroup_inode_permission(struct inode *inode, int mask)
17{ return 0; } 70{ return 0; }
diff --git a/security/device_cgroup.c b/security/device_cgroup.c
index 968c21557ba7..c65b39bafdfe 100644
--- a/security/device_cgroup.c
+++ b/security/device_cgroup.c
@@ -15,15 +15,6 @@
15#include <linux/rcupdate.h> 15#include <linux/rcupdate.h>
16#include <linux/mutex.h> 16#include <linux/mutex.h>
17 17
18#define DEVCG_ACC_MKNOD 1
19#define DEVCG_ACC_READ 2
20#define DEVCG_ACC_WRITE 4
21#define DEVCG_ACC_MASK (DEVCG_ACC_MKNOD | DEVCG_ACC_READ | DEVCG_ACC_WRITE)
22
23#define DEVCG_DEV_BLOCK 1
24#define DEVCG_DEV_CHAR 2
25#define DEVCG_DEV_ALL 4 /* this represents all devices */
26
27static DEFINE_MUTEX(devcgroup_mutex); 18static DEFINE_MUTEX(devcgroup_mutex);
28 19
29enum devcg_behavior { 20enum devcg_behavior {
@@ -810,8 +801,8 @@ struct cgroup_subsys devices_cgrp_subsys = {
810 * 801 *
811 * returns 0 on success, -EPERM case the operation is not permitted 802 * returns 0 on success, -EPERM case the operation is not permitted
812 */ 803 */
813static int __devcgroup_check_permission(short type, u32 major, u32 minor, 804int __devcgroup_check_permission(short type, u32 major, u32 minor,
814 short access) 805 short access)
815{ 806{
816 struct dev_cgroup *dev_cgroup; 807 struct dev_cgroup *dev_cgroup;
817 bool rc; 808 bool rc;
@@ -833,37 +824,3 @@ static int __devcgroup_check_permission(short type, u32 major, u32 minor,
833 824
834 return 0; 825 return 0;
835} 826}
836
837int __devcgroup_inode_permission(struct inode *inode, int mask)
838{
839 short type, access = 0;
840
841 if (S_ISBLK(inode->i_mode))
842 type = DEVCG_DEV_BLOCK;
843 if (S_ISCHR(inode->i_mode))
844 type = DEVCG_DEV_CHAR;
845 if (mask & MAY_WRITE)
846 access |= DEVCG_ACC_WRITE;
847 if (mask & MAY_READ)
848 access |= DEVCG_ACC_READ;
849
850 return __devcgroup_check_permission(type, imajor(inode), iminor(inode),
851 access);
852}
853
854int devcgroup_inode_mknod(int mode, dev_t dev)
855{
856 short type;
857
858 if (!S_ISBLK(mode) && !S_ISCHR(mode))
859 return 0;
860
861 if (S_ISBLK(mode))
862 type = DEVCG_DEV_BLOCK;
863 else
864 type = DEVCG_DEV_CHAR;
865
866 return __devcgroup_check_permission(type, MAJOR(dev), MINOR(dev),
867 DEVCG_ACC_MKNOD);
868
869}