Skip to content

Commit 3323eec

Browse files
Mimi ZoharJames Morris
authored andcommitted
integrity: IMA as an integrity service provider
IMA provides hardware (TPM) based measurement and attestation for file measurements. As the Trusted Computing (TPM) model requires, IMA measures all files before they are accessed in any way (on the integrity_bprm_check, integrity_path_check and integrity_file_mmap hooks), and commits the measurements to the TPM. Once added to the TPM, measurements can not be removed. In addition, IMA maintains a list of these file measurements, which can be used to validate the aggregate value stored in the TPM. The TPM can sign these measurements, and thus the system can prove, to itself and to a third party, the system's integrity in a way that cannot be circumvented by malicious or compromised software. - alloc ima_template_entry before calling ima_store_template() - log ima_add_boot_aggregate() failure - removed unused IMA_TEMPLATE_NAME_LEN - replaced hard coded string length with #define name Signed-off-by: Mimi Zohar <[email protected]> Signed-off-by: James Morris <[email protected]>
1 parent 6146f0d commit 3323eec

File tree

16 files changed

+1454
-1
lines changed

16 files changed

+1454
-1
lines changed

Documentation/kernel-parameters.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -895,6 +895,15 @@ and is between 256 and 4096 characters. It is defined in the file
895895
ihash_entries= [KNL]
896896
Set number of hash buckets for inode cache.
897897

898+
ima_audit= [IMA]
899+
Format: { "0" | "1" }
900+
0 -- integrity auditing messages. (Default)
901+
1 -- enable informational integrity auditing messages.
902+
903+
ima_hash= [IMA]
904+
Formt: { "sha1" | "md5" }
905+
default: "sha1"
906+
898907
in2000= [HW,SCSI]
899908
See header of drivers/scsi/in2000.c.
900909

include/linux/audit.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,11 @@
125125
#define AUDIT_LAST_KERN_ANOM_MSG 1799
126126
#define AUDIT_ANOM_PROMISCUOUS 1700 /* Device changed promiscuous mode */
127127
#define AUDIT_ANOM_ABEND 1701 /* Process ended abnormally */
128+
#define AUDIT_INTEGRITY_DATA 1800 /* Data integrity verification */
129+
#define AUDIT_INTEGRITY_METADATA 1801 /* Metadata integrity verification */
130+
#define AUDIT_INTEGRITY_STATUS 1802 /* Integrity enable status */
131+
#define AUDIT_INTEGRITY_HASH 1803 /* Integrity HASH type */
132+
#define AUDIT_INTEGRITY_PCR 1804 /* PCR invalidation msgs */
128133

129134
#define AUDIT_KERNEL 2000 /* Asynchronous audit record. NOT A REQUEST. */
130135

include/linux/ima.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,15 @@
1212
#ifndef _LINUX_IMA_H
1313
#define _LINUX_IMA_H
1414

15+
#ifdef CONFIG_IMA
16+
extern int ima_bprm_check(struct linux_binprm *bprm);
17+
extern int ima_inode_alloc(struct inode *inode);
18+
extern void ima_inode_free(struct inode *inode);
19+
extern int ima_path_check(struct path *path, int mask);
20+
extern void ima_file_free(struct file *file);
21+
extern int ima_file_mmap(struct file *file, unsigned long prot);
22+
23+
#else
1524
static inline int ima_bprm_check(struct linux_binprm *bprm)
1625
{
1726
return 0;
@@ -41,4 +50,5 @@ static inline int ima_file_mmap(struct file *file, unsigned long prot)
4150
{
4251
return 0;
4352
}
53+
#endif /* CONFIG_IMA_H */
4454
#endif /* _LINUX_IMA_H */

security/Kconfig

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ config SECURITYFS
5555
bool "Enable the securityfs filesystem"
5656
help
5757
This will build the securityfs filesystem. It is currently used by
58-
the TPM bios character driver. It is not used by SELinux or SMACK.
58+
the TPM bios character driver and IMA, an integrity provider. It is
59+
not used by SELinux or SMACK.
5960

6061
If you are unsure how to answer this question, answer N.
6162

@@ -126,5 +127,7 @@ config SECURITY_DEFAULT_MMAP_MIN_ADDR
126127
source security/selinux/Kconfig
127128
source security/smack/Kconfig
128129

130+
source security/integrity/ima/Kconfig
131+
129132
endmenu
130133

security/Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,7 @@ obj-$(CONFIG_SECURITY_SELINUX) += selinux/built-in.o
1717
obj-$(CONFIG_SECURITY_SMACK) += smack/built-in.o
1818
obj-$(CONFIG_SECURITY_ROOTPLUG) += root_plug.o
1919
obj-$(CONFIG_CGROUP_DEVICE) += device_cgroup.o
20+
21+
# Object integrity file lists
22+
subdir-$(CONFIG_IMA) += integrity/ima
23+
obj-$(CONFIG_IMA) += integrity/ima/built-in.o

security/integrity/ima/Kconfig

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# IBM Integrity Measurement Architecture
2+
#
3+
config IMA
4+
bool "Integrity Measurement Architecture(IMA)"
5+
depends on ACPI
6+
select SECURITYFS
7+
select CRYPTO
8+
select CRYPTO_HMAC
9+
select CRYPTO_MD5
10+
select CRYPTO_SHA1
11+
select TCG_TPM
12+
select TCG_TIS
13+
help
14+
The Trusted Computing Group(TCG) runtime Integrity
15+
Measurement Architecture(IMA) maintains a list of hash
16+
values of executables and other sensitive system files,
17+
as they are read or executed. If an attacker manages
18+
to change the contents of an important system file
19+
being measured, we can tell.
20+
21+
If your system has a TPM chip, then IMA also maintains
22+
an aggregate integrity value over this list inside the
23+
TPM hardware, so that the TPM can prove to a third party
24+
whether or not critical system files have been modified.
25+
Read <http://www.usenix.org/events/sec04/tech/sailer.html>
26+
to learn more about IMA.
27+
If unsure, say N.
28+
29+
config IMA_MEASURE_PCR_IDX
30+
int
31+
depends on IMA
32+
range 8 14
33+
default 10
34+
help
35+
IMA_MEASURE_PCR_IDX determines the TPM PCR register index
36+
that IMA uses to maintain the integrity aggregate of the
37+
measurement list. If unsure, use the default 10.
38+
39+
config IMA_AUDIT
40+
bool
41+
depends on IMA
42+
default y
43+
help
44+
This option adds a kernel parameter 'ima_audit', which
45+
allows informational auditing messages to be enabled
46+
at boot. If this option is selected, informational integrity
47+
auditing messages can be enabled with 'ima_audit=1' on
48+
the kernel command line.
49+

security/integrity/ima/Makefile

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#
2+
# Makefile for building Trusted Computing Group's(TCG) runtime Integrity
3+
# Measurement Architecture(IMA).
4+
#
5+
6+
obj-$(CONFIG_IMA) += ima.o
7+
8+
ima-y := ima_queue.o ima_init.o ima_main.o ima_crypto.o ima_api.o \
9+
ima_policy.o ima_iint.o ima_audit.o

security/integrity/ima/ima.h

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
/*
2+
* Copyright (C) 2005,2006,2007,2008 IBM Corporation
3+
*
4+
* Authors:
5+
* Reiner Sailer <[email protected]>
6+
* Mimi Zohar <[email protected]>
7+
*
8+
* This program is free software; you can redistribute it and/or
9+
* modify it under the terms of the GNU General Public License as
10+
* published by the Free Software Foundation, version 2 of the
11+
* License.
12+
*
13+
* File: ima.h
14+
* internal Integrity Measurement Architecture (IMA) definitions
15+
*/
16+
17+
#ifndef __LINUX_IMA_H
18+
#define __LINUX_IMA_H
19+
20+
#include <linux/types.h>
21+
#include <linux/crypto.h>
22+
#include <linux/security.h>
23+
#include <linux/hash.h>
24+
#include <linux/tpm.h>
25+
#include <linux/audit.h>
26+
27+
enum ima_show_type { IMA_SHOW_BINARY, IMA_SHOW_ASCII };
28+
enum tpm_pcrs { TPM_PCR0 = 0, TPM_PCR8 = 8 };
29+
30+
/* digest size for IMA, fits SHA1 or MD5 */
31+
#define IMA_DIGEST_SIZE 20
32+
#define IMA_EVENT_NAME_LEN_MAX 255
33+
34+
#define IMA_HASH_BITS 9
35+
#define IMA_MEASURE_HTABLE_SIZE (1 << IMA_HASH_BITS)
36+
37+
/* set during initialization */
38+
extern int ima_initialized;
39+
extern int ima_used_chip;
40+
extern char *ima_hash;
41+
42+
/* IMA inode template definition */
43+
struct ima_template_data {
44+
u8 digest[IMA_DIGEST_SIZE]; /* sha1/md5 measurement hash */
45+
char file_name[IMA_EVENT_NAME_LEN_MAX + 1]; /* name + \0 */
46+
};
47+
48+
struct ima_template_entry {
49+
u8 digest[IMA_DIGEST_SIZE]; /* sha1 or md5 measurement hash */
50+
char *template_name;
51+
int template_len;
52+
struct ima_template_data template;
53+
};
54+
55+
struct ima_queue_entry {
56+
struct hlist_node hnext; /* place in hash collision list */
57+
struct list_head later; /* place in ima_measurements list */
58+
struct ima_template_entry *entry;
59+
};
60+
extern struct list_head ima_measurements; /* list of all measurements */
61+
62+
/* declarations */
63+
void integrity_audit_msg(int audit_msgno, struct inode *inode,
64+
const unsigned char *fname, const char *op,
65+
const char *cause, int result, int info);
66+
67+
/* Internal IMA function definitions */
68+
void ima_iintcache_init(void);
69+
int ima_init(void);
70+
int ima_add_template_entry(struct ima_template_entry *entry, int violation,
71+
const char *op, struct inode *inode);
72+
int ima_calc_hash(struct file *file, char *digest);
73+
int ima_calc_template_hash(int template_len, void *template, char *digest);
74+
int ima_calc_boot_aggregate(char *digest);
75+
void ima_add_violation(struct inode *inode, const unsigned char *filename,
76+
const char *op, const char *cause);
77+
78+
/*
79+
* used to protect h_table and sha_table
80+
*/
81+
extern spinlock_t ima_queue_lock;
82+
83+
struct ima_h_table {
84+
atomic_long_t len; /* number of stored measurements in the list */
85+
atomic_long_t violations;
86+
struct hlist_head queue[IMA_MEASURE_HTABLE_SIZE];
87+
};
88+
extern struct ima_h_table ima_htable;
89+
90+
static inline unsigned long ima_hash_key(u8 *digest)
91+
{
92+
return hash_long(*digest, IMA_HASH_BITS);
93+
}
94+
95+
/* iint cache flags */
96+
#define IMA_MEASURED 1
97+
98+
/* integrity data associated with an inode */
99+
struct ima_iint_cache {
100+
u64 version; /* track inode changes */
101+
unsigned long flags;
102+
u8 digest[IMA_DIGEST_SIZE];
103+
struct mutex mutex; /* protects: version, flags, digest */
104+
long readcount; /* measured files readcount */
105+
long writecount; /* measured files writecount */
106+
struct kref refcount; /* ima_iint_cache reference count */
107+
struct rcu_head rcu;
108+
};
109+
110+
/* LIM API function definitions */
111+
int ima_must_measure(struct ima_iint_cache *iint, struct inode *inode,
112+
int mask, int function);
113+
int ima_collect_measurement(struct ima_iint_cache *iint, struct file *file);
114+
void ima_store_measurement(struct ima_iint_cache *iint, struct file *file,
115+
const unsigned char *filename);
116+
int ima_store_template(struct ima_template_entry *entry, int violation,
117+
struct inode *inode);
118+
119+
/* radix tree calls to lookup, insert, delete
120+
* integrity data associated with an inode.
121+
*/
122+
struct ima_iint_cache *ima_iint_insert(struct inode *inode);
123+
struct ima_iint_cache *ima_iint_find_get(struct inode *inode);
124+
struct ima_iint_cache *ima_iint_find_insert_get(struct inode *inode);
125+
void ima_iint_delete(struct inode *inode);
126+
void iint_free(struct kref *kref);
127+
void iint_rcu_free(struct rcu_head *rcu);
128+
129+
/* IMA policy related functions */
130+
enum ima_hooks { PATH_CHECK = 1, FILE_MMAP, BPRM_CHECK };
131+
132+
int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask);
133+
void ima_init_policy(void);
134+
void ima_update_policy(void);
135+
#endif

0 commit comments

Comments
 (0)