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