xref: /openbmc/linux/include/linux/capability.h (revision f122a08b)
1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds  * This is <linux/capability.h>
41da177e4SLinus Torvalds  *
5b5376771SSerge E. Hallyn  * Andrew G. Morgan <morgan@kernel.org>
61da177e4SLinus Torvalds  * Alexander Kjeldaas <astor@guardian.no>
71da177e4SLinus Torvalds  * with help from Aleph1, Roland Buresund and Andrew Main.
81da177e4SLinus Torvalds  *
91da177e4SLinus Torvalds  * See here for the libcap library ("POSIX draft" compliance):
101da177e4SLinus Torvalds  *
11bcf56442SGeunSik Lim  * ftp://www.kernel.org/pub/linux/libs/security/linux-privs/kernel-2.6/
121da177e4SLinus Torvalds  */
131da177e4SLinus Torvalds #ifndef _LINUX_CAPABILITY_H
141da177e4SLinus Torvalds #define _LINUX_CAPABILITY_H
151da177e4SLinus Torvalds 
16607ca46eSDavid Howells #include <uapi/linux/capability.h>
172fec30e2SRichard Guy Briggs #include <linux/uidgid.h>
18*f122a08bSLinus Torvalds #include <linux/bits.h>
19ca05a99aSAndrew G. Morgan 
20ca05a99aSAndrew G. Morgan #define _KERNEL_CAPABILITY_VERSION _LINUX_CAPABILITY_VERSION_3
211da177e4SLinus Torvalds 
229fa91d99SJaswinder Singh Rajput extern int file_caps_enabled;
239fa91d99SJaswinder Singh Rajput 
24*f122a08bSLinus Torvalds typedef struct { u64 val; } kernel_cap_t;
251da177e4SLinus Torvalds 
262fec30e2SRichard Guy Briggs /* same as vfs_ns_cap_data but in cpu endian and always filled completely */
27c0b00441SEric Paris struct cpu_vfs_cap_data {
28c0b00441SEric Paris 	__u32 magic_etc;
29*f122a08bSLinus Torvalds 	kuid_t rootid;
30c0b00441SEric Paris 	kernel_cap_t permitted;
31c0b00441SEric Paris 	kernel_cap_t inheritable;
32c0b00441SEric Paris };
33c0b00441SEric Paris 
34e338d263SAndrew Morgan #define _USER_CAP_HEADER_SIZE  (sizeof(struct __user_cap_header_struct))
351da177e4SLinus Torvalds #define _KERNEL_CAP_T_SIZE     (sizeof(kernel_cap_t))
361da177e4SLinus Torvalds 
37935d8aabSLinus Torvalds struct file;
381a48e2acSEric W. Biederman struct inode;
393486740aSSerge E. Hallyn struct dentry;
40db3f6001SAlexey Dobriyan struct task_struct;
413486740aSSerge E. Hallyn struct user_namespace;
4239f60c1cSChristian Brauner struct mnt_idmap;
433486740aSSerge E. Hallyn 
440ad30b8fSSerge E. Hallyn /*
450ad30b8fSSerge E. Hallyn  * CAP_FS_MASK and CAP_NFSD_MASKS:
460ad30b8fSSerge E. Hallyn  *
470ad30b8fSSerge E. Hallyn  * The fs mask is all the privileges that fsuid==0 historically meant.
480ad30b8fSSerge E. Hallyn  * At one time in the past, that included CAP_MKNOD and CAP_LINUX_IMMUTABLE.
490ad30b8fSSerge E. Hallyn  *
500ad30b8fSSerge E. Hallyn  * It has never meant setting security.* and trusted.* xattrs.
510ad30b8fSSerge E. Hallyn  *
520ad30b8fSSerge E. Hallyn  * We could also define fsmask as follows:
530ad30b8fSSerge E. Hallyn  *   1. CAP_FS_MASK is the privilege to bypass all fs-related DAC permissions
540ad30b8fSSerge E. Hallyn  *   2. The security.* and trusted.* xattrs are fs-related MAC permissions
550ad30b8fSSerge E. Hallyn  */
560ad30b8fSSerge E. Hallyn 
57*f122a08bSLinus Torvalds # define CAP_FS_MASK     (BIT_ULL(CAP_CHOWN)		\
58*f122a08bSLinus Torvalds 			| BIT_ULL(CAP_MKNOD)		\
59*f122a08bSLinus Torvalds 			| BIT_ULL(CAP_DAC_OVERRIDE)	\
60*f122a08bSLinus Torvalds 			| BIT_ULL(CAP_DAC_READ_SEARCH)	\
61*f122a08bSLinus Torvalds 			| BIT_ULL(CAP_FOWNER)		\
62*f122a08bSLinus Torvalds 			| BIT_ULL(CAP_FSETID)		\
63*f122a08bSLinus Torvalds 			| BIT_ULL(CAP_MAC_OVERRIDE))
64*f122a08bSLinus Torvalds #define CAP_VALID_MASK	 (BIT_ULL(CAP_LAST_CAP+1)-1)
651da177e4SLinus Torvalds 
66*f122a08bSLinus Torvalds # define CAP_EMPTY_SET    ((kernel_cap_t) { 0 })
67*f122a08bSLinus Torvalds # define CAP_FULL_SET     ((kernel_cap_t) { CAP_VALID_MASK })
68*f122a08bSLinus Torvalds # define CAP_FS_SET       ((kernel_cap_t) { CAP_FS_MASK | BIT_ULL(CAP_LINUX_IMMUTABLE) })
69*f122a08bSLinus Torvalds # define CAP_NFSD_SET     ((kernel_cap_t) { CAP_FS_MASK | BIT_ULL(CAP_SYS_RESOURCE) })
70e114e473SCasey Schaufler 
71*f122a08bSLinus Torvalds # define cap_clear(c)         do { (c).val = 0; } while (0)
721da177e4SLinus Torvalds 
73*f122a08bSLinus Torvalds #define cap_raise(c, flag)  ((c).val |= BIT_ULL(flag))
74*f122a08bSLinus Torvalds #define cap_lower(c, flag)  ((c).val &= ~BIT_ULL(flag))
75*f122a08bSLinus Torvalds #define cap_raised(c, flag) (((c).val & BIT_ULL(flag)) != 0)
76e338d263SAndrew Morgan 
cap_combine(const kernel_cap_t a,const kernel_cap_t b)77e338d263SAndrew Morgan static inline kernel_cap_t cap_combine(const kernel_cap_t a,
78e338d263SAndrew Morgan 				       const kernel_cap_t b)
791da177e4SLinus Torvalds {
80*f122a08bSLinus Torvalds 	return (kernel_cap_t) { a.val | b.val };
811da177e4SLinus Torvalds }
821da177e4SLinus Torvalds 
cap_intersect(const kernel_cap_t a,const kernel_cap_t b)83e338d263SAndrew Morgan static inline kernel_cap_t cap_intersect(const kernel_cap_t a,
84e338d263SAndrew Morgan 					 const kernel_cap_t b)
851da177e4SLinus Torvalds {
86*f122a08bSLinus Torvalds 	return (kernel_cap_t) { a.val & b.val };
871da177e4SLinus Torvalds }
881da177e4SLinus Torvalds 
cap_drop(const kernel_cap_t a,const kernel_cap_t drop)89e338d263SAndrew Morgan static inline kernel_cap_t cap_drop(const kernel_cap_t a,
90e338d263SAndrew Morgan 				    const kernel_cap_t drop)
911da177e4SLinus Torvalds {
92*f122a08bSLinus Torvalds 	return (kernel_cap_t) { a.val &~ drop.val };
931da177e4SLinus Torvalds }
941da177e4SLinus Torvalds 
cap_isclear(const kernel_cap_t a)95e42852bfSYaowei Bai static inline bool cap_isclear(const kernel_cap_t a)
96e338d263SAndrew Morgan {
97*f122a08bSLinus Torvalds 	return !a.val;
98e338d263SAndrew Morgan }
991da177e4SLinus Torvalds 
cap_isidentical(const kernel_cap_t a,const kernel_cap_t b)100a4eecbaeSMateusz Guzik static inline bool cap_isidentical(const kernel_cap_t a, const kernel_cap_t b)
101a4eecbaeSMateusz Guzik {
102*f122a08bSLinus Torvalds 	return a.val == b.val;
103a4eecbaeSMateusz Guzik }
104a4eecbaeSMateusz Guzik 
1059d36be76SEric Paris /*
1069d36be76SEric Paris  * Check if "a" is a subset of "set".
107e42852bfSYaowei Bai  * return true if ALL of the capabilities in "a" are also in "set"
108e42852bfSYaowei Bai  *	cap_issubset(0101, 1111) will return true
109e42852bfSYaowei Bai  * return false if ANY of the capabilities in "a" are not in "set"
110e42852bfSYaowei Bai  *	cap_issubset(1111, 0101) will return false
1119d36be76SEric Paris  */
cap_issubset(const kernel_cap_t a,const kernel_cap_t set)112e42852bfSYaowei Bai static inline bool cap_issubset(const kernel_cap_t a, const kernel_cap_t set)
113e338d263SAndrew Morgan {
114*f122a08bSLinus Torvalds 	return !(a.val & ~set.val);
115e338d263SAndrew Morgan }
1161da177e4SLinus Torvalds 
117e338d263SAndrew Morgan /* Used to decide between falling back on the old suser() or fsuser(). */
118e338d263SAndrew Morgan 
cap_drop_fs_set(const kernel_cap_t a)119e338d263SAndrew Morgan static inline kernel_cap_t cap_drop_fs_set(const kernel_cap_t a)
120e338d263SAndrew Morgan {
121*f122a08bSLinus Torvalds 	return cap_drop(a, CAP_FS_SET);
122e338d263SAndrew Morgan }
123e338d263SAndrew Morgan 
cap_raise_fs_set(const kernel_cap_t a,const kernel_cap_t permitted)124e338d263SAndrew Morgan static inline kernel_cap_t cap_raise_fs_set(const kernel_cap_t a,
125e338d263SAndrew Morgan 					    const kernel_cap_t permitted)
126e338d263SAndrew Morgan {
127*f122a08bSLinus Torvalds 	return cap_combine(a, cap_intersect(permitted, CAP_FS_SET));
128e338d263SAndrew Morgan }
129e338d263SAndrew Morgan 
cap_drop_nfsd_set(const kernel_cap_t a)130e338d263SAndrew Morgan static inline kernel_cap_t cap_drop_nfsd_set(const kernel_cap_t a)
131e338d263SAndrew Morgan {
132*f122a08bSLinus Torvalds 	return cap_drop(a, CAP_NFSD_SET);
133e338d263SAndrew Morgan }
134e338d263SAndrew Morgan 
cap_raise_nfsd_set(const kernel_cap_t a,const kernel_cap_t permitted)135e338d263SAndrew Morgan static inline kernel_cap_t cap_raise_nfsd_set(const kernel_cap_t a,
136e338d263SAndrew Morgan 					      const kernel_cap_t permitted)
137e338d263SAndrew Morgan {
138*f122a08bSLinus Torvalds 	return cap_combine(a, cap_intersect(permitted, CAP_NFSD_SET));
139e338d263SAndrew Morgan }
140e338d263SAndrew Morgan 
1412813893fSIulia Manda #ifdef CONFIG_MULTIUSER
1423263245dSSerge E. Hallyn extern bool has_capability(struct task_struct *t, int cap);
1433263245dSSerge E. Hallyn extern bool has_ns_capability(struct task_struct *t,
1443263245dSSerge E. Hallyn 			      struct user_namespace *ns, int cap);
1453263245dSSerge E. Hallyn extern bool has_capability_noaudit(struct task_struct *t, int cap);
1467b61d648SEric Paris extern bool has_ns_capability_noaudit(struct task_struct *t,
1477b61d648SEric Paris 				      struct user_namespace *ns, int cap);
1483486740aSSerge E. Hallyn extern bool capable(int cap);
1493486740aSSerge E. Hallyn extern bool ns_capable(struct user_namespace *ns, int cap);
15098f368e9STyler Hicks extern bool ns_capable_noaudit(struct user_namespace *ns, int cap);
15140852275SMicah Morton extern bool ns_capable_setid(struct user_namespace *ns, int cap);
1522813893fSIulia Manda #else
has_capability(struct task_struct * t,int cap)1532813893fSIulia Manda static inline bool has_capability(struct task_struct *t, int cap)
1542813893fSIulia Manda {
1552813893fSIulia Manda 	return true;
1562813893fSIulia Manda }
has_ns_capability(struct task_struct * t,struct user_namespace * ns,int cap)1572813893fSIulia Manda static inline bool has_ns_capability(struct task_struct *t,
1582813893fSIulia Manda 			      struct user_namespace *ns, int cap)
1592813893fSIulia Manda {
1602813893fSIulia Manda 	return true;
1612813893fSIulia Manda }
has_capability_noaudit(struct task_struct * t,int cap)1622813893fSIulia Manda static inline bool has_capability_noaudit(struct task_struct *t, int cap)
1632813893fSIulia Manda {
1642813893fSIulia Manda 	return true;
1652813893fSIulia Manda }
has_ns_capability_noaudit(struct task_struct * t,struct user_namespace * ns,int cap)1662813893fSIulia Manda static inline bool has_ns_capability_noaudit(struct task_struct *t,
1672813893fSIulia Manda 				      struct user_namespace *ns, int cap)
1682813893fSIulia Manda {
1692813893fSIulia Manda 	return true;
1702813893fSIulia Manda }
capable(int cap)1712813893fSIulia Manda static inline bool capable(int cap)
1722813893fSIulia Manda {
1732813893fSIulia Manda 	return true;
1742813893fSIulia Manda }
ns_capable(struct user_namespace * ns,int cap)1752813893fSIulia Manda static inline bool ns_capable(struct user_namespace *ns, int cap)
1762813893fSIulia Manda {
1772813893fSIulia Manda 	return true;
1782813893fSIulia Manda }
ns_capable_noaudit(struct user_namespace * ns,int cap)17998f368e9STyler Hicks static inline bool ns_capable_noaudit(struct user_namespace *ns, int cap)
18098f368e9STyler Hicks {
18198f368e9STyler Hicks 	return true;
18298f368e9STyler Hicks }
ns_capable_setid(struct user_namespace * ns,int cap)18340852275SMicah Morton static inline bool ns_capable_setid(struct user_namespace *ns, int cap)
18440852275SMicah Morton {
18540852275SMicah Morton 	return true;
18640852275SMicah Morton }
1872813893fSIulia Manda #endif /* CONFIG_MULTIUSER */
1880558c1bfSChristian Brauner bool privileged_wrt_inode_uidgid(struct user_namespace *ns,
1899452e93eSChristian Brauner 				 struct mnt_idmap *idmap,
1900558c1bfSChristian Brauner 				 const struct inode *inode);
1919452e93eSChristian Brauner bool capable_wrt_inode_uidgid(struct mnt_idmap *idmap,
1920558c1bfSChristian Brauner 			      const struct inode *inode, int cap);
193935d8aabSLinus Torvalds extern bool file_ns_capable(const struct file *file, struct user_namespace *ns, int cap);
19464b875f7SEric W. Biederman extern bool ptracer_capable(struct task_struct *tsk, struct user_namespace *ns);
perfmon_capable(void)19598073728SAlexey Budankov static inline bool perfmon_capable(void)
19698073728SAlexey Budankov {
19798073728SAlexey Budankov 	return capable(CAP_PERFMON) || capable(CAP_SYS_ADMIN);
19898073728SAlexey Budankov }
199c59ede7bSRandy.Dunlap 
bpf_capable(void)200a17b53c4SAlexei Starovoitov static inline bool bpf_capable(void)
201a17b53c4SAlexei Starovoitov {
202a17b53c4SAlexei Starovoitov 	return capable(CAP_BPF) || capable(CAP_SYS_ADMIN);
203a17b53c4SAlexei Starovoitov }
204a17b53c4SAlexei Starovoitov 
checkpoint_restore_ns_capable(struct user_namespace * ns)205124ea650SAdrian Reber static inline bool checkpoint_restore_ns_capable(struct user_namespace *ns)
206124ea650SAdrian Reber {
207124ea650SAdrian Reber 	return ns_capable(ns, CAP_CHECKPOINT_RESTORE) ||
208124ea650SAdrian Reber 		ns_capable(ns, CAP_SYS_ADMIN);
209124ea650SAdrian Reber }
210124ea650SAdrian Reber 
211851f7ff5SEric Paris /* audit system wants to get cap info from files as well */
21239f60c1cSChristian Brauner int get_vfs_caps_from_disk(struct mnt_idmap *idmap,
21371bc356fSChristian Brauner 			   const struct dentry *dentry,
21471bc356fSChristian Brauner 			   struct cpu_vfs_cap_data *cpu_caps);
215851f7ff5SEric Paris 
21639f60c1cSChristian Brauner int cap_convert_nscap(struct mnt_idmap *idmap, struct dentry *dentry,
217e65ce2a5SChristian Brauner 		      const void **ivalue, size_t size);
2188db6c34fSSerge E. Hallyn 
2191da177e4SLinus Torvalds #endif /* !_LINUX_CAPABILITY_H */
220