Blame view
include/linux/capability.h
7.31 KB
1da177e4c
|
1 2 3 |
/* * This is <linux/capability.h> * |
b53767719
|
4 |
* Andrew G. Morgan <morgan@kernel.org> |
1da177e4c
|
5 6 7 8 9 |
* Alexander Kjeldaas <astor@guardian.no> * with help from Aleph1, Roland Buresund and Andrew Main. * * See here for the libcap library ("POSIX draft" compliance): * |
bcf564424
|
10 |
* ftp://www.kernel.org/pub/linux/libs/security/linux-privs/kernel-2.6/ |
b53767719
|
11 |
*/ |
1da177e4c
|
12 13 |
#ifndef _LINUX_CAPABILITY_H #define _LINUX_CAPABILITY_H |
607ca46e9
|
14 |
#include <uapi/linux/capability.h> |
e338d263a
|
15 |
|
ca05a99a5
|
16 17 18 |
#define _KERNEL_CAPABILITY_VERSION _LINUX_CAPABILITY_VERSION_3 #define _KERNEL_CAPABILITY_U32S _LINUX_CAPABILITY_U32S_3 |
1da177e4c
|
19 |
|
9fa91d99b
|
20 |
extern int file_caps_enabled; |
9fa91d99b
|
21 |
|
1da177e4c
|
22 |
typedef struct kernel_cap_struct { |
ca05a99a5
|
23 |
__u32 cap[_KERNEL_CAPABILITY_U32S]; |
1da177e4c
|
24 |
} kernel_cap_t; |
c0b004413
|
25 26 27 28 29 30 |
/* exact same as vfs_cap_data but in cpu endian and always filled completely */ struct cpu_vfs_cap_data { __u32 magic_etc; kernel_cap_t permitted; kernel_cap_t inheritable; }; |
e338d263a
|
31 |
#define _USER_CAP_HEADER_SIZE (sizeof(struct __user_cap_header_struct)) |
1da177e4c
|
32 |
#define _KERNEL_CAP_T_SIZE (sizeof(kernel_cap_t)) |
1da177e4c
|
33 |
|
935d8aabd
|
34 |
struct file; |
1a48e2ac0
|
35 |
struct inode; |
3486740a4
|
36 37 |
struct dentry; struct user_namespace; |
3486740a4
|
38 39 40 |
struct user_namespace *current_user_ns(void); extern const kernel_cap_t __cap_empty_set; |
3486740a4
|
41 |
extern const kernel_cap_t __cap_init_eff_set; |
1da177e4c
|
42 43 44 |
/* * Internal kernel functions only */ |
b53767719
|
45 |
|
e338d263a
|
46 |
#define CAP_FOR_EACH_U32(__capi) \ |
ca05a99a5
|
47 |
for (__capi = 0; __capi < _KERNEL_CAPABILITY_U32S; ++__capi) |
e338d263a
|
48 |
|
0ad30b8fd
|
49 50 51 52 53 54 55 56 57 58 59 60 |
/* * CAP_FS_MASK and CAP_NFSD_MASKS: * * The fs mask is all the privileges that fsuid==0 historically meant. * At one time in the past, that included CAP_MKNOD and CAP_LINUX_IMMUTABLE. * * It has never meant setting security.* and trusted.* xattrs. * * We could also define fsmask as follows: * 1. CAP_FS_MASK is the privilege to bypass all fs-related DAC permissions * 2. The security.* and trusted.* xattrs are fs-related MAC permissions */ |
e338d263a
|
61 |
# define CAP_FS_MASK_B0 (CAP_TO_MASK(CAP_CHOWN) \ |
0ad30b8fd
|
62 |
| CAP_TO_MASK(CAP_MKNOD) \ |
e338d263a
|
63 64 65 66 |
| CAP_TO_MASK(CAP_DAC_OVERRIDE) \ | CAP_TO_MASK(CAP_DAC_READ_SEARCH) \ | CAP_TO_MASK(CAP_FOWNER) \ | CAP_TO_MASK(CAP_FSETID)) |
e114e4737
|
67 |
# define CAP_FS_MASK_B1 (CAP_TO_MASK(CAP_MAC_OVERRIDE)) |
ca05a99a5
|
68 |
#if _KERNEL_CAPABILITY_U32S != 2 |
e338d263a
|
69 70 |
# error Fix up hand-coded capability macro initializers #else /* HAND-CODED capability initializers */ |
7d8b6c637
|
71 72 |
#define CAP_LAST_U32 ((_KERNEL_CAPABILITY_U32S) - 1) #define CAP_LAST_U32_VALID_MASK (CAP_TO_MASK(CAP_LAST_CAP + 1) -1) |
25f2ea9fc
|
73 |
# define CAP_EMPTY_SET ((kernel_cap_t){{ 0, 0 }}) |
7d8b6c637
|
74 |
# define CAP_FULL_SET ((kernel_cap_t){{ ~0, CAP_LAST_U32_VALID_MASK }}) |
0ad30b8fd
|
75 76 77 |
# define CAP_FS_SET ((kernel_cap_t){{ CAP_FS_MASK_B0 \ | CAP_TO_MASK(CAP_LINUX_IMMUTABLE), \ CAP_FS_MASK_B1 } }) |
76a67ec6f
|
78 |
# define CAP_NFSD_SET ((kernel_cap_t){{ CAP_FS_MASK_B0 \ |
0ad30b8fd
|
79 80 |
| CAP_TO_MASK(CAP_SYS_RESOURCE), \ CAP_FS_MASK_B1 } }) |
e338d263a
|
81 |
|
ca05a99a5
|
82 |
#endif /* _KERNEL_CAPABILITY_U32S != 2 */ |
e338d263a
|
83 |
|
e338d263a
|
84 |
# define cap_clear(c) do { (c) = __cap_empty_set; } while (0) |
e338d263a
|
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
#define cap_raise(c, flag) ((c).cap[CAP_TO_INDEX(flag)] |= CAP_TO_MASK(flag)) #define cap_lower(c, flag) ((c).cap[CAP_TO_INDEX(flag)] &= ~CAP_TO_MASK(flag)) #define cap_raised(c, flag) ((c).cap[CAP_TO_INDEX(flag)] & CAP_TO_MASK(flag)) #define CAP_BOP_ALL(c, a, b, OP) \ do { \ unsigned __capi; \ CAP_FOR_EACH_U32(__capi) { \ c.cap[__capi] = a.cap[__capi] OP b.cap[__capi]; \ } \ } while (0) #define CAP_UOP_ALL(c, a, OP) \ do { \ unsigned __capi; \ CAP_FOR_EACH_U32(__capi) { \ c.cap[__capi] = OP a.cap[__capi]; \ } \ } while (0) static inline kernel_cap_t cap_combine(const kernel_cap_t a, const kernel_cap_t b) { kernel_cap_t dest; CAP_BOP_ALL(dest, a, b, |); return dest; } |
1da177e4c
|
113 |
|
e338d263a
|
114 115 116 117 118 119 120 |
static inline kernel_cap_t cap_intersect(const kernel_cap_t a, const kernel_cap_t b) { kernel_cap_t dest; CAP_BOP_ALL(dest, a, b, &); return dest; } |
1da177e4c
|
121 |
|
e338d263a
|
122 123 124 125 126 127 128 |
static inline kernel_cap_t cap_drop(const kernel_cap_t a, const kernel_cap_t drop) { kernel_cap_t dest; CAP_BOP_ALL(dest, a, drop, &~); return dest; } |
1da177e4c
|
129 |
|
e338d263a
|
130 131 132 133 134 135 |
static inline kernel_cap_t cap_invert(const kernel_cap_t c) { kernel_cap_t dest; CAP_UOP_ALL(dest, c, ~); return dest; } |
1da177e4c
|
136 |
|
e338d263a
|
137 138 139 140 141 142 143 144 145 |
static inline int cap_isclear(const kernel_cap_t a) { unsigned __capi; CAP_FOR_EACH_U32(__capi) { if (a.cap[__capi] != 0) return 0; } return 1; } |
1da177e4c
|
146 |
|
9d36be76c
|
147 148 149 150 151 152 153 |
/* * Check if "a" is a subset of "set". * return 1 if ALL of the capabilities in "a" are also in "set" * cap_issubset(0101, 1111) will return 1 * return 0 if ANY of the capabilities in "a" are not in "set" * cap_issubset(1111, 0101) will return 0 */ |
e338d263a
|
154 155 156 157 158 159 |
static inline int cap_issubset(const kernel_cap_t a, const kernel_cap_t set) { kernel_cap_t dest; dest = cap_drop(a, set); return cap_isclear(dest); } |
1da177e4c
|
160 |
|
e338d263a
|
161 |
/* Used to decide between falling back on the old suser() or fsuser(). */ |
1da177e4c
|
162 |
|
e338d263a
|
163 |
static inline int cap_is_fs_cap(int cap) |
1da177e4c
|
164 |
{ |
e338d263a
|
165 166 |
const kernel_cap_t __cap_fs_set = CAP_FS_SET; return !!(CAP_TO_MASK(cap) & __cap_fs_set.cap[CAP_TO_INDEX(cap)]); |
1da177e4c
|
167 |
} |
e338d263a
|
168 |
static inline kernel_cap_t cap_drop_fs_set(const kernel_cap_t a) |
1da177e4c
|
169 |
{ |
e338d263a
|
170 171 |
const kernel_cap_t __cap_fs_set = CAP_FS_SET; return cap_drop(a, __cap_fs_set); |
1da177e4c
|
172 |
} |
e338d263a
|
173 174 |
static inline kernel_cap_t cap_raise_fs_set(const kernel_cap_t a, const kernel_cap_t permitted) |
1da177e4c
|
175 |
{ |
e338d263a
|
176 177 178 |
const kernel_cap_t __cap_fs_set = CAP_FS_SET; return cap_combine(a, cap_intersect(permitted, __cap_fs_set)); |
1da177e4c
|
179 |
} |
e338d263a
|
180 |
static inline kernel_cap_t cap_drop_nfsd_set(const kernel_cap_t a) |
1da177e4c
|
181 |
{ |
e338d263a
|
182 183 |
const kernel_cap_t __cap_fs_set = CAP_NFSD_SET; return cap_drop(a, __cap_fs_set); |
1da177e4c
|
184 |
} |
e338d263a
|
185 186 187 188 189 190 191 |
static inline kernel_cap_t cap_raise_nfsd_set(const kernel_cap_t a, const kernel_cap_t permitted) { const kernel_cap_t __cap_nfsd_set = CAP_NFSD_SET; return cap_combine(a, cap_intersect(permitted, __cap_nfsd_set)); } |
1da177e4c
|
192 |
|
2813893f8
|
193 |
#ifdef CONFIG_MULTIUSER |
3263245de
|
194 195 196 197 |
extern bool has_capability(struct task_struct *t, int cap); extern bool has_ns_capability(struct task_struct *t, struct user_namespace *ns, int cap); extern bool has_capability_noaudit(struct task_struct *t, int cap); |
7b61d6484
|
198 199 |
extern bool has_ns_capability_noaudit(struct task_struct *t, struct user_namespace *ns, int cap); |
3486740a4
|
200 201 |
extern bool capable(int cap); extern bool ns_capable(struct user_namespace *ns, int cap); |
2813893f8
|
202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 |
#else static inline bool has_capability(struct task_struct *t, int cap) { return true; } static inline bool has_ns_capability(struct task_struct *t, struct user_namespace *ns, int cap) { return true; } static inline bool has_capability_noaudit(struct task_struct *t, int cap) { return true; } static inline bool has_ns_capability_noaudit(struct task_struct *t, struct user_namespace *ns, int cap) { return true; } static inline bool capable(int cap) { return true; } static inline bool ns_capable(struct user_namespace *ns, int cap) { return true; } #endif /* CONFIG_MULTIUSER */ |
23adbe12e
|
230 |
extern bool capable_wrt_inode_uidgid(const struct inode *inode, int cap); |
935d8aabd
|
231 |
extern bool file_ns_capable(const struct file *file, struct user_namespace *ns, int cap); |
c59ede7b7
|
232 |
|
851f7ff56
|
233 |
/* audit system wants to get cap info from files as well */ |
851f7ff56
|
234 |
extern int get_vfs_caps_from_disk(const struct dentry *dentry, struct cpu_vfs_cap_data *cpu_caps); |
1da177e4c
|
235 |
#endif /* !_LINUX_CAPABILITY_H */ |