Commit ae191417 authored by Jens Axboe's avatar Jens Axboe Committed by Linus Torvalds

cred: get rid of CONFIG_DEBUG_CREDENTIALS

This code is rarely (never?) enabled by distros, and it hasn't caught
anything in decades. Let's kill off this legacy debug code.
Suggested-by: default avatarLinus Torvalds <torvalds@linuxfoundation.org>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent f8fa5d76
...@@ -301,7 +301,6 @@ CONFIG_WQ_WATCHDOG=y ...@@ -301,7 +301,6 @@ CONFIG_WQ_WATCHDOG=y
CONFIG_DEBUG_SG=y CONFIG_DEBUG_SG=y
CONFIG_DEBUG_NOTIFIERS=y CONFIG_DEBUG_NOTIFIERS=y
CONFIG_BUG_ON_DATA_CORRUPTION=y CONFIG_BUG_ON_DATA_CORRUPTION=y
CONFIG_DEBUG_CREDENTIALS=y
# CONFIG_FTRACE is not set # CONFIG_FTRACE is not set
CONFIG_XMON=y CONFIG_XMON=y
# CONFIG_RUNTIME_TESTING_MENU is not set # CONFIG_RUNTIME_TESTING_MENU is not set
...@@ -834,7 +834,6 @@ CONFIG_DEBUG_IRQFLAGS=y ...@@ -834,7 +834,6 @@ CONFIG_DEBUG_IRQFLAGS=y
CONFIG_DEBUG_LIST=y CONFIG_DEBUG_LIST=y
CONFIG_DEBUG_SG=y CONFIG_DEBUG_SG=y
CONFIG_DEBUG_NOTIFIERS=y CONFIG_DEBUG_NOTIFIERS=y
CONFIG_DEBUG_CREDENTIALS=y
CONFIG_RCU_TORTURE_TEST=m CONFIG_RCU_TORTURE_TEST=m
CONFIG_RCU_REF_SCALE_TEST=m CONFIG_RCU_REF_SCALE_TEST=m
CONFIG_RCU_CPU_STALL_TIMEOUT=300 CONFIG_RCU_CPU_STALL_TIMEOUT=300
......
...@@ -26,8 +26,6 @@ int nfsd_setuser(struct svc_rqst *rqstp, struct svc_export *exp) ...@@ -26,8 +26,6 @@ int nfsd_setuser(struct svc_rqst *rqstp, struct svc_export *exp)
int i; int i;
int flags = nfsexp_flags(rqstp, exp); int flags = nfsexp_flags(rqstp, exp);
validate_process_creds();
/* discard any old override before preparing the new set */ /* discard any old override before preparing the new set */
revert_creds(get_cred(current_real_cred())); revert_creds(get_cred(current_real_cred()));
new = prepare_creds(); new = prepare_creds();
...@@ -81,10 +79,8 @@ int nfsd_setuser(struct svc_rqst *rqstp, struct svc_export *exp) ...@@ -81,10 +79,8 @@ int nfsd_setuser(struct svc_rqst *rqstp, struct svc_export *exp)
else else
new->cap_effective = cap_raise_nfsd_set(new->cap_effective, new->cap_effective = cap_raise_nfsd_set(new->cap_effective,
new->cap_permitted); new->cap_permitted);
validate_process_creds();
put_cred(override_creds(new)); put_cred(override_creds(new));
put_cred(new); put_cred(new);
validate_process_creds();
return 0; return 0;
oom: oom:
......
...@@ -955,7 +955,6 @@ nfsd(void *vrqstp) ...@@ -955,7 +955,6 @@ nfsd(void *vrqstp)
rqstp->rq_server->sv_maxconn = nn->max_connections; rqstp->rq_server->sv_maxconn = nn->max_connections;
svc_recv(rqstp); svc_recv(rqstp);
validate_process_creds();
} }
atomic_dec(&nfsdstats.th_cnt); atomic_dec(&nfsdstats.th_cnt);
......
...@@ -901,7 +901,6 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type, ...@@ -901,7 +901,6 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type,
int host_err; int host_err;
bool retried = false; bool retried = false;
validate_process_creds();
/* /*
* If we get here, then the client has already done an "open", * If we get here, then the client has already done an "open",
* and (hopefully) checked permission - so allow OWNER_OVERRIDE * and (hopefully) checked permission - so allow OWNER_OVERRIDE
...@@ -926,7 +925,6 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type, ...@@ -926,7 +925,6 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type,
} }
err = nfserrno(host_err); err = nfserrno(host_err);
} }
validate_process_creds();
return err; return err;
} }
...@@ -943,12 +941,7 @@ int ...@@ -943,12 +941,7 @@ int
nfsd_open_verified(struct svc_rqst *rqstp, struct svc_fh *fhp, int may_flags, nfsd_open_verified(struct svc_rqst *rqstp, struct svc_fh *fhp, int may_flags,
struct file **filp) struct file **filp)
{ {
int err; return __nfsd_open(rqstp, fhp, S_IFREG, may_flags, filp);
validate_process_creds();
err = __nfsd_open(rqstp, fhp, S_IFREG, may_flags, filp);
validate_process_creds();
return err;
} }
/* /*
......
...@@ -1088,8 +1088,6 @@ struct file *dentry_open(const struct path *path, int flags, ...@@ -1088,8 +1088,6 @@ struct file *dentry_open(const struct path *path, int flags,
int error; int error;
struct file *f; struct file *f;
validate_creds(cred);
/* We must always pass in a valid mount pointer. */ /* We must always pass in a valid mount pointer. */
BUG_ON(!path->mnt); BUG_ON(!path->mnt);
...@@ -1128,7 +1126,6 @@ struct file *dentry_create(const struct path *path, int flags, umode_t mode, ...@@ -1128,7 +1126,6 @@ struct file *dentry_create(const struct path *path, int flags, umode_t mode,
struct file *f; struct file *f;
int error; int error;
validate_creds(cred);
f = alloc_empty_file(flags, cred); f = alloc_empty_file(flags, cred);
if (IS_ERR(f)) if (IS_ERR(f))
return f; return f;
......
...@@ -110,13 +110,6 @@ static inline int groups_search(const struct group_info *group_info, kgid_t grp) ...@@ -110,13 +110,6 @@ static inline int groups_search(const struct group_info *group_info, kgid_t grp)
*/ */
struct cred { struct cred {
atomic_long_t usage; atomic_long_t usage;
#ifdef CONFIG_DEBUG_CREDENTIALS
atomic_t subscribers; /* number of processes subscribed */
void *put_addr;
unsigned magic;
#define CRED_MAGIC 0x43736564
#define CRED_MAGIC_DEAD 0x44656144
#endif
kuid_t uid; /* real UID of the task */ kuid_t uid; /* real UID of the task */
kgid_t gid; /* real GID of the task */ kgid_t gid; /* real GID of the task */
kuid_t suid; /* saved UID of the task */ kuid_t suid; /* saved UID of the task */
...@@ -172,46 +165,6 @@ extern int cred_fscmp(const struct cred *, const struct cred *); ...@@ -172,46 +165,6 @@ extern int cred_fscmp(const struct cred *, const struct cred *);
extern void __init cred_init(void); extern void __init cred_init(void);
extern int set_cred_ucounts(struct cred *); extern int set_cred_ucounts(struct cred *);
/*
* check for validity of credentials
*/
#ifdef CONFIG_DEBUG_CREDENTIALS
extern void __noreturn __invalid_creds(const struct cred *, const char *, unsigned);
extern void __validate_process_creds(struct task_struct *,
const char *, unsigned);
extern bool creds_are_invalid(const struct cred *cred);
static inline void __validate_creds(const struct cred *cred,
const char *file, unsigned line)
{
if (unlikely(creds_are_invalid(cred)))
__invalid_creds(cred, file, line);
}
#define validate_creds(cred) \
do { \
__validate_creds((cred), __FILE__, __LINE__); \
} while(0)
#define validate_process_creds() \
do { \
__validate_process_creds(current, __FILE__, __LINE__); \
} while(0)
extern void validate_creds_for_do_exit(struct task_struct *);
#else
static inline void validate_creds(const struct cred *cred)
{
}
static inline void validate_creds_for_do_exit(struct task_struct *tsk)
{
}
static inline void validate_process_creds(void)
{
}
#endif
static inline bool cap_ambient_invariant_ok(const struct cred *cred) static inline bool cap_ambient_invariant_ok(const struct cred *cred)
{ {
return cap_issubset(cred->cap_ambient, return cap_issubset(cred->cap_ambient,
...@@ -264,7 +217,6 @@ static inline const struct cred *get_cred_many(const struct cred *cred, int nr) ...@@ -264,7 +217,6 @@ static inline const struct cred *get_cred_many(const struct cred *cred, int nr)
struct cred *nonconst_cred = (struct cred *) cred; struct cred *nonconst_cred = (struct cred *) cred;
if (!cred) if (!cred)
return cred; return cred;
validate_creds(cred);
nonconst_cred->non_rcu = 0; nonconst_cred->non_rcu = 0;
return get_new_cred_many(nonconst_cred, nr); return get_new_cred_many(nonconst_cred, nr);
} }
...@@ -290,7 +242,6 @@ static inline const struct cred *get_cred_rcu(const struct cred *cred) ...@@ -290,7 +242,6 @@ static inline const struct cred *get_cred_rcu(const struct cred *cred)
return NULL; return NULL;
if (!atomic_long_inc_not_zero(&nonconst_cred->usage)) if (!atomic_long_inc_not_zero(&nonconst_cred->usage))
return NULL; return NULL;
validate_creds(cred);
nonconst_cred->non_rcu = 0; nonconst_cred->non_rcu = 0;
return cred; return cred;
} }
...@@ -312,7 +263,6 @@ static inline void put_cred_many(const struct cred *_cred, int nr) ...@@ -312,7 +263,6 @@ static inline void put_cred_many(const struct cred *_cred, int nr)
struct cred *cred = (struct cred *) _cred; struct cred *cred = (struct cred *) _cred;
if (cred) { if (cred) {
validate_creds(cred);
if (atomic_long_sub_and_test(nr, &cred->usage)) if (atomic_long_sub_and_test(nr, &cred->usage))
__put_cred(cred); __put_cred(cred);
} }
......
...@@ -43,10 +43,6 @@ static struct group_info init_groups = { .usage = REFCOUNT_INIT(2) }; ...@@ -43,10 +43,6 @@ static struct group_info init_groups = { .usage = REFCOUNT_INIT(2) };
*/ */
struct cred init_cred = { struct cred init_cred = {
.usage = ATOMIC_INIT(4), .usage = ATOMIC_INIT(4),
#ifdef CONFIG_DEBUG_CREDENTIALS
.subscribers = ATOMIC_INIT(2),
.magic = CRED_MAGIC,
#endif
.uid = GLOBAL_ROOT_UID, .uid = GLOBAL_ROOT_UID,
.gid = GLOBAL_ROOT_GID, .gid = GLOBAL_ROOT_GID,
.suid = GLOBAL_ROOT_UID, .suid = GLOBAL_ROOT_UID,
...@@ -66,31 +62,6 @@ struct cred init_cred = { ...@@ -66,31 +62,6 @@ struct cred init_cred = {
.ucounts = &init_ucounts, .ucounts = &init_ucounts,
}; };
static inline void set_cred_subscribers(struct cred *cred, int n)
{
#ifdef CONFIG_DEBUG_CREDENTIALS
atomic_set(&cred->subscribers, n);
#endif
}
static inline int read_cred_subscribers(const struct cred *cred)
{
#ifdef CONFIG_DEBUG_CREDENTIALS
return atomic_read(&cred->subscribers);
#else
return 0;
#endif
}
static inline void alter_cred_subscribers(const struct cred *_cred, int n)
{
#ifdef CONFIG_DEBUG_CREDENTIALS
struct cred *cred = (struct cred *) _cred;
atomic_add(n, &cred->subscribers);
#endif
}
/* /*
* The RCU callback to actually dispose of a set of credentials * The RCU callback to actually dispose of a set of credentials
*/ */
...@@ -100,20 +71,9 @@ static void put_cred_rcu(struct rcu_head *rcu) ...@@ -100,20 +71,9 @@ static void put_cred_rcu(struct rcu_head *rcu)
kdebug("put_cred_rcu(%p)", cred); kdebug("put_cred_rcu(%p)", cred);
#ifdef CONFIG_DEBUG_CREDENTIALS
if (cred->magic != CRED_MAGIC_DEAD ||
atomic_long_read(&cred->usage) != 0 ||
read_cred_subscribers(cred) != 0)
panic("CRED: put_cred_rcu() sees %p with"
" mag %x, put %p, usage %ld, subscr %d\n",
cred, cred->magic, cred->put_addr,
atomic_long_read(&cred->usage),
read_cred_subscribers(cred));
#else
if (atomic_long_read(&cred->usage) != 0) if (atomic_long_read(&cred->usage) != 0)
panic("CRED: put_cred_rcu() sees %p with usage %ld\n", panic("CRED: put_cred_rcu() sees %p with usage %ld\n",
cred, atomic_long_read(&cred->usage)); cred, atomic_long_read(&cred->usage));
#endif
security_cred_free(cred); security_cred_free(cred);
key_put(cred->session_keyring); key_put(cred->session_keyring);
...@@ -137,16 +97,10 @@ static void put_cred_rcu(struct rcu_head *rcu) ...@@ -137,16 +97,10 @@ static void put_cred_rcu(struct rcu_head *rcu)
*/ */
void __put_cred(struct cred *cred) void __put_cred(struct cred *cred)
{ {
kdebug("__put_cred(%p{%ld,%d})", cred, kdebug("__put_cred(%p{%ld})", cred,
atomic_long_read(&cred->usage), atomic_long_read(&cred->usage));
read_cred_subscribers(cred));
BUG_ON(atomic_long_read(&cred->usage) != 0); BUG_ON(atomic_long_read(&cred->usage) != 0);
#ifdef CONFIG_DEBUG_CREDENTIALS
BUG_ON(read_cred_subscribers(cred) != 0);
cred->magic = CRED_MAGIC_DEAD;
cred->put_addr = __builtin_return_address(0);
#endif
BUG_ON(cred == current->cred); BUG_ON(cred == current->cred);
BUG_ON(cred == current->real_cred); BUG_ON(cred == current->real_cred);
...@@ -164,9 +118,8 @@ void exit_creds(struct task_struct *tsk) ...@@ -164,9 +118,8 @@ void exit_creds(struct task_struct *tsk)
{ {
struct cred *real_cred, *cred; struct cred *real_cred, *cred;
kdebug("exit_creds(%u,%p,%p,{%ld,%d})", tsk->pid, tsk->real_cred, tsk->cred, kdebug("exit_creds(%u,%p,%p,{%ld})", tsk->pid, tsk->real_cred, tsk->cred,
atomic_long_read(&tsk->cred->usage), atomic_long_read(&tsk->cred->usage));
read_cred_subscribers(tsk->cred));
real_cred = (struct cred *) tsk->real_cred; real_cred = (struct cred *) tsk->real_cred;
tsk->real_cred = NULL; tsk->real_cred = NULL;
...@@ -174,15 +127,10 @@ void exit_creds(struct task_struct *tsk) ...@@ -174,15 +127,10 @@ void exit_creds(struct task_struct *tsk)
cred = (struct cred *) tsk->cred; cred = (struct cred *) tsk->cred;
tsk->cred = NULL; tsk->cred = NULL;
validate_creds(cred);
if (real_cred == cred) { if (real_cred == cred) {
alter_cred_subscribers(cred, -2);
put_cred_many(cred, 2); put_cred_many(cred, 2);
} else { } else {
validate_creds(real_cred);
alter_cred_subscribers(real_cred, -1);
put_cred(real_cred); put_cred(real_cred);
alter_cred_subscribers(cred, -1);
put_cred(cred); put_cred(cred);
} }
...@@ -231,9 +179,6 @@ struct cred *cred_alloc_blank(void) ...@@ -231,9 +179,6 @@ struct cred *cred_alloc_blank(void)
return NULL; return NULL;
atomic_long_set(&new->usage, 1); atomic_long_set(&new->usage, 1);
#ifdef CONFIG_DEBUG_CREDENTIALS
new->magic = CRED_MAGIC;
#endif
if (security_cred_alloc_blank(new, GFP_KERNEL_ACCOUNT) < 0) if (security_cred_alloc_blank(new, GFP_KERNEL_ACCOUNT) < 0)
goto error; goto error;
...@@ -264,8 +209,6 @@ struct cred *prepare_creds(void) ...@@ -264,8 +209,6 @@ struct cred *prepare_creds(void)
const struct cred *old; const struct cred *old;
struct cred *new; struct cred *new;
validate_process_creds();
new = kmem_cache_alloc(cred_jar, GFP_KERNEL); new = kmem_cache_alloc(cred_jar, GFP_KERNEL);
if (!new) if (!new)
return NULL; return NULL;
...@@ -277,7 +220,6 @@ struct cred *prepare_creds(void) ...@@ -277,7 +220,6 @@ struct cred *prepare_creds(void)
new->non_rcu = 0; new->non_rcu = 0;
atomic_long_set(&new->usage, 1); atomic_long_set(&new->usage, 1);
set_cred_subscribers(new, 0);
get_group_info(new->group_info); get_group_info(new->group_info);
get_uid(new->user); get_uid(new->user);
get_user_ns(new->user_ns); get_user_ns(new->user_ns);
...@@ -300,7 +242,6 @@ struct cred *prepare_creds(void) ...@@ -300,7 +242,6 @@ struct cred *prepare_creds(void)
if (security_prepare_creds(new, old, GFP_KERNEL_ACCOUNT) < 0) if (security_prepare_creds(new, old, GFP_KERNEL_ACCOUNT) < 0)
goto error; goto error;
validate_creds(new);
return new; return new;
error: error:
...@@ -362,10 +303,8 @@ int copy_creds(struct task_struct *p, unsigned long clone_flags) ...@@ -362,10 +303,8 @@ int copy_creds(struct task_struct *p, unsigned long clone_flags)
clone_flags & CLONE_THREAD clone_flags & CLONE_THREAD
) { ) {
p->real_cred = get_cred_many(p->cred, 2); p->real_cred = get_cred_many(p->cred, 2);
alter_cred_subscribers(p->cred, 2); kdebug("share_creds(%p{%ld})",
kdebug("share_creds(%p{%ld,%d})", p->cred, atomic_long_read(&p->cred->usage));
p->cred, atomic_long_read(&p->cred->usage),
read_cred_subscribers(p->cred));
inc_rlimit_ucounts(task_ucounts(p), UCOUNT_RLIMIT_NPROC, 1); inc_rlimit_ucounts(task_ucounts(p), UCOUNT_RLIMIT_NPROC, 1);
return 0; return 0;
} }
...@@ -404,8 +343,6 @@ int copy_creds(struct task_struct *p, unsigned long clone_flags) ...@@ -404,8 +343,6 @@ int copy_creds(struct task_struct *p, unsigned long clone_flags)
p->cred = p->real_cred = get_cred(new); p->cred = p->real_cred = get_cred(new);
inc_rlimit_ucounts(task_ucounts(p), UCOUNT_RLIMIT_NPROC, 1); inc_rlimit_ucounts(task_ucounts(p), UCOUNT_RLIMIT_NPROC, 1);
alter_cred_subscribers(new, 2);
validate_creds(new);
return 0; return 0;
error_put: error_put:
...@@ -457,16 +394,10 @@ int commit_creds(struct cred *new) ...@@ -457,16 +394,10 @@ int commit_creds(struct cred *new)
struct task_struct *task = current; struct task_struct *task = current;
const struct cred *old = task->real_cred; const struct cred *old = task->real_cred;
kdebug("commit_creds(%p{%ld,%d})", new, kdebug("commit_creds(%p{%ld})", new,
atomic_long_read(&new->usage), atomic_long_read(&new->usage));
read_cred_subscribers(new));
BUG_ON(task->cred != old); BUG_ON(task->cred != old);
#ifdef CONFIG_DEBUG_CREDENTIALS
BUG_ON(read_cred_subscribers(old) < 2);
validate_creds(old);
validate_creds(new);
#endif
BUG_ON(atomic_long_read(&new->usage) < 1); BUG_ON(atomic_long_read(&new->usage) < 1);
get_cred(new); /* we will require a ref for the subj creds too */ get_cred(new); /* we will require a ref for the subj creds too */
...@@ -502,14 +433,12 @@ int commit_creds(struct cred *new) ...@@ -502,14 +433,12 @@ int commit_creds(struct cred *new)
* RLIMIT_NPROC limits on user->processes have already been checked * RLIMIT_NPROC limits on user->processes have already been checked
* in set_user(). * in set_user().
*/ */
alter_cred_subscribers(new, 2);
if (new->user != old->user || new->user_ns != old->user_ns) if (new->user != old->user || new->user_ns != old->user_ns)
inc_rlimit_ucounts(new->ucounts, UCOUNT_RLIMIT_NPROC, 1); inc_rlimit_ucounts(new->ucounts, UCOUNT_RLIMIT_NPROC, 1);
rcu_assign_pointer(task->real_cred, new); rcu_assign_pointer(task->real_cred, new);
rcu_assign_pointer(task->cred, new); rcu_assign_pointer(task->cred, new);
if (new->user != old->user || new->user_ns != old->user_ns) if (new->user != old->user || new->user_ns != old->user_ns)
dec_rlimit_ucounts(old->ucounts, UCOUNT_RLIMIT_NPROC, 1); dec_rlimit_ucounts(old->ucounts, UCOUNT_RLIMIT_NPROC, 1);
alter_cred_subscribers(old, -2);
/* send notifications */ /* send notifications */
if (!uid_eq(new->uid, old->uid) || if (!uid_eq(new->uid, old->uid) ||
...@@ -539,13 +468,9 @@ EXPORT_SYMBOL(commit_creds); ...@@ -539,13 +468,9 @@ EXPORT_SYMBOL(commit_creds);
*/ */
void abort_creds(struct cred *new) void abort_creds(struct cred *new)
{ {
kdebug("abort_creds(%p{%ld,%d})", new, kdebug("abort_creds(%p{%ld})", new,
atomic_long_read(&new->usage), atomic_long_read(&new->usage));
read_cred_subscribers(new));
#ifdef CONFIG_DEBUG_CREDENTIALS
BUG_ON(read_cred_subscribers(new) != 0);
#endif
BUG_ON(atomic_long_read(&new->usage) < 1); BUG_ON(atomic_long_read(&new->usage) < 1);
put_cred(new); put_cred(new);
} }
...@@ -562,12 +487,8 @@ const struct cred *override_creds(const struct cred *new) ...@@ -562,12 +487,8 @@ const struct cred *override_creds(const struct cred *new)
{ {
const struct cred *old = current->cred; const struct cred *old = current->cred;
kdebug("override_creds(%p{%ld,%d})", new, kdebug("override_creds(%p{%ld})", new,
atomic_long_read(&new->usage), atomic_long_read(&new->usage));
read_cred_subscribers(new));
validate_creds(old);
validate_creds(new);
/* /*
* NOTE! This uses 'get_new_cred()' rather than 'get_cred()'. * NOTE! This uses 'get_new_cred()' rather than 'get_cred()'.
...@@ -576,18 +497,12 @@ const struct cred *override_creds(const struct cred *new) ...@@ -576,18 +497,12 @@ const struct cred *override_creds(const struct cred *new)
* we are only installing the cred into the thread-synchronous * we are only installing the cred into the thread-synchronous
* '->cred' pointer, not the '->real_cred' pointer that is * '->cred' pointer, not the '->real_cred' pointer that is
* visible to other threads under RCU. * visible to other threads under RCU.
*
* Also note that we did validate_creds() manually, not depending
* on the validation in 'get_cred()'.
*/ */
get_new_cred((struct cred *)new); get_new_cred((struct cred *)new);
alter_cred_subscribers(new, 1);
rcu_assign_pointer(current->cred, new); rcu_assign_pointer(current->cred, new);
alter_cred_subscribers(old, -1);
kdebug("override_creds() = %p{%ld,%d}", old, kdebug("override_creds() = %p{%ld}", old,
atomic_long_read(&old->usage), atomic_long_read(&old->usage));
read_cred_subscribers(old));
return old; return old;
} }
EXPORT_SYMBOL(override_creds); EXPORT_SYMBOL(override_creds);
...@@ -603,15 +518,10 @@ void revert_creds(const struct cred *old) ...@@ -603,15 +518,10 @@ void revert_creds(const struct cred *old)
{ {
const struct cred *override = current->cred; const struct cred *override = current->cred;
kdebug("revert_creds(%p{%ld,%d})", old, kdebug("revert_creds(%p{%ld})", old,
atomic_long_read(&old->usage), atomic_long_read(&old->usage));
read_cred_subscribers(old));
validate_creds(old);
validate_creds(override);
alter_cred_subscribers(old, 1);
rcu_assign_pointer(current->cred, old); rcu_assign_pointer(current->cred, old);
alter_cred_subscribers(override, -1);
put_cred(override); put_cred(override);
} }
EXPORT_SYMBOL(revert_creds); EXPORT_SYMBOL(revert_creds);
...@@ -731,12 +641,10 @@ struct cred *prepare_kernel_cred(struct task_struct *daemon) ...@@ -731,12 +641,10 @@ struct cred *prepare_kernel_cred(struct task_struct *daemon)
kdebug("prepare_kernel_cred() alloc %p", new); kdebug("prepare_kernel_cred() alloc %p", new);
old = get_task_cred(daemon); old = get_task_cred(daemon);
validate_creds(old);
*new = *old; *new = *old;
new->non_rcu = 0; new->non_rcu = 0;
atomic_long_set(&new->usage, 1); atomic_long_set(&new->usage, 1);
set_cred_subscribers(new, 0);
get_uid(new->user); get_uid(new->user);
get_user_ns(new->user_ns); get_user_ns(new->user_ns);
get_group_info(new->group_info); get_group_info(new->group_info);
...@@ -760,7 +668,6 @@ struct cred *prepare_kernel_cred(struct task_struct *daemon) ...@@ -760,7 +668,6 @@ struct cred *prepare_kernel_cred(struct task_struct *daemon)
goto error; goto error;
put_cred(old); put_cred(old);
validate_creds(new);
return new; return new;
error: error:
...@@ -825,109 +732,3 @@ int set_create_files_as(struct cred *new, struct inode *inode) ...@@ -825,109 +732,3 @@ int set_create_files_as(struct cred *new, struct inode *inode)
return security_kernel_create_files_as(new, inode); return security_kernel_create_files_as(new, inode);
} }
EXPORT_SYMBOL(set_create_files_as); EXPORT_SYMBOL(set_create_files_as);
#ifdef CONFIG_DEBUG_CREDENTIALS
bool creds_are_invalid(const struct cred *cred)
{
if (cred->magic != CRED_MAGIC)
return true;
return false;
}
EXPORT_SYMBOL(creds_are_invalid);
/*
* dump invalid credentials
*/
static void dump_invalid_creds(const struct cred *cred, const char *label,
const struct task_struct *tsk)
{
pr_err("%s credentials: %p %s%s%s\n",
label, cred,
cred == &init_cred ? "[init]" : "",
cred == tsk->real_cred ? "[real]" : "",
cred == tsk->cred ? "[eff]" : "");
pr_err("->magic=%x, put_addr=%p\n",
cred->magic, cred->put_addr);
pr_err("->usage=%ld, subscr=%d\n",
atomic_long_read(&cred->usage),
read_cred_subscribers(cred));
pr_err("->*uid = { %d,%d,%d,%d }\n",
from_kuid_munged(&init_user_ns, cred->uid),
from_kuid_munged(&init_user_ns, cred->euid),
from_kuid_munged(&init_user_ns, cred->suid),
from_kuid_munged(&init_user_ns, cred->fsuid));
pr_err("->*gid = { %d,%d,%d,%d }\n",
from_kgid_munged(&init_user_ns, cred->gid),
from_kgid_munged(&init_user_ns, cred->egid),
from_kgid_munged(&init_user_ns, cred->sgid),
from_kgid_munged(&init_user_ns, cred->fsgid));
#ifdef CONFIG_SECURITY
pr_err("->security is %p\n", cred->security);
if ((unsigned long) cred->security >= PAGE_SIZE &&
(((unsigned long) cred->security & 0xffffff00) !=
(POISON_FREE << 24 | POISON_FREE << 16 | POISON_FREE << 8)))
pr_err("->security {%x, %x}\n",
((u32*)cred->security)[0],
((u32*)cred->security)[1]);
#endif
}
/*
* report use of invalid credentials
*/
void __noreturn __invalid_creds(const struct cred *cred, const char *file, unsigned line)
{
pr_err("Invalid credentials\n");
pr_err("At %s:%u\n", file, line);
dump_invalid_creds(cred, "Specified", current);
BUG();
}
EXPORT_SYMBOL(__invalid_creds);
/*
* check the credentials on a process
*/
void __validate_process_creds(struct task_struct *tsk,
const char *file, unsigned line)
{
if (tsk->cred == tsk->real_cred) {
if (unlikely(read_cred_subscribers(tsk->cred) < 2 ||
creds_are_invalid(tsk->cred)))
goto invalid_creds;
} else {
if (unlikely(read_cred_subscribers(tsk->real_cred) < 1 ||
read_cred_subscribers(tsk->cred) < 1 ||
creds_are_invalid(tsk->real_cred) ||
creds_are_invalid(tsk->cred)))
goto invalid_creds;
}
return;
invalid_creds:
pr_err("Invalid process credentials\n");
pr_err("At %s:%u\n", file, line);
dump_invalid_creds(tsk->real_cred, "Real", tsk);
if (tsk->cred != tsk->real_cred)
dump_invalid_creds(tsk->cred, "Effective", tsk);
else
pr_err("Effective creds == Real creds\n");
BUG();
}
EXPORT_SYMBOL(__validate_process_creds);
/*
* check creds for do_exit()
*/
void validate_creds_for_do_exit(struct task_struct *tsk)
{
kdebug("validate_creds_for_do_exit(%p,%p{%ld,%d})",
tsk->real_cred, tsk->cred,
atomic_long_read(&tsk->cred->usage),
read_cred_subscribers(tsk->cred));
__validate_process_creds(tsk, __FILE__, __LINE__);
}
#endif /* CONFIG_DEBUG_CREDENTIALS */
...@@ -824,8 +824,6 @@ void __noreturn do_exit(long code) ...@@ -824,8 +824,6 @@ void __noreturn do_exit(long code)
ptrace_event(PTRACE_EVENT_EXIT, code); ptrace_event(PTRACE_EVENT_EXIT, code);
user_events_exit(tsk); user_events_exit(tsk);
validate_creds_for_do_exit(tsk);
io_uring_files_cancel(); io_uring_files_cancel();
exit_signals(tsk); /* sets PF_EXITING */ exit_signals(tsk); /* sets PF_EXITING */
...@@ -909,7 +907,6 @@ void __noreturn do_exit(long code) ...@@ -909,7 +907,6 @@ void __noreturn do_exit(long code)
if (tsk->task_frag.page) if (tsk->task_frag.page)
put_page(tsk->task_frag.page); put_page(tsk->task_frag.page);
validate_creds_for_do_exit(tsk);
exit_task_stack_account(tsk); exit_task_stack_account(tsk);
check_stack_usage(); check_stack_usage();
......
...@@ -1739,21 +1739,6 @@ config DEBUG_MAPLE_TREE ...@@ -1739,21 +1739,6 @@ config DEBUG_MAPLE_TREE
endmenu endmenu
config DEBUG_CREDENTIALS
bool "Debug credential management"
depends on DEBUG_KERNEL
help
Enable this to turn on some debug checking for credential
management. The additional code keeps track of the number of
pointers from task_structs to any given cred struct, and checks to
see that this number never exceeds the usage count of the cred
struct.
Furthermore, if SELinux is enabled, this also checks that the
security pointer in the cred struct is never seen to be invalid.
If unsure, say N.
source "kernel/rcu/Kconfig.debug" source "kernel/rcu/Kconfig.debug"
config DEBUG_WQ_FORCE_RR_CPU config DEBUG_WQ_FORCE_RR_CPU
......
...@@ -40,9 +40,6 @@ static unsigned long number_cred_unused; ...@@ -40,9 +40,6 @@ static unsigned long number_cred_unused;
static struct cred machine_cred = { static struct cred machine_cred = {
.usage = ATOMIC_INIT(1), .usage = ATOMIC_INIT(1),
#ifdef CONFIG_DEBUG_CREDENTIALS
.magic = CRED_MAGIC,
#endif
}; };
/* /*
......
...@@ -1660,8 +1660,6 @@ static int inode_has_perm(const struct cred *cred, ...@@ -1660,8 +1660,6 @@ static int inode_has_perm(const struct cred *cred,
struct inode_security_struct *isec; struct inode_security_struct *isec;
u32 sid; u32 sid;
validate_creds(cred);
if (unlikely(IS_PRIVATE(inode))) if (unlikely(IS_PRIVATE(inode)))
return 0; return 0;
...@@ -3056,8 +3054,6 @@ static int selinux_inode_follow_link(struct dentry *dentry, struct inode *inode, ...@@ -3056,8 +3054,6 @@ static int selinux_inode_follow_link(struct dentry *dentry, struct inode *inode,
struct inode_security_struct *isec; struct inode_security_struct *isec;
u32 sid; u32 sid;
validate_creds(cred);
ad.type = LSM_AUDIT_DATA_DENTRY; ad.type = LSM_AUDIT_DATA_DENTRY;
ad.u.dentry = dentry; ad.u.dentry = dentry;
sid = cred_sid(cred); sid = cred_sid(cred);
...@@ -3101,8 +3097,6 @@ static int selinux_inode_permission(struct inode *inode, int mask) ...@@ -3101,8 +3097,6 @@ static int selinux_inode_permission(struct inode *inode, int mask)
if (!mask) if (!mask)
return 0; return 0;
validate_creds(cred);
if (unlikely(IS_PRIVATE(inode))) if (unlikely(IS_PRIVATE(inode)))
return 0; return 0;
......
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
* *
* Yes, this is unfortunate. A better solution is in the works. * Yes, this is unfortunate. A better solution is in the works.
*/ */
NORETURN(__invalid_creds)
NORETURN(__kunit_abort) NORETURN(__kunit_abort)
NORETURN(__module_put_and_kthread_exit) NORETURN(__module_put_and_kthread_exit)
NORETURN(__reiserfs_panic) NORETURN(__reiserfs_panic)
......
...@@ -50,7 +50,6 @@ CONFIG_CRYPTO_SEQIV=y ...@@ -50,7 +50,6 @@ CONFIG_CRYPTO_SEQIV=y
CONFIG_CRYPTO_XXHASH=y CONFIG_CRYPTO_XXHASH=y
CONFIG_DCB=y CONFIG_DCB=y
CONFIG_DEBUG_ATOMIC_SLEEP=y CONFIG_DEBUG_ATOMIC_SLEEP=y
CONFIG_DEBUG_CREDENTIALS=y
CONFIG_DEBUG_INFO_BTF=y CONFIG_DEBUG_INFO_BTF=y
CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y
CONFIG_DEBUG_MEMORY_INIT=y CONFIG_DEBUG_MEMORY_INIT=y
......
...@@ -46,7 +46,6 @@ CONFIG_CRYPTO_SEQIV=y ...@@ -46,7 +46,6 @@ CONFIG_CRYPTO_SEQIV=y
CONFIG_CRYPTO_XXHASH=y CONFIG_CRYPTO_XXHASH=y
CONFIG_DCB=y CONFIG_DCB=y
CONFIG_DEBUG_ATOMIC_SLEEP=y CONFIG_DEBUG_ATOMIC_SLEEP=y
CONFIG_DEBUG_CREDENTIALS=y
CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y
CONFIG_DEBUG_MEMORY_INIT=y CONFIG_DEBUG_MEMORY_INIT=y
CONFIG_DEFAULT_FQ_CODEL=y CONFIG_DEFAULT_FQ_CODEL=y
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment