1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
208ce5f16SSerge E. Hallyn #include <linux/fs.h>
3ebc614f6SRoman Gushchin
408ce5f16SSerge E. Hallyn #define DEVCG_ACC_MKNOD 1
5ecf8fecbSRoman Gushchin #define DEVCG_ACC_READ 2
6ecf8fecbSRoman Gushchin #define DEVCG_ACC_WRITE 4
7ecf8fecbSRoman Gushchin #define DEVCG_ACC_MASK (DEVCG_ACC_MKNOD | DEVCG_ACC_READ | DEVCG_ACC_WRITE)
8ecf8fecbSRoman Gushchin
9ecf8fecbSRoman Gushchin #define DEVCG_DEV_BLOCK 1
10ecf8fecbSRoman Gushchin #define DEVCG_DEV_CHAR 2
11ecf8fecbSRoman Gushchin #define DEVCG_DEV_ALL 4 /* this represents all devices */
12ecf8fecbSRoman Gushchin
13ecf8fecbSRoman Gushchin
1408ce5f16SSerge E. Hallyn #if defined(CONFIG_CGROUP_DEVICE) || defined(CONFIG_CGROUP_BPF)
154b7d4d45SHarish Kasiviswanathan int devcgroup_check_permission(short type, u32 major, u32 minor,
16ecf8fecbSRoman Gushchin short access);
devcgroup_inode_permission(struct inode * inode,int mask)17ecf8fecbSRoman Gushchin static inline int devcgroup_inode_permission(struct inode *inode, int mask)
184b7d4d45SHarish Kasiviswanathan {
19ecf8fecbSRoman Gushchin short type, access = 0;
20ecf8fecbSRoman Gushchin
21ecf8fecbSRoman Gushchin if (likely(!inode->i_rdev))
22ecf8fecbSRoman Gushchin return 0;
23ebc614f6SRoman Gushchin
24482e0cd3SAl Viro if (S_ISBLK(inode->i_mode))
25482e0cd3SAl Viro type = DEVCG_DEV_BLOCK;
26ecf8fecbSRoman Gushchin else if (S_ISCHR(inode->i_mode))
27ecf8fecbSRoman Gushchin type = DEVCG_DEV_CHAR;
28482e0cd3SAl Viro else
29482e0cd3SAl Viro return 0;
30ecf8fecbSRoman Gushchin
31ecf8fecbSRoman Gushchin if (mask & MAY_WRITE)
32ecf8fecbSRoman Gushchin access |= DEVCG_ACC_WRITE;
33ecf8fecbSRoman Gushchin if (mask & MAY_READ)
34ecf8fecbSRoman Gushchin access |= DEVCG_ACC_READ;
35ecf8fecbSRoman Gushchin
36482e0cd3SAl Viro return devcgroup_check_permission(type, imajor(inode), iminor(inode),
37ecf8fecbSRoman Gushchin access);
38ecf8fecbSRoman Gushchin }
39ecf8fecbSRoman Gushchin
devcgroup_inode_mknod(int mode,dev_t dev)40ecf8fecbSRoman Gushchin static inline int devcgroup_inode_mknod(int mode, dev_t dev)
41ecf8fecbSRoman Gushchin {
42ecf8fecbSRoman Gushchin short type;
43ecf8fecbSRoman Gushchin
44ecf8fecbSRoman Gushchin if (!S_ISBLK(mode) && !S_ISCHR(mode))
45482e0cd3SAl Viro return 0;
46ecf8fecbSRoman Gushchin
47ecf8fecbSRoman Gushchin if (S_ISCHR(mode) && dev == WHITEOUT_DEV)
48ecf8fecbSRoman Gushchin return 0;
49ecf8fecbSRoman Gushchin
50ecf8fecbSRoman Gushchin if (S_ISBLK(mode))
51ecf8fecbSRoman Gushchin type = DEVCG_DEV_BLOCK;
52ecf8fecbSRoman Gushchin else
53ecf8fecbSRoman Gushchin type = DEVCG_DEV_CHAR;
54a3c751a5SMiklos Szeredi
55a3c751a5SMiklos Szeredi return devcgroup_check_permission(type, MAJOR(dev), MINOR(dev),
56a3c751a5SMiklos Szeredi DEVCG_ACC_MKNOD);
57ecf8fecbSRoman Gushchin }
58ecf8fecbSRoman Gushchin
59ecf8fecbSRoman Gushchin #else
devcgroup_check_permission(short type,u32 major,u32 minor,short access)60ecf8fecbSRoman Gushchin static inline int devcgroup_check_permission(short type, u32 major, u32 minor,
61ecf8fecbSRoman Gushchin short access)
62ecf8fecbSRoman Gushchin { return 0; }
devcgroup_inode_permission(struct inode * inode,int mask)63ecf8fecbSRoman Gushchin static inline int devcgroup_inode_permission(struct inode *inode, int mask)
64ecf8fecbSRoman Gushchin { return 0; }
devcgroup_inode_mknod(int mode,dev_t dev)65ecf8fecbSRoman Gushchin static inline int devcgroup_inode_mknod(int mode, dev_t dev)
6608ce5f16SSerge E. Hallyn { return 0; }
6708ce5f16SSerge E. Hallyn #endif
6808ce5f16SSerge E. Hallyn