PROBLEM: null-ptr deref in keyring_search_aux may lead to denial of service

[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

 



<resend as plain-text>

Hi David,

While working on some legacy kernel I found a null-ptr deref in
keyring_search_aux. Further test shows that it also affects some long-term
kernel branches so I think it still needs to be fixed. It has been verified
on 3.2.86.

Description
===========
Some of the key types (?dead? for example) registered in key_init does not
have match func-ptr assigned. By calling request_key, null-ptr deref may
happen and cause kernel oops like this:

[  193.478718] Unable to handle kernel NULL pointer dereference at virtual
address 00000000
[  193.479382] pgd = eed40000
[  193.479655] [00000000] *pgd=8f19b831, *pte=00000000, *ppte=00000000
[  193.480568] Internal error: Oops: 80000017 [#1] PREEMPT SMP
[  193.482722] last sysfs file: 
[  193.483358] CPU: 3    Not tainted  (2.6.39+ #9)
[  193.483983] PC is at 0x0
[  193.484658] LR is at keyring_search_aux+0x194/0x360
[  193.485396] pc : [<00000000>]    lr : [<c02358c8>]    psr: 80090013
[  193.485454] sp : eed55e50  ip : eed55f18  fp : 00000029
[  193.486537] r10: ef3f8a00  r9 : ef3f8a14  r8 : c0645c68
[  193.486988] r7 : 00000000  r6 : 00000001  r5 : c0645c9c  r4 : ef397080
[  193.487553] r3 : 00000000  r2 : 0000021f  r1 : ef3f8ac0  r0 : ef397080
[  193.488261] Flags: Nzcv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment
user
[  193.488913] Control: 10c53c7d  Table: 8ed4006a  DAC: 00000015
[  193.489431] Process syz-executor0 (pid: 813, stack limit = 0xeed542f0)
[  193.490130] Stack: (0xeed55e50 to 0xeed56000)
[  193.492151] 5e40:                                     ef3f8ac0 58b908bd
00000001 ef90e480
[  193.493341] 5e60: fffffff5 c00b5ab0 58b908bd 3b023382 ef3f8b00 c0ce8f00
00000b00 00000040
[  193.494543] 5e80: 00000000 c00cc100 ef3f8aa8 0000005a 00000018 c00b0440
c0f22b90 ef3f8a80
[  193.495854] 5ea0: 0000001f ef90e480 ef90e480 ef397000 c0645c68 ef3f8ac0
00000000 00000000
[  193.496990] 5ec0: 00000000 c0238db0 00000000 c0ce8f00 c0f22b90 ef3f8a80
ef90e480 c0645c68
[  193.497901] 5ee0: ef3f8ac0 00000000 eed54000 00000000 00000000 c0238f74
ef3f8a80 c0645c68
[  193.498827] 5f00: ef3f8ac0 ef3f8a80 00000000 eed54000 00000000 c0239ef4
00000000 00000001
[  193.499553] 5f20: ffffffff 00000004 00000001 c026ca14 c0645c68 c0645dbc
c0645c48 ef3f8a80
[  193.500264] 5f40: 00000000 ef397000 ef3f8ac0 c0645c68 eed54000 00000000
00000000 c0236dd0
[  193.501844] 5f60: 00000000 ef397000 00000000 c02341d4 64616564 c0237100
ffffffff ffffffea
[  193.503696] 5f80: 00000008 00000000 00000000 00000000 00000000 00000000
00000000 00000136
[  193.505693] 5fa0: c003d464 c003d2e0 00000000 00000000 a0759ffb a098a000
a01cf000 ffffffff
[  193.507524] 5fc0: 00000000 00000000 00000000 00000136 a01cf000 ffffffff
00000000 00000000
[  193.508451] 5fe0: 4003aa98 4003aa88 00010d87 000308b2 20090030 a0759ffb
00000000 00000000
[  193.510308] [<c02358c8>] (keyring_search_aux+0x194/0x360) from
[<c0238db0>] (search_my_process_keyrings+0x44/0x1dc)
[  193.512714] [<c0238db0>] (search_my_process_keyrings+0x44/0x1dc) from
[<c0238f74>] (search_process_keyrings+0x2c/0x130)
[  193.513916] [<c0238f74>] (search_process_keyrings+0x2c/0x130) from
[<c0239ef4>] (request_key_and_link+0x40/0x4f8)
[  193.515152] [<c0239ef4>] (request_key_and_link+0x40/0x4f8) from
[<c0236dd0>] (sys_request_key+0xf8/0x194)
[  193.516576] [<c0236dd0>] (sys_request_key+0xf8/0x194) from [<c003d2e0>]
(ret_fast_syscall+0x0/0x30)
[  193.517298] Code: bad PC value

Repro
=====
#include <unistd.h>
#include <sys/syscall.h>

int main()
{
     for (;;) {
           syscall(__NR_request_key, "dead", "abc", "abc", 0, 0, 0);
     }

     return 0;
}

Patch
=====
commit b0b24f7e699894403d352ff69d07d808fef522a5
Author: idl3r <idler1984@xxxxxxxxx>
Date:   Fri Mar 3 15:16:00 2017 +0800

    keyring: fix null-ptr deref in keyring_search_aux

diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index cdd2f3f..4250e48 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -318,6 +318,11 @@ key_ref_t keyring_search_aux(key_ref_t keyring_ref,
        long err;
        int sp, kix;

+       if (!match) {
+               key_ref = ERR_PTR(-EINVAL);
+               goto error;
+       }
+
        keyring = key_ref_to_ptr(keyring_ref);
        possessed = is_key_possessed(keyring_ref);
        key_check(keyring);


I?m not sure if ?EINVAL is the proper err to return, the patch is for your
reference only.

Best Regards,
James

--
To unsubscribe from this list: send the line "unsubscribe keyrings" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html





[Index of Archives]     [Linux Kernel Discussion]     [Linux Crypto]     [The Year; 2038 Problem]     [Ethernet Bridging]     [Linux Wireless Networking]     [Linux WPAN Networking]     [Linux Bluetooth Networking]     [Linux ATH6KL Networking]     [Linux Networking Users]     [Linux Coverity]     [VLAN]     [Git]     [IETF Annouce]     [Linux Assembly]     [Security]     [Bugtraq]     [Yosemite Information]     [MIPS Linux]     [ARM Linux Kernel]     [ARM Linux]     [Linux Virtualization]     [Linux IDE]     [Linux RAID]     [Linux SCSI]

  Powered by Linux