diff options
Diffstat (limited to 'include/linux/cred.h')
-rw-r--r-- | include/linux/cred.h | 340 |
1 files changed, 317 insertions, 23 deletions
diff --git a/include/linux/cred.h b/include/linux/cred.h index b69222cc1fd2..26c1ab179946 100644 --- a/include/linux/cred.h +++ b/include/linux/cred.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* Credentials management | 1 | /* Credentials management - see Documentation/credentials.txt |
2 | * | 2 | * |
3 | * Copyright (C) 2008 Red Hat, Inc. All Rights Reserved. | 3 | * Copyright (C) 2008 Red Hat, Inc. All Rights Reserved. |
4 | * Written by David Howells (dhowells@redhat.com) | 4 | * Written by David Howells (dhowells@redhat.com) |
@@ -12,39 +12,333 @@ | |||
12 | #ifndef _LINUX_CRED_H | 12 | #ifndef _LINUX_CRED_H |
13 | #define _LINUX_CRED_H | 13 | #define _LINUX_CRED_H |
14 | 14 | ||
15 | #define get_current_user() (get_uid(current->user)) | 15 | #include <linux/capability.h> |
16 | #include <linux/key.h> | ||
17 | #include <asm/atomic.h> | ||
16 | 18 | ||
17 | #define task_uid(task) ((task)->uid) | 19 | struct user_struct; |
18 | #define task_gid(task) ((task)->gid) | 20 | struct cred; |
19 | #define task_euid(task) ((task)->euid) | 21 | struct inode; |
20 | #define task_egid(task) ((task)->egid) | ||
21 | 22 | ||
22 | #define current_uid() (current->uid) | 23 | /* |
23 | #define current_gid() (current->gid) | 24 | * COW Supplementary groups list |
24 | #define current_euid() (current->euid) | 25 | */ |
25 | #define current_egid() (current->egid) | 26 | #define NGROUPS_SMALL 32 |
26 | #define current_suid() (current->suid) | 27 | #define NGROUPS_PER_BLOCK ((unsigned int)(PAGE_SIZE / sizeof(gid_t))) |
27 | #define current_sgid() (current->sgid) | 28 | |
28 | #define current_fsuid() (current->fsuid) | 29 | struct group_info { |
29 | #define current_fsgid() (current->fsgid) | 30 | atomic_t usage; |
30 | #define current_cap() (current->cap_effective) | 31 | int ngroups; |
32 | int nblocks; | ||
33 | gid_t small_block[NGROUPS_SMALL]; | ||
34 | gid_t *blocks[0]; | ||
35 | }; | ||
36 | |||
37 | /** | ||
38 | * get_group_info - Get a reference to a group info structure | ||
39 | * @group_info: The group info to reference | ||
40 | * | ||
41 | * This gets a reference to a set of supplementary groups. | ||
42 | * | ||
43 | * If the caller is accessing a task's credentials, they must hold the RCU read | ||
44 | * lock when reading. | ||
45 | */ | ||
46 | static inline struct group_info *get_group_info(struct group_info *gi) | ||
47 | { | ||
48 | atomic_inc(&gi->usage); | ||
49 | return gi; | ||
50 | } | ||
51 | |||
52 | /** | ||
53 | * put_group_info - Release a reference to a group info structure | ||
54 | * @group_info: The group info to release | ||
55 | */ | ||
56 | #define put_group_info(group_info) \ | ||
57 | do { \ | ||
58 | if (atomic_dec_and_test(&(group_info)->usage)) \ | ||
59 | groups_free(group_info); \ | ||
60 | } while (0) | ||
61 | |||
62 | extern struct group_info *groups_alloc(int); | ||
63 | extern void groups_free(struct group_info *); | ||
64 | extern int set_current_groups(struct group_info *); | ||
65 | extern int set_groups(struct cred *, struct group_info *); | ||
66 | extern int groups_search(const struct group_info *, gid_t); | ||
67 | |||
68 | /* access the groups "array" with this macro */ | ||
69 | #define GROUP_AT(gi, i) \ | ||
70 | ((gi)->blocks[(i) / NGROUPS_PER_BLOCK][(i) % NGROUPS_PER_BLOCK]) | ||
71 | |||
72 | extern int in_group_p(gid_t); | ||
73 | extern int in_egroup_p(gid_t); | ||
74 | |||
75 | /* | ||
76 | * The common credentials for a thread group | ||
77 | * - shared by CLONE_THREAD | ||
78 | */ | ||
79 | #ifdef CONFIG_KEYS | ||
80 | struct thread_group_cred { | ||
81 | atomic_t usage; | ||
82 | pid_t tgid; /* thread group process ID */ | ||
83 | spinlock_t lock; | ||
84 | struct key *session_keyring; /* keyring inherited over fork */ | ||
85 | struct key *process_keyring; /* keyring private to this process */ | ||
86 | struct rcu_head rcu; /* RCU deletion hook */ | ||
87 | }; | ||
88 | #endif | ||
89 | |||
90 | /* | ||
91 | * The security context of a task | ||
92 | * | ||
93 | * The parts of the context break down into two categories: | ||
94 | * | ||
95 | * (1) The objective context of a task. These parts are used when some other | ||
96 | * task is attempting to affect this one. | ||
97 | * | ||
98 | * (2) The subjective context. These details are used when the task is acting | ||
99 | * upon another object, be that a file, a task, a key or whatever. | ||
100 | * | ||
101 | * Note that some members of this structure belong to both categories - the | ||
102 | * LSM security pointer for instance. | ||
103 | * | ||
104 | * A task has two security pointers. task->real_cred points to the objective | ||
105 | * context that defines that task's actual details. The objective part of this | ||
106 | * context is used whenever that task is acted upon. | ||
107 | * | ||
108 | * task->cred points to the subjective context that defines the details of how | ||
109 | * that task is going to act upon another object. This may be overridden | ||
110 | * temporarily to point to another security context, but normally points to the | ||
111 | * same context as task->real_cred. | ||
112 | */ | ||
113 | struct cred { | ||
114 | atomic_t usage; | ||
115 | uid_t uid; /* real UID of the task */ | ||
116 | gid_t gid; /* real GID of the task */ | ||
117 | uid_t suid; /* saved UID of the task */ | ||
118 | gid_t sgid; /* saved GID of the task */ | ||
119 | uid_t euid; /* effective UID of the task */ | ||
120 | gid_t egid; /* effective GID of the task */ | ||
121 | uid_t fsuid; /* UID for VFS ops */ | ||
122 | gid_t fsgid; /* GID for VFS ops */ | ||
123 | unsigned securebits; /* SUID-less security management */ | ||
124 | kernel_cap_t cap_inheritable; /* caps our children can inherit */ | ||
125 | kernel_cap_t cap_permitted; /* caps we're permitted */ | ||
126 | kernel_cap_t cap_effective; /* caps we can actually use */ | ||
127 | kernel_cap_t cap_bset; /* capability bounding set */ | ||
128 | #ifdef CONFIG_KEYS | ||
129 | unsigned char jit_keyring; /* default keyring to attach requested | ||
130 | * keys to */ | ||
131 | struct key *thread_keyring; /* keyring private to this thread */ | ||
132 | struct key *request_key_auth; /* assumed request_key authority */ | ||
133 | struct thread_group_cred *tgcred; /* thread-group shared credentials */ | ||
134 | #endif | ||
135 | #ifdef CONFIG_SECURITY | ||
136 | void *security; /* subjective LSM security */ | ||
137 | #endif | ||
138 | struct user_struct *user; /* real user ID subscription */ | ||
139 | struct group_info *group_info; /* supplementary groups for euid/fsgid */ | ||
140 | struct rcu_head rcu; /* RCU deletion hook */ | ||
141 | }; | ||
142 | |||
143 | extern void __put_cred(struct cred *); | ||
144 | extern int copy_creds(struct task_struct *, unsigned long); | ||
145 | extern struct cred *prepare_creds(void); | ||
146 | extern struct cred *prepare_exec_creds(void); | ||
147 | extern struct cred *prepare_usermodehelper_creds(void); | ||
148 | extern int commit_creds(struct cred *); | ||
149 | extern void abort_creds(struct cred *); | ||
150 | extern const struct cred *override_creds(const struct cred *); | ||
151 | extern void revert_creds(const struct cred *); | ||
152 | extern struct cred *prepare_kernel_cred(struct task_struct *); | ||
153 | extern int change_create_files_as(struct cred *, struct inode *); | ||
154 | extern int set_security_override(struct cred *, u32); | ||
155 | extern int set_security_override_from_ctx(struct cred *, const char *); | ||
156 | extern int set_create_files_as(struct cred *, struct inode *); | ||
157 | extern void __init cred_init(void); | ||
158 | |||
159 | /** | ||
160 | * get_new_cred - Get a reference on a new set of credentials | ||
161 | * @cred: The new credentials to reference | ||
162 | * | ||
163 | * Get a reference on the specified set of new credentials. The caller must | ||
164 | * release the reference. | ||
165 | */ | ||
166 | static inline struct cred *get_new_cred(struct cred *cred) | ||
167 | { | ||
168 | atomic_inc(&cred->usage); | ||
169 | return cred; | ||
170 | } | ||
171 | |||
172 | /** | ||
173 | * get_cred - Get a reference on a set of credentials | ||
174 | * @cred: The credentials to reference | ||
175 | * | ||
176 | * Get a reference on the specified set of credentials. The caller must | ||
177 | * release the reference. | ||
178 | * | ||
179 | * This is used to deal with a committed set of credentials. Although the | ||
180 | * pointer is const, this will temporarily discard the const and increment the | ||
181 | * usage count. The purpose of this is to attempt to catch at compile time the | ||
182 | * accidental alteration of a set of credentials that should be considered | ||
183 | * immutable. | ||
184 | */ | ||
185 | static inline const struct cred *get_cred(const struct cred *cred) | ||
186 | { | ||
187 | return get_new_cred((struct cred *) cred); | ||
188 | } | ||
189 | |||
190 | /** | ||
191 | * put_cred - Release a reference to a set of credentials | ||
192 | * @cred: The credentials to release | ||
193 | * | ||
194 | * Release a reference to a set of credentials, deleting them when the last ref | ||
195 | * is released. | ||
196 | * | ||
197 | * This takes a const pointer to a set of credentials because the credentials | ||
198 | * on task_struct are attached by const pointers to prevent accidental | ||
199 | * alteration of otherwise immutable credential sets. | ||
200 | */ | ||
201 | static inline void put_cred(const struct cred *_cred) | ||
202 | { | ||
203 | struct cred *cred = (struct cred *) _cred; | ||
204 | |||
205 | BUG_ON(atomic_read(&(cred)->usage) <= 0); | ||
206 | if (atomic_dec_and_test(&(cred)->usage)) | ||
207 | __put_cred(cred); | ||
208 | } | ||
209 | |||
210 | /** | ||
211 | * current_cred - Access the current task's subjective credentials | ||
212 | * | ||
213 | * Access the subjective credentials of the current task. | ||
214 | */ | ||
215 | #define current_cred() \ | ||
216 | (current->cred) | ||
217 | |||
218 | /** | ||
219 | * __task_cred - Access a task's objective credentials | ||
220 | * @task: The task to query | ||
221 | * | ||
222 | * Access the objective credentials of a task. The caller must hold the RCU | ||
223 | * readlock. | ||
224 | * | ||
225 | * The caller must make sure task doesn't go away, either by holding a ref on | ||
226 | * task or by holding tasklist_lock to prevent it from being unlinked. | ||
227 | */ | ||
228 | #define __task_cred(task) \ | ||
229 | ((const struct cred *)(rcu_dereference((task)->real_cred))) | ||
230 | |||
231 | /** | ||
232 | * get_task_cred - Get another task's objective credentials | ||
233 | * @task: The task to query | ||
234 | * | ||
235 | * Get the objective credentials of a task, pinning them so that they can't go | ||
236 | * away. Accessing a task's credentials directly is not permitted. | ||
237 | * | ||
238 | * The caller must make sure task doesn't go away, either by holding a ref on | ||
239 | * task or by holding tasklist_lock to prevent it from being unlinked. | ||
240 | */ | ||
241 | #define get_task_cred(task) \ | ||
242 | ({ \ | ||
243 | struct cred *__cred; \ | ||
244 | rcu_read_lock(); \ | ||
245 | __cred = (struct cred *) __task_cred((task)); \ | ||
246 | get_cred(__cred); \ | ||
247 | rcu_read_unlock(); \ | ||
248 | __cred; \ | ||
249 | }) | ||
250 | |||
251 | /** | ||
252 | * get_current_cred - Get the current task's subjective credentials | ||
253 | * | ||
254 | * Get the subjective credentials of the current task, pinning them so that | ||
255 | * they can't go away. Accessing the current task's credentials directly is | ||
256 | * not permitted. | ||
257 | */ | ||
258 | #define get_current_cred() \ | ||
259 | (get_cred(current_cred())) | ||
260 | |||
261 | /** | ||
262 | * get_current_user - Get the current task's user_struct | ||
263 | * | ||
264 | * Get the user record of the current task, pinning it so that it can't go | ||
265 | * away. | ||
266 | */ | ||
267 | #define get_current_user() \ | ||
268 | ({ \ | ||
269 | struct user_struct *__u; \ | ||
270 | struct cred *__cred; \ | ||
271 | __cred = (struct cred *) current_cred(); \ | ||
272 | __u = get_uid(__cred->user); \ | ||
273 | __u; \ | ||
274 | }) | ||
275 | |||
276 | /** | ||
277 | * get_current_groups - Get the current task's supplementary group list | ||
278 | * | ||
279 | * Get the supplementary group list of the current task, pinning it so that it | ||
280 | * can't go away. | ||
281 | */ | ||
282 | #define get_current_groups() \ | ||
283 | ({ \ | ||
284 | struct group_info *__groups; \ | ||
285 | struct cred *__cred; \ | ||
286 | __cred = (struct cred *) current_cred(); \ | ||
287 | __groups = get_group_info(__cred->group_info); \ | ||
288 | __groups; \ | ||
289 | }) | ||
290 | |||
291 | #define task_cred_xxx(task, xxx) \ | ||
292 | ({ \ | ||
293 | __typeof__(((struct cred *)NULL)->xxx) ___val; \ | ||
294 | rcu_read_lock(); \ | ||
295 | ___val = __task_cred((task))->xxx; \ | ||
296 | rcu_read_unlock(); \ | ||
297 | ___val; \ | ||
298 | }) | ||
299 | |||
300 | #define task_uid(task) (task_cred_xxx((task), uid)) | ||
301 | #define task_euid(task) (task_cred_xxx((task), euid)) | ||
302 | |||
303 | #define current_cred_xxx(xxx) \ | ||
304 | ({ \ | ||
305 | current->cred->xxx; \ | ||
306 | }) | ||
307 | |||
308 | #define current_uid() (current_cred_xxx(uid)) | ||
309 | #define current_gid() (current_cred_xxx(gid)) | ||
310 | #define current_euid() (current_cred_xxx(euid)) | ||
311 | #define current_egid() (current_cred_xxx(egid)) | ||
312 | #define current_suid() (current_cred_xxx(suid)) | ||
313 | #define current_sgid() (current_cred_xxx(sgid)) | ||
314 | #define current_fsuid() (current_cred_xxx(fsuid)) | ||
315 | #define current_fsgid() (current_cred_xxx(fsgid)) | ||
316 | #define current_cap() (current_cred_xxx(cap_effective)) | ||
317 | #define current_user() (current_cred_xxx(user)) | ||
318 | #define current_security() (current_cred_xxx(security)) | ||
31 | 319 | ||
32 | #define current_uid_gid(_uid, _gid) \ | 320 | #define current_uid_gid(_uid, _gid) \ |
33 | do { \ | 321 | do { \ |
34 | *(_uid) = current->uid; \ | 322 | const struct cred *__cred; \ |
35 | *(_gid) = current->gid; \ | 323 | __cred = current_cred(); \ |
324 | *(_uid) = __cred->uid; \ | ||
325 | *(_gid) = __cred->gid; \ | ||
36 | } while(0) | 326 | } while(0) |
37 | 327 | ||
38 | #define current_euid_egid(_uid, _gid) \ | 328 | #define current_euid_egid(_euid, _egid) \ |
39 | do { \ | 329 | do { \ |
40 | *(_uid) = current->euid; \ | 330 | const struct cred *__cred; \ |
41 | *(_gid) = current->egid; \ | 331 | __cred = current_cred(); \ |
332 | *(_euid) = __cred->euid; \ | ||
333 | *(_egid) = __cred->egid; \ | ||
42 | } while(0) | 334 | } while(0) |
43 | 335 | ||
44 | #define current_fsuid_fsgid(_uid, _gid) \ | 336 | #define current_fsuid_fsgid(_fsuid, _fsgid) \ |
45 | do { \ | 337 | do { \ |
46 | *(_uid) = current->fsuid; \ | 338 | const struct cred *__cred; \ |
47 | *(_gid) = current->fsgid; \ | 339 | __cred = current_cred(); \ |
340 | *(_fsuid) = __cred->fsuid; \ | ||
341 | *(_fsgid) = __cred->fsgid; \ | ||
48 | } while(0) | 342 | } while(0) |
49 | 343 | ||
50 | #endif /* _LINUX_CRED_H */ | 344 | #endif /* _LINUX_CRED_H */ |