xref: /linux-6.15/include/linux/capability.h (revision a4eecbae)
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 <[email protected]>
61da177e4SLinus Torvalds  * Alexander Kjeldaas <[email protected]>
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>
18ca05a99aSAndrew G. Morgan 
19ca05a99aSAndrew G. Morgan #define _KERNEL_CAPABILITY_VERSION _LINUX_CAPABILITY_VERSION_3
20ca05a99aSAndrew G. Morgan #define _KERNEL_CAPABILITY_U32S    _LINUX_CAPABILITY_U32S_3
211da177e4SLinus Torvalds 
229fa91d99SJaswinder Singh Rajput extern int file_caps_enabled;
239fa91d99SJaswinder Singh Rajput 
241da177e4SLinus Torvalds typedef struct kernel_cap_struct {
25ca05a99aSAndrew G. Morgan 	__u32 cap[_KERNEL_CAPABILITY_U32S];
261da177e4SLinus Torvalds } kernel_cap_t;
271da177e4SLinus Torvalds 
282fec30e2SRichard Guy Briggs /* same as vfs_ns_cap_data but in cpu endian and always filled completely */
29c0b00441SEric Paris struct cpu_vfs_cap_data {
30c0b00441SEric Paris 	__u32 magic_etc;
31c0b00441SEric Paris 	kernel_cap_t permitted;
32c0b00441SEric Paris 	kernel_cap_t inheritable;
332fec30e2SRichard Guy Briggs 	kuid_t rootid;
34c0b00441SEric Paris };
35c0b00441SEric Paris 
36e338d263SAndrew Morgan #define _USER_CAP_HEADER_SIZE  (sizeof(struct __user_cap_header_struct))
371da177e4SLinus Torvalds #define _KERNEL_CAP_T_SIZE     (sizeof(kernel_cap_t))
381da177e4SLinus Torvalds 
391da177e4SLinus Torvalds 
40935d8aabSLinus Torvalds struct file;
411a48e2acSEric W. Biederman struct inode;
423486740aSSerge E. Hallyn struct dentry;
43db3f6001SAlexey Dobriyan struct task_struct;
443486740aSSerge E. Hallyn struct user_namespace;
4539f60c1cSChristian Brauner struct mnt_idmap;
463486740aSSerge E. Hallyn 
473486740aSSerge E. Hallyn extern const kernel_cap_t __cap_empty_set;
483486740aSSerge E. Hallyn extern const kernel_cap_t __cap_init_eff_set;
493486740aSSerge E. Hallyn 
501da177e4SLinus Torvalds /*
511da177e4SLinus Torvalds  * Internal kernel functions only
521da177e4SLinus Torvalds  */
531da177e4SLinus Torvalds 
54e338d263SAndrew Morgan #define CAP_FOR_EACH_U32(__capi)  \
55ca05a99aSAndrew G. Morgan 	for (__capi = 0; __capi < _KERNEL_CAPABILITY_U32S; ++__capi)
561da177e4SLinus Torvalds 
570ad30b8fSSerge E. Hallyn /*
580ad30b8fSSerge E. Hallyn  * CAP_FS_MASK and CAP_NFSD_MASKS:
590ad30b8fSSerge E. Hallyn  *
600ad30b8fSSerge E. Hallyn  * The fs mask is all the privileges that fsuid==0 historically meant.
610ad30b8fSSerge E. Hallyn  * At one time in the past, that included CAP_MKNOD and CAP_LINUX_IMMUTABLE.
620ad30b8fSSerge E. Hallyn  *
630ad30b8fSSerge E. Hallyn  * It has never meant setting security.* and trusted.* xattrs.
640ad30b8fSSerge E. Hallyn  *
650ad30b8fSSerge E. Hallyn  * We could also define fsmask as follows:
660ad30b8fSSerge E. Hallyn  *   1. CAP_FS_MASK is the privilege to bypass all fs-related DAC permissions
670ad30b8fSSerge E. Hallyn  *   2. The security.* and trusted.* xattrs are fs-related MAC permissions
680ad30b8fSSerge E. Hallyn  */
690ad30b8fSSerge E. Hallyn 
70e338d263SAndrew Morgan # define CAP_FS_MASK_B0     (CAP_TO_MASK(CAP_CHOWN)		\
710ad30b8fSSerge E. Hallyn 			    | CAP_TO_MASK(CAP_MKNOD)		\
72e338d263SAndrew Morgan 			    | CAP_TO_MASK(CAP_DAC_OVERRIDE)	\
73e338d263SAndrew Morgan 			    | CAP_TO_MASK(CAP_DAC_READ_SEARCH)	\
74e338d263SAndrew Morgan 			    | CAP_TO_MASK(CAP_FOWNER)		\
75e338d263SAndrew Morgan 			    | CAP_TO_MASK(CAP_FSETID))
761da177e4SLinus Torvalds 
77e114e473SCasey Schaufler # define CAP_FS_MASK_B1     (CAP_TO_MASK(CAP_MAC_OVERRIDE))
78e114e473SCasey Schaufler 
79ca05a99aSAndrew G. Morgan #if _KERNEL_CAPABILITY_U32S != 2
80e338d263SAndrew Morgan # error Fix up hand-coded capability macro initializers
81e338d263SAndrew Morgan #else /* HAND-CODED capability initializers */
821da177e4SLinus Torvalds 
837d8b6c63SEric Paris #define CAP_LAST_U32			((_KERNEL_CAPABILITY_U32S) - 1)
847d8b6c63SEric Paris #define CAP_LAST_U32_VALID_MASK		(CAP_TO_MASK(CAP_LAST_CAP + 1) -1)
857d8b6c63SEric Paris 
8625f2ea9fSDavid Howells # define CAP_EMPTY_SET    ((kernel_cap_t){{ 0, 0 }})
877d8b6c63SEric Paris # define CAP_FULL_SET     ((kernel_cap_t){{ ~0, CAP_LAST_U32_VALID_MASK }})
880ad30b8fSSerge E. Hallyn # define CAP_FS_SET       ((kernel_cap_t){{ CAP_FS_MASK_B0 \
890ad30b8fSSerge E. Hallyn 				    | CAP_TO_MASK(CAP_LINUX_IMMUTABLE), \
900ad30b8fSSerge E. Hallyn 				    CAP_FS_MASK_B1 } })
9176a67ec6SJ. Bruce Fields # define CAP_NFSD_SET     ((kernel_cap_t){{ CAP_FS_MASK_B0 \
920ad30b8fSSerge E. Hallyn 				    | CAP_TO_MASK(CAP_SYS_RESOURCE), \
9325f2ea9fSDavid Howells 				    CAP_FS_MASK_B1 } })
941da177e4SLinus Torvalds 
95ca05a99aSAndrew G. Morgan #endif /* _KERNEL_CAPABILITY_U32S != 2 */
961da177e4SLinus Torvalds 
97e338d263SAndrew Morgan # define cap_clear(c)         do { (c) = __cap_empty_set; } while (0)
981da177e4SLinus Torvalds 
99e338d263SAndrew Morgan #define cap_raise(c, flag)  ((c).cap[CAP_TO_INDEX(flag)] |= CAP_TO_MASK(flag))
100e338d263SAndrew Morgan #define cap_lower(c, flag)  ((c).cap[CAP_TO_INDEX(flag)] &= ~CAP_TO_MASK(flag))
101e338d263SAndrew Morgan #define cap_raised(c, flag) ((c).cap[CAP_TO_INDEX(flag)] & CAP_TO_MASK(flag))
102e338d263SAndrew Morgan 
103e338d263SAndrew Morgan #define CAP_BOP_ALL(c, a, b, OP)                                    \
104e338d263SAndrew Morgan do {                                                                \
105e338d263SAndrew Morgan 	unsigned __capi;                                            \
106e338d263SAndrew Morgan 	CAP_FOR_EACH_U32(__capi) {                                  \
107e338d263SAndrew Morgan 		c.cap[__capi] = a.cap[__capi] OP b.cap[__capi];     \
108e338d263SAndrew Morgan 	}                                                           \
109e338d263SAndrew Morgan } while (0)
110e338d263SAndrew Morgan 
111e338d263SAndrew Morgan #define CAP_UOP_ALL(c, a, OP)                                       \
112e338d263SAndrew Morgan do {                                                                \
113e338d263SAndrew Morgan 	unsigned __capi;                                            \
114e338d263SAndrew Morgan 	CAP_FOR_EACH_U32(__capi) {                                  \
115e338d263SAndrew Morgan 		c.cap[__capi] = OP a.cap[__capi];                   \
116e338d263SAndrew Morgan 	}                                                           \
117e338d263SAndrew Morgan } while (0)
118e338d263SAndrew Morgan 
119e338d263SAndrew Morgan static inline kernel_cap_t cap_combine(const kernel_cap_t a,
120e338d263SAndrew Morgan 				       const kernel_cap_t b)
1211da177e4SLinus Torvalds {
1221da177e4SLinus Torvalds 	kernel_cap_t dest;
123e338d263SAndrew Morgan 	CAP_BOP_ALL(dest, a, b, |);
1241da177e4SLinus Torvalds 	return dest;
1251da177e4SLinus Torvalds }
1261da177e4SLinus Torvalds 
127e338d263SAndrew Morgan static inline kernel_cap_t cap_intersect(const kernel_cap_t a,
128e338d263SAndrew Morgan 					 const kernel_cap_t b)
1291da177e4SLinus Torvalds {
1301da177e4SLinus Torvalds 	kernel_cap_t dest;
131e338d263SAndrew Morgan 	CAP_BOP_ALL(dest, a, b, &);
1321da177e4SLinus Torvalds 	return dest;
1331da177e4SLinus Torvalds }
1341da177e4SLinus Torvalds 
135e338d263SAndrew Morgan static inline kernel_cap_t cap_drop(const kernel_cap_t a,
136e338d263SAndrew Morgan 				    const kernel_cap_t drop)
1371da177e4SLinus Torvalds {
1381da177e4SLinus Torvalds 	kernel_cap_t dest;
139e338d263SAndrew Morgan 	CAP_BOP_ALL(dest, a, drop, &~);
1401da177e4SLinus Torvalds 	return dest;
1411da177e4SLinus Torvalds }
1421da177e4SLinus Torvalds 
143e338d263SAndrew Morgan static inline kernel_cap_t cap_invert(const kernel_cap_t c)
1441da177e4SLinus Torvalds {
1451da177e4SLinus Torvalds 	kernel_cap_t dest;
146e338d263SAndrew Morgan 	CAP_UOP_ALL(dest, c, ~);
1471da177e4SLinus Torvalds 	return dest;
1481da177e4SLinus Torvalds }
1491da177e4SLinus Torvalds 
150e42852bfSYaowei Bai static inline bool cap_isclear(const kernel_cap_t a)
151e338d263SAndrew Morgan {
152e338d263SAndrew Morgan 	unsigned __capi;
153e338d263SAndrew Morgan 	CAP_FOR_EACH_U32(__capi) {
154e338d263SAndrew Morgan 		if (a.cap[__capi] != 0)
155e42852bfSYaowei Bai 			return false;
156e338d263SAndrew Morgan 	}
157e42852bfSYaowei Bai 	return true;
158e338d263SAndrew Morgan }
1591da177e4SLinus Torvalds 
160*a4eecbaeSMateusz Guzik static inline bool cap_isidentical(const kernel_cap_t a, const kernel_cap_t b)
161*a4eecbaeSMateusz Guzik {
162*a4eecbaeSMateusz Guzik 	unsigned __capi;
163*a4eecbaeSMateusz Guzik 	CAP_FOR_EACH_U32(__capi) {
164*a4eecbaeSMateusz Guzik 		if (a.cap[__capi] != b.cap[__capi])
165*a4eecbaeSMateusz Guzik 			return false;
166*a4eecbaeSMateusz Guzik 	}
167*a4eecbaeSMateusz Guzik 	return true;
168*a4eecbaeSMateusz Guzik }
169*a4eecbaeSMateusz Guzik 
1709d36be76SEric Paris /*
1719d36be76SEric Paris  * Check if "a" is a subset of "set".
172e42852bfSYaowei Bai  * return true if ALL of the capabilities in "a" are also in "set"
173e42852bfSYaowei Bai  *	cap_issubset(0101, 1111) will return true
174e42852bfSYaowei Bai  * return false if ANY of the capabilities in "a" are not in "set"
175e42852bfSYaowei Bai  *	cap_issubset(1111, 0101) will return false
1769d36be76SEric Paris  */
177e42852bfSYaowei Bai static inline bool cap_issubset(const kernel_cap_t a, const kernel_cap_t set)
178e338d263SAndrew Morgan {
179e338d263SAndrew Morgan 	kernel_cap_t dest;
180e338d263SAndrew Morgan 	dest = cap_drop(a, set);
181e338d263SAndrew Morgan 	return cap_isclear(dest);
182e338d263SAndrew Morgan }
1831da177e4SLinus Torvalds 
184e338d263SAndrew Morgan /* Used to decide between falling back on the old suser() or fsuser(). */
185e338d263SAndrew Morgan 
186e338d263SAndrew Morgan static inline kernel_cap_t cap_drop_fs_set(const kernel_cap_t a)
187e338d263SAndrew Morgan {
188e338d263SAndrew Morgan 	const kernel_cap_t __cap_fs_set = CAP_FS_SET;
189e338d263SAndrew Morgan 	return cap_drop(a, __cap_fs_set);
190e338d263SAndrew Morgan }
191e338d263SAndrew Morgan 
192e338d263SAndrew Morgan static inline kernel_cap_t cap_raise_fs_set(const kernel_cap_t a,
193e338d263SAndrew Morgan 					    const kernel_cap_t permitted)
194e338d263SAndrew Morgan {
195e338d263SAndrew Morgan 	const kernel_cap_t __cap_fs_set = CAP_FS_SET;
196e338d263SAndrew Morgan 	return cap_combine(a,
197e338d263SAndrew Morgan 			   cap_intersect(permitted, __cap_fs_set));
198e338d263SAndrew Morgan }
199e338d263SAndrew Morgan 
200e338d263SAndrew Morgan static inline kernel_cap_t cap_drop_nfsd_set(const kernel_cap_t a)
201e338d263SAndrew Morgan {
202e338d263SAndrew Morgan 	const kernel_cap_t __cap_fs_set = CAP_NFSD_SET;
203e338d263SAndrew Morgan 	return cap_drop(a, __cap_fs_set);
204e338d263SAndrew Morgan }
205e338d263SAndrew Morgan 
206e338d263SAndrew Morgan static inline kernel_cap_t cap_raise_nfsd_set(const kernel_cap_t a,
207e338d263SAndrew Morgan 					      const kernel_cap_t permitted)
208e338d263SAndrew Morgan {
209e338d263SAndrew Morgan 	const kernel_cap_t __cap_nfsd_set = CAP_NFSD_SET;
210e338d263SAndrew Morgan 	return cap_combine(a,
211e338d263SAndrew Morgan 			   cap_intersect(permitted, __cap_nfsd_set));
212e338d263SAndrew Morgan }
213e338d263SAndrew Morgan 
2142813893fSIulia Manda #ifdef CONFIG_MULTIUSER
2153263245dSSerge E. Hallyn extern bool has_capability(struct task_struct *t, int cap);
2163263245dSSerge E. Hallyn extern bool has_ns_capability(struct task_struct *t,
2173263245dSSerge E. Hallyn 			      struct user_namespace *ns, int cap);
2183263245dSSerge E. Hallyn extern bool has_capability_noaudit(struct task_struct *t, int cap);
2197b61d648SEric Paris extern bool has_ns_capability_noaudit(struct task_struct *t,
2207b61d648SEric Paris 				      struct user_namespace *ns, int cap);
2213486740aSSerge E. Hallyn extern bool capable(int cap);
2223486740aSSerge E. Hallyn extern bool ns_capable(struct user_namespace *ns, int cap);
22398f368e9STyler Hicks extern bool ns_capable_noaudit(struct user_namespace *ns, int cap);
22440852275SMicah Morton extern bool ns_capable_setid(struct user_namespace *ns, int cap);
2252813893fSIulia Manda #else
2262813893fSIulia Manda static inline bool has_capability(struct task_struct *t, int cap)
2272813893fSIulia Manda {
2282813893fSIulia Manda 	return true;
2292813893fSIulia Manda }
2302813893fSIulia Manda static inline bool has_ns_capability(struct task_struct *t,
2312813893fSIulia Manda 			      struct user_namespace *ns, int cap)
2322813893fSIulia Manda {
2332813893fSIulia Manda 	return true;
2342813893fSIulia Manda }
2352813893fSIulia Manda static inline bool has_capability_noaudit(struct task_struct *t, int cap)
2362813893fSIulia Manda {
2372813893fSIulia Manda 	return true;
2382813893fSIulia Manda }
2392813893fSIulia Manda static inline bool has_ns_capability_noaudit(struct task_struct *t,
2402813893fSIulia Manda 				      struct user_namespace *ns, int cap)
2412813893fSIulia Manda {
2422813893fSIulia Manda 	return true;
2432813893fSIulia Manda }
2442813893fSIulia Manda static inline bool capable(int cap)
2452813893fSIulia Manda {
2462813893fSIulia Manda 	return true;
2472813893fSIulia Manda }
2482813893fSIulia Manda static inline bool ns_capable(struct user_namespace *ns, int cap)
2492813893fSIulia Manda {
2502813893fSIulia Manda 	return true;
2512813893fSIulia Manda }
25298f368e9STyler Hicks static inline bool ns_capable_noaudit(struct user_namespace *ns, int cap)
25398f368e9STyler Hicks {
25498f368e9STyler Hicks 	return true;
25598f368e9STyler Hicks }
25640852275SMicah Morton static inline bool ns_capable_setid(struct user_namespace *ns, int cap)
25740852275SMicah Morton {
25840852275SMicah Morton 	return true;
25940852275SMicah Morton }
2602813893fSIulia Manda #endif /* CONFIG_MULTIUSER */
2610558c1bfSChristian Brauner bool privileged_wrt_inode_uidgid(struct user_namespace *ns,
2629452e93eSChristian Brauner 				 struct mnt_idmap *idmap,
2630558c1bfSChristian Brauner 				 const struct inode *inode);
2649452e93eSChristian Brauner bool capable_wrt_inode_uidgid(struct mnt_idmap *idmap,
2650558c1bfSChristian Brauner 			      const struct inode *inode, int cap);
266935d8aabSLinus Torvalds extern bool file_ns_capable(const struct file *file, struct user_namespace *ns, int cap);
26764b875f7SEric W. Biederman extern bool ptracer_capable(struct task_struct *tsk, struct user_namespace *ns);
26898073728SAlexey Budankov static inline bool perfmon_capable(void)
26998073728SAlexey Budankov {
27098073728SAlexey Budankov 	return capable(CAP_PERFMON) || capable(CAP_SYS_ADMIN);
27198073728SAlexey Budankov }
272c59ede7bSRandy.Dunlap 
273a17b53c4SAlexei Starovoitov static inline bool bpf_capable(void)
274a17b53c4SAlexei Starovoitov {
275a17b53c4SAlexei Starovoitov 	return capable(CAP_BPF) || capable(CAP_SYS_ADMIN);
276a17b53c4SAlexei Starovoitov }
277a17b53c4SAlexei Starovoitov 
278124ea650SAdrian Reber static inline bool checkpoint_restore_ns_capable(struct user_namespace *ns)
279124ea650SAdrian Reber {
280124ea650SAdrian Reber 	return ns_capable(ns, CAP_CHECKPOINT_RESTORE) ||
281124ea650SAdrian Reber 		ns_capable(ns, CAP_SYS_ADMIN);
282124ea650SAdrian Reber }
283124ea650SAdrian Reber 
284851f7ff5SEric Paris /* audit system wants to get cap info from files as well */
28539f60c1cSChristian Brauner int get_vfs_caps_from_disk(struct mnt_idmap *idmap,
28671bc356fSChristian Brauner 			   const struct dentry *dentry,
28771bc356fSChristian Brauner 			   struct cpu_vfs_cap_data *cpu_caps);
288851f7ff5SEric Paris 
28939f60c1cSChristian Brauner int cap_convert_nscap(struct mnt_idmap *idmap, struct dentry *dentry,
290e65ce2a5SChristian Brauner 		      const void **ivalue, size_t size);
2918db6c34fSSerge E. Hallyn 
2921da177e4SLinus Torvalds #endif /* !_LINUX_CAPABILITY_H */
293