1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #include <linux/fs.h> 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 22 #ifdef CONFIG_CGROUP_DEVICE 23 static inline int devcgroup_check_permission(short type, u32 major, u32 minor, 24 short access) 25 { 26 return __devcgroup_check_permission(type, major, minor, access); 27 } 28 29 static inline int devcgroup_inode_permission(struct inode *inode, int mask) 30 { 31 short type, access = 0; 32 33 if (likely(!inode->i_rdev)) 34 return 0; 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 41 return 0; 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); 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 68 #else 69 static inline int devcgroup_inode_permission(struct inode *inode, int mask) 70 { return 0; } 71 static inline int devcgroup_inode_mknod(int mode, dev_t dev) 72 { return 0; } 73 #endif 74