Eric Biggers
dda70d28c0
KEYS: prevent KEYCTL_READ on negative key
commit 37863c43b2c6464f252862bf2e9768264e961678 upstream.
Because keyctl_read_key() looks up the key with no permissions
requested, it may find a negatively instantiated key. If the key is
also possessed, we went ahead and called ->read() on the key. But the
key payload will actually contain the ->reject_error rather than the
normal payload. Thus, the kernel oopses trying to read the
user_key_payload from memory address (int)-ENOKEY = 0x00000000ffffff82.
Fortunately the payload data is stored inline, so it shouldn't be
possible to abuse this as an arbitrary memory read primitive...
Reproducer:
keyctl new_session
keyctl request2 user desc '' @s
keyctl read $(keyctl show | awk '/user: desc/ {print $1}')
It causes a crash like the following:
BUG: unable to handle kernel paging request at 00000000ffffff92
IP: user_read+0x33/0xa0
PGD 36a54067 P4D 36a54067 PUD 0
Oops: 0000 [#1] SMP
CPU: 0 PID: 211 Comm: keyctl Not tainted 4.14.0-rc1 #337
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-20170228_101828-anatol 04/01/2014
task: ffff90aa3b74c3c0 task.stack: ffff9878c0478000
RIP: 0010:user_read+0x33/0xa0
RSP: 0018:ffff9878c047bee8 EFLAGS: 00010246
RAX: 0000000000000001 RBX: ffff90aa3d7da340 RCX: 0000000000000017
RDX: 0000000000000000 RSI: 00000000ffffff82 RDI: ffff90aa3d7da340
RBP: ffff9878c047bf00 R08: 00000024f95da94f R09: 0000000000000000
R10: 0000000000000001 R11: 0000000000000000 R12: 0000000000000000
R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
FS: 00007f58ece69740(0000) GS:ffff90aa3e200000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00000000ffffff92 CR3: 0000000036adc001 CR4: 00000000003606f0
Call Trace:
keyctl_read_key+0xac/0xe0
SyS_keyctl+0x99/0x120
entry_SYSCALL_64_fastpath+0x1f/0xbe
RIP: 0033:0x7f58ec787bb9
RSP: 002b:00007ffc8d401678 EFLAGS: 00000206 ORIG_RAX: 00000000000000fa
RAX: ffffffffffffffda RBX: 00007ffc8d402800 RCX: 00007f58ec787bb9
RDX: 0000000000000000 RSI: 00000000174a63ac RDI: 000000000000000b
RBP: 0000000000000004 R08: 00007ffc8d402809 R09: 0000000000000020
R10: 0000000000000000 R11: 0000000000000206 R12: 00007ffc8d402800
R13: 00007ffc8d4016e0 R14: 0000000000000000 R15: 0000000000000000
Code: e5 41 55 49 89 f5 41 54 49 89 d4 53 48 89 fb e8 a4 b4 ad ff 85 c0 74 09 80 3d b9 4c 96 00 00 74 43 48 8b b3 20 01 00 00 4d 85 ed <0f> b7 5e 10 74 29 4d 85 e4 74 24 4c 39 e3 4c 89 e2 4c 89 ef 48
RIP: user_read+0x33/0xa0 RSP: ffff9878c047bee8
CR2: 00000000ffffff92
Fixes: 61ea0c0ba9 ("KEYS: Skip key state checks when checking for possession")
Signed-off-by: Eric Biggers <ebiggers@google.com>
Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
2017-10-05 09:44:00 +02:00 |
| .. |
|
encrypted-keys
|
KEYS: Fix an error code in request_master_key()
|
2017-07-12 15:01:06 +02:00 |
|
big_key.c
|
security/keys: rewrite all of big_key crypto
|
2017-10-05 09:44:00 +02:00 |
|
compat.c
|
KEYS: Add placeholder for KDF usage with DH
|
2016-06-03 16:14:34 +10:00 |
|
dh.c
|
KEYS: Add placeholder for KDF usage with DH
|
2016-06-03 16:14:34 +10:00 |
|
gc.c
|
KEYS: Change the name of the dead type to ".dead" to prevent user access
|
2017-04-27 09:10:37 +02:00 |
|
internal.h
|
KEYS: prevent creating a different user's keyrings
|
2017-10-05 09:44:00 +02:00 |
|
Kconfig
|
security/keys: rewrite all of big_key crypto
|
2017-10-05 09:44:00 +02:00 |
|
key.c
|
KEYS: prevent creating a different user's keyrings
|
2017-10-05 09:44:00 +02:00 |
|
keyctl.c
|
KEYS: prevent KEYCTL_READ on negative key
|
2017-10-05 09:44:00 +02:00 |
|
keyring.c
|
KEYS: prevent creating a different user's keyrings
|
2017-10-05 09:44:00 +02:00 |
|
Makefile
|
KEYS: Add KEYCTL_DH_COMPUTE command
|
2016-04-12 19:54:58 +01:00 |
|
permission.c
|
KEYS: Move the flags representing required permission to linux/key.h
|
2014-03-14 17:44:49 +00:00 |
|
persistent.c
|
KEYS: Strip trailing spaces
|
2016-06-14 10:29:44 +01:00 |
|
proc.c
|
KEYS: Fix short sprintf buffer in /proc/keys show function
|
2016-10-27 16:03:24 +11:00 |
|
process_keys.c
|
KEYS: prevent creating a different user's keyrings
|
2017-10-05 09:44:00 +02:00 |
|
request_key.c
|
KEYS: Strip trailing spaces
|
2016-06-14 10:29:44 +01:00 |
|
request_key_auth.c
|
KEYS: Add a facility to restrict new links into a keyring
|
2016-04-11 22:37:37 +01:00 |
|
sysctl.c
|
security: Convert use of typedef ctl_table to struct ctl_table
|
2014-04-15 13:39:58 +10:00 |
|
trusted.c
|
tpm: fix checks for policy digest existence in tpm2_seal_trusted()
|
2016-02-10 04:10:55 +02:00 |
|
trusted.h
|
keys, trusted: move struct trusted_key_options to trusted-type.h
|
2015-10-19 01:01:21 +02:00 |
|
user_defined.c
|
KEYS: user_update should use copy of payload made during preparsing
|
2016-04-12 19:54:58 +01:00 |