ima: Add modsig appraise_type option for module-style appended signatures

Introduce the modsig keyword to the IMA policy syntax to specify that
a given hook should expect the file to have the IMA signature appended
to it. Here is how it can be used in a rule:

appraise func=KEXEC_KERNEL_CHECK appraise_type=imasig|modsig

With this rule, IMA will accept either a signature stored in the extended
attribute or an appended signature.

For now, the rule above will behave exactly the same as if
appraise_type=imasig was specified. The actual modsig implementation
will be introduced separately.

Suggested-by: Mimi Zohar <zohar@linux.ibm.com>
Signed-off-by: Thiago Jung Bauermann <bauerman@linux.ibm.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
This commit is contained in:
Thiago Jung Bauermann 2019-06-27 23:19:28 -03:00 committed by Mimi Zohar
parent cf38fed1e1
commit 9044d627fd
7 changed files with 67 additions and 3 deletions

View File

@ -37,7 +37,7 @@ Description:
euid:= decimal value euid:= decimal value
fowner:= decimal value fowner:= decimal value
lsm: are LSM specific lsm: are LSM specific
option: appraise_type:= [imasig] option: appraise_type:= [imasig] [imasig|modsig]
template:= name of a defined IMA template type template:= name of a defined IMA template type
(eg, ima-ng). Only valid when action is "measure". (eg, ima-ng). Only valid when action is "measure".
pcr:= decimal value pcr:= decimal value
@ -105,3 +105,7 @@ Description:
measure func=KEXEC_KERNEL_CHECK pcr=4 measure func=KEXEC_KERNEL_CHECK pcr=4
measure func=KEXEC_INITRAMFS_CHECK pcr=5 measure func=KEXEC_INITRAMFS_CHECK pcr=5
Example of appraise rule allowing modsig appended signatures:
appraise func=KEXEC_KERNEL_CHECK appraise_type=imasig|modsig

View File

@ -233,6 +233,16 @@ config IMA_APPRAISE_BOOTPARAM
This option enables the different "ima_appraise=" modes This option enables the different "ima_appraise=" modes
(eg. fix, log) from the boot command line. (eg. fix, log) from the boot command line.
config IMA_APPRAISE_MODSIG
bool "Support module-style signatures for appraisal"
depends on IMA_APPRAISE
default n
help
Adds support for signatures appended to files. The format of the
appended signature is the same used for signed kernel modules.
The modsig keyword can be used in the IMA policy to allow a hook
to accept such signatures.
config IMA_TRUSTED_KEYRING config IMA_TRUSTED_KEYRING
bool "Require all keys on the .ima keyring be signed (deprecated)" bool "Require all keys on the .ima keyring be signed (deprecated)"
depends on IMA_APPRAISE && SYSTEM_TRUSTED_KEYRING depends on IMA_APPRAISE && SYSTEM_TRUSTED_KEYRING

View File

@ -9,5 +9,6 @@ obj-$(CONFIG_IMA) += ima.o
ima-y := ima_fs.o ima_queue.o ima_init.o ima_main.o ima_crypto.o ima_api.o \ ima-y := ima_fs.o ima_queue.o ima_init.o ima_main.o ima_crypto.o ima_api.o \
ima_policy.o ima_template.o ima_template_lib.o ima_policy.o ima_template.o ima_template_lib.o
ima-$(CONFIG_IMA_APPRAISE) += ima_appraise.o ima-$(CONFIG_IMA_APPRAISE) += ima_appraise.o
ima-$(CONFIG_IMA_APPRAISE_MODSIG) += ima_modsig.o
ima-$(CONFIG_HAVE_IMA_KEXEC) += ima_kexec.o ima-$(CONFIG_HAVE_IMA_KEXEC) += ima_kexec.o
obj-$(CONFIG_IMA_BLACKLIST_KEYRING) += ima_mok.o obj-$(CONFIG_IMA_BLACKLIST_KEYRING) += ima_mok.o

View File

