Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 329104
b: refs/heads/master
c: 2fe5d6d
h: refs/heads/master
v: v3
  • Loading branch information
Mimi Zohar committed Sep 7, 2012
1 parent 62012a6 commit 48d7336
Show file tree
Hide file tree
Showing 14 changed files with 359 additions and 54 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 4199d35cbc90c15db447d115bd96ffa5f1d60d3a
refs/heads/master: 2fe5d6def1672ae6635dd71867bf36dcfaa7434b
4 changes: 4 additions & 0 deletions trunk/Documentation/kernel-parameters.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1051,6 +1051,10 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
ihash_entries= [KNL]
Set number of hash buckets for inode cache.

ima_appraise= [IMA] appraise integrity measurements
Format: { "off" | "enforce" | "fix" }
default: "enforce"

ima_audit= [IMA]
Format: { "0" | "1" }
0 -- integrity auditing messages. (Default)
Expand Down
3 changes: 3 additions & 0 deletions trunk/include/linux/xattr.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@
#define XATTR_EVM_SUFFIX "evm"
#define XATTR_NAME_EVM XATTR_SECURITY_PREFIX XATTR_EVM_SUFFIX

#define XATTR_IMA_SUFFIX "ima"
#define XATTR_NAME_IMA XATTR_SECURITY_PREFIX XATTR_IMA_SUFFIX

#define XATTR_SELINUX_SUFFIX "selinux"
#define XATTR_NAME_SELINUX XATTR_SECURITY_PREFIX XATTR_SELINUX_SUFFIX

Expand Down
3 changes: 3 additions & 0 deletions trunk/security/integrity/evm/evm_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ char *evm_config_xattrnames[] = {
#endif
#ifdef CONFIG_SECURITY_SMACK
XATTR_NAME_SMACK,
#endif
#ifdef CONFIG_IMA_APPRAISE
XATTR_NAME_IMA,
#endif
XATTR_NAME_CAPS,
NULL
Expand Down
3 changes: 2 additions & 1 deletion trunk/security/integrity/iint.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ static void iint_free(struct integrity_iint_cache *iint)
{
iint->version = 0;
iint->flags = 0UL;
iint->ima_status = INTEGRITY_UNKNOWN;
iint->evm_status = INTEGRITY_UNKNOWN;
kmem_cache_free(iint_cache, iint);
}
Expand Down Expand Up @@ -157,7 +158,7 @@ static void init_once(void *foo)
memset(iint, 0, sizeof *iint);
iint->version = 0;
iint->flags = 0UL;
mutex_init(&iint->mutex);
iint->ima_status = INTEGRITY_UNKNOWN;
iint->evm_status = INTEGRITY_UNKNOWN;
}

Expand Down
15 changes: 15 additions & 0 deletions trunk/security/integrity/ima/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,18 @@ config IMA_LSM_RULES
default y
help
Disabling this option will disregard LSM based policy rules.

config IMA_APPRAISE
bool "Appraise integrity measurements"
depends on IMA
default n
help
This option enables local measurement integrity appraisal.
It requires the system to be labeled with a security extended
attribute containing the file hash measurement. To protect
the security extended attributes from offline attack, enable
and configure EVM.

For more information on integrity appraisal refer to:
<http://linux-ima.sourceforge.net>
If unsure, say N.
1 change: 1 addition & 0 deletions trunk/security/integrity/ima/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ obj-$(CONFIG_IMA) += ima.o
ima-y := ima_fs.o ima_queue.o ima_init.o ima_main.o ima_crypto.o ima_api.o \
ima_policy.o
ima-$(CONFIG_IMA_AUDIT) += ima_audit.o
ima-$(CONFIG_IMA_APPRAISE) += ima_appraise.o
37 changes: 35 additions & 2 deletions trunk/security/integrity/ima/ima.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ enum tpm_pcrs { TPM_PCR0 = 0, TPM_PCR8 = 8 };
extern int ima_initialized;
extern int ima_used_chip;
extern char *ima_hash;
extern int ima_appraise;

/* IMA inode template definition */
struct ima_template_data {
Expand Down Expand Up @@ -107,6 +108,7 @@ static inline unsigned long ima_hash_key(u8 *digest)
}

/* LIM API function definitions */
int ima_must_appraise_or_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,
struct file *file);
Expand All @@ -123,14 +125,45 @@ struct integrity_iint_cache *integrity_iint_insert(struct inode *inode);
struct integrity_iint_cache *integrity_iint_find(struct inode *inode);

/* IMA policy related functions */
enum ima_hooks { FILE_CHECK = 1, FILE_MMAP, BPRM_CHECK };
enum ima_hooks { FILE_CHECK = 1, FILE_MMAP, BPRM_CHECK, POST_SETATTR };

