Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

cred: switch to using atomic_long_t

There are multiple ways to grab references to credentials, and the only
protection we have against overflowing it is the memory required to do
so.

With memory sizes only moving in one direction, let's bump the reference
count to 64-bit and move it outside the realm of feasibly overflowing.

Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Jens Axboe and committed by
Linus Torvalds
f8fa5d76 3bd7d748

+36 -36
+4 -4
include/linux/cred.h
··· 109 109 * same context as task->real_cred. 110 110 */ 111 111 struct cred { 112 - atomic_t usage; 112 + atomic_long_t usage; 113 113 #ifdef CONFIG_DEBUG_CREDENTIALS 114 114 atomic_t subscribers; /* number of processes subscribed */ 115 115 void *put_addr; ··· 229 229 */ 230 230 static inline struct cred *get_new_cred_many(struct cred *cred, int nr) 231 231 { 232 - atomic_add(nr, &cred->usage); 232 + atomic_long_add(nr, &cred->usage); 233 233 return cred; 234 234 } 235 235 ··· 288 288 struct cred *nonconst_cred = (struct cred *) cred; 289 289 if (!cred) 290 290 return NULL; 291 - if (!atomic_inc_not_zero(&nonconst_cred->usage)) 291 + if (!atomic_long_inc_not_zero(&nonconst_cred->usage)) 292 292 return NULL; 293 293 validate_creds(cred); 294 294 nonconst_cred->non_rcu = 0; ··· 313 313 314 314 if (cred) { 315 315 validate_creds(cred); 316 - if (atomic_sub_and_test(nr, &cred->usage)) 316 + if (atomic_long_sub_and_test(nr, &cred->usage)) 317 317 __put_cred(cred); 318 318 } 319 319 }
+32 -32
kernel/cred.c
··· 102 102 103 103 #ifdef CONFIG_DEBUG_CREDENTIALS 104 104 if (cred->magic != CRED_MAGIC_DEAD || 105 - atomic_read(&cred->usage) != 0 || 105 + atomic_long_read(&cred->usage) != 0 || 106 106 read_cred_subscribers(cred) != 0) 107 107 panic("CRED: put_cred_rcu() sees %p with" 108 - " mag %x, put %p, usage %d, subscr %d\n", 108 + " mag %x, put %p, usage %ld, subscr %d\n", 109 109 cred, cred->magic, cred->put_addr, 110 - atomic_read(&cred->usage), 110 + atomic_long_read(&cred->usage), 111 111 read_cred_subscribers(cred)); 112 112 #else 113 - if (atomic_read(&cred->usage) != 0) 114 - panic("CRED: put_cred_rcu() sees %p with usage %d\n", 115 - cred, atomic_read(&cred->usage)); 113 + if (atomic_long_read(&cred->usage) != 0) 114 + panic("CRED: put_cred_rcu() sees %p with usage %ld\n", 115 + cred, atomic_long_read(&cred->usage)); 116 116 #endif 117 117 118 118 security_cred_free(cred); ··· 137 137 */ 138 138 void __put_cred(struct cred *cred) 139 139 { 140 - kdebug("__put_cred(%p{%d,%d})", cred, 141 - atomic_read(&cred->usage), 140 + kdebug("__put_cred(%p{%ld,%d})", cred, 141 + atomic_long_read(&cred->usage), 142 142 read_cred_subscribers(cred)); 143 143 144 - BUG_ON(atomic_read(&cred->usage) != 0); 144 + BUG_ON(atomic_long_read(&cred->usage) != 0); 145 145 #ifdef CONFIG_DEBUG_CREDENTIALS 146 146 BUG_ON(read_cred_subscribers(cred) != 0); 147 147 cred->magic = CRED_MAGIC_DEAD; ··· 164 164 { 165 165 struct cred *real_cred, *cred; 166 166 167 - kdebug("exit_creds(%u,%p,%p,{%d,%d})", tsk->pid, tsk->real_cred, tsk->cred, 168 - atomic_read(&tsk->cred->usage), 167 + kdebug("exit_creds(%u,%p,%p,{%ld,%d})", tsk->pid, tsk->real_cred, tsk->cred, 168 + atomic_long_read(&tsk->cred->usage), 169 169 read_cred_subscribers(tsk->cred)); 170 170 171 171 real_cred = (struct cred *) tsk->real_cred; ··· 230 230 if (!new) 231 231 return NULL; 232 232 233 - atomic_set(&new->usage, 1); 233 + atomic_long_set(&new->usage, 1); 234 234 #ifdef CONFIG_DEBUG_CREDENTIALS 235 235 new->magic = CRED_MAGIC; 236 236 #endif ··· 276 276 memcpy(new, old, sizeof(struct cred)); 277 277 278 278 new->non_rcu = 0; 279 - atomic_set(&new->usage, 1); 279 + atomic_long_set(&new->usage, 1); 280 280 set_cred_subscribers(new, 0); 281 281 get_group_info(new->group_info); 282 282 get_uid(new->user); ··· 363 363 ) { 364 364 p->real_cred = get_cred_many(p->cred, 2); 365 365 alter_cred_subscribers(p->cred, 2); 366 - kdebug("share_creds(%p{%d,%d})", 367 - p->cred, atomic_read(&p->cred->usage), 366 + kdebug("share_creds(%p{%ld,%d})", 367 + p->cred, atomic_long_read(&p->cred->usage), 368 368 read_cred_subscribers(p->cred)); 369 369 inc_rlimit_ucounts(task_ucounts(p), UCOUNT_RLIMIT_NPROC, 1); 370 370 return 0; ··· 457 457 struct task_struct *task = current; 458 458 const struct cred *old = task->real_cred; 459 459 460 - kdebug("commit_creds(%p{%d,%d})", new, 461 - atomic_read(&new->usage), 460 + kdebug("commit_creds(%p{%ld,%d})", new, 461 + atomic_long_read(&new->usage), 462 462 read_cred_subscribers(new)); 463 463 464 464 BUG_ON(task->cred != old); ··· 467 467 validate_creds(old); 468 468 validate_creds(new); 469 469 #endif 470 - BUG_ON(atomic_read(&new->usage) < 1); 470 + BUG_ON(atomic_long_read(&new->usage) < 1); 471 471 472 472 get_cred(new); /* we will require a ref for the subj creds too */ 473 473 ··· 539 539 */ 540 540 void abort_creds(struct cred *new) 541 541 { 542 - kdebug("abort_creds(%p{%d,%d})", new, 543 - atomic_read(&new->usage), 542 + kdebug("abort_creds(%p{%ld,%d})", new, 543 + atomic_long_read(&new->usage), 544 544 read_cred_subscribers(new)); 545 545 546 546 #ifdef CONFIG_DEBUG_CREDENTIALS 547 547 BUG_ON(read_cred_subscribers(new) != 0); 548 548 #endif 549 - BUG_ON(atomic_read(&new->usage) < 1); 549 + BUG_ON(atomic_long_read(&new->usage) < 1); 550 550 put_cred(new); 551 551 } 552 552 EXPORT_SYMBOL(abort_creds); ··· 562 562 { 563 563 const struct cred *old = current->cred; 564 564 565 - kdebug("override_creds(%p{%d,%d})", new, 566 - atomic_read(&new->usage), 565 + kdebug("override_creds(%p{%ld,%d})", new, 566 + atomic_long_read(&new->usage), 567 567 read_cred_subscribers(new)); 568 568 569 569 validate_creds(old); ··· 585 585 rcu_assign_pointer(current->cred, new); 586 586 alter_cred_subscribers(old, -1); 587 587 588 - kdebug("override_creds() = %p{%d,%d}", old, 589 - atomic_read(&old->usage), 588 + kdebug("override_creds() = %p{%ld,%d}", old, 589 + atomic_long_read(&old->usage), 590 590 read_cred_subscribers(old)); 591 591 return old; 592 592 } ··· 603 603 { 604 604 const struct cred *override = current->cred; 605 605 606 - kdebug("revert_creds(%p{%d,%d})", old, 607 - atomic_read(&old->usage), 606 + kdebug("revert_creds(%p{%ld,%d})", old, 607 + atomic_long_read(&old->usage), 608 608 read_cred_subscribers(old)); 609 609 610 610 validate_creds(old); ··· 735 735 736 736 *new = *old; 737 737 new->non_rcu = 0; 738 - atomic_set(&new->usage, 1); 738 + atomic_long_set(&new->usage, 1); 739 739 set_cred_subscribers(new, 0); 740 740 get_uid(new->user); 741 741 get_user_ns(new->user_ns); ··· 849 849 cred == tsk->cred ? "[eff]" : ""); 850 850 pr_err("->magic=%x, put_addr=%p\n", 851 851 cred->magic, cred->put_addr); 852 - pr_err("->usage=%d, subscr=%d\n", 853 - atomic_read(&cred->usage), 852 + pr_err("->usage=%ld, subscr=%d\n", 853 + atomic_long_read(&cred->usage), 854 854 read_cred_subscribers(cred)); 855 855 pr_err("->*uid = { %d,%d,%d,%d }\n", 856 856 from_kuid_munged(&init_user_ns, cred->uid), ··· 922 922 */ 923 923 void validate_creds_for_do_exit(struct task_struct *tsk) 924 924 { 925 - kdebug("validate_creds_for_do_exit(%p,%p{%d,%d})", 925 + kdebug("validate_creds_for_do_exit(%p,%p{%ld,%d})", 926 926 tsk->real_cred, tsk->cred, 927 - atomic_read(&tsk->cred->usage), 927 + atomic_long_read(&tsk->cred->usage), 928 928 read_cred_subscribers(tsk->cred)); 929 929 930 930 __validate_process_creds(tsk, __FILE__, __LINE__);