@ -302,6 +302,15 @@ static inline int ima_read_xattr(struct dentry *dentry,
#endif /* CONFIG_IMA_APPRAISE */ #endif /* CONFIG_IMA_APPRAISE */
#ifdef CONFIG_IMA_APPRAISE_MODSIG
bool ima_hook_supports_modsig(enum ima_hooks func);
#else
static inline bool ima_hook_supports_modsig(enum ima_hooks func)
{
return false;
}
#endif /* CONFIG_IMA_APPRAISE_MODSIG */
/* LSM based policy rules require audit */ /* LSM based policy rules require audit */
#ifdef CONFIG_IMA_LSM_RULES #ifdef CONFIG_IMA_LSM_RULES

View File

@ -0,0 +1,31 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* IMA support for appraising module-style appended signatures.
*
* Copyright (C) 2019 IBM Corporation
*
* Author:
* Thiago Jung Bauermann <bauerman@linux.ibm.com>
*/
#include "ima.h"
/**
* ima_hook_supports_modsig - can the policy allow modsig for this hook?
*
* modsig is only supported by hooks using ima_post_read_file(), because only
* they preload the contents of the file in a buffer. FILE_CHECK does that in
* some cases, but not when reached from vfs_open(). POLICY_CHECK can support
* it, but it's not useful in practice because it's a text file so deny.
*/
bool ima_hook_supports_modsig(enum ima_hooks func)
{
switch (func) {
case KEXEC_KERNEL_CHECK:
case KEXEC_INITRAMFS_CHECK:
case MODULE_CHECK:
return true;
default:
return false;
}
}

View File

@ -1130,6 +1130,10 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
ima_log_string(ab, "appraise_type", args[0].from); ima_log_string(ab, "appraise_type", args[0].from);
if ((strcmp(args[0].from, "imasig")) == 0) if ((strcmp(args[0].from, "imasig")) == 0)
entry->flags |= IMA_DIGSIG_REQUIRED; entry->flags |= IMA_DIGSIG_REQUIRED;
else if (ima_hook_supports_modsig(entry->func) &&
strcmp(args[0].from, "imasig|modsig") == 0)
entry->flags |= IMA_DIGSIG_REQUIRED |
IMA_MODSIG_ALLOWED;
else else
result = -EINVAL; result = -EINVAL;
break; break;
@ -1449,8 +1453,12 @@ int ima_policy_show(struct seq_file *m, void *v)
} }
if (entry->template) if (entry->template)
seq_printf(m, "template=%s ", entry->template->name); seq_printf(m, "template=%s ", entry->template->name);
if (entry->flags & IMA_DIGSIG_REQUIRED) if (entry->flags & IMA_DIGSIG_REQUIRED) {
seq_puts(m, "appraise_type=imasig "); if (entry->flags & IMA_MODSIG_ALLOWED)
seq_puts(m, "appraise_type=imasig|modsig ");
else
seq_puts(m, "appraise_type=imasig ");
}
if (entry->flags & IMA_PERMIT_DIRECTIO) if (entry->flags & IMA_PERMIT_DIRECTIO)
seq_puts(m, "permit_directio "); seq_puts(m, "permit_directio ");
rcu_read_unlock(); rcu_read_unlock();

View File

@ -31,6 +31,7 @@
#define IMA_NEW_FILE 0x04000000 #define IMA_NEW_FILE 0x04000000
#define EVM_IMMUTABLE_DIGSIG 0x08000000 #define EVM_IMMUTABLE_DIGSIG 0x08000000
#define IMA_FAIL_UNVERIFIABLE_SIGS 0x10000000 #define IMA_FAIL_UNVERIFIABLE_SIGS 0x10000000
#define IMA_MODSIG_ALLOWED 0x20000000
#define IMA_DO_MASK (IMA_MEASURE | IMA_APPRAISE | IMA_AUDIT | \ #define IMA_DO_MASK (IMA_MEASURE | IMA_APPRAISE | IMA_AUDIT | \
IMA_HASH | IMA_APPRAISE_SUBMASK) IMA_HASH | IMA_APPRAISE_SUBMASK)