diff options
author | David Howells <dhowells@redhat.com> | 2011-06-21 09:32:05 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-06-21 21:31:45 -0400 |
commit | b1d7dd80aadb9042e83f9778b484a2f92e0b04d4 (patch) | |
tree | 33044314f0a058724e9ee912cca6fe55c2284cf1 /security | |
parent | 35052cffe0081904f3362c05818db900dd9dc7de (diff) |
KEYS: Fix error handling in construct_key_and_link()
Fix error handling in construct_key_and_link().
If construct_alloc_key() returns an error, it shouldn't pass out through
the normal path as the key_serial() called by the kleave() statement
will oops when it gets an error code in the pointer:
BUG: unable to handle kernel paging request at ffffffffffffff84
IP: [<ffffffff8120b401>] request_key_and_link+0x4d7/0x52f
..
Call Trace:
[<ffffffff8120b52c>] request_key+0x41/0x75
[<ffffffffa00ed6e8>] cifs_get_spnego_key+0x206/0x226 [cifs]
[<ffffffffa00eb0c9>] CIFS_SessSetup+0x511/0x1234 [cifs]
[<ffffffffa00d9799>] cifs_setup_session+0x90/0x1ae [cifs]
[<ffffffffa00d9c02>] cifs_get_smb_ses+0x34b/0x40f [cifs]
[<ffffffffa00d9e05>] cifs_mount+0x13f/0x504 [cifs]
[<ffffffffa00caabb>] cifs_do_mount+0xc4/0x672 [cifs]
[<ffffffff8113ae8c>] mount_fs+0x69/0x155
[<ffffffff8114ff0e>] vfs_kern_mount+0x63/0xa0
[<ffffffff81150be2>] do_kern_mount+0x4d/0xdf
[<ffffffff81152278>] do_mount+0x63c/0x69f
[<ffffffff8115255c>] sys_mount+0x88/0xc2
[<ffffffff814fbdc2>] system_call_fastpath+0x16/0x1b
Signed-off-by: David Howells <dhowells@redhat.com>
Acked-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'security')
-rw-r--r-- | security/keys/request_key.c | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/security/keys/request_key.c b/security/keys/request_key.c index 8e319a416eec..82465328c39b 100644 --- a/security/keys/request_key.c +++ b/security/keys/request_key.c | |||
@@ -469,7 +469,7 @@ static struct key *construct_key_and_link(struct key_type *type, | |||
469 | } else if (ret == -EINPROGRESS) { | 469 | } else if (ret == -EINPROGRESS) { |
470 | ret = 0; | 470 | ret = 0; |
471 | } else { | 471 | } else { |
472 | key = ERR_PTR(ret); | 472 | goto couldnt_alloc_key; |
473 | } | 473 | } |
474 | 474 | ||
475 | key_put(dest_keyring); | 475 | key_put(dest_keyring); |
@@ -479,6 +479,7 @@ static struct key *construct_key_and_link(struct key_type *type, | |||
479 | construction_failed: | 479 | construction_failed: |
480 | key_negate_and_link(key, key_negative_timeout, NULL, NULL); | 480 | key_negate_and_link(key, key_negative_timeout, NULL, NULL); |
481 | key_put(key); | 481 | key_put(key); |
482 | couldnt_alloc_key: | ||
482 | key_put(dest_keyring); | 483 | key_put(dest_keyring); |
483 | kleave(" = %d", ret); | 484 | kleave(" = %d", ret); |
484 | return ERR_PTR(ret); | 485 | return ERR_PTR(ret); |