linux-integrity.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Mimi Zohar <zohar@linux.ibm.com>
To: Nayna Jain <nayna@linux.ibm.com>,
	linuxppc-dev@ozlabs.org, linux-efi@vger.kernel.org,
	linux-integrity@vger.kernel.org
Cc: linux-kernel@vger.kernel.org,
	Michael Ellerman <mpe@ellerman.id.au>,
	Benjamin Herrenschmidt <benh@kernel.crashing.org>,
	Paul Mackerras <paulus@samba.org>,
	Ard Biesheuvel <ard.biesheuvel@linaro.org>,
	Jeremy Kerr <jk@ozlabs.org>,
	Matthew Garret <matthew.garret@nebula.com>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Claudio Carvalho <cclaudio@linux.ibm.com>,
	George Wilson <gcwilson@linux.ibm.com>,
	Elaine Palmer <erpalmer@us.ibm.com>,
	Eric Ricther <erichte@linux.ibm.com>,
	"Oliver O'Halloran" <oohall@gmail.com>
Subject: Re: [PATCH v7 7/8] ima: check against blacklisted hashes for files with modsig
Date: Fri, 11 Oct 2019 09:19:55 -0400	[thread overview]
Message-ID: <1570799995.5250.81.camel@linux.ibm.com> (raw)
In-Reply-To: <1570497267-13672-8-git-send-email-nayna@linux.ibm.com>

On Mon, 2019-10-07 at 21:14 -0400, Nayna Jain wrote:
> Asymmetric private keys are used to sign multiple files. The kernel
> currently support checking against the blacklisted keys. However, if the
> public key is blacklisted, any file signed by the blacklisted key will
> automatically fail signature verification. We might not want to blacklist
> all the files signed by a particular key, but just a single file.
> Blacklisting the public key is not fine enough granularity.
> 
> This patch adds support for blacklisting binaries with appended signatures,
> based on the IMA policy.  Defined is a new policy option
> "appraise_flag=check_blacklist".

The blacklisted hash is not the same as the file hash, but is the file
hash without the appended signature.  Are there tools for calculating
the blacklisted hash?  Can you provide an example?

