Blame view
include/linux/cred.h
11.8 KB
d410fa4ef
|
1 |
/* Credentials management - see Documentation/security/credentials.txt |
9e2b2dc41
|
2 3 4 5 6 7 8 9 10 11 12 13 |
* * Copyright (C) 2008 Red Hat, Inc. All Rights Reserved. * Written by David Howells (dhowells@redhat.com) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public Licence * as published by the Free Software Foundation; either version * 2 of the Licence, or (at your option) any later version. */ #ifndef _LINUX_CRED_H #define _LINUX_CRED_H |
b6dff3ec5
|
14 |
#include <linux/capability.h> |
b2e1feaf0
|
15 |
#include <linux/init.h> |
b6dff3ec5
|
16 |
#include <linux/key.h> |
ed868a569
|
17 |
#include <linux/selinux.h> |
60063497a
|
18 |
#include <linux/atomic.h> |
ae2975bc3
|
19 |
#include <linux/uidgid.h> |
b6dff3ec5
|
20 21 22 |
struct user_struct; struct cred; |
3a3b7ce93
|
23 |
struct inode; |
b6dff3ec5
|
24 25 26 27 28 |
/* * COW Supplementary groups list */ #define NGROUPS_SMALL 32 |
ae2975bc3
|
29 |
#define NGROUPS_PER_BLOCK ((unsigned int)(PAGE_SIZE / sizeof(kgid_t))) |
b6dff3ec5
|
30 31 32 33 34 |
struct group_info { atomic_t usage; int ngroups; int nblocks; |
ae2975bc3
|
35 36 |
kgid_t small_block[NGROUPS_SMALL]; kgid_t *blocks[0]; |
b6dff3ec5
|
37 38 39 40 41 42 |
}; /** * get_group_info - Get a reference to a group info structure * @group_info: The group info to reference * |
86a264abe
|
43 44 45 46 |
* This gets a reference to a set of supplementary groups. * * If the caller is accessing a task's credentials, they must hold the RCU read * lock when reading. |
b6dff3ec5
|
47 |
*/ |
86a264abe
|
48 49 50 51 52 |
static inline struct group_info *get_group_info(struct group_info *gi) { atomic_inc(&gi->usage); return gi; } |
b6dff3ec5
|
53 54 55 56 57 58 59 60 61 62 |
/** * put_group_info - Release a reference to a group info structure * @group_info: The group info to release */ #define put_group_info(group_info) \ do { \ if (atomic_dec_and_test(&(group_info)->usage)) \ groups_free(group_info); \ } while (0) |
18b6e0414
|
63 |
extern struct group_info init_groups; |
2813893f8
|
64 65 |
#ifdef CONFIG_MULTIUSER extern struct group_info *groups_alloc(int); |
b6dff3ec5
|
66 |
extern void groups_free(struct group_info *); |
2813893f8
|
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
extern int in_group_p(kgid_t); extern int in_egroup_p(kgid_t); #else static inline void groups_free(struct group_info *group_info) { } static inline int in_group_p(kgid_t grp) { return 1; } static inline int in_egroup_p(kgid_t grp) { return 1; } #endif |
b6dff3ec5
|
84 |
extern int set_current_groups(struct group_info *); |
8f6c5ffc8
|
85 |
extern void set_groups(struct cred *, struct group_info *); |
ae2975bc3
|
86 |
extern int groups_search(const struct group_info *, kgid_t); |
7ff4d90b4
|
87 |
extern bool may_setgroups(void); |
b6dff3ec5
|
88 89 90 91 |
/* access the groups "array" with this macro */ #define GROUP_AT(gi, i) \ ((gi)->blocks[(i) / NGROUPS_PER_BLOCK][(i) % NGROUPS_PER_BLOCK]) |
b6dff3ec5
|
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
/* * The security context of a task * * The parts of the context break down into two categories: * * (1) The objective context of a task. These parts are used when some other * task is attempting to affect this one. * * (2) The subjective context. These details are used when the task is acting * upon another object, be that a file, a task, a key or whatever. * * Note that some members of this structure belong to both categories - the * LSM security pointer for instance. * * A task has two security pointers. task->real_cred points to the objective * context that defines that task's actual details. The objective part of this * context is used whenever that task is acted upon. * * task->cred points to the subjective context that defines the details of how * that task is going to act upon another object. This may be overridden * temporarily to point to another security context, but normally points to the * same context as task->real_cred. */ struct cred { atomic_t usage; |
e0e817392
|
117 118 119 120 121 122 123 |
#ifdef CONFIG_DEBUG_CREDENTIALS atomic_t subscribers; /* number of processes subscribed */ void *put_addr; unsigned magic; #define CRED_MAGIC 0x43736564 #define CRED_MAGIC_DEAD 0x44656144 #endif |
078de5f70
|
124 125 126 127 128 129 130 131 |
kuid_t uid; /* real UID of the task */ kgid_t gid; /* real GID of the task */ kuid_t suid; /* saved UID of the task */ kgid_t sgid; /* saved GID of the task */ kuid_t euid; /* effective UID of the task */ kgid_t egid; /* effective GID of the task */ kuid_t fsuid; /* UID for VFS ops */ kgid_t fsgid; /* GID for VFS ops */ |
b6dff3ec5
|
132 133 134 135 136 137 138 139 |
unsigned securebits; /* SUID-less security management */ kernel_cap_t cap_inheritable; /* caps our children can inherit */ kernel_cap_t cap_permitted; /* caps we're permitted */ kernel_cap_t cap_effective; /* caps we can actually use */ kernel_cap_t cap_bset; /* capability bounding set */ #ifdef CONFIG_KEYS unsigned char jit_keyring; /* default keyring to attach requested * keys to */ |
3a50597de
|
140 141 |
struct key __rcu *session_keyring; /* keyring inherited over fork */ struct key *process_keyring; /* keyring private to this process */ |
b6dff3ec5
|
142 143 144 145 146 147 148 |
struct key *thread_keyring; /* keyring private to this thread */ struct key *request_key_auth; /* assumed request_key authority */ #endif #ifdef CONFIG_SECURITY void *security; /* subjective LSM security */ #endif struct user_struct *user; /* real user ID subscription */ |
0093ccb68
|
149 |
struct user_namespace *user_ns; /* user_ns the caps and keyrings are relative to. */ |
b6dff3ec5
|
150 151 |
struct group_info *group_info; /* supplementary groups for euid/fsgid */ struct rcu_head rcu; /* RCU deletion hook */ |
b6dff3ec5
|
152 |
}; |
f1752eec6
|
153 |
extern void __put_cred(struct cred *); |
e0e817392
|
154 |
extern void exit_creds(struct task_struct *); |
f1752eec6
|
155 |
extern int copy_creds(struct task_struct *, unsigned long); |
de09a9771
|
156 |
extern const struct cred *get_task_cred(struct task_struct *); |
ee18d64c1
|
157 |
extern struct cred *cred_alloc_blank(void); |
d84f4f992
|
158 |
extern struct cred *prepare_creds(void); |
a6f76f23d
|
159 |
extern struct cred *prepare_exec_creds(void); |
d84f4f992
|
160 161 |
extern int commit_creds(struct cred *); extern void abort_creds(struct cred *); |
3b11a1dec
|
162 163 |
extern const struct cred *override_creds(const struct cred *); extern void revert_creds(const struct cred *); |
3a3b7ce93
|
164 165 166 167 168 |
extern struct cred *prepare_kernel_cred(struct task_struct *); extern int change_create_files_as(struct cred *, struct inode *); extern int set_security_override(struct cred *, u32); extern int set_security_override_from_ctx(struct cred *, const char *); extern int set_create_files_as(struct cred *, struct inode *); |
d84f4f992
|
169 |
extern void __init cred_init(void); |
e0e817392
|
170 171 172 173 174 175 176 |
/* * check for validity of credentials */ #ifdef CONFIG_DEBUG_CREDENTIALS extern void __invalid_creds(const struct cred *, const char *, unsigned); extern void __validate_process_creds(struct task_struct *, const char *, unsigned); |
74908a000
|
177 |
extern bool creds_are_invalid(const struct cred *cred); |
e0e817392
|
178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 |
static inline void __validate_creds(const struct cred *cred, const char *file, unsigned line) { if (unlikely(creds_are_invalid(cred))) __invalid_creds(cred, file, line); } #define validate_creds(cred) \ do { \ __validate_creds((cred), __FILE__, __LINE__); \ } while(0) #define validate_process_creds() \ do { \ __validate_process_creds(current, __FILE__, __LINE__); \ } while(0) extern void validate_creds_for_do_exit(struct task_struct *); #else static inline void validate_creds(const struct cred *cred) { } static inline void validate_creds_for_do_exit(struct task_struct *tsk) { } static inline void validate_process_creds(void) { } #endif |
d84f4f992
|
208 209 210 211 212 213 214 215 216 217 218 219 |
/** * get_new_cred - Get a reference on a new set of credentials * @cred: The new credentials to reference * * Get a reference on the specified set of new credentials. The caller must * release the reference. */ static inline struct cred *get_new_cred(struct cred *cred) { atomic_inc(&cred->usage); return cred; } |
f1752eec6
|
220 221 222 223 224 225 226 |
/** * get_cred - Get a reference on a set of credentials * @cred: The credentials to reference * * Get a reference on the specified set of credentials. The caller must * release the reference. |
98870ab0a
|
227 228 229 230 231 232 |
* * This is used to deal with a committed set of credentials. Although the * pointer is const, this will temporarily discard the const and increment the * usage count. The purpose of this is to attempt to catch at compile time the * accidental alteration of a set of credentials that should be considered * immutable. |
f1752eec6
|
233 |
*/ |
d84f4f992
|
234 |
static inline const struct cred *get_cred(const struct cred *cred) |
f1752eec6
|
235 |
{ |
1c388ad05
|
236 |
struct cred *nonconst_cred = (struct cred *) cred; |
e0e817392
|
237 |
validate_creds(cred); |
1c388ad05
|
238 |
return get_new_cred(nonconst_cred); |
f1752eec6
|
239 240 241 242 243 244 245 246 |
} /** * put_cred - Release a reference to a set of credentials * @cred: The credentials to release * * Release a reference to a set of credentials, deleting them when the last ref * is released. |
98870ab0a
|
247 248 249 250 |
* * This takes a const pointer to a set of credentials because the credentials * on task_struct are attached by const pointers to prevent accidental * alteration of otherwise immutable credential sets. |
f1752eec6
|
251 |
*/ |
c69e8d9c0
|
252 |
static inline void put_cred(const struct cred *_cred) |
f1752eec6
|
253 |
{ |
c69e8d9c0
|
254 |
struct cred *cred = (struct cred *) _cred; |
d84f4f992
|
255 |
|
e0e817392
|
256 |
validate_creds(cred); |
f1752eec6
|
257 258 259 |
if (atomic_dec_and_test(&(cred)->usage)) __put_cred(cred); } |
86a264abe
|
260 |
/** |
3b11a1dec
|
261 |
* current_cred - Access the current task's subjective credentials |
86a264abe
|
262 |
* |
329551484
|
263 264 |
* Access the subjective credentials of the current task. RCU-safe, * since nobody else can modify it. |
86a264abe
|
265 266 |
*/ #define current_cred() \ |
27e4e4362
|
267 |
rcu_dereference_protected(current->cred, 1) |
86a264abe
|
268 269 |
/** |
ae4b884fc
|
270 271 272 273 274 275 276 277 278 |
* current_real_cred - Access the current task's objective credentials * * Access the objective credentials of the current task. RCU-safe, * since nobody else can modify it. */ #define current_real_cred() \ rcu_dereference_protected(current->real_cred, 1) /** |
3b11a1dec
|
279 |
* __task_cred - Access a task's objective credentials |
86a264abe
|
280 281 |
* @task: The task to query * |
3b11a1dec
|
282 |
* Access the objective credentials of a task. The caller must hold the RCU |
43e13cc10
|
283 |
* readlock. |
86a264abe
|
284 |
* |
8f92054e7
|
285 286 |
* The result of this function should not be passed directly to get_cred(); * rather get_task_cred() should be used instead. |
86a264abe
|
287 |
*/ |
43e13cc10
|
288 289 |
#define __task_cred(task) \ rcu_dereference((task)->real_cred) |
86a264abe
|
290 291 |
/** |
3b11a1dec
|
292 |
* get_current_cred - Get the current task's subjective credentials |
86a264abe
|
293 |
* |
3b11a1dec
|
294 295 296 |
* Get the subjective credentials of the current task, pinning them so that * they can't go away. Accessing the current task's credentials directly is * not permitted. |
86a264abe
|
297 298 299 300 301 302 303 304 305 306 307 308 309 |
*/ #define get_current_cred() \ (get_cred(current_cred())) /** * get_current_user - Get the current task's user_struct * * Get the user record of the current task, pinning it so that it can't go * away. */ #define get_current_user() \ ({ \ struct user_struct *__u; \ |
638a84390
|
310 |
const struct cred *__cred; \ |
329551484
|
311 |
__cred = current_cred(); \ |
86a264abe
|
312 313 314 315 316 317 318 319 320 321 322 323 324 |
__u = get_uid(__cred->user); \ __u; \ }) /** * get_current_groups - Get the current task's supplementary group list * * Get the supplementary group list of the current task, pinning it so that it * can't go away. */ #define get_current_groups() \ ({ \ struct group_info *__groups; \ |
638a84390
|
325 |
const struct cred *__cred; \ |
329551484
|
326 |
__cred = current_cred(); \ |
86a264abe
|
327 328 329 |
__groups = get_group_info(__cred->group_info); \ __groups; \ }) |
d84f4f992
|
330 331 332 333 334 335 336 |
#define task_cred_xxx(task, xxx) \ ({ \ __typeof__(((struct cred *)NULL)->xxx) ___val; \ rcu_read_lock(); \ ___val = __task_cred((task))->xxx; \ rcu_read_unlock(); \ ___val; \ |
86a264abe
|
337 338 339 340 341 342 343 |
}) #define task_uid(task) (task_cred_xxx((task), uid)) #define task_euid(task) (task_cred_xxx((task), euid)) #define current_cred_xxx(xxx) \ ({ \ |
329551484
|
344 |
current_cred()->xxx; \ |
86a264abe
|
345 346 347 348 349 350 351 352 353 354 355 356 357 |
}) #define current_uid() (current_cred_xxx(uid)) #define current_gid() (current_cred_xxx(gid)) #define current_euid() (current_cred_xxx(euid)) #define current_egid() (current_cred_xxx(egid)) #define current_suid() (current_cred_xxx(suid)) #define current_sgid() (current_cred_xxx(sgid)) #define current_fsuid() (current_cred_xxx(fsuid)) #define current_fsgid() (current_cred_xxx(fsgid)) #define current_cap() (current_cred_xxx(cap_effective)) #define current_user() (current_cred_xxx(user)) #define current_security() (current_cred_xxx(security)) |
7e6bd8fad
|
358 |
extern struct user_namespace init_user_ns; |
47a150edc
|
359 |
#ifdef CONFIG_USER_NS |
f1c84dae0
|
360 |
#define current_user_ns() (current_cred_xxx(user_ns)) |
47a150edc
|
361 |
#else |
f1c84dae0
|
362 |
#define current_user_ns() (&init_user_ns) |
47a150edc
|
363 |
#endif |
3486740a4
|
364 |
|
86a264abe
|
365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 |
#define current_uid_gid(_uid, _gid) \ do { \ const struct cred *__cred; \ __cred = current_cred(); \ *(_uid) = __cred->uid; \ *(_gid) = __cred->gid; \ } while(0) #define current_euid_egid(_euid, _egid) \ do { \ const struct cred *__cred; \ __cred = current_cred(); \ *(_euid) = __cred->euid; \ *(_egid) = __cred->egid; \ } while(0) #define current_fsuid_fsgid(_fsuid, _fsgid) \ do { \ const struct cred *__cred; \ __cred = current_cred(); \ *(_fsuid) = __cred->fsuid; \ *(_fsgid) = __cred->fsgid; \ } while(0) |
9e2b2dc41
|
388 |
#endif /* _LINUX_CRED_H */ |