[Linux-ima-devel] [PATCH v4 1/5] ima: always measure and audit files in policy

Dmitry Kasatkin dmitry.kasatkin at gmail.com
Tue Aug 22 09:24:40 UTC 2017


On Wed, Jul 26, 2017 at 4:22 PM, Mimi Zohar <zohar at linux.vnet.ibm.com> wrote:
> All files matching a "measure" rule must be included in the IMA
> measurement list, even when the file hash cannot be calculated.
> Similarly, all files matching an "audit" rule must be audited, even when
> the file hash can not be calculated.
>
> The file data hash field contained in the IMA measurement list template
> data will contain 0's instead of the actual file hash digest.
>
> Mimi Zohar <zohar at linux.vnet.ibm.com>
>
> ---
> Changelog v4:
> - Based on both -EBADF and -EINVAL
> - clean up ima_collect_measurement()
>
>  security/integrity/ima/ima_api.c  | 58 +++++++++++++++++++++++----------------
>  security/integrity/ima/ima_main.c |  4 +--
>  2 files changed, 37 insertions(+), 25 deletions(-)
>
> diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
> index c2edba8de35e..bbf3ba8bbb09 100644
> --- a/security/integrity/ima/ima_api.c
> +++ b/security/integrity/ima/ima_api.c
> @@ -199,37 +199,49 @@ int ima_collect_measurement(struct integrity_iint_cache *iint,
>         struct inode *inode = file_inode(file);
>         const char *filename = file->f_path.dentry->d_name.name;
>         int result = 0;
> +       int length;
> +       void *tmpbuf;
> +       u64 i_version;
>         struct {
>                 struct ima_digest_data hdr;
>                 char digest[IMA_MAX_DIGEST_SIZE];
>         } hash;
>
> -       if (!(iint->flags & IMA_COLLECTED)) {
> -               u64 i_version = file_inode(file)->i_version;
> +       if (iint->flags & IMA_COLLECTED)
> +               goto out;
>
> -               if (file->f_flags & O_DIRECT) {
> -                       audit_cause = "failed(directio)";
> -                       result = -EACCES;
> -                       goto out;
> -               }
> +       if (file->f_flags & O_DIRECT) {
> +               audit_cause = "failed(directio)";
> +               result = -EACCES;
> +               goto out;
> +       }
>
> -               hash.hdr.algo = algo;
> -
> -               result = (!buf) ?  ima_calc_file_hash(file, &hash.hdr) :
> -                       ima_calc_buffer_hash(buf, size, &hash.hdr);
> -               if (!result) {
> -                       int length = sizeof(hash.hdr) + hash.hdr.length;
> -                       void *tmpbuf = krealloc(iint->ima_hash, length,
> -                                               GFP_NOFS);
> -                       if (tmpbuf) {
> -                               iint->ima_hash = tmpbuf;
> -                               memcpy(iint->ima_hash, &hash, length);
> -                               iint->version = i_version;
> -                               iint->flags |= IMA_COLLECTED;
> -                       } else
> -                               result = -ENOMEM;
> -               }
> +       i_version = file_inode(file)->i_version;
> +       hash.hdr.algo = algo;
> +
> +       /* Initialize hash digest to 0's in case of failure */
> +       memset(&hash.digest, 0, sizeof(hash.digest));
> +
> +       result = (!buf) ?  ima_calc_file_hash(file, &hash.hdr) :
> +               ima_calc_buffer_hash(buf, size, &hash.hdr);
> +
> +       if (result && result != -EBADF && result != -EINVAL)
> +               goto out;
> +
> +       length = sizeof(hash.hdr) + hash.hdr.length;
> +       tmpbuf = krealloc(iint->ima_hash, length, GFP_NOFS);
> +       if (!tmpbuf) {
> +               result = -ENOMEM;
> +               goto out;
>         }
> +
> +       iint->ima_hash = tmpbuf;
> +       memcpy(iint->ima_hash, &hash, length);
> +       iint->version = i_version;
> +
> +       /* Possibly temporary failure due to type of read (eg. DAX, O_DIRECT) */
> +       if (result != -EBADF && result != -EINVAL)
> +               iint->flags |= IMA_COLLECTED;

Result can be other than 0, EBADF and EINVAL here?
It is confusing.. simpler than can be just

if (!result)
 iint->flags |= IMA_COLLECTED;

Isn't it?

>  out:
>         if (result)
>                 integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode,
> diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
> index 2aebb7984437..3941371402ff 100644
> --- a/security/integrity/ima/ima_main.c
> +++ b/security/integrity/ima/ima_main.c
> @@ -235,7 +235,7 @@ static int process_measurement(struct file *file, char *buf, loff_t size,
>         hash_algo = ima_get_hash_algo(xattr_value, xattr_len);
>
>         rc = ima_collect_measurement(iint, file, buf, size, hash_algo);
> -       if (rc != 0) {
> +       if (rc != 0 && rc != -EBADF && rc != -EINVAL) {
>                 if (file->f_flags & O_DIRECT)
>                         rc = (iint->flags & IMA_PERMIT_DIRECTIO) ? 0 : -EACCES;
>                 goto out_digsig;
> @@ -247,7 +247,7 @@ static int process_measurement(struct file *file, char *buf, loff_t size,
>         if (action & IMA_MEASURE)
>                 ima_store_measurement(iint, file, pathname,
>                                       xattr_value, xattr_len, pcr);
> -       if (action & IMA_APPRAISE_SUBMASK)
> +       if ((rc == 0) && (action & IMA_APPRAISE_SUBMASK))
>                 rc = ima_appraise_measurement(func, iint, file, pathname,
>                                               xattr_value, xattr_len, opened);
>         if (action & IMA_AUDIT)
> --
> 2.7.4
>
>
> ------------------------------------------------------------------------------
> Check out the vibrant tech community on one of the world's most
> engaging tech sites, Slashdot.org! http://sdm.link/slashdot
> _______________________________________________
> Linux-ima-devel mailing list
> Linux-ima-devel at lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/linux-ima-devel



-- 
Thanks,
Dmitry
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html



More information about the Linux-security-module-archive mailing list