1 /* Task credentials management - see Documentation/credentials.txt 2 * 3 * Copyright (C) 2008 Red Hat, Inc. All Rights Reserved. 4 * Written by David Howells (dhowells@redhat.com) 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public Licence 8 * as published by the Free Software Foundation; either version 9 * 2 of the Licence, or (at your option) any later version. 10 */ 11 #include <linux/module.h> 12 #include <linux/cred.h> 13 #include <linux/sched.h> 14 #include <linux/key.h> 15 #include <linux/keyctl.h> 16 #include <linux/init_task.h> 17 #include <linux/security.h> 18 #include <linux/cn_proc.h> 19 #include "cred-internals.h" 20 21 static struct kmem_cache *cred_jar; 22 23 /* 24 * The common credentials for the initial task's thread group 25 */ 26 #ifdef CONFIG_KEYS 27 static struct thread_group_cred init_tgcred = { 28 .usage = ATOMIC_INIT(2), 29 .tgid = 0, 30 .lock = SPIN_LOCK_UNLOCKED, 31 }; 32 #endif 33 34 /* 35 * The initial credentials for the initial task 36 */ 37 struct cred init_cred = { 38 .usage = ATOMIC_INIT(4), 39 .securebits = SECUREBITS_DEFAULT, 40 .cap_inheritable = CAP_INIT_INH_SET, 41 .cap_permitted = CAP_FULL_SET, 42 .cap_effective = CAP_INIT_EFF_SET, 43 .cap_bset = CAP_INIT_BSET, 44 .user = INIT_USER, 45 .group_info = &init_groups, 46 #ifdef CONFIG_KEYS 47 .tgcred = &init_tgcred, 48 #endif 49 }; 50 51 /* 52 * Dispose of the shared task group credentials 53 */ 54 #ifdef CONFIG_KEYS 55 static void release_tgcred_rcu(struct rcu_head *rcu) 56 { 57 struct thread_group_cred *tgcred = 58 container_of(rcu, struct thread_group_cred, rcu); 59 60 BUG_ON(atomic_read(&tgcred->usage) != 0); 61 62 key_put(tgcred->session_keyring); 63 key_put(tgcred->process_keyring); 64 kfree(tgcred); 65 } 66 #endif 67 68 /* 69 * Release a set of thread group credentials. 70 */ 71 static void release_tgcred(struct cred *cred) 72 { 73 #ifdef CONFIG_KEYS 74 struct thread_group_cred *tgcred = cred->tgcred; 75 76 if (atomic_dec_and_test(&tgcred->usage)) 77 call_rcu(&tgcred->rcu, release_tgcred_rcu); 78 #endif 79 } 80 81 /* 82 * The RCU callback to actually dispose of a set of credentials 83 */ 84 static void put_cred_rcu(struct rcu_head *rcu) 85 { 86 struct cred *cred = container_of(rcu, struct cred, rcu); 87 88 if (atomic_read(&cred->usage) != 0) 89 panic("CRED: put_cred_rcu() sees %p with usage %d\n", 90 cred, atomic_read(&cred->usage)); 91 92 security_cred_free(cred); 93 key_put(cred->thread_keyring); 94 key_put(cred->request_key_auth); 95 release_tgcred(cred); 96 put_group_info(cred->group_info); 97 free_uid(cred->user); 98 kmem_cache_free(cred_jar, cred); 99 } 100 101 /** 102 * __put_cred - Destroy a set of credentials 103 * @cred: The record to release 104 * 105 * Destroy a set of credentials on which no references remain. 106 */ 107 void __put_cred(struct cred *cred) 108 { 109 BUG_ON(atomic_read(&cred->usage) != 0); 110 111 call_rcu(&cred->rcu, put_cred_rcu); 112 } 113 EXPORT_SYMBOL(__put_cred); 114 115 /** 116 * prepare_creds - Prepare a new set of credentials for modification 117 * 118 * Prepare a new set of task credentials for modification. A task's creds 119 * shouldn't generally be modified directly, therefore this function is used to 120 * prepare a new copy, which the caller then modifies and then commits by 121 * calling commit_creds(). 122 * 123 * Preparation involves making a copy of the objective creds for modification. 124 * 125 * Returns a pointer to the new creds-to-be if successful, NULL otherwise. 126 * 127 * Call commit_creds() or abort_creds() to clean up. 128 */ 129 struct cred *prepare_creds(void) 130 { 131 struct task_struct *task = current; 132 const struct cred *old; 133 struct cred *new; 134 135 BUG_ON(atomic_read(&task->real_cred->usage) < 1); 136 137 new = kmem_cache_alloc(cred_jar, GFP_KERNEL); 138 if (!new) 139 return NULL; 140 141 old = task->cred; 142 memcpy(new, old, sizeof(struct cred)); 143 144 atomic_set(&new->usage, 1); 145 get_group_info(new->group_info); 146 get_uid(new->user); 147 148 #ifdef CONFIG_KEYS 149 key_get(new->thread_keyring); 150 key_get(new->request_key_auth); 151 atomic_inc(&new->tgcred->usage); 152 #endif 153 154 #ifdef CONFIG_SECURITY 155 new->security = NULL; 156 #endif 157 158 if (security_prepare_creds(new, old, GFP_KERNEL) < 0) 159 goto error; 160 return new; 161 162 error: 163 abort_creds(new); 164 return NULL; 165 } 166 EXPORT_SYMBOL(prepare_creds); 167 168 /* 169 * Prepare credentials for current to perform an execve() 170 * - The caller must hold current->cred_exec_mutex 171 */ 172 struct cred *prepare_exec_creds(void) 173 { 174 struct thread_group_cred *tgcred = NULL; 175 struct cred *new; 176 177 #ifdef CONFIG_KEYS 178 tgcred = kmalloc(sizeof(*tgcred), GFP_KERNEL); 179 if (!tgcred) 180 return NULL; 181 #endif 182 183 new = prepare_creds(); 184 if (!new) { 185 kfree(tgcred); 186 return new; 187 } 188 189 #ifdef CONFIG_KEYS 190 /* newly exec'd tasks don't get a thread keyring */ 191 key_put(new->thread_keyring); 192 new->thread_keyring = NULL; 193 194 /* create a new per-thread-group creds for all this set of threads to 195 * share */ 196 memcpy(tgcred, new->tgcred, sizeof(struct thread_group_cred)); 197 198 atomic_set(&tgcred->usage, 1); 199 spin_lock_init(&tgcred->lock); 200 201 /* inherit the session keyring; new process keyring */ 202 key_get(tgcred->session_keyring); 203 tgcred->process_keyring = NULL; 204 205 release_tgcred(new); 206 new->tgcred = tgcred; 207 #endif 208 209 return new; 210 } 211 212 /* 213 * prepare new credentials for the usermode helper dispatcher 214 */ 215 struct cred *prepare_usermodehelper_creds(void) 216 { 217 #ifdef CONFIG_KEYS 218 struct thread_group_cred *tgcred = NULL; 219 #endif 220 struct cred *new; 221 222 #ifdef CONFIG_KEYS 223 tgcred = kzalloc(sizeof(*new->tgcred), GFP_ATOMIC); 224 if (!tgcred) 225 return NULL; 226 #endif 227 228 new = kmem_cache_alloc(cred_jar, GFP_ATOMIC); 229 if (!new) 230 return NULL; 231 232 memcpy(new, &init_cred, sizeof(struct cred)); 233 234 atomic_set(&new->usage, 1); 235 get_group_info(new->group_info); 236 get_uid(new->user); 237 238 #ifdef CONFIG_KEYS 239 new->thread_keyring = NULL; 240 new->request_key_auth = NULL; 241 new->jit_keyring = KEY_REQKEY_DEFL_DEFAULT; 242 243 atomic_set(&tgcred->usage, 1); 244 spin_lock_init(&tgcred->lock); 245 new->tgcred = tgcred; 246 #endif 247 248 #ifdef CONFIG_SECURITY 249 new->security = NULL; 250 #endif 251 if (security_prepare_creds(new, &init_cred, GFP_ATOMIC) < 0) 252 goto error; 253 254 BUG_ON(atomic_read(&new->usage) != 1); 255 return new; 256 257 error: 258 put_cred(new); 259 return NULL; 260 } 261 262 /* 263 * Copy credentials for the new process created by fork() 264 * 265 * We share if we can, but under some circumstances we have to generate a new 266 * set. 267 * 268 * The new process gets the current process's subjective credentials as its 269 * objective and subjective credentials 270 */ 271 int copy_creds(struct task_struct *p, unsigned long clone_flags) 272 { 273 #ifdef CONFIG_KEYS 274 struct thread_group_cred *tgcred; 275 #endif 276 struct cred *new; 277 int ret; 278 279 mutex_init(&p->cred_exec_mutex); 280 281 if ( 282 #ifdef CONFIG_KEYS 283 !p->cred->thread_keyring && 284 #endif 285 clone_flags & CLONE_THREAD 286 ) { 287 p->real_cred = get_cred(p->cred); 288 get_cred(p->cred); 289 atomic_inc(&p->cred->user->processes); 290 return 0; 291 } 292 293 new = prepare_creds(); 294 if (!new) 295 return -ENOMEM; 296 297 if (clone_flags & CLONE_NEWUSER) { 298 ret = create_user_ns(new); 299 if (ret < 0) 300 goto error_put; 301 } 302 303 #ifdef CONFIG_KEYS 304 /* new threads get their own thread keyrings if their parent already 305 * had one */ 306 if (new->thread_keyring) { 307 key_put(new->thread_keyring); 308 new->thread_keyring = NULL; 309 if (clone_flags & CLONE_THREAD) 310 install_thread_keyring_to_cred(new); 311 } 312 313 /* we share the process and session keyrings between all the threads in 314 * a process - this is slightly icky as we violate COW credentials a 315 * bit */ 316 if (!(clone_flags & CLONE_THREAD)) { 317 tgcred = kmalloc(sizeof(*tgcred), GFP_KERNEL); 318 if (!tgcred) { 319 ret = -ENOMEM; 320 goto error_put; 321 } 322 atomic_set(&tgcred->usage, 1); 323 spin_lock_init(&tgcred->lock); 324 tgcred->process_keyring = NULL; 325 tgcred->session_keyring = key_get(new->tgcred->session_keyring); 326 327 release_tgcred(new); 328 new->tgcred = tgcred; 329 } 330 #endif 331 332 atomic_inc(&new->user->processes); 333 p->cred = p->real_cred = get_cred(new); 334 return 0; 335 336 error_put: 337 put_cred(new); 338 return ret; 339 } 340 341 /** 342 * commit_creds - Install new credentials upon the current task 343 * @new: The credentials to be assigned 344 * 345 * Install a new set of credentials to the current task, using RCU to replace 346 * the old set. Both the objective and the subjective credentials pointers are 347 * updated. This function may not be called if the subjective credentials are 348 * in an overridden state. 349 * 350 * This function eats the caller's reference to the new credentials. 351 * 352 * Always returns 0 thus allowing this function to be tail-called at the end 353 * of, say, sys_setgid(). 354 */ 355 int commit_creds(struct cred *new) 356 { 357 struct task_struct *task = current; 358 const struct cred *old; 359 360 BUG_ON(task->cred != task->real_cred); 361 BUG_ON(atomic_read(&task->real_cred->usage) < 2); 362 BUG_ON(atomic_read(&new->usage) < 1); 363 364 old = task->real_cred; 365 security_commit_creds(new, old); 366 367 get_cred(new); /* we will require a ref for the subj creds too */ 368 369 /* dumpability changes */ 370 if (old->euid != new->euid || 371 old->egid != new->egid || 372 old->fsuid != new->fsuid || 373 old->fsgid != new->fsgid || 374 !cap_issubset(new->cap_permitted, old->cap_permitted)) { 375 if (task->mm) 376 set_dumpable(task->mm, suid_dumpable); 377 task->pdeath_signal = 0; 378 smp_wmb(); 379 } 380 381 /* alter the thread keyring */ 382 if (new->fsuid != old->fsuid) 383 key_fsuid_changed(task); 384 if (new->fsgid != old->fsgid) 385 key_fsgid_changed(task); 386 387 /* do it 388 * - What if a process setreuid()'s and this brings the 389 * new uid over his NPROC rlimit? We can check this now 390 * cheaply with the new uid cache, so if it matters 391 * we should be checking for it. -DaveM 392 */ 393 if (new->user != old->user) 394 atomic_inc(&new->user->processes); 395 rcu_assign_pointer(task->real_cred, new); 396 rcu_assign_pointer(task->cred, new); 397 if (new->user != old->user) 398 atomic_dec(&old->user->processes); 399 400 sched_switch_user(task); 401 402 /* send notifications */ 403 if (new->uid != old->uid || 404 new->euid != old->euid || 405 new->suid != old->suid || 406 new->fsuid != old->fsuid) 407 proc_id_connector(task, PROC_EVENT_UID); 408 409 if (new->gid != old->gid || 410 new->egid != old->egid || 411 new->sgid != old->sgid || 412 new->fsgid != old->fsgid) 413 proc_id_connector(task, PROC_EVENT_GID); 414 415 /* release the old obj and subj refs both */ 416 put_cred(old); 417 put_cred(old); 418 return 0; 419 } 420 EXPORT_SYMBOL(commit_creds); 421 422 /** 423 * abort_creds - Discard a set of credentials and unlock the current task 424 * @new: The credentials that were going to be applied 425 * 426 * Discard a set of credentials that were under construction and unlock the 427 * current task. 428 */ 429 void abort_creds(struct cred *new) 430 { 431 BUG_ON(atomic_read(&new->usage) < 1); 432 put_cred(new); 433 } 434 EXPORT_SYMBOL(abort_creds); 435 436 /** 437 * override_creds - Override the current process's subjective credentials 438 * @new: The credentials to be assigned 439 * 440 * Install a set of temporary override subjective credentials on the current 441 * process, returning the old set for later reversion. 442 */ 443 const struct cred *override_creds(const struct cred *new) 444 { 445 const struct cred *old = current->cred; 446 447 rcu_assign_pointer(current->cred, get_cred(new)); 448 return old; 449 } 450 EXPORT_SYMBOL(override_creds); 451 452 /** 453 * revert_creds - Revert a temporary subjective credentials override 454 * @old: The credentials to be restored 455 * 456 * Revert a temporary set of override subjective credentials to an old set, 457 * discarding the override set. 458 */ 459 void revert_creds(const struct cred *old) 460 { 461 const struct cred *override = current->cred; 462 463 rcu_assign_pointer(current->cred, old); 464 put_cred(override); 465 } 466 EXPORT_SYMBOL(revert_creds); 467 468 /* 469 * initialise the credentials stuff 470 */ 471 void __init cred_init(void) 472 { 473 /* allocate a slab in which we can store credentials */ 474 cred_jar = kmem_cache_create("cred_jar", sizeof(struct cred), 475 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL); 476 } 477 478 /** 479 * prepare_kernel_cred - Prepare a set of credentials for a kernel service 480 * @daemon: A userspace daemon to be used as a reference 481 * 482 * Prepare a set of credentials for a kernel service. This can then be used to 483 * override a task's own credentials so that work can be done on behalf of that 484 * task that requires a different subjective context. 485 * 486 * @daemon is used to provide a base for the security record, but can be NULL. 487 * If @daemon is supplied, then the security data will be derived from that; 488 * otherwise they'll be set to 0 and no groups, full capabilities and no keys. 489 * 490 * The caller may change these controls afterwards if desired. 491 * 492 * Returns the new credentials or NULL if out of memory. 493 * 494 * Does not take, and does not return holding current->cred_replace_mutex. 495 */ 496 struct cred *prepare_kernel_cred(struct task_struct *daemon) 497 { 498 const struct cred *old; 499 struct cred *new; 500 501 new = kmem_cache_alloc(cred_jar, GFP_KERNEL); 502 if (!new) 503 return NULL; 504 505 if (daemon) 506 old = get_task_cred(daemon); 507 else 508 old = get_cred(&init_cred); 509 510 *new = *old; 511 get_uid(new->user); 512 get_group_info(new->group_info); 513 514 #ifdef CONFIG_KEYS 515 atomic_inc(&init_tgcred.usage); 516 new->tgcred = &init_tgcred; 517 new->request_key_auth = NULL; 518 new->thread_keyring = NULL; 519 new->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING; 520 #endif 521 522 #ifdef CONFIG_SECURITY 523 new->security = NULL; 524 #endif 525 if (security_prepare_creds(new, old, GFP_KERNEL) < 0) 526 goto error; 527 528 atomic_set(&new->usage, 1); 529 put_cred(old); 530 return new; 531 532 error: 533 put_cred(new); 534 put_cred(old); 535 return NULL; 536 } 537 EXPORT_SYMBOL(prepare_kernel_cred); 538 539 /** 540 * set_security_override - Set the security ID in a set of credentials 541 * @new: The credentials to alter 542 * @secid: The LSM security ID to set 543 * 544 * Set the LSM security ID in a set of credentials so that the subjective 545 * security is overridden when an alternative set of credentials is used. 546 */ 547 int set_security_override(struct cred *new, u32 secid) 548 { 549 return security_kernel_act_as(new, secid); 550 } 551 EXPORT_SYMBOL(set_security_override); 552 553 /** 554 * set_security_override_from_ctx - Set the security ID in a set of credentials 555 * @new: The credentials to alter 556 * @secctx: The LSM security context to generate the security ID from. 557 * 558 * Set the LSM security ID in a set of credentials so that the subjective 559 * security is overridden when an alternative set of credentials is used. The 560 * security ID is specified in string form as a security context to be 561 * interpreted by the LSM. 562 */ 563 int set_security_override_from_ctx(struct cred *new, const char *secctx) 564 { 565 u32 secid; 566 int ret; 567 568 ret = security_secctx_to_secid(secctx, strlen(secctx), &secid); 569 if (ret < 0) 570 return ret; 571 572 return set_security_override(new, secid); 573 } 574 EXPORT_SYMBOL(set_security_override_from_ctx); 575 576 /** 577 * set_create_files_as - Set the LSM file create context in a set of credentials 578 * @new: The credentials to alter 579 * @inode: The inode to take the context from 580 * 581 * Change the LSM file creation context in a set of credentials to be the same 582 * as the object context of the specified inode, so that the new inodes have 583 * the same MAC context as that inode. 584 */ 585 int set_create_files_as(struct cred *new, struct inode *inode) 586 { 587 new->fsuid = inode->i_uid; 588 new->fsgid = inode->i_gid; 589 return security_kernel_create_files_as(new, inode); 590 } 591 EXPORT_SYMBOL(set_create_files_as); 592