int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask);
int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask,
int flags);
void ima_init_policy(void);
void ima_update_policy(void);
ssize_t ima_parse_add_rule(char *);
void ima_delete_rules(void);

/* Appraise integrity measurements */
#define IMA_APPRAISE_ENFORCE 0x01
#define IMA_APPRAISE_FIX 0x02

#ifdef CONFIG_IMA_APPRAISE
int ima_appraise_measurement(struct integrity_iint_cache *iint,
struct file *file, const unsigned char *filename);
int ima_must_appraise(struct inode *inode, enum ima_hooks func, int mask);
void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file);

#else
static inline int ima_appraise_measurement(struct integrity_iint_cache *iint,
struct file *file,
const unsigned char *filename)
{
return INTEGRITY_UNKNOWN;
}

static inline int ima_must_appraise(struct inode *inode,
enum ima_hooks func, int mask)
{
return 0;
}

static inline void ima_update_xattr(struct integrity_iint_cache *iint,
struct file *file)
{
}
#endif

/* LSM based policy rules require audit */
#ifdef CONFIG_IMA_LSM_RULES

Expand Down
50 changes: 36 additions & 14 deletions trunk/security/integrity/ima/ima_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,17 @@
* License.
*
* File: ima_api.c
* Implements must_measure, collect_measurement, store_measurement,
* and store_template.
* Implements must_appraise_or_measure, collect_measurement,
* appraise_measurement, store_measurement and store_template.
*/
#include <linux/module.h>
#include <linux/slab.h>

#include <linux/file.h>
#include <linux/fs.h>
#include <linux/xattr.h>
#include <linux/evm.h>
#include "ima.h"

static const char *IMA_TEMPLATE_NAME = "ima";

/*
Expand Down Expand Up @@ -93,7 +97,7 @@ void ima_add_violation(struct inode *inode, const unsigned char *filename,
}

/**
* ima_must_measure - measure decision based on policy.
* ima_must_appraise_or_measure - appraise & measure decision based on policy.
* @inode: pointer to inode to measure
* @mask: contains the permission mask (MAY_READ, MAY_WRITE, MAY_EXECUTE)
* @function: calling function (FILE_CHECK, BPRM_CHECK, FILE_MMAP)
Expand All @@ -105,15 +109,22 @@ void ima_add_violation(struct inode *inode, const unsigned char *filename,
* mask: contains the permission mask
* fsmagic: hex value
*
* Return 0 to measure. For matching a DONT_MEASURE policy, no policy,
* or other error, return an error code.
*/
int ima_must_measure(struct inode *inode, int mask, int function)
* Returns IMA_MEASURE, IMA_APPRAISE mask.
*
*/
int ima_must_appraise_or_measure(struct inode *inode, int mask, int function)
{
int must_measure;
int flags = IMA_MEASURE | IMA_APPRAISE;

if (!ima_appraise)
flags &= ~IMA_APPRAISE;

return ima_match_policy(inode, function, mask, flags);
}

must_measure = ima_match_policy(inode, function, mask);
return must_measure ? 0 : -EACCES;
int ima_must_measure(struct inode *inode, int mask, int function)
{
return ima_match_policy(inode, function, mask, IMA_MEASURE);
}

/*
Expand All @@ -129,16 +140,24 @@ int ima_must_measure(struct inode *inode, int mask, int function)
int ima_collect_measurement(struct integrity_iint_cache *iint,
struct file *file)
{
int result = -EEXIST;
struct inode *inode = file->f_dentry->d_inode;
const char *filename = file->f_dentry->d_name.name;
int result = 0;

if (!(iint->flags & IMA_MEASURED)) {
if (!(iint->flags & IMA_COLLECTED)) {
u64 i_version = file->f_dentry->d_inode->i_version;

memset(iint->digest, 0, IMA_DIGEST_SIZE);
result = ima_calc_hash(file, iint->digest);
if (!result)
if (!result) {
iint->version = i_version;
iint->flags |= IMA_COLLECTED;
}
}
if (result)
integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode,
filename, "collect_data", "failed",
result, 0);
return result;
}

Expand Down Expand Up @@ -167,6 +186,9 @@ void ima_store_measurement(struct integrity_iint_cache *iint,
struct ima_template_entry *entry;
int violation = 0;

if (iint->flags & IMA_MEASURED)
return;

entry = kmalloc(sizeof(*entry), GFP_KERNEL);
if (!entry) {
integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, filename,
Expand Down
Loading

0 comments on commit 48d7336

Please sign in to comment.