Skip to content

Commit f8fa5d7

Browse files
axboetorvalds
authored andcommitted
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>
1 parent 3bd7d74 commit f8fa5d7

2 files changed

Lines changed: 36 additions & 36 deletions

File tree

include/linux/cred.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ static inline int groups_search(const struct group_info *group_info, kgid_t grp)
109109
* same context as task->real_cred.
110110
*/
111111
struct cred {
112-
atomic_t usage;
112+
atomic_long_t usage;
113113
#ifdef CONFIG_DEBUG_CREDENTIALS
114114
atomic_t subscribers; /* number of processes subscribed */
115115
void *put_addr;
@@ -229,7 +229,7 @@ static inline bool cap_ambient_invariant_ok(const struct cred *cred)
229229
*/
230230
static inline struct cred *get_new_cred_many(struct cred *cred, int nr)
231231
{
232-
atomic_add(nr, &cred->usage);
232+
atomic_long_add(nr, &cred->usage);
233233
return cred;
234234
}
235235

@@ -288,7 +288,7 @@ static inline const struct cred *get_cred_rcu(const struct cred *cred)
288288
struct cred *nonconst_cred = (struct cred *) cred;
289289
if (!cred)
290290
return NULL;
291-
if (!atomic_inc_not_zero(&nonconst_cred->usage))
291+
if (!atomic_long_inc_not_zero(&nonconst_cred->usage))
292292
return NULL;
293293
validate_creds(cred);
294294
nonconst_cred->non_rcu = 0;
@@ -313,7 +313,7 @@ static inline void put_cred_many(const struct cred *_cred, int nr)
313313

314314
if (cred) {
315315
validate_creds(cred);
316-
if (atomic_sub_and_test(nr, &cred->usage))
316+
if (atomic_long_sub_and_test(nr, &cred->usage))
317317
__put_cred(cred);
318318
}
319319
}

kernel/cred.c

Lines changed: 32 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -102,17 +102,17 @@ static void put_cred_rcu(struct rcu_head *rcu)
102102

103103
#ifdef CONFIG_DEBUG_CREDENTIALS
104104
if (cred->magic != CRED_MAGIC_DEAD ||
105-
atomic_read(&cred->usage) != 0 ||
105+
atomic_long_read(&cred->usage) != 0 ||
106106
read_cred_subscribers(cred) != 0)
107107
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",
109109
cred, cred->magic, cred->put_addr,
110-
atomic_read(&cred->usage),
110+
atomic_long_read(&cred->usage),
111111
read_cred_subscribers(cred));
112112
#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));
116116
#endif
117117

118118
security_cred_free(cred);
@@ -137,11 +137,11 @@ static void put_cred_rcu(struct rcu_head *rcu)
137137
*/
138138
void __put_cred(struct cred *cred)
139139
{
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),
142142
read_cred_subscribers(cred));
143143

144-
BUG_ON(atomic_read(&cred->usage) != 0);
144+
BUG_ON(atomic_long_read(&cred->usage) != 0);
145145
#ifdef CONFIG_DEBUG_CREDENTIALS
146146
BUG_ON(read_cred_subscribers(cred) != 0);
147147
cred->magic = CRED_MAGIC_DEAD;
@@ -164,8 +164,8 @@ void exit_creds(struct task_struct *tsk)
164164
{
165165
struct cred *real_cred, *cred;
166166

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),
169169
read_cred_subscribers(tsk->cred));
170170

171171
real_cred = (struct cred *) tsk->real_cred;
@@ -230,7 +230,7 @@ struct cred *cred_alloc_blank(void)
230230
if (!new)
231231
return NULL;
232232

233-
atomic_set(&new->usage, 1);
233+
atomic_long_set(&new->usage, 1);
234234
#ifdef CONFIG_DEBUG_CREDENTIALS
235235
new->magic = CRED_MAGIC;
236236
#endif
@@ -276,7 +276,7 @@ struct cred *prepare_creds(void)
276276
memcpy(new, old, sizeof(struct cred));
277277

278278
new->non_rcu = 0;
279-
atomic_set(&new->usage, 1);
279+
atomic_long_set(&new->usage, 1);
280280
set_cred_subscribers(new, 0);
281281
get_group_info(new->group_info);
282282
get_uid(new->user);
@@ -363,8 +363,8 @@ int copy_creds(struct task_struct *p, unsigned long clone_flags)
363363
) {
364364
p->real_cred = get_cred_many(p->cred, 2);
365365
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),
368368
read_cred_subscribers(p->cred));
369369
inc_rlimit_ucounts(task_ucounts(p), UCOUNT_RLIMIT_NPROC, 1);
370370
return 0;
@@ -457,8 +457,8 @@ int commit_creds(struct cred *new)
457457
struct task_struct *task = current;
458458
const struct cred *old = task->real_cred;
459459

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),
462462
read_cred_subscribers(new));
463463

464464
BUG_ON(task->cred != old);
@@ -467,7 +467,7 @@ int commit_creds(struct cred *new)
467467
validate_creds(old);
468468
validate_creds(new);
469469
#endif
470-
BUG_ON(atomic_read(&new->usage) < 1);
470+
BUG_ON(atomic_long_read(&new->usage) < 1);
471471

472472
get_cred(new); /* we will require a ref for the subj creds too */
473473

@@ -539,14 +539,14 @@ EXPORT_SYMBOL(commit_creds);
539539
*/
540540
void abort_creds(struct cred *new)
541541
{
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),
544544
read_cred_subscribers(new));
545545

546546
#ifdef CONFIG_DEBUG_CREDENTIALS
547547
BUG_ON(read_cred_subscribers(new) != 0);
548548
#endif
549-
BUG_ON(atomic_read(&new->usage) < 1);
549+
BUG_ON(atomic_long_read(&new->usage) < 1);
550550
put_cred(new);
551551
}
552552
EXPORT_SYMBOL(abort_creds);
@@ -562,8 +562,8 @@ const struct cred *override_creds(const struct cred *new)
562562
{
563563
const struct cred *old = current->cred;
564564

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),
567567
read_cred_subscribers(new));
568568

569569
validate_creds(old);
@@ -585,8 +585,8 @@ const struct cred *override_creds(const struct cred *new)
585585
rcu_assign_pointer(current->cred, new);
586586
alter_cred_subscribers(old, -1);
587587

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),
590590
read_cred_subscribers(old));
591591
return old;
592592
}
@@ -603,8 +603,8 @@ void revert_creds(const struct cred *old)
603603
{
604604
const struct cred *override = current->cred;
605605

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),
608608
read_cred_subscribers(old));
609609

610610
validate_creds(old);
@@ -735,7 +735,7 @@ struct cred *prepare_kernel_cred(struct task_struct *daemon)
735735

736736
*new = *old;
737737
new->non_rcu = 0;
738-
atomic_set(&new->usage, 1);
738+
atomic_long_set(&new->usage, 1);
739739
set_cred_subscribers(new, 0);
740740
get_uid(new->user);
741741
get_user_ns(new->user_ns);
@@ -849,8 +849,8 @@ static void dump_invalid_creds(const struct cred *cred, const char *label,
849849
cred == tsk->cred ? "[eff]" : "");
850850
pr_err("->magic=%x, put_addr=%p\n",
851851
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),
854854
read_cred_subscribers(cred));
855855
pr_err("->*uid = { %d,%d,%d,%d }\n",
856856
from_kuid_munged(&init_user_ns, cred->uid),
@@ -922,9 +922,9 @@ EXPORT_SYMBOL(__validate_process_creds);
922922
*/
923923
void validate_creds_for_do_exit(struct task_struct *tsk)
924924
{
925-
kdebug("validate_creds_for_do_exit(%p,%p{%d,%d})",
925+
kdebug("validate_creds_for_do_exit(%p,%p{%ld,%d})",
926926
tsk->real_cred, tsk->cred,
927-
atomic_read(&tsk->cred->usage),
927+
atomic_long_read(&tsk->cred->usage),
928928
read_cred_subscribers(tsk->cred));
929929

930930
__validate_process_creds(tsk, __FILE__, __LINE__);

0 commit comments

Comments
 (0)