From: Mimi Zohar <zohar@linux.ibm.com>
To: Matthew Garrett <matthewgarrett@google.com>,
linux-integrity@vger.kernel.org
Cc: dmitry.kasatkin@gmail.com, linux-fsdevel@vger.kernel.org,
miklos@szeredi.hu, Matthew Garrett <mjg59@google.com>
Subject: Re: [PATCH V2 3/4] IMA: Optionally make use of filesystem-provided hashes
Date: Thu, 28 Feb 2019 11:03:54 -0500 [thread overview]
Message-ID: <1551369834.10911.195.camel@linux.ibm.com> (raw)
In-Reply-To: <20190226215034.68772-4-matthewgarrett@google.com>
On Tue, 2019-02-26 at 13:50 -0800, Matthew Garrett wrote:
> From: Matthew Garrett <mjg59@google.com>
>
> Some filesystems may be able to provide hashes in an out of band manner,
> and allowing them to do so is a performance win. This is especially true
> of FUSE-based filesystems where otherwise we recalculate the hash on
> every measurement.
To be more correct, please limit this statement to trusted mounted
fuse filesystem.
> Make use of this if policy says we should, but provide
> a parameter to force recalculation rather than trusting the filesystem.
>
> Signed-off-by: Matthew Garrett <mjg59@google.com>
> ---
> Documentation/ABI/testing/ima_policy | 5 +++-
> .../admin-guide/kernel-parameters.txt | 5 ++++
> security/integrity/ima/ima.h | 3 ++-
> security/integrity/ima/ima_api.c | 5 +++-
> security/integrity/ima/ima_crypto.c | 23 ++++++++++++++++++-
> security/integrity/ima/ima_policy.c | 8 ++++++-
> security/integrity/ima/ima_template_lib.c | 2 +-
> security/integrity/integrity.h | 1 +
> 8 files changed, 46 insertions(+), 6 deletions(-)
>
> diff --git a/Documentation/ABI/testing/ima_policy b/Documentation/ABI/testing/ima_policy
> index 09a5def7e28a..6a517282068d 100644
> --- a/Documentation/ABI/testing/ima_policy
> +++ b/Documentation/ABI/testing/ima_policy
> @@ -24,7 +24,8 @@ Description:
> [euid=] [fowner=] [fsname=] [subtype=]]
> lsm: [[subj_user=] [subj_role=] [subj_type=]
> [obj_user=] [obj_role=] [obj_type=]]
> - option: [[appraise_type=]] [permit_directio]
> + option: [[appraise_type=] [permit_directio]
> + [trust_vfs]]
Let's generalize "trust_vfs" a bit. How about introducing
"collect_type=", with the default being reading and calculating the
file hash?
>
> base: func:= [BPRM_CHECK][MMAP_CHECK][CREDS_CHECK][FILE_CHECK][MODULE_CHECK]
> [FIRMWARE_CHECK]
> @@ -41,6 +42,8 @@ Description:
> lsm: are LSM specific
> option: appraise_type:= [imasig]
> pcr:= decimal value
> + permit_directio:= allow directio accesses
> + trust_vfs:= trust VFS-provided hash values
>
> default policy:
> # PROC_SUPER_MAGIC
> diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
> index 858b6c0b9a15..d3054a67e700 100644
> --- a/Documentation/admin-guide/kernel-parameters.txt
> +++ b/Documentation/admin-guide/kernel-parameters.txt
> @@ -1640,6 +1640,11 @@
> different crypto accelerators. This option can be used
> to achieve best performance for particular HW.
>
> + ima.force_hash= [IMA] Force hash calculation in IMA
> + Format: <bool>
> + Always calculate hashes rather than trusting the
> + filesystem to provide them to us.
Unless the IMA policy specifically defines rules with "trust_vfs", the
default is to read the file, calculating the file hash. I don't see a
need for this boot command line option. I do think that "trust_vfs"
needs to be limited. Perhaps limiting it to a specific mounted
filesystem? Perhaps limiting it to systems requiring signed IMA
policies?
Mimi
> +
> init= [KNL]
> Format: <full_path>
> Run specified binary instead of /sbin/init as init
> diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
> index cc12f3449a72..24d9b3a3bfc0 100644
> --- a/security/integrity/ima/ima.h
> +++ b/security/integrity/ima/ima.h
> @@ -133,7 +133,8 @@ int ima_fs_init(void);
> int ima_add_template_entry(struct ima_template_entry *entry, int violation,
> const char *op, struct inode *inode,
> const unsigned char *filename);
> -int ima_calc_file_hash(struct file *file, struct ima_digest_data *hash);
> +int ima_calc_file_hash(struct file *file, struct ima_digest_data *hash,
> + bool trust_vfs);
> int ima_calc_buffer_hash(const void *buf, loff_t len,
> struct ima_digest_data *hash);
> int ima_calc_field_array_hash(struct ima_field_data *field_data,
> diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
> index c7505fb122d4..0def9cf43549 100644
> --- a/security/integrity/ima/ima_api.c
> +++ b/security/integrity/ima/ima_api.c
> @@ -206,6 +206,7 @@ int ima_collect_measurement(struct integrity_iint_cache *iint,
> int length;
> void *tmpbuf;
> u64 i_version;
> + bool trust_vfs;
> struct {
> struct ima_digest_data hdr;
> char digest[IMA_MAX_DIGEST_SIZE];
> @@ -225,10 +226,12 @@ int ima_collect_measurement(struct integrity_iint_cache *iint,
> /* Initialize hash digest to 0's in case of failure */
> memset(&hash.digest, 0, sizeof(hash.digest));
>
> + trust_vfs = iint->flags & IMA_TRUST_VFS;
> +
> if (buf)
> result = ima_calc_buffer_hash(buf, size, &hash.hdr);
> else
> - result = ima_calc_file_hash(file, &hash.hdr);
> + result = ima_calc_file_hash(file, &hash.hdr, trust_vfs);
>
> if (result && result != -EBADF && result != -EINVAL)
> goto out;
> diff --git a/security/integrity/ima/ima_crypto.c b/security/integrity/ima/ima_crypto.c
> index acf2c7df7145..94105089ad41 100644
> --- a/security/integrity/ima/ima_crypto.c
> +++ b/security/integrity/ima/ima_crypto.c
> @@ -32,6 +32,10 @@ static unsigned long ima_ahash_minsize;
> module_param_named(ahash_minsize, ima_ahash_minsize, ulong, 0644);
> MODULE_PARM_DESC(ahash_minsize, "Minimum file size for ahash use");
>
> +static bool ima_force_hash;
> +module_param_named(force_hash, ima_force_hash, bool_enable_only, 0644);
> +MODULE_PARM_DESC(force_hash, "Always calculate hashes");
> +
> /* default is 0 - 1 page. */
> static int ima_maxorder;
> static unsigned int ima_bufsize = PAGE_SIZE;
> @@ -402,11 +406,14 @@ static int ima_calc_file_shash(struct file *file, struct ima_digest_data *hash)
> * shash for the hash calculation. If ahash fails, it falls back to using
> * shash.
> */
> -int ima_calc_file_hash(struct file *file, struct ima_digest_data *hash)
> +int ima_calc_file_hash(struct file *file, struct ima_digest_data *hash,
> + bool trust_vfs)
> {
> loff_t i_size;
> int rc;
> struct file *f = file;
> + struct dentry *dentry = file_dentry(file);
> + struct inode *inode = d_backing_inode(dentry);
> bool new_file_instance = false, modified_flags = false;
>
> /*
> @@ -419,6 +426,20 @@ int ima_calc_file_hash(struct file *file, struct ima_digest_data *hash)
> return -EINVAL;
> }
>
> + /*
> + * If policy says we should trust VFS-provided hashes, and
> + * we're not configured to force hashing, and if the
> + * filesystem is trusted, ask the VFS if it can obtain the
> + * hash without us having to calculate it ourself.
> + */
> + if (trust_vfs && !ima_force_hash &&
> + !(inode->i_sb->s_iflags & SB_I_UNTRUSTED_MOUNTER)) {
> + hash->length = hash_digest_size[hash->algo];
> + rc = vfs_get_hash(file, hash->algo, hash->digest, hash->length);
> + if (!rc)
> + return 0;
> + }
> +
> /* Open a new file instance in O_RDONLY if we cannot read */
> if (!(file->f_mode & FMODE_READ)) {
> int flags = file->f_flags & ~(O_WRONLY | O_APPEND |
> diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
> index dcecb6aae5ec..af632c31f856 100644
> --- a/security/integrity/ima/ima_policy.c
> +++ b/security/integrity/ima/ima_policy.c
> @@ -683,7 +683,7 @@ enum {
> 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_err
> + Opt_pcr, Opt_trust_vfs, Opt_err
> };
>
> static const match_table_t policy_tokens = {
> @@ -718,6 +718,7 @@ static const match_table_t policy_tokens = {
> {Opt_appraise_type, "appraise_type=%s"},
> {Opt_permit_directio, "permit_directio"},
> {Opt_pcr, "pcr=%s"},
> + {Opt_trust_vfs, "trust_vfs"},
> {Opt_err, NULL}
> };
>
> @@ -1060,6 +1061,9 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
> case Opt_permit_directio:
> entry->flags |= IMA_PERMIT_DIRECTIO;
> break;
> + case Opt_trust_vfs:
> + entry->flags |= IMA_TRUST_VFS;
> + break;
> case Opt_pcr:
> if (entry->action != MEASURE) {
> result = -EINVAL;
> @@ -1356,6 +1360,8 @@ int ima_policy_show(struct seq_file *m, void *v)
> seq_puts(m, "appraise_type=imasig ");
> if (entry->flags & IMA_PERMIT_DIRECTIO)
> seq_puts(m, "permit_directio ");
> + if (entry->flags & IMA_TRUST_VFS)
> + seq_puts(m, "trust_vfs ");
> rcu_read_unlock();
> seq_puts(m, "\n");
> return 0;
> diff --git a/security/integrity/ima/ima_template_lib.c b/security/integrity/ima/ima_template_lib.c
> index 43752002c222..a36cdc6651b7 100644
> --- a/security/integrity/ima/ima_template_lib.c
> +++ b/security/integrity/ima/ima_template_lib.c
> @@ -290,7 +290,7 @@ int ima_eventdigest_init(struct ima_event_data *event_data,
> inode = file_inode(event_data->file);
> hash.hdr.algo = ima_template_hash_algo_allowed(ima_hash_algo) ?
> ima_hash_algo : HASH_ALGO_SHA1;
> - result = ima_calc_file_hash(event_data->file, &hash.hdr);
> + result = ima_calc_file_hash(event_data->file, &hash.hdr, false);
> if (result) {
> integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode,
> event_data->filename, "collect_data",
> diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h
> index 7de59f44cba3..a03f859c1602 100644
> --- a/security/integrity/integrity.h
> +++ b/security/integrity/integrity.h
> @@ -36,6 +36,7 @@
> #define IMA_NEW_FILE 0x04000000
> #define EVM_IMMUTABLE_DIGSIG 0x08000000
> #define IMA_FAIL_UNVERIFIABLE_SIGS 0x10000000
> +#define IMA_TRUST_VFS 0x20000000
>
> #define IMA_DO_MASK (IMA_MEASURE | IMA_APPRAISE | IMA_AUDIT | \
> IMA_HASH | IMA_APPRAISE_SUBMASK)
next prev parent reply other threads:[~2019-02-28 16:04 UTC|newest]
Thread overview: 41+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-02-26 21:50 Allow trusted filesystems to provide IMA hashes directly Matthew Garrett
2019-02-26 21:50 ` [PATCH V2 1/4] VFS: Add a call to obtain a file's hash Matthew Garrett
2019-02-26 21:50 ` [PATCH V2 2/4] IMA: Allow rule matching on filesystem subtype Matthew Garrett
2019-02-26 21:50 ` [PATCH V2 3/4] IMA: Optionally make use of filesystem-provided hashes Matthew Garrett
2019-02-28 16:03 ` Mimi Zohar [this message]
2019-02-28 18:05 ` Mimi Zohar
2019-02-28 21:41 ` Matthew Garrett
2019-02-28 21:59 ` Mimi Zohar
2019-02-28 22:38 ` Matthew Garrett
2019-03-04 19:52 ` Matthew Garrett
2019-03-04 20:32 ` Mimi Zohar
2019-03-04 22:10 ` Matthew Garrett
2019-03-05 13:18 ` Mimi Zohar
2019-03-05 18:39 ` Matthew Garrett
2019-03-05 19:51 ` Mimi Zohar
2019-03-05 20:27 ` Matthew Garrett
2019-03-06 12:30 ` Mimi Zohar
2019-03-06 18:31 ` Matthew Garrett
2019-03-06 22:38 ` Mimi Zohar
2019-03-06 23:36 ` Matthew Garrett
2019-03-07 1:54 ` Mimi Zohar
2019-03-07 4:19 ` Matthew Garrett
2019-03-07 20:48 ` Mimi Zohar
2019-03-07 22:41 ` Matthew Garrett
2019-04-04 21:46 ` Matthew Garrett
2019-04-04 22:18 ` James Bottomley
2019-04-04 22:26 ` Matthew Garrett
2019-04-04 22:35 ` James Bottomley
2019-04-05 1:50 ` Matthew Garrett
2019-04-05 2:26 ` James Bottomley
2019-04-05 20:55 ` Matthew Garrett
2019-04-29 22:51 ` Matthew Garrett
2019-05-02 20:25 ` Mimi Zohar
2019-05-02 22:37 ` Matthew Garrett
2019-05-02 23:02 ` Mimi Zohar
2019-05-03 6:51 ` Roberto Sassu
2019-05-03 8:17 ` Roberto Sassu
2019-05-03 12:47 ` Mimi Zohar
2019-05-03 13:20 ` Roberto Sassu
2019-02-26 21:50 ` [PATCH V2 4/4] FUSE: Allow filesystems to provide gethash methods Matthew Garrett
2019-02-27 14:26 ` Jann Horn
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=1551369834.10911.195.camel@linux.ibm.com \
--to=zohar@linux.ibm.com \
--cc=dmitry.kasatkin@gmail.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-integrity@vger.kernel.org \
--cc=matthewgarrett@google.com \
--cc=miklos@szeredi.hu \
--cc=mjg59@google.com \
/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).