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 set_dumpable(task->mm, suid_dumpable); 376 task->pdeath_signal = 0; 377 smp_wmb(); 378 } 379 380 /* alter the thread keyring */ 381 if (new->fsuid != old->fsuid) 382 key_fsuid_changed(task); 383 if (new->fsgid != old->fsgid) 384 key_fsgid_changed(task); 385 386 /* do it 387 * - What if a process setreuid()'s and this brings the 388 * new uid over his NPROC rlimit? We can check this now 389 * cheaply with the new uid cache, so if it matters 390 * we should be checking for it. -DaveM 391 */ 392 if (new->user != old->user) 393 atomic_inc(&new->user->processes); 394 rcu_assign_pointer(task->real_cred, new); 395 rcu_assign_pointer(task->cred, new); 396 if (new->user != old->user) 397 atomic_dec(&old->user->processes); 398 399 sched_switch_user(task); 400 401 /* send notifications */ 402 if (new->uid != old->uid || 403 new->euid != old->euid || 404 new->suid != old->suid || 405 new->fsuid != old->fsuid) 406 proc_id_connector(task, PROC_EVENT_UID); 407 408 if (new->gid != old->gid || 409 new->egid != old->egid || 410 new->sgid != old->sgid || 411 new->fsgid != old->fsgid) 412 proc_id_connector(task, PROC_EVENT_GID); 413 414 /* release the old obj and subj refs both */ 415 put_cred(old); 416 put_cred(old); 417 return 0; 418 } 419 EXPORT_SYMBOL(commit_creds); 420 421 /** 422 * abort_creds - Discard a set of credentials and unlock the current task 423 * @new: The credentials that were going to be applied 424 * 425 * Discard a set of credentials that were under construction and unlock the 426 * current task. 427 */ 428 void abort_creds(struct cred *new) 429 { 430 BUG_ON(atomic_read(&new->usage) < 1); 431 put_cred(new); 432 } 433 EXPORT_SYMBOL(abort_creds); 434 435 /** 436 * override_creds - Override the current process's subjective credentials 437 * @new: The credentials to be assigned 438 * 439 * Install a set of temporary override subjective credentials on the current 440 * process, returning the old set for later reversion. 441 */ 442 const struct cred *override_creds(const struct cred *new) 443 { 444 const struct cred *old = current->cred; 445 446 rcu_assign_pointer(current->cred, get_cred(new)); 447 return old; 448 } 449 EXPORT_SYMBOL(override_creds); 450 451 /** 452 * revert_creds - Revert a temporary subjective credentials override 453 * @old: The credentials to be restored 454 * 455 * Revert a temporary set of override subjective credentials to an old set, 456 * discarding the override set. 457 */ 458 void revert_creds(const struct cred *old) 459 { 460 const struct cred *override = current->cred; 461 462 rcu_assign_pointer(current->cred, old); 463 put_cred(override); 464 } 465 EXPORT_SYMBOL(revert_creds); 466 467 /* 468 * initialise the credentials stuff 469 */ 470 void __init cred_init(void) 471 { 472 /* allocate a slab in which we can store credentials */ 473 cred_jar = kmem_cache_create("cred_jar", sizeof(struct cred), 474 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL); 475 } 476 477 /** 478 * prepare_kernel_cred - Prepare a set of credentials for a kernel service 479 * @daemon: A userspace daemon to be used as a reference 480 * 481 * Prepare a set of credentials for a kernel service. This can then be used to 482 * override a task's own credentials so that work can be done on behalf of that 483 * task that requires a different subjective context. 484 * 485 * @daemon is used to provide a base for the security record, but can be NULL. 486 * If @daemon is supplied, then the security data will be derived from that; 487 * otherwise they'll be set to 0 and no groups, full capabilities and no keys. 488 * 489 * The caller may change these controls afterwards if desired. 490 * 491 * Returns the new credentials or NULL if out of memory. 492 * 493 * Does not take, and does not return holding current->cred_replace_mutex. 494 */ 495 struct cred *prepare_kernel_cred(struct task_struct *daemon) 496 { 497 const struct cred *old; 498 struct cred *new; 499 500 new = kmem_cache_alloc(cred_jar, GFP_KERNEL); 501 if (!new) 502 return NULL; 503 504 if (daemon) 505 old = get_task_cred(daemon); 506 else 507 old = get_cred(&init_cred); 508 509 get_uid(new->user); 510 get_group_info(new->group_info); 511 512 #ifdef CONFIG_KEYS 513 atomic_inc(&init_tgcred.usage); 514 new->tgcred = &init_tgcred; 515 new->request_key_auth = NULL; 516 new->thread_keyring = NULL; 517 new->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING; 518 #endif 519 520 #ifdef CONFIG_SECURITY 521 new->security = NULL; 522 #endif 523 if (security_prepare_creds(new, old, GFP_KERNEL) < 0) 524 goto error; 525 526 atomic_set(&new->usage, 1); 527 put_cred(old); 528 return new; 529 530 error: 531 put_cred(new); 532 return NULL; 533 } 534 EXPORT_SYMBOL(prepare_kernel_cred); 535 536 /** 537 * set_security_override - Set the security ID in a set of credentials 538 * @new: The credentials to alter 539 * @secid: The LSM security ID to set 540 * 541 * Set the LSM security ID in a set of credentials so that the subjective 542 * security is overridden when an alternative set of credentials is used. 543 */ 544 int set_security_override(struct cred *new, u32 secid) 545 { 546 return security_kernel_act_as(new, secid); 547 } 548 EXPORT_SYMBOL(set_security_override); 549 550 /** 551 * set_security_override_from_ctx - Set the security ID in a set of credentials 552 * @new: The credentials to alter 553 * @secctx: The LSM security context to generate the security ID from. 554 * 555 * Set the LSM security ID in a set of credentials so that the subjective 556 * security is overridden when an alternative set of credentials is used. The 557 * security ID is specified in string form as a security context to be 558 * interpreted by the LSM. 559 */ 560 int set_security_override_from_ctx(struct cred *new, const char *secctx) 561 { 562 u32 secid; 563 int ret; 564 565 ret = security_secctx_to_secid(secctx, strlen(secctx), &secid); 566 if (ret < 0) 567 return ret; 568 569 return set_security_override(new, secid); 570 } 571 EXPORT_SYMBOL(set_security_override_from_ctx); 572 573 /** 574 * set_create_files_as - Set the LSM file create context in a set of credentials 575 * @new: The credentials to alter 576 * @inode: The inode to take the context from 577 * 578 * Change the LSM file creation context in a set of credentials to be the same 579 * as the object context of the specified inode, so that the new inodes have 580 * the same MAC context as that inode. 581 */ 582 int set_create_files_as(struct cred *new, struct inode *inode) 583 { 584 new->fsuid = inode->i_uid; 585 new->fsgid = inode->i_gid; 586 return security_kernel_create_files_as(new, inode); 587 } 588 EXPORT_SYMBOL(set_create_files_as); 589