> 
> Signed-off-by: Nayna Jain <nayna@linux.ibm.com>
> ---
>  Documentation/ABI/testing/ima_policy  |  1 +
>  security/integrity/ima/ima.h          |  9 +++++++
>  security/integrity/ima/ima_appraise.c | 39 +++++++++++++++++++++++++++
>  security/integrity/ima/ima_main.c     | 12 ++++++---
>  security/integrity/ima/ima_policy.c   | 10 +++++--
>  security/integrity/integrity.h        |  1 +
>  6 files changed, 66 insertions(+), 6 deletions(-)
> 
> diff --git a/Documentation/ABI/testing/ima_policy b/Documentation/ABI/testing/ima_policy
> index 29ebe9afdac4..4c97afcc0f3c 100644
> --- a/Documentation/ABI/testing/ima_policy
> +++ b/Documentation/ABI/testing/ima_policy
> @@ -25,6 +25,7 @@ Description:
>  			lsm:	[[subj_user=] [subj_role=] [subj_type=]
>  				 [obj_user=] [obj_role=] [obj_type=]]
>  			option:	[[appraise_type=]] [template=] [permit_directio]
> +				[appraise_flag=[check_blacklist]]
>  		base: 	func:= [BPRM_CHECK][MMAP_CHECK][CREDS_CHECK][FILE_CHECK][MODULE_CHECK]
>  				[FIRMWARE_CHECK]
>  				[KEXEC_KERNEL_CHECK] [KEXEC_INITRAMFS_CHECK]
> diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
> index ed86c1f70d7f..63e20ccc91ce 100644
> --- a/security/integrity/ima/ima.h
> +++ b/security/integrity/ima/ima.h
> @@ -256,6 +256,8 @@ int ima_policy_show(struct seq_file *m, void *v);
>  #define IMA_APPRAISE_KEXEC	0x40
>  
>  #ifdef CONFIG_IMA_APPRAISE
> +int ima_check_blacklist(struct integrity_iint_cache *iint,
> +			const struct modsig *modsig, int action, int pcr);
>  int ima_appraise_measurement(enum ima_hooks func,
>  			     struct integrity_iint_cache *iint,
>  			     struct file *file, const unsigned char *filename,
> @@ -271,6 +273,13 @@ int ima_read_xattr(struct dentry *dentry,
>  		   struct evm_ima_xattr_data **xattr_value);
>  
>  #else
> +static inline int ima_check_blacklist(struct integrity_iint_cache *iint,
> +				      const struct modsig *modsig, int action,
> +				      int pcr)
> +{
> +	return 0;
> +}
> +
>  static inline int ima_appraise_measurement(enum ima_hooks func,
>  					   struct integrity_iint_cache *iint,
>  					   struct file *file,
> diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c
> index 136ae4e0ee92..fe34d64a684c 100644
> --- a/security/integrity/ima/ima_appraise.c
> +++ b/security/integrity/ima/ima_appraise.c
> @@ -12,6 +12,7 @@
>  #include <linux/magic.h>
>  #include <linux/ima.h>
>  #include <linux/evm.h>
> +#include <keys/system_keyring.h>
>  
>  #include "ima.h"
>  
> @@ -303,6 +304,44 @@ static int modsig_verify(enum ima_hooks func, const struct modsig *modsig,
>  	return rc;
>  }
>  
> +/*
> + * ima_blacklist_measurement - Checks whether the binary is blacklisted. If
> + * yes, then adds the hash of the blacklisted binary to the measurement list.
> + *
> + * Returns -EPERM if the hash is blacklisted.
> + */
> +int ima_check_blacklist(struct integrity_iint_cache *iint,
> +			const struct modsig *modsig, int action, int pcr)
> +{
> +	enum hash_algo hash_algo;
> +	const u8 *digest = NULL;
> +	u32 digestsize = 0;
> +	u32 secid;
> +	int rc = 0;
> +	struct ima_template_desc *template_desc;
> +
> +	template_desc = lookup_template_desc("ima-buf");
> +	template_desc_init_fields(template_desc->fmt, &(template_desc->fields),
> +				  &(template_desc->num_fields));

Before using template_desc, make sure that template_desc isn't NULL.
 For completeness, check the return code of
template_desc_init_fields()

> +
> +	if (!(iint->flags & IMA_CHECK_BLACKLIST))
> +		return 0;

Move this check before getting the template_desc and make sure that
modsig isn't NULL.

> +
> +	if (iint->flags & IMA_MODSIG_ALLOWED) {
> +		security_task_getsecid(current, &secid);

secid isn't being used.

> +		ima_get_modsig_digest(modsig, &hash_algo, &digest, &digestsize);
> +		rc = is_binary_blacklisted(digest, digestsize);
> +
> +		/* Returns -EPERM on blacklisted hash found */

Now that it is returning a sane errno, the comment isn't needed.

Mimi

> +		if ((rc == -EPERM) && (iint->flags & IMA_MEASURE))
> +			process_buffer_measurement(digest, digestsize,
> +						   "blacklisted-hash", pcr,
> +						   template_desc);
> +	}
> +
> +	return rc;
> +}
> +
>  /*
>   * ima_appraise_measurement - appraise file measurement
>   *
> diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
> index 77115e884496..40d30ab17cbe 100644
> --- a/security/integrity/ima/ima_main.c
> +++ b/security/integrity/ima/ima_main.c
> @@ -335,10 +335,14 @@ static int process_measurement(struct file *file, const struct cred *cred,
>  				      xattr_value, xattr_len, modsig, pcr,
>  				      template_desc);
>  	if (rc == 0 && (action & IMA_APPRAISE_SUBMASK)) {
> -		inode_lock(inode);
> -		rc = ima_appraise_measurement(func, iint, file, pathname,
> -					      xattr_value, xattr_len, modsig);
> -		inode_unlock(inode);
> +		rc = ima_check_blacklist(iint, modsig, action, pcr);
> +		if (rc != -EPERM) {
> +			inode_lock(inode);
> +			rc = ima_appraise_measurement(func, iint, file,
> +						      pathname, xattr_value,
> +						      xattr_len, modsig);
> +			inode_unlock(inode);
> +		}
>  		if (!rc)
>  			rc = mmap_violation_check(func, file, &pathbuf,
>  						  &pathname, filename);
> diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
> index 5380aca2b351..bfaae7a8443a 100644
> --- a/security/integrity/ima/ima_policy.c
> +++ b/security/integrity/ima/ima_policy.c
> @@ -765,8 +765,8 @@ enum {
>  	Opt_fsuuid, Opt_uid_eq, Opt_euid_eq, Opt_fowner_eq,
>  	Opt_uid_gt, Opt_euid_gt, Opt_fowner_gt,
>  	Opt_uid_lt, Opt_euid_lt, Opt_fowner_lt,
> -	Opt_appraise_type, Opt_permit_directio,
> -	Opt_pcr, Opt_template, Opt_err
> +	Opt_appraise_type, Opt_appraise_flag,
> +	Opt_permit_directio, Opt_pcr, Opt_template, Opt_err
>  };
>  
>  static const match_table_t policy_tokens = {
> @@ -798,6 +798,7 @@ static const match_table_t policy_tokens = {
>  	{Opt_euid_lt, "euid<%s"},
>  	{Opt_fowner_lt, "fowner<%s"},
>  	{Opt_appraise_type, "appraise_type=%s"},
> +	{Opt_appraise_flag, "appraise_flag=%s"},
>  	{Opt_permit_directio, "permit_directio"},
>  	{Opt_pcr, "pcr=%s"},
>  	{Opt_template, "template=%s"},
> @@ -1172,6 +1173,11 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
>  			else
>  				result = -EINVAL;
>  			break;
> +		case Opt_appraise_flag:
> +			ima_log_string(ab, "appraise_flag", args[0].from);
> +			if (strstr(args[0].from, "blacklist"))
> +				entry->flags |= IMA_CHECK_BLACKLIST;
> +			break;
>  		case Opt_permit_directio:
>  			entry->flags |= IMA_PERMIT_DIRECTIO;
>  			break;
> diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h
> index d9323d31a3a8..73fc286834d7 100644
> --- a/security/integrity/integrity.h
> +++ b/security/integrity/integrity.h
> @@ -32,6 +32,7 @@
>  #define EVM_IMMUTABLE_DIGSIG	0x08000000
>  #define IMA_FAIL_UNVERIFIABLE_SIGS	0x10000000
>  #define IMA_MODSIG_ALLOWED	0x20000000
> +#define IMA_CHECK_BLACKLIST	0x40000000
>  
>  #define IMA_DO_MASK		(IMA_MEASURE | IMA_APPRAISE | IMA_AUDIT | \
>  				 IMA_HASH | IMA_APPRAISE_SUBMASK)


  reply	other threads:[~2019-10-11 13:20 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-10-08  1:14 [PATCH v7 0/8] powerpc: Enabling IMA arch specific secure boot policies Nayna Jain
2019-10-08  1:14 ` [PATCH v7 1/8] powerpc: detect the secure boot mode of the system Nayna Jain
2019-10-15 11:30   ` Michael Ellerman
2019-10-08  1:14 ` [PATCH v7 2/8] powerpc: add support to initialize ima policy rules Nayna Jain
2019-10-11 13:12   ` Mimi Zohar
2019-10-15  9:59     ` Michael Ellerman
2019-10-15 11:29   ` Michael Ellerman
2019-10-17 12:58     ` Nayna
2019-10-08  1:14 ` [PATCH v7 3/8] powerpc: detect the trusted boot state of the system Nayna Jain
2019-10-15 10:23   ` Michael Ellerman
2019-10-08  1:14 ` [PATCH v7 4/8] powerpc/ima: add measurement rules to ima arch specific policy Nayna Jain
2019-10-15 11:29   ` Michael Ellerman
2019-10-19 18:27     ` Nayna
2019-10-08  1:14 ` [PATCH v7 5/8] ima: make process_buffer_measurement() generic Nayna Jain
2019-10-11 13:14   ` Mimi Zohar
2019-10-08  1:14 ` [PATCH v7 6/8] certs: add wrapper function to check blacklisted binary hash Nayna Jain
2019-10-11 13:18   ` Mimi Zohar
2019-10-08  1:14 ` [PATCH v7 7/8] ima: check against blacklisted hashes for files with modsig Nayna Jain
2019-10-11 13:19   ` Mimi Zohar [this message]
2019-10-19 18:30     ` Nayna
2019-10-08  1:14 ` [PATCH v7 8/8] powerpc/ima: update ima arch policy to check for blacklist Nayna Jain
2019-10-11 13:19   ` Mimi Zohar

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1570799995.5250.81.camel@linux.ibm.com \
    --to=zohar@linux.ibm.com \
    --cc=ard.biesheuvel@linaro.org \
    --cc=benh@kernel.crashing.org \
    --cc=cclaudio@linux.ibm.com \
    --cc=erichte@linux.ibm.com \
    --cc=erpalmer@us.ibm.com \
    --cc=gcwilson@linux.ibm.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=jk@ozlabs.org \
    --cc=linux-efi@vger.kernel.org \
    --cc=linux-integrity@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linuxppc-dev@ozlabs.org \
    --cc=matthew.garret@nebula.com \
    --cc=mpe@ellerman.id.au \
    --cc=nayna@linux.ibm.com \
    --cc=oohall@gmail.com \
    --cc=paulus@samba.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).