On Wed, 2014-04-23 at 16:30 +0300, Dmitry Kasatkin wrote: 
> Currently policy is loaded by writing policy content to
> '<securityfs>/ima/policy' file.
> 
> This patch extends policy loading meachanism with possibility
> to load signed policy using a path to the policy.
> Policy signature must be available in the <policy>.sig file.

Assuming (big assumption) you're permitted to open the policy file from
the kernel, why are you verifying the signature inline based on a .sig?
Shouldn't this be a new integrity/security hook?

thanks,

Mimi

> 
> Policy can be loaded like:
> echo /etc/ima/ima_policy > /sys/kernel/security/ima/policy
> 
> Signed-off-by: Dmitry Kasatkin <d.kasat...@samsung.com>
> ---
>  security/integrity/ima/Kconfig      | 13 +++++++
>  security/integrity/ima/ima.h        |  9 +++++
>  security/integrity/ima/ima_fs.c     |  2 +-
>  security/integrity/ima/ima_policy.c | 74 
> +++++++++++++++++++++++++++++++++++++
>  4 files changed, 97 insertions(+), 1 deletion(-)
> 
> diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig
> index 5474c47..465cef4 100644
> --- a/security/integrity/ima/Kconfig
> +++ b/security/integrity/ima/Kconfig
> @@ -140,3 +140,16 @@ config IMA_LOAD_X509
>       help
>          This option enables X509 certificate loading from the kernel
>          to the '_ima' trusted keyring.
> +
> +config IMA_POLICY_LOADER
> +     bool "Path based policy loading interface"
> +     depends on IMA_TRUSTED_KEYRING
> +     default n
> +     help
> +       This option enables path based signed policy loading interface.
> +       Policy signature must be provided in the <policy>.sig file
> +       along with the policy. When this option is enabled, kernel
> +       tries to load default policy from /etc/ima_policy.
> +
> +       Loading policy is like:
> +       echo /etc/ima/ima_policy > /sys/kernel/security/ima/policy
> diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
> index 3b90b60..f2722bb 100644
> --- a/security/integrity/ima/ima.h
> +++ b/security/integrity/ima/ima.h
> @@ -170,6 +170,15 @@ bool ima_default_policy(void);
>  ssize_t ima_parse_add_rule(char *);
>  void ima_delete_rules(void);
> 
> +#ifdef CONFIG_IMA_POLICY_LOADER
> +ssize_t ima_read_policy(char *path);
> +#else
> +static inline ssize_t ima_read_policy(char *data)
> +{
> +     return ima_parse_add_rule(data);
> +}
> +#endif
> +
>  /* Appraise integrity measurements */
>  #define IMA_APPRAISE_ENFORCE 0x01
>  #define IMA_APPRAISE_FIX     0x02
> diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
> index 34ae5f2..bde7a0e 100644
> --- a/security/integrity/ima/ima_fs.c
> +++ b/security/integrity/ima/ima_fs.c
> @@ -273,7 +273,7 @@ static ssize_t ima_write_policy(struct file *file, const 
> char __user *buf,
>       if (copy_from_user(data, buf, datalen))
>               goto out;
> 
> -     result = ima_parse_add_rule(data);
> +     result = ima_read_policy(data);
>  out:
>       if (result < 0)
>               valid_policy = 0;
> diff --git a/security/integrity/ima/ima_policy.c 
> b/security/integrity/ima/ima_policy.c
> index b24e7d1..c6da801 100644
> --- a/security/integrity/ima/ima_policy.c
> +++ b/security/integrity/ima/ima_policy.c
> @@ -17,6 +17,9 @@
>  #include <linux/parser.h>
>  #include <linux/slab.h>
>  #include <linux/genhd.h>
> +#ifdef CONFIG_IMA_POLICY_LOADER
> +#include <linux/file.h>
> +#endif
> 
>  #include "ima.h"
> 
> @@ -747,3 +750,74 @@ void ima_delete_rules(void)
>       }
>       mutex_unlock(&ima_rules_mutex);
>  }
> +
> +#ifdef CONFIG_IMA_POLICY_LOADER
> +
> +ssize_t ima_read_policy(char *path)
> +{
> +     char *data, *datap, *sig;
> +     int rc, psize, pathlen = strlen(path);
> +     char *p, *sigpath;
> +     struct {
> +             struct ima_digest_data hdr;
> +             char digest[IMA_MAX_DIGEST_SIZE];
> +     } hash;
> +
> +     if (path[0] != '/')
> +             return ima_parse_add_rule(path);
> +
> +     /* remove \n */
> +     datap = path;
> +     strsep(&datap, "\n");
> +
> +     /* we always want signature? */
> +     sigpath = __getname();
> +     if (!sigpath)
> +             return -ENOMEM;
> +
> +     rc = integrity_read_file(path, &data);
> +     if (rc < 0)
> +             goto free_path;
> +
> +     psize = rc;
> +     datap = data;
> +
> +     sprintf(sigpath, "%s.sig", path);
> +     /* we always want signature? */
> +     rc = integrity_read_file(sigpath, &sig);
> +     if (rc < 0)
> +             goto free_data;
> +
> +     hash.hdr.algo = ima_hash_algo;
> +     ima_get_hash_algo((void *)sig, rc, &hash.hdr);
> +     ima_calc_buffer_hash(data, psize, &hash.hdr);
> +     rc = integrity_digsig_verify(INTEGRITY_KEYRING_IMA,
> +                                  (const char *)sig, rc,
> +                                  hash.hdr.digest, hash.hdr.length);
> +     if (rc) {
> +             pr_err("integrity_digsig_verify() = %d\n", rc);
> +             goto free_sig;
> +     }
> +
> +     while (psize > 0 && (p = strsep(&datap, "\n"))) {
> +             pr_debug("rule: %s\n", p);
> +             rc = ima_parse_add_rule(p);
> +             if (rc < 0)
> +                     break;
> +             psize -= rc;
> +     }
> +free_sig:
> +     kfree(sig);
> +free_data:
> +     kfree(data);
> +free_path:
> +     __putname(sigpath);
> +     if (rc < 0)
> +             return rc;
> +     else if (psize)
> +             return -EINVAL;
> +     else
> +             return pathlen;
> +}
> +
> +#endif


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to