diff options
-rw-r--r-- | include/linux/device_cgroup.h | 61 | ||||
-rw-r--r-- | security/device_cgroup.c | 47 |
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 | ||
14 | extern int __devcgroup_check_permission(short type, u32 major, u32 minor, | ||
15 | short access); | ||
16 | #else | ||
17 | static 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 |
5 | extern int __devcgroup_inode_permission(struct inode *inode, int mask); | 23 | static inline int devcgroup_check_permission(short type, u32 major, u32 minor, |
6 | extern int devcgroup_inode_mknod(int mode, dev_t dev); | 24 | short access) |
25 | { | ||
26 | return __devcgroup_check_permission(type, major, minor, access); | ||
27 | } | ||
28 | |||
7 | static inline int devcgroup_inode_permission(struct inode *inode, int mask) | 29 | static 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 | |||
52 | static 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 |
16 | static inline int devcgroup_inode_permission(struct inode *inode, int mask) | 69 | static 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 | |||
27 | static DEFINE_MUTEX(devcgroup_mutex); | 18 | static DEFINE_MUTEX(devcgroup_mutex); |
28 | 19 | ||
29 | enum devcg_behavior { | 20 | enum 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 | */ |
813 | static int __devcgroup_check_permission(short type, u32 major, u32 minor, | 804 | int __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 | |||
837 | int __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 | |||
854 | int 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 | } | ||