1 | /* SPDX-License-Identifier: GPL-2.0-or-later */ |
2 | /* Credentials management - see Documentation/security/credentials.rst |
3 | * |
4 | * Copyright (C) 2008 Red Hat, Inc. All Rights Reserved. |
5 | * Written by David Howells (dhowells@redhat.com) |
6 | */ |
7 | |
8 | #ifndef _LINUX_CRED_H |
9 | #define _LINUX_CRED_H |
10 | |
11 | #include <linux/capability.h> |
12 | #include <linux/init.h> |
13 | #include <linux/key.h> |
14 | #include <linux/atomic.h> |
15 | #include <linux/refcount.h> |
16 | #include <linux/uidgid.h> |
17 | #include <linux/sched.h> |
18 | #include <linux/sched/user.h> |
19 | |
20 | struct cred; |
21 | struct inode; |
22 | |
23 | /* |
24 | * COW Supplementary groups list |
25 | */ |
26 | struct group_info { |
27 | refcount_t usage; |
28 | int ngroups; |
29 | kgid_t gid[]; |
30 | } __randomize_layout; |
31 | |
32 | /** |
33 | * get_group_info - Get a reference to a group info structure |
34 | * @group_info: The group info to reference |
35 | * |
36 | * This gets a reference to a set of supplementary groups. |
37 | * |
38 | * If the caller is accessing a task's credentials, they must hold the RCU read |
39 | * lock when reading. |
40 | */ |
41 | static inline struct group_info *get_group_info(struct group_info *gi) |
42 | { |
43 | refcount_inc(r: &gi->usage); |
44 | return gi; |
45 | } |
46 | |
47 | /** |
48 | * put_group_info - Release a reference to a group info structure |
49 | * @group_info: The group info to release |
50 | */ |
51 | #define put_group_info(group_info) \ |
52 | do { \ |
53 | if (refcount_dec_and_test(&(group_info)->usage)) \ |
54 | groups_free(group_info); \ |
55 | } while (0) |
56 | |
57 | #ifdef CONFIG_MULTIUSER |
58 | extern struct group_info *groups_alloc(int); |
59 | extern void groups_free(struct group_info *); |
60 | |
61 | extern int in_group_p(kgid_t); |
62 | extern int in_egroup_p(kgid_t); |
63 | extern int groups_search(const struct group_info *, kgid_t); |
64 | |
65 | extern int set_current_groups(struct group_info *); |
66 | extern void set_groups(struct cred *, struct group_info *); |
67 | extern bool may_setgroups(void); |
68 | extern void groups_sort(struct group_info *); |
69 | #else |
70 | static inline void groups_free(struct group_info *group_info) |
71 | { |
72 | } |
73 | |
74 | static inline int in_group_p(kgid_t grp) |
75 | { |
76 | return 1; |
77 | } |
78 | static inline int in_egroup_p(kgid_t grp) |
79 | { |
80 | return 1; |
81 | } |
82 | static inline int groups_search(const struct group_info *group_info, kgid_t grp) |
83 | { |
84 | return 1; |
85 | } |
86 | #endif |
87 | |
88 | /* |
89 | * The security context of a task |
90 | * |
91 | * The parts of the context break down into two categories: |
92 | * |
93 | * (1) The objective context of a task. These parts are used when some other |
94 | * task is attempting to affect this one. |
95 | * |
96 | * (2) The subjective context. These details are used when the task is acting |
97 | * upon another object, be that a file, a task, a key or whatever. |
98 | * |
99 | * Note that some members of this structure belong to both categories - the |
100 | * LSM security pointer for instance. |
101 | * |
102 | * A task has two security pointers. task->real_cred points to the objective |
103 | * context that defines that task's actual details. The objective part of this |
104 | * context is used whenever that task is acted upon. |
105 | * |
106 | * task->cred points to the subjective context that defines the details of how |
107 | * that task is going to act upon another object. This may be overridden |
108 | * temporarily to point to another security context, but normally points to the |
109 | * same context as task->real_cred. |
110 | */ |
111 | struct cred { |
112 | atomic_t usage; |
113 | #ifdef CONFIG_DEBUG_CREDENTIALS |
114 | atomic_t subscribers; /* number of processes subscribed */ |
115 | void *put_addr; |
116 | unsigned magic; |
117 | #define CRED_MAGIC 0x43736564 |
118 | #define CRED_MAGIC_DEAD 0x44656144 |
119 | #endif |
120 | kuid_t uid; /* real UID of the task */ |
121 | kgid_t gid; /* real GID of the task */ |
122 | kuid_t suid; /* saved UID of the task */ |
123 | kgid_t sgid; /* saved GID of the task */ |
124 | kuid_t euid; /* effective UID of the task */ |
125 | kgid_t egid; /* effective GID of the task */ |
126 | kuid_t fsuid; /* UID for VFS ops */ |
127 | kgid_t fsgid; /* GID for VFS ops */ |
128 | unsigned securebits; /* SUID-less security management */ |
129 | kernel_cap_t cap_inheritable; /* caps our children can inherit */ |
130 | kernel_cap_t cap_permitted; /* caps we're permitted */ |
131 | kernel_cap_t cap_effective; /* caps we can actually use */ |
132 | kernel_cap_t cap_bset; /* capability bounding set */ |
133 | kernel_cap_t cap_ambient; /* Ambient capability set */ |
134 | #ifdef CONFIG_KEYS |
135 | unsigned char jit_keyring; /* default keyring to attach requested |
136 | * keys to */ |
137 | struct key *session_keyring; /* keyring inherited over fork */ |
138 | struct key *process_keyring; /* keyring private to this process */ |
139 | struct key *thread_keyring; /* keyring private to this thread */ |
140 | struct key *request_key_auth; /* assumed request_key authority */ |
141 | #endif |
142 | #ifdef CONFIG_SECURITY |
143 | void *security; /* LSM security */ |
144 | #endif |
145 | struct user_struct *user; /* real user ID subscription */ |
146 | struct user_namespace *user_ns; /* user_ns the caps and keyrings are relative to. */ |
147 | struct ucounts *ucounts; |
148 | struct group_info *group_info; /* supplementary groups for euid/fsgid */ |
149 | /* RCU deletion */ |
150 | union { |
151 | int non_rcu; /* Can we skip RCU deletion? */ |
152 | struct rcu_head rcu; /* RCU deletion hook */ |
153 | }; |
154 | } __randomize_layout; |
155 | |
156 | extern void __put_cred(struct cred *); |
157 | extern void exit_creds(struct task_struct *); |
158 | extern int copy_creds(struct task_struct *, unsigned long); |
159 | extern const struct cred *get_task_cred(struct task_struct *); |
160 | extern struct cred *cred_alloc_blank(void); |
161 | extern struct cred *prepare_creds(void); |
162 | extern struct cred *prepare_exec_creds(void); |
163 | extern int commit_creds(struct cred *); |
164 | extern void abort_creds(struct cred *); |
165 | extern const struct cred *override_creds(const struct cred *); |
166 | extern void revert_creds(const struct cred *); |
167 | extern struct cred *prepare_kernel_cred(struct task_struct *); |
168 | extern int set_security_override(struct cred *, u32); |
169 | extern int set_security_override_from_ctx(struct cred *, const char *); |
170 | extern int set_create_files_as(struct cred *, struct inode *); |
171 | extern int cred_fscmp(const struct cred *, const struct cred *); |
172 | extern void __init cred_init(void); |
173 | extern int set_cred_ucounts(struct cred *); |
174 | |
175 | /* |
176 | * check for validity of credentials |
177 | */ |
178 | #ifdef CONFIG_DEBUG_CREDENTIALS |
179 | extern void __noreturn __invalid_creds(const struct cred *, const char *, unsigned); |
180 | extern void __validate_process_creds(struct task_struct *, |
181 | const char *, unsigned); |
182 | |
183 | extern bool creds_are_invalid(const struct cred *cred); |
184 | |
185 | static inline void __validate_creds(const struct cred *cred, |
186 | const char *file, unsigned line) |
187 | { |
188 | if (unlikely(creds_are_invalid(cred))) |
189 | __invalid_creds(cred, file, line); |
190 | } |
191 | |
192 | #define validate_creds(cred) \ |
193 | do { \ |
194 | __validate_creds((cred), __FILE__, __LINE__); \ |
195 | } while(0) |
196 | |
197 | #define validate_process_creds() \ |
198 | do { \ |
199 | __validate_process_creds(current, __FILE__, __LINE__); \ |
200 | } while(0) |
201 | |
202 | extern void validate_creds_for_do_exit(struct task_struct *); |
203 | #else |
204 | static inline void validate_creds(const struct cred *cred) |
205 | { |
206 | } |
207 | static inline void validate_creds_for_do_exit(struct task_struct *tsk) |
208 | { |
209 | } |
210 | static inline void validate_process_creds(void) |
211 | { |
212 | } |
213 | #endif |
214 | |
215 | static inline bool cap_ambient_invariant_ok(const struct cred *cred) |
216 | { |
217 | return cap_issubset(a: cred->cap_ambient, |
218 | set: cap_intersect(a: cred->cap_permitted, |
219 | b: cred->cap_inheritable)); |
220 | } |
221 | |
222 | /** |
223 | * get_new_cred_many - Get references on a new set of credentials |
224 | * @cred: The new credentials to reference |
225 | * @nr: Number of references to acquire |
226 | * |
227 | * Get references on the specified set of new credentials. The caller must |
228 | * release all acquired references. |
229 | */ |
230 | static inline struct cred *get_new_cred_many(struct cred *cred, int nr) |
231 | { |
232 | atomic_add(i: nr, v: &cred->usage); |
233 | return cred; |
234 | } |
235 | |
236 | /** |
237 | * get_new_cred - Get a reference on a new set of credentials |
238 | * @cred: The new credentials to reference |
239 | * |
240 | * Get a reference on the specified set of new credentials. The caller must |
241 | * release the reference. |
242 | */ |
243 | static inline struct cred *get_new_cred(struct cred *cred) |
244 | { |
245 | return get_new_cred_many(cred, nr: 1); |
246 | } |
247 | |
248 | /** |
249 | * get_cred_many - Get references on a set of credentials |
250 | * @cred: The credentials to reference |
251 | * @nr: Number of references to acquire |
252 | * |
253 | * Get references on the specified set of credentials. The caller must release |
254 | * all acquired reference. If %NULL is passed, it is returned with no action. |
255 | * |
256 | * This is used to deal with a committed set of credentials. Although the |
257 | * pointer is const, this will temporarily discard the const and increment the |
258 | * usage count. The purpose of this is to attempt to catch at compile time the |
259 | * accidental alteration of a set of credentials that should be considered |
260 | * immutable. |
261 | */ |
262 | static inline const struct cred *get_cred_many(const struct cred *cred, int nr) |
263 | { |
264 | struct cred *nonconst_cred = (struct cred *) cred; |
265 | if (!cred) |
266 | return cred; |
267 | validate_creds(cred); |
268 | nonconst_cred->non_rcu = 0; |
269 | return get_new_cred_many(cred: nonconst_cred, nr); |
270 | } |
271 | |
272 | /* |
273 | * get_cred - Get a reference on a set of credentials |
274 | * @cred: The credentials to reference |
275 | * |
276 | * Get a reference on the specified set of credentials. The caller must |
277 | * release the reference. If %NULL is passed, it is returned with no action. |
278 | * |
279 | * This is used to deal with a committed set of credentials. |
280 | */ |
281 | static inline const struct cred *get_cred(const struct cred *cred) |
282 | { |
283 | return get_cred_many(cred, nr: 1); |
284 | } |
285 | |
286 | static inline const struct cred *get_cred_rcu(const struct cred *cred) |
287 | { |
288 | struct cred *nonconst_cred = (struct cred *) cred; |
289 | if (!cred) |
290 | return NULL; |
291 | if (!atomic_inc_not_zero(v: &nonconst_cred->usage)) |
292 | return NULL; |
293 | validate_creds(cred); |
294 | nonconst_cred->non_rcu = 0; |
295 | return cred; |
296 | } |
297 | |
298 | /** |
299 | * put_cred - Release a reference to a set of credentials |
300 | * @cred: The credentials to release |
301 | * @nr: Number of references to release |
302 | * |
303 | * Release a reference to a set of credentials, deleting them when the last ref |
304 | * is released. If %NULL is passed, nothing is done. |
305 | * |
306 | * This takes a const pointer to a set of credentials because the credentials |
307 | * on task_struct are attached by const pointers to prevent accidental |
308 | * alteration of otherwise immutable credential sets. |
309 | */ |
310 | static inline void put_cred_many(const struct cred *_cred, int nr) |
311 | { |
312 | struct cred *cred = (struct cred *) _cred; |
313 | |
314 | if (cred) { |
315 | validate_creds(cred); |
316 | if (atomic_sub_and_test(i: nr, v: &cred->usage)) |
317 | __put_cred(cred); |
318 | } |
319 | } |
320 | |
321 | /* |
322 | * put_cred - Release a reference to a set of credentials |
323 | * @cred: The credentials to release |
324 | * |
325 | * Release a reference to a set of credentials, deleting them when the last ref |
326 | * is released. If %NULL is passed, nothing is done. |
327 | */ |
328 | static inline void put_cred(const struct cred *cred) |
329 | { |
330 | put_cred_many(cred: cred, nr: 1); |
331 | } |
332 | |
333 | /** |
334 | * current_cred - Access the current task's subjective credentials |
335 | * |
336 | * Access the subjective credentials of the current task. RCU-safe, |
337 | * since nobody else can modify it. |
338 | */ |
339 | #define current_cred() \ |
340 | rcu_dereference_protected(current->cred, 1) |
341 | |
342 | /** |
343 | * current_real_cred - Access the current task's objective credentials |
344 | * |
345 | * Access the objective credentials of the current task. RCU-safe, |
346 | * since nobody else can modify it. |
347 | */ |
348 | #define current_real_cred() \ |
349 | rcu_dereference_protected(current->real_cred, 1) |
350 | |
351 | /** |
352 | * __task_cred - Access a task's objective credentials |
353 | * @task: The task to query |
354 | * |
355 | * Access the objective credentials of a task. The caller must hold the RCU |
356 | * readlock. |
357 | * |
358 | * The result of this function should not be passed directly to get_cred(); |
359 | * rather get_task_cred() should be used instead. |
360 | */ |
361 | #define __task_cred(task) \ |
362 | rcu_dereference((task)->real_cred) |
363 | |
364 | /** |
365 | * get_current_cred - Get the current task's subjective credentials |
366 | * |
367 | * Get the subjective credentials of the current task, pinning them so that |
368 | * they can't go away. Accessing the current task's credentials directly is |
369 | * not permitted. |
370 | */ |
371 | #define get_current_cred() \ |
372 | (get_cred(current_cred())) |
373 | |
374 | /** |
375 | * get_current_user - Get the current task's user_struct |
376 | * |
377 | * Get the user record of the current task, pinning it so that it can't go |
378 | * away. |
379 | */ |
380 | #define get_current_user() \ |
381 | ({ \ |
382 | struct user_struct *__u; \ |
383 | const struct cred *__cred; \ |
384 | __cred = current_cred(); \ |
385 | __u = get_uid(__cred->user); \ |
386 | __u; \ |
387 | }) |
388 | |
389 | /** |
390 | * get_current_groups - Get the current task's supplementary group list |
391 | * |
392 | * Get the supplementary group list of the current task, pinning it so that it |
393 | * can't go away. |
394 | */ |
395 | #define get_current_groups() \ |
396 | ({ \ |
397 | struct group_info *__groups; \ |
398 | const struct cred *__cred; \ |
399 | __cred = current_cred(); \ |
400 | __groups = get_group_info(__cred->group_info); \ |
401 | __groups; \ |
402 | }) |
403 | |
404 | #define task_cred_xxx(task, xxx) \ |
405 | ({ \ |
406 | __typeof__(((struct cred *)NULL)->xxx) ___val; \ |
407 | rcu_read_lock(); \ |
408 | ___val = __task_cred((task))->xxx; \ |
409 | rcu_read_unlock(); \ |
410 | ___val; \ |
411 | }) |
412 | |
413 | #define task_uid(task) (task_cred_xxx((task), uid)) |
414 | #define task_euid(task) (task_cred_xxx((task), euid)) |
415 | #define task_ucounts(task) (task_cred_xxx((task), ucounts)) |
416 | |
417 | #define current_cred_xxx(xxx) \ |
418 | ({ \ |
419 | current_cred()->xxx; \ |
420 | }) |
421 | |
422 | #define current_uid() (current_cred_xxx(uid)) |
423 | #define current_gid() (current_cred_xxx(gid)) |
424 | #define current_euid() (current_cred_xxx(euid)) |
425 | #define current_egid() (current_cred_xxx(egid)) |
426 | #define current_suid() (current_cred_xxx(suid)) |
427 | #define current_sgid() (current_cred_xxx(sgid)) |
428 | #define current_fsuid() (current_cred_xxx(fsuid)) |
429 | #define current_fsgid() (current_cred_xxx(fsgid)) |
430 | #define current_cap() (current_cred_xxx(cap_effective)) |
431 | #define current_user() (current_cred_xxx(user)) |
432 | #define current_ucounts() (current_cred_xxx(ucounts)) |
433 | |
434 | extern struct user_namespace init_user_ns; |
435 | #ifdef CONFIG_USER_NS |
436 | #define current_user_ns() (current_cred_xxx(user_ns)) |
437 | #else |
438 | static inline struct user_namespace *current_user_ns(void) |
439 | { |
440 | return &init_user_ns; |
441 | } |
442 | #endif |
443 | |
444 | |
445 | #define current_uid_gid(_uid, _gid) \ |
446 | do { \ |
447 | const struct cred *__cred; \ |
448 | __cred = current_cred(); \ |
449 | *(_uid) = __cred->uid; \ |
450 | *(_gid) = __cred->gid; \ |
451 | } while(0) |
452 | |
453 | #define current_euid_egid(_euid, _egid) \ |
454 | do { \ |
455 | const struct cred *__cred; \ |
456 | __cred = current_cred(); \ |
457 | *(_euid) = __cred->euid; \ |
458 | *(_egid) = __cred->egid; \ |
459 | } while(0) |
460 | |
461 | #define current_fsuid_fsgid(_fsuid, _fsgid) \ |
462 | do { \ |
463 | const struct cred *__cred; \ |
464 | __cred = current_cred(); \ |
465 | *(_fsuid) = __cred->fsuid; \ |
466 | *(_fsgid) = __cred->fsgid; \ |
467 | } while(0) |
468 | |
469 | #endif /* _LINUX_CRED_H */ |
470 | |