Commit 1525b06d authored by Dmitry Kasatkin's avatar Dmitry Kasatkin Committed by Mimi Zohar

ima: separate 'security.ima' reading functionality from collect

Instead of passing pointers to pointers to ima_collect_measurent() to
read and return the 'security.ima' xattr value, this patch moves the
functionality to the calling process_measurement() to directly read
the xattr and pass only the hash algo to the ima_collect_measurement().
Signed-off-by: default avatarDmitry Kasatkin <dmitry.kasatkin@huawei.com>
Signed-off-by: default avatarMimi Zohar <zohar@linux.vnet.ibm.com>
parent c75d8e96
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include <linux/hash.h> #include <linux/hash.h>
#include <linux/tpm.h> #include <linux/tpm.h>
#include <linux/audit.h> #include <linux/audit.h>
#include <crypto/hash_info.h>
#include "../integrity.h" #include "../integrity.h"
...@@ -140,9 +141,7 @@ static inline unsigned long ima_hash_key(u8 *digest) ...@@ -140,9 +141,7 @@ static inline unsigned long ima_hash_key(u8 *digest)
int ima_get_action(struct inode *inode, int mask, int function); int ima_get_action(struct inode *inode, int mask, int function);
int ima_must_measure(struct inode *inode, int mask, int function); int ima_must_measure(struct inode *inode, int mask, int function);
int ima_collect_measurement(struct integrity_iint_cache *iint, int ima_collect_measurement(struct integrity_iint_cache *iint,
struct file *file, struct file *file, enum hash_algo algo);
struct evm_ima_xattr_data **xattr_value,
int *xattr_len);
void ima_store_measurement(struct integrity_iint_cache *iint, struct file *file, void ima_store_measurement(struct integrity_iint_cache *iint, struct file *file,
const unsigned char *filename, const unsigned char *filename,
struct evm_ima_xattr_data *xattr_value, struct evm_ima_xattr_data *xattr_value,
...@@ -188,8 +187,8 @@ int ima_must_appraise(struct inode *inode, int mask, enum ima_hooks func); ...@@ -188,8 +187,8 @@ int ima_must_appraise(struct inode *inode, int mask, enum ima_hooks func);
void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file); void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file);
enum integrity_status ima_get_cache_status(struct integrity_iint_cache *iint, enum integrity_status ima_get_cache_status(struct integrity_iint_cache *iint,
int func); int func);
void ima_get_hash_algo(struct evm_ima_xattr_data *xattr_value, int xattr_len, enum hash_algo ima_get_hash_algo(struct evm_ima_xattr_data *xattr_value,
struct ima_digest_data *hash); int xattr_len);
int ima_read_xattr(struct dentry *dentry, int ima_read_xattr(struct dentry *dentry,
struct evm_ima_xattr_data **xattr_value); struct evm_ima_xattr_data **xattr_value);
...@@ -221,10 +220,10 @@ static inline enum integrity_status ima_get_cache_status(struct integrity_iint_c ...@@ -221,10 +220,10 @@ static inline enum integrity_status ima_get_cache_status(struct integrity_iint_c
return INTEGRITY_UNKNOWN; return INTEGRITY_UNKNOWN;
} }
static inline void ima_get_hash_algo(struct evm_ima_xattr_data *xattr_value, static inline enum hash_algo
int xattr_len, ima_get_hash_algo(struct evm_ima_xattr_data *xattr_value, int xattr_len)
struct ima_digest_data *hash)
{ {
return ima_hash_algo;
} }
static inline int ima_read_xattr(struct dentry *dentry, static inline int ima_read_xattr(struct dentry *dentry,
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/xattr.h> #include <linux/xattr.h>
#include <linux/evm.h> #include <linux/evm.h>
#include <crypto/hash_info.h>
#include "ima.h" #include "ima.h"
/* /*
...@@ -188,9 +188,7 @@ int ima_get_action(struct inode *inode, int mask, int function) ...@@ -188,9 +188,7 @@ int ima_get_action(struct inode *inode, int mask, int function)
* Return 0 on success, error code otherwise * Return 0 on success, error code otherwise
*/ */
int ima_collect_measurement(struct integrity_iint_cache *iint, int ima_collect_measurement(struct integrity_iint_cache *iint,
struct file *file, struct file *file, enum hash_algo algo)
struct evm_ima_xattr_data **xattr_value,
int *xattr_len)
{ {
const char *audit_cause = "failed"; const char *audit_cause = "failed";
struct inode *inode = file_inode(file); struct inode *inode = file_inode(file);
...@@ -201,9 +199,6 @@ int ima_collect_measurement(struct integrity_iint_cache *iint, ...@@ -201,9 +199,6 @@ int ima_collect_measurement(struct integrity_iint_cache *iint,
char digest[IMA_MAX_DIGEST_SIZE]; char digest[IMA_MAX_DIGEST_SIZE];
} hash; } hash;
if (xattr_value)
*xattr_len = ima_read_xattr(file->f_path.dentry, xattr_value);
if (!(iint->flags & IMA_COLLECTED)) { if (!(iint->flags & IMA_COLLECTED)) {
u64 i_version = file_inode(file)->i_version; u64 i_version = file_inode(file)->i_version;
...@@ -213,11 +208,7 @@ int ima_collect_measurement(struct integrity_iint_cache *iint, ...@@ -213,11 +208,7 @@ int ima_collect_measurement(struct integrity_iint_cache *iint,
goto out; goto out;
} }
/* use default hash algorithm */ hash.hdr.algo = algo;
hash.hdr.algo = ima_hash_algo;
if (xattr_value)
ima_get_hash_algo(*xattr_value, *xattr_len, &hash.hdr);
result = ima_calc_file_hash(file, &hash.hdr); result = ima_calc_file_hash(file, &hash.hdr);
if (!result) { if (!result) {
......
...@@ -15,7 +15,6 @@ ...@@ -15,7 +15,6 @@
#include <linux/magic.h> #include <linux/magic.h>
#include <linux/ima.h> #include <linux/ima.h>
#include <linux/evm.h> #include <linux/evm.h>
#include <crypto/hash_info.h>
#include "ima.h" #include "ima.h"
...@@ -130,36 +129,40 @@ static void ima_cache_flags(struct integrity_iint_cache *iint, int func) ...@@ -130,36 +129,40 @@ static void ima_cache_flags(struct integrity_iint_cache *iint, int func)
} }
} }
void ima_get_hash_algo(struct evm_ima_xattr_data *xattr_value, int xattr_len, enum hash_algo ima_get_hash_algo(struct evm_ima_xattr_data *xattr_value,
struct ima_digest_data *hash) int xattr_len)
{ {
struct signature_v2_hdr *sig; struct signature_v2_hdr *sig;
if (!xattr_value || xattr_len < 2) if (!xattr_value || xattr_len < 2)
return; /* return default hash algo */
return ima_hash_algo;
switch (xattr_value->type) { switch (xattr_value->type) {
case EVM_IMA_XATTR_DIGSIG: case EVM_IMA_XATTR_DIGSIG:
sig = (typeof(sig))xattr_value; sig = (typeof(sig))xattr_value;
if (sig->version != 2 || xattr_len <= sizeof(*sig)) if (sig->version != 2 || xattr_len <= sizeof(*sig))
return; return ima_hash_algo;
hash->algo = sig->hash_algo; return sig->hash_algo;
break; break;
case IMA_XATTR_DIGEST_NG: case IMA_XATTR_DIGEST_NG:
hash->algo = xattr_value->digest[0]; return xattr_value->digest[0];
break; break;
case IMA_XATTR_DIGEST: case IMA_XATTR_DIGEST:
/* this is for backward compatibility */ /* this is for backward compatibility */
if (xattr_len == 21) { if (xattr_len == 21) {
unsigned int zero = 0; unsigned int zero = 0;
if (!memcmp(&xattr_value->digest[16], &zero, 4)) if (!memcmp(&xattr_value->digest[16], &zero, 4))
hash->algo = HASH_ALGO_MD5; return HASH_ALGO_MD5;
else else
hash->algo = HASH_ALGO_SHA1; return HASH_ALGO_SHA1;
} else if (xattr_len == 17) } else if (xattr_len == 17)
hash->algo = HASH_ALGO_MD5; return HASH_ALGO_MD5;
break; break;
} }
/* return default hash algo */
return ima_hash_algo;
} }
int ima_read_xattr(struct dentry *dentry, int ima_read_xattr(struct dentry *dentry,
...@@ -296,7 +299,7 @@ void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file) ...@@ -296,7 +299,7 @@ void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file)
if (iint->flags & IMA_DIGSIG) if (iint->flags & IMA_DIGSIG)
return; return;
rc = ima_collect_measurement(iint, file, NULL, NULL); rc = ima_collect_measurement(iint, file, ima_hash_algo);
if (rc < 0) if (rc < 0)
return; return;
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
#include <linux/err.h> #include <linux/err.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <crypto/hash.h> #include <crypto/hash.h>
#include <crypto/hash_info.h>
#include "ima.h" #include "ima.h"
struct ahash_completion { struct ahash_completion {
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
#include <linux/scatterlist.h> #include <linux/scatterlist.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/err.h> #include <linux/err.h>
#include <crypto/hash_info.h>
#include "ima.h" #include "ima.h"
/* name for boot aggregate entry */ /* name for boot aggregate entry */
......
...@@ -24,7 +24,6 @@ ...@@ -24,7 +24,6 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/xattr.h> #include <linux/xattr.h>
#include <linux/ima.h> #include <linux/ima.h>
#include <crypto/hash_info.h>
#include "ima.h" #include "ima.h"
...@@ -163,9 +162,10 @@ static int process_measurement(struct file *file, int mask, int function, ...@@ -163,9 +162,10 @@ static int process_measurement(struct file *file, int mask, int function,
char *pathbuf = NULL; char *pathbuf = NULL;
const char *pathname = NULL; const char *pathname = NULL;
int rc = -ENOMEM, action, must_appraise; int rc = -ENOMEM, action, must_appraise;
struct evm_ima_xattr_data *xattr_value = NULL, **xattr_ptr = NULL; struct evm_ima_xattr_data *xattr_value = NULL;
int xattr_len = 0; int xattr_len = 0;
bool violation_check; bool violation_check;
enum hash_algo hash_algo;
if (!ima_policy_flag || !S_ISREG(inode->i_mode)) if (!ima_policy_flag || !S_ISREG(inode->i_mode))
return 0; return 0;
...@@ -221,9 +221,12 @@ static int process_measurement(struct file *file, int mask, int function, ...@@ -221,9 +221,12 @@ static int process_measurement(struct file *file, int mask, int function,
template_desc = ima_template_desc_current(); template_desc = ima_template_desc_current();
if ((action & IMA_APPRAISE_SUBMASK) || if ((action & IMA_APPRAISE_SUBMASK) ||
strcmp(template_desc->name, IMA_TEMPLATE_IMA_NAME) != 0) strcmp(template_desc->name, IMA_TEMPLATE_IMA_NAME) != 0)
xattr_ptr = &xattr_value; /* read 'security.ima' */
xattr_len = ima_read_xattr(file->f_path.dentry, &xattr_value);
rc = ima_collect_measurement(iint, file, xattr_ptr, &xattr_len); hash_algo = ima_get_hash_algo(xattr_value, xattr_len);
rc = ima_collect_measurement(iint, file, hash_algo);
if (rc != 0) { if (rc != 0) {
if (file->f_flags & O_DIRECT) if (file->f_flags & O_DIRECT)
rc = (iint->flags & IMA_PERMIT_DIRECTIO) ? 0 : -EACCES; rc = (iint->flags & IMA_PERMIT_DIRECTIO) ? 0 : -EACCES;
......
...@@ -15,8 +15,6 @@ ...@@ -15,8 +15,6 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <crypto/hash_info.h>
#include "ima.h" #include "ima.h"
#include "ima_template_lib.h" #include "ima_template_lib.h"
......
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
* File: ima_template_lib.c * File: ima_template_lib.c
* Library of supported template fields. * Library of supported template fields.
*/ */
#include <crypto/hash_info.h>
#include "ima_template_lib.h" #include "ima_template_lib.h"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment