diff mbox

ima: Avoid using not initialized IMA

Message ID 20180316232827.3791-1-pvorel@suse.cz (mailing list archive)
State New, archived
Headers show

Commit Message

Petr Vorel March 16, 2018, 11:28 p.m. UTC
IMA requires have it's hash algorithm to be compiled-in due it's early
use. Default IMA algorithm is protected by Kconfig to be compiled-in.

ima_hash kernel parameter allows to choose hash algorithm. When
specified algorithm not available or available as module, IMA
initialization fails, but mknodat syscall expect it and calls
ima_post_path_mknod(). This leads to to kernel oops:

$ grep CONFIG_CRYPTO_MD4 .config
CONFIG_CRYPTO_MD4=m

[    0.000000] Command line: BOOT_IMAGE=/boot/vmlinuz-4.12.14-2.3-default root=UUID=74ae8202-9ca7-4e39-813b-22287ec52f7a video=1024x768-16 plymouth.ignore-serial-consoles console=ttyS0 console=tty resume=/dev/disk/by-path/pci-0000:00:07.0-part3 splash=silent showopts ima_hash=md4
...
[    1.545190] ima: Can not allocate md4 (reason: -2)
...
[    2.610120] BUG: unable to handle kernel NULL pointer dereference at           (null)
[    2.611903] IP: ima_match_policy+0x23/0x390
[    2.612967] PGD 0 P4D 0
[    2.613080] Oops: 0000 [#1] SMP
[    2.613080] Modules linked in: autofs4
[    2.613080] Supported: Yes
[    2.613080] CPU: 0 PID: 1 Comm: systemd Not tainted 4.12.14-2.3-default #1
[    2.613080] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.0.0-prebuilt.qemu-project.org 04/01/2014
[    2.613080] task: ffff88003e2d0040 task.stack: ffffc90000190000
[    2.613080] RIP: 0010:ima_match_policy+0x23/0x390
[    2.613080] RSP: 0018:ffffc90000193e88 EFLAGS: 00010296
[    2.613080] RAX: 0000000000000000 RBX: 000000000000000c RCX: 0000000000000004
[    2.613080] RDX: 0000000000000010 RSI: 0000000000000001 RDI: ffff880037071728
[    2.613080] RBP: 0000000000008000 R08: 0000000000000000 R09: 0000000000000000
[    2.613080] R10: 0000000000000008 R11: 61c8864680b583eb R12: 00005580ff10086f
[    2.613080] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000008000
[    2.613080] FS:  00007f5c1da08940(0000) GS:ffff88003fc00000(0000) knlGS:0000000000000000
[    2.613080] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[    2.613080] CR2: 0000000000000000 CR3: 0000000037002000 CR4: 00000000003406f0
[    2.613080] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[    2.613080] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
[    2.613080] Call Trace:
[    2.613080]  ? shmem_mknod+0xbf/0xd0
[    2.613080]  ima_post_path_mknod+0x1c/0x40
[    2.613080]  SyS_mknod+0x210/0x220
[    2.613080]  entry_SYSCALL_64_fastpath+0x1a/0xa5
[    2.613080] RIP: 0033:0x7f5c1bfde570
[    2.613080] RSP: 002b:00007ffde1c90dc8 EFLAGS: 00000246 ORIG_RAX: 0000000000000085
[    2.613080] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f5c1bfde570
[    2.613080] RDX: 0000000000000000 RSI: 0000000000008000 RDI: 00005580ff10086f
[    2.613080] RBP: 00007ffde1c91040 R08: 00005580ff10086f R09: 0000000000000000
[    2.613080] R10: 0000000000104000 R11: 0000000000000246 R12: 00005580ffb99660
[    2.613080] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000002
[    2.613080] Code: 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 41 57 41 56 44 8d 14 09 41 55 41 54 55 53 44 89 d3 09 cb 48 83 ec 38 48 8b 05 c5 03 29 01 <4c> 8b 20 4c 39 e0 0f 84 d7 01 00 00 4c 89 44 24 08 89 54 24 20
[    2.613080] RIP: ima_match_policy+0x23/0x390 RSP: ffffc90000193e88
[    2.613080] CR2: 0000000000000000
[    2.613080] ---[ end trace 9a9f0a8a73079f6a ]---
[    2.673052] Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000009
[    2.673052]
[    2.675337] Kernel Offset: disabled
[    2.676405] ---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000009

Signed-off-by: Petr Vorel <pvorel@suse.cz>
---
 security/integrity/ima/ima_main.c | 3 +++
 1 file changed, 3 insertions(+)

--
2.12.3

Comments

Mimi Zohar March 18, 2018, 1:27 a.m. UTC | #1
On Sat, 2018-03-17 at 00:28 +0100, Petr Vorel wrote:
> IMA requires have it's hash algorithm to be compiled-in due it's early
> use. Default IMA algorithm is protected by Kconfig to be compiled-in.
> 
> ima_hash kernel parameter allows to choose hash algorithm. When
> specified algorithm not available or available as module, IMA
> initialization fails, but mknodat syscall expect it and calls
> ima_post_path_mknod(). This leads to to kernel oops:
> 
> $ grep CONFIG_CRYPTO_MD4 .config
> CONFIG_CRYPTO_MD4=m
> 
> [    0.000000] Command line: BOOT_IMAGE=/boot/vmlinuz-4.12.14-2.3-default root=UUID=74ae8202-9ca7-4e39-813b-22287ec52f7a video=1024x768-16 plymouth.ignore-serial-consoles console=ttyS0 console=tty resume=/dev/disk/by-path/pci-0000:00:07.0-part3 splash=silent showopts ima_hash=md4
> ...
> [    1.545190] ima: Can not allocate md4 (reason: -2)

The hash algorithm specified on the boot command line needs to be
builtin.  For whatever reason it isn't builtin, rather than skipping
measurements, a better solution I think would be to fallback to the
builtin hash algorithm.

Mimi

> ...
> [    2.610120] BUG: unable to handle kernel NULL pointer dereference at           (null)
> [    2.611903] IP: ima_match_policy+0x23/0x390
> [    2.612967] PGD 0 P4D 0
> [    2.613080] Oops: 0000 [#1] SMP
> [    2.613080] Modules linked in: autofs4
> [    2.613080] Supported: Yes
> [    2.613080] CPU: 0 PID: 1 Comm: systemd Not tainted 4.12.14-2.3-default #1
> [    2.613080] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.0.0-prebuilt.qemu-project.org 04/01/2014
> [    2.613080] task: ffff88003e2d0040 task.stack: ffffc90000190000
> [    2.613080] RIP: 0010:ima_match_policy+0x23/0x390
> [    2.613080] RSP: 0018:ffffc90000193e88 EFLAGS: 00010296
> [    2.613080] RAX: 0000000000000000 RBX: 000000000000000c RCX: 0000000000000004
> [    2.613080] RDX: 0000000000000010 RSI: 0000000000000001 RDI: ffff880037071728
> [    2.613080] RBP: 0000000000008000 R08: 0000000000000000 R09: 0000000000000000
> [    2.613080] R10: 0000000000000008 R11: 61c8864680b583eb R12: 00005580ff10086f
> [    2.613080] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000008000
> [    2.613080] FS:  00007f5c1da08940(0000) GS:ffff88003fc00000(0000) knlGS:0000000000000000
> [    2.613080] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> [    2.613080] CR2: 0000000000000000 CR3: 0000000037002000 CR4: 00000000003406f0
> [    2.613080] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
> [    2.613080] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
> [    2.613080] Call Trace:
> [    2.613080]  ? shmem_mknod+0xbf/0xd0
> [    2.613080]  ima_post_path_mknod+0x1c/0x40
> [    2.613080]  SyS_mknod+0x210/0x220
> [    2.613080]  entry_SYSCALL_64_fastpath+0x1a/0xa5
> [    2.613080] RIP: 0033:0x7f5c1bfde570
> [    2.613080] RSP: 002b:00007ffde1c90dc8 EFLAGS: 00000246 ORIG_RAX: 0000000000000085
> [    2.613080] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f5c1bfde570
> [    2.613080] RDX: 0000000000000000 RSI: 0000000000008000 RDI: 00005580ff10086f
> [    2.613080] RBP: 00007ffde1c91040 R08: 00005580ff10086f R09: 0000000000000000
> [    2.613080] R10: 0000000000104000 R11: 0000000000000246 R12: 00005580ffb99660
> [    2.613080] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000002
> [    2.613080] Code: 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 41 57 41 56 44 8d 14 09 41 55 41 54 55 53 44 89 d3 09 cb 48 83 ec 38 48 8b 05 c5 03 29 01 <4c> 8b 20 4c 39 e0 0f 84 d7 01 00 00 4c 89 44 24 08 89 54 24 20
> [    2.613080] RIP: ima_match_policy+0x23/0x390 RSP: ffffc90000193e88
> [    2.613080] CR2: 0000000000000000
> [    2.613080] ---[ end trace 9a9f0a8a73079f6a ]---
> [    2.673052] Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000009
> [    2.673052]
> [    2.675337] Kernel Offset: disabled
> [    2.676405] ---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000009
> 
> Signed-off-by: Petr Vorel <pvorel@suse.cz>
> ---
>  security/integrity/ima/ima_main.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
> index 2cfb0c714967..503366805554 100644
> --- a/security/integrity/ima/ima_main.c
> +++ b/security/integrity/ima/ima_main.c
> @@ -380,6 +380,9 @@ void ima_post_path_mknod(struct dentry *dentry)
>  	struct inode *inode = dentry->d_inode;
>  	int must_appraise;
> 
> +	if (!ima_initialized)
> +		return;
> +
>  	must_appraise = ima_must_appraise(inode, MAY_ACCESS, FILE_CHECK);
>  	if (!must_appraise)
>  		return;
> --
> 2.12.3
>
James Morris March 19, 2018, 4:43 a.m. UTC | #2
On Sat, 17 Mar 2018, Mimi Zohar wrote:

> On Sat, 2018-03-17 at 00:28 +0100, Petr Vorel wrote:
> > IMA requires have it's hash algorithm to be compiled-in due it's early
> > use. Default IMA algorithm is protected by Kconfig to be compiled-in.
> > 
> > ima_hash kernel parameter allows to choose hash algorithm. When
> > specified algorithm not available or available as module, IMA
> > initialization fails, but mknodat syscall expect it and calls
> > ima_post_path_mknod(). This leads to to kernel oops:
> > 
> > $ grep CONFIG_CRYPTO_MD4 .config
> > CONFIG_CRYPTO_MD4=m
> > 
> > [    0.000000] Command line: BOOT_IMAGE=/boot/vmlinuz-4.12.14-2.3-default root=UUID=74ae8202-9ca7-4e39-813b-22287ec52f7a video=1024x768-16 plymouth.ignore-serial-consoles console=ttyS0 console=tty resume=/dev/disk/by-path/pci-0000:00:07.0-part3 splash=silent showopts ima_hash=md4
> > ...
> > [    1.545190] ima: Can not allocate md4 (reason: -2)
> 
> The hash algorithm specified on the boot command line needs to be
> builtin.  For whatever reason it isn't builtin, rather than skipping
> measurements, a better solution I think would be to fallback to the
> builtin hash algorithm.

What if this falls back to a hash which is not secure enough?
Mimi Zohar March 19, 2018, 10:59 a.m. UTC | #3
On Mon, 2018-03-19 at 15:43 +1100, James Morris wrote:
> On Sat, 17 Mar 2018, Mimi Zohar wrote:
> 
> > On Sat, 2018-03-17 at 00:28 +0100, Petr Vorel wrote:
> > > IMA requires have it's hash algorithm to be compiled-in due it's early
> > > use. Default IMA algorithm is protected by Kconfig to be compiled-in.
> > > 
> > > ima_hash kernel parameter allows to choose hash algorithm. When
> > > specified algorithm not available or available as module, IMA
> > > initialization fails, but mknodat syscall expect it and calls
> > > ima_post_path_mknod(). This leads to to kernel oops:
> > > 
> > > $ grep CONFIG_CRYPTO_MD4 .config
> > > CONFIG_CRYPTO_MD4=m
> > > 
> > > [    0.000000] Command line: BOOT_IMAGE=/boot/vmlinuz-4.12.14-2.3-default root=UUID=74ae8202-9ca7-4e39-813b-22287ec52f7a video=1024x768-16 plymouth.ignore-serial-consoles console=ttyS0 console=tty resume=/dev/disk/by-path/pci-0000:00:07.0-part3 splash=silent showopts ima_hash=md4
> > > ...
> > > [    1.545190] ima: Can not allocate md4 (reason: -2)
> > 
> > The hash algorithm specified on the boot command line needs to be
> > builtin.  For whatever reason it isn't builtin, rather than skipping
> > measurements, a better solution I think would be to fallback to the
> > builtin hash algorithm.
> 
> What if this falls back to a hash which is not secure enough?

It should fallback to the Kconfig selected hash algorithm as defined
in CONFIG_IMA_DEFAULT_HASH.

Mimi
Petr Vorel March 19, 2018, 8:05 p.m. UTC | #4
Hi Mimi,

> On Mon, 2018-03-19 at 15:43 +1100, James Morris wrote:
> > On Sat, 17 Mar 2018, Mimi Zohar wrote:

> > > On Sat, 2018-03-17 at 00:28 +0100, Petr Vorel wrote:
> > > > IMA requires have it's hash algorithm to be compiled-in due it's early
> > > > use. Default IMA algorithm is protected by Kconfig to be compiled-in.

> > > > ima_hash kernel parameter allows to choose hash algorithm. When
> > > > specified algorithm not available or available as module, IMA
> > > > initialization fails, but mknodat syscall expect it and calls
> > > > ima_post_path_mknod(). This leads to to kernel oops:

> > > > $ grep CONFIG_CRYPTO_MD4 .config
> > > > CONFIG_CRYPTO_MD4=m

> > > > [    0.000000] Command line: BOOT_IMAGE=/boot/vmlinuz-4.12.14-2.3-default root=UUID=74ae8202-9ca7-4e39-813b-22287ec52f7a video=1024x768-16 plymouth.ignore-serial-consoles console=ttyS0 console=tty resume=/dev/disk/by-path/pci-0000:00:07.0-part3 splash=silent showopts ima_hash=md4
> > > > ...
> > > > [    1.545190] ima: Can not allocate md4 (reason: -2)

> > > The hash algorithm specified on the boot command line needs to be
> > > builtin.  For whatever reason it isn't builtin, rather than skipping
> > > measurements, a better solution I think would be to fallback to the
> > > builtin hash algorithm.

> > What if this falls back to a hash which is not secure enough?

> It should fallback to the Kconfig selected hash algorithm as defined
> in CONFIG_IMA_DEFAULT_HASH.

OK, I have v2 which use CONFIG_IMA_DEFAULT_HASH, I'll post it tomorrow.
But I'd also keep this patch as well, this check doesn't harm and IMHO you can never be
sure it does not fail.

> Mimi

Kind regards,
Petr
Mimi Zohar March 19, 2018, 8:20 p.m. UTC | #5
On Mon, 2018-03-19 at 21:05 +0100, Petr Vorel wrote:
> Hi Mimi,
> 
> > On Mon, 2018-03-19 at 15:43 +1100, James Morris wrote:
> > > On Sat, 17 Mar 2018, Mimi Zohar wrote:
> 
> > > > On Sat, 2018-03-17 at 00:28 +0100, Petr Vorel wrote:
> > > > > IMA requires have it's hash algorithm to be compiled-in due it's early
> > > > > use. Default IMA algorithm is protected by Kconfig to be compiled-in.
> 
> > > > > ima_hash kernel parameter allows to choose hash algorithm. When
> > > > > specified algorithm not available or available as module, IMA
> > > > > initialization fails, but mknodat syscall expect it and calls
> > > > > ima_post_path_mknod(). This leads to to kernel oops:
> 
> > > > > $ grep CONFIG_CRYPTO_MD4 .config
> > > > > CONFIG_CRYPTO_MD4=m
> 
> > > > > [    0.000000] Command line: BOOT_IMAGE=/boot/vmlinuz-4.12.14-2.3-default root=UUID=74ae8202-9ca7-4e39-813b-22287ec52f7a video=1024x768-16 plymouth.ignore-serial-consoles console=ttyS0 console=tty resume=/dev/disk/by-path/pci-0000:00:07.0-part3 splash=silent showopts ima_hash=md4
> > > > > ...
> > > > > [    1.545190] ima: Can not allocate md4 (reason: -2)
> 
> > > > The hash algorithm specified on the boot command line needs to be
> > > > builtin.  For whatever reason it isn't builtin, rather than skipping
> > > > measurements, a better solution I think would be to fallback to the
> > > > builtin hash algorithm.
> 
> > > What if this falls back to a hash which is not secure enough?
> 
> > It should fallback to the Kconfig selected hash algorithm as defined
> > in CONFIG_IMA_DEFAULT_HASH.
> 
> OK, I have v2 which use CONFIG_IMA_DEFAULT_HASH, I'll post it tomorrow.
> But I'd also keep this patch as well, this check doesn't harm and IMHO you can never be
> sure it does not fail.

Adding a new measurement gap is not an acceptable solution.  Either an
ima_init() failure causes the kernel to panic, or we force IMA to use
the default builtin Kconfig hash algorithm.

Mimi
Petr Vorel March 20, 2018, 8:40 a.m. UTC | #6
Hi Mimi,

> > OK, I have v2 which use CONFIG_IMA_DEFAULT_HASH, I'll post it tomorrow.
> > But I'd also keep this patch as well, this check doesn't harm and IMHO you can never be
> > sure it does not fail.

> Adding a new measurement gap is not an acceptable solution.  Either an
> ima_init() failure causes the kernel to panic, or we force IMA to use
> the default builtin Kconfig hash algorithm.

Thank you for a clarification. I posted new patch which forces using default hash in case
of error and using different algorithm.

I don't know whether even this (third) attempt (to use default hash) can fail, but in case
it can, how do you prefer to handle this situation? If you really prefer kernel panic
(e.g. don't like previous patch fixing at least ima_post_path_mknod()), I suggest removing
ima_initialized as it's unused and confusing.

> Mimi


Kind regards,
Petr
diff mbox

Patch

diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index 2cfb0c714967..503366805554 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -380,6 +380,9 @@  void ima_post_path_mknod(struct dentry *dentry)
 	struct inode *inode = dentry->d_inode;
 	int must_appraise;

+	if (!ima_initialized)
+		return;
+
 	must_appraise = ima_must_appraise(inode, MAY_ACCESS, FILE_CHECK);
 	if (!must_appraise)
 		return;