Skip to content

Commit d33edec

Browse files
Tetsuo HandaKali-
Tetsuo Handa
authored andcommitted
CRED: Fix BUG() upon security_cred_alloc_blank() failure
commit 2edeaa34a6e3f2c43b667f6c4f7b27944b811695 upstream. In cred_alloc_blank() since 2.6.32, abort_creds(new) is called with new->security == NULL and new->magic == 0 when security_cred_alloc_blank() returns an error. As a result, BUG() will be triggered if SELinux is enabled or CONFIG_DEBUG_CREDENTIALS=y. If CONFIG_DEBUG_CREDENTIALS=y, BUG() is called from __invalid_creds() because cred->magic == 0. Failing that, BUG() is called from selinux_cred_free() because selinux_cred_free() is not expecting cred->security == NULL. This does not affect smack_cred_free(), tomoyo_cred_free() or apparmor_cred_free(). Fix these bugs by (1) Set new->magic before calling security_cred_alloc_blank(). (2) Handle null cred->security in creds_are_invalid() and selinux_cred_free(). Signed-off-by: Tetsuo Handa <[email protected]> Signed-off-by: David Howells <[email protected]> Signed-off-by: Linus Torvalds <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]> Signed-off-by: Andi Kleen <[email protected]>
1 parent 87a3ba7 commit d33edec

File tree

2 files changed

+13
-5
lines changed

2 files changed

+13
-5
lines changed

kernel/cred.c

+8-4
Original file line numberDiff line numberDiff line change
@@ -256,13 +256,13 @@ struct cred *cred_alloc_blank(void)
256256
#endif
257257

258258
atomic_set(&new->usage, 1);
259+
#ifdef CONFIG_DEBUG_CREDENTIALS
260+
new->magic = CRED_MAGIC;
261+
#endif
259262

260263
if (security_cred_alloc_blank(new, GFP_KERNEL) < 0)
261264
goto error;
262265

263-
#ifdef CONFIG_DEBUG_CREDENTIALS
264-
new->magic = CRED_MAGIC;
265-
#endif
266266
return new;
267267

268268
error:
@@ -754,7 +754,11 @@ bool creds_are_invalid(const struct cred *cred)
754754
if (cred->magic != CRED_MAGIC)
755755
return true;
756756
#ifdef CONFIG_SECURITY_SELINUX
757-
if (selinux_is_enabled()) {
757+
/*
758+
* cred->security == NULL if security_cred_alloc_blank() or
759+
* security_prepare_creds() returned an error.
760+
*/
761+
if (selinux_is_enabled() && cred->security) {
758762
if ((unsigned long) cred->security < PAGE_SIZE)
759763
return true;
760764
if ((*(u32 *)cred->security & 0xffffff00) ==

security/selinux/hooks.c

+5-1
Original file line numberDiff line numberDiff line change
@@ -3234,7 +3234,11 @@ static void selinux_cred_free(struct cred *cred)
32343234
{
32353235
struct task_security_struct *tsec = cred->security;
32363236

3237-
BUG_ON((unsigned long) cred->security < PAGE_SIZE);
3237+
/*
3238+
* cred->security == NULL if security_cred_alloc_blank() or
3239+
* security_prepare_creds() returned an error.
3240+
*/
3241+
BUG_ON(cred->security && (unsigned long) cred->security < PAGE_SIZE);
32383242
cred->security = (void *) 0x7UL;
32393243
kfree(tsec);
32403244
}

0 commit comments

Comments
 (0)