integrity: IMA as an integrity service provider
Subsystems (4)
RFC PATCH 4/4 integrity: IMA as an integrity service provider
This is a re-release of Integrity Measurement Architecture(IMA) as an independent Linunx Integrity Module(LIM) service provider, which implements the new LIM must_measure(), collect_measurement(), store_measurement(), and display_template() API calls. The store_measurement() call supports two types of data, IMA (i.e. file data) and generic template data.
When store_measurement() is called for the IMA type of data, the file measurement and the file name hint are used to form an IMA template. IMA then calculates the IMA template measurement(hash) and submits it to the TPM chip for inclusion in one of the chip's Platform Configuration Registers (PCR).
When store_measurement() is called for generic template data, IMA calculates the measurement(hash) of the template data, and submits the template measurement to the TPM chip for inclusion in one of the chip's Platform Configuration Registers(PCR).
In order to view the contents of template data through securityfs, the template_display() function must be defined in the registered template_operations. In the case of the IMA template, the list of file names and files hashes submitted can be viewed through securityfs.
IMA can be included or excluded in the kernel configuration. If included in the kernel and the IMA_BOOTPARAM is selected, IMA can also be enabled/disabled on the kernel command line with 'ima='.
---
security/integrity/ima/Kconfig new file +68 -0
@@ -0,0 +1,68 @@ +# +# IBM Integrity Measurement Architecture +# + +config IMA_MEASURE + bool "TCG run-time Integrity Measurement Architecture(IMA)" + depends on INTEGRITY + depends on ACPI + select CRYPTO + select CRYPTO_HMAC + select CRYPTO_MD5 + select CRYPTO_SHA1 + select TCG_TPM + help + IMA maintains a list of hash values of executables and + other sensitive system files loaded into the run-time + of this system. If your system has a TPM chip, then IMA + also maintains an aggregate integrity value over this + list inside the TPM hardware. These measurements and + the aggregate (signed inside the TPM) can be retrieved + and presented to remote parties to establish system + properties. If unsure, say N. + +config IMA_BOOTPARAM + bool "IMA boot parameter" + depends on IMA_MEASURE + default n + help + This option adds a kernel parameter 'ima', which allows IMA + to be disabled at boot. If this option is selected, IMA + functionality can be disabled with ima=0 on the kernel + command line. The purpose of this option is to allow a single + kernel image to be distributed with IMA built in, but not + necessarily enabled. + + If you are unsure how to answer this question, answer N. + +config IMA_BOOTPARAM_VALUE + int "IMA boot parameter default value" + depends on IMA_BOOTPARAM + range 0 1 + default 0 + help + This option sets the default value for the kernel parameter + 'ima=', which allows IMA to be disabled at boot. If this + option is set to 0 (zero), the IMA kernel parameter will + default to 0, disabling IMA at bootup. If this option is + set to 1 (one), the IMA kernel parameter will default to 1, + enabling IMA at bootup. + + If you are unsure how to answer this question, answer 0. + +config IMA_MEASURE_PCR_IDX + int "PCR for Aggregate (8<= Index <= 14)" + depends on IMA_MEASURE + range 8 14 + default 10 + help + IMA_MEASURE_PCR_IDX determines the TPM PCR register index + that IMA uses to maintain the integrity aggregate of the + measurement list. If unsure, use the default 10. + +config IMA_BASE_HOOKS + bool "IMA base hooks" + depends on IMA_MEASURE + default n + help + Enable this option to allow the LSM module to enforce integrity.
security/integrity/ima/Makefile new file +6 -0
@@ -0,0 +1,6 @@ + +obj-$(CONFIG_IMA_MEASURE) += ima.o + +ifeq ($(CONFIG_IMA_MEASURE), y) +ima-y := ima_fs.o ima_queue.o ima_init.o ima_main.o ima_crypto.o ima_api.o +endif
security/integrity/ima/ima.h new file +137 -0
137 lines not on this page · raw message
security/integrity/ima/ima_crypto.c new file +170 -0
170 lines not on this page · raw message
security/integrity/ima/ima_fs.c new file +437 -0
437 lines not on this page · raw message
security/integrity/ima/ima_init.c new file +103 -0
103 lines not on this page · raw message
security/integrity/ima/ima_main.c new file +418 -0
418 lines not on this page · raw message
security/integrity/ima/ima_queue.c new file +125 -0
125 lines not on this page · raw message
Documentation/kernel-parameters.txt +12 -0
@@ -44,6 +44,7 @@ parameter is applicable: FB The frame buffer device is enabled. HW Appropriate hardware is enabled. IA-64 IA-64 architecture is enabled. + IMA Integrity measurement architecture is enabled. IOSCHED More than one I/O scheduler is enabled. IP_PNP IP DHCP, BOOTP, or RARP is enabled. ISAPNP ISA PnP code is enabled.
@@ -804,6 +805,17 @@ and is between 256 and 4096 characters. ihash_entries= [KNL] Set number of hash buckets for inode cache. + ima= [IMA] Disable or enable IMA at boot time. + Format: { "0" | "1" } + See security/ima/Kconfig help text. + 0 -- disable. + 1 -- enable. + Default value is set via kernel config option. + + ima_hash= [IMA] runtime ability to define hash crypto alg. + Format: { "MD5" | "SHA1" } + Default is "SHA1". + in2000= [HW,SCSI] See header of drivers/scsi/in2000.c.
security/integrity/Kconfig +2 -3
@@ -2,8 +2,6 @@ # Integrity configuration # -menu "Integrity options" - config INTEGRITY bool "Enable different integrity models" help
@@ -21,4 +19,5 @@ config INTEGRITY_AUDIT allows integrity auditing to be disabled at boot. If this option is selected, integrity auditing can be disabled with 'integrity_audit=0' on the kernel command line. -endmenu + +source security/integrity/ima/Kconfig
security/integrity/Makefile +2 -0
@@ -5,3 +5,5 @@ # Object file lists obj-$(CONFIG_INTEGRITY) += integrity.o integrity_dummy.o \ integrity_audit.o integrity_policy.o + +obj-$(CONFIG_IMA_MEASURE) += ima/
include/linux/ima.h new file +48 -0
48 lines not on this page · raw message
security/integrity/ima/ima_api.c new file +362 -0
362 lines not on this page · raw message
James Morris
maintainersecurity/integrity/ima/ima.h line 43
Quoted 2 lines · Mimi Zohar
security/integrity/ima/ima.h new file +2
-0+#define IMA_HASH_KEY (digest) (hash_long(\ + (unsigned long)(*digest), IMA_HASH_BITS));
Please make this a static inline and use hash_ptr().
security/integrity/ima/ima_crypto.c line 79
Quoted 7 lines
security/integrity/ima/ima_crypto.c new file +7
-0+ i_size =i_size_read (file->f_dentry->d_inode); +while (offset < i_size) { +int error; + + rbuf_len =kernel_read (file, offset, rbuf,PAGE_SIZE ); +if (rbuf_len <=0 ) +break ;
Why is the return value of kernel_read() not being propagated to the caller?
security/integrity/ima/ima_crypto.c line 87
Quoted 5 lines
security/integrity/ima/ima_crypto.c new file +5
-0+ error =crypto_hash_update (desc, sg, rbuf_len); +if (error) { + result = -EINVAL ; +break ; + }
Why are you replacing the error code from crypto_hash_update() with -EINVAL ?
security/integrity/ima/ima_crypto.c line 115
Quoted 6 lines
security/integrity/ima/ima_crypto.c new file +6
-0+ tfm =crypto_alloc_hash (ima_hash,0 ,CRYPTO_ALG_ASYNC ); +if (IS_ERR (tfm)) { +printk (KERN_INFO "%s: failed to load %s transform: %ld\n" , + __func__, ima_hash,PTR_ERR (tfm)); +return -ENOSYS ; + }
Similarly, why not propagate the actual error ?
(This kind of thing happens quite a lot in the code).
Quoted 7 lines
security/integrity/ima/ima_main.c new file +7
-0+static int __init init_ima (void ) +{ +int error; + tfm_hash =crypto_alloc_hash (ima_hash,0 ,CRYPTO_ALG_ASYNC ); + + error =ima_init (); +if (error)
security/integrity/ima/ima_main.c line 405
Quoted 10 lines
security/integrity/ima/ima_main.c new file +10
-0+ goto out; +ima_fixup_inodes (); +if (ima_base_hooks) + error =register_integrity (&ima_base_ops); +else + error =register_integrity (&ima_integrity_ops); +register_template ("ima" , &ima_template_ops); +out: +return error; +}
What if crypto_alloc_hash() fails ? Actually, where is it used?
- James
Signature · 2 lines
James Morris <[email protected]>
Thank you for reviewing the code. Will fix these and add locking around integrity_templates.
Mimi
Quoted 62 lines · James Morris
security/integrity/ima/ima.h line 43
Quoted 2 lines · Mimi Zohar
security/integrity/ima/ima.h new file +2
-0+#define IMA_HASH_KEY (digest) (hash_long(\ + (unsigned long)(*digest), IMA_HASH_BITS));Please make this a static inline and use
hash_ptr().security/integrity/ima/ima_crypto.c line 79
Quoted 7 lines
security/integrity/ima/ima_crypto.c new file +7
-0+ i_size =i_size_read (file->f_dentry->d_inode); +while (offset < i_size) { +int error; + + rbuf_len =kernel_read (file, offset, rbuf,PAGE_SIZE ); +if (rbuf_len <=0 ) +break ;Why is the return value of
kernel_read()not being propagated to the caller?security/integrity/ima/ima_crypto.c line 87
Quoted 5 lines
security/integrity/ima/ima_crypto.c new file +5
-0+ error =crypto_hash_update (desc, sg, rbuf_len); +if (error) { + result = -EINVAL ; +break ; + }Why are you replacing the error code from
crypto_hash_update()with-EINVAL?security/integrity/ima/ima_crypto.c line 115
Quoted 6 lines
security/integrity/ima/ima_crypto.c new file +6
-0+ tfm =crypto_alloc_hash (ima_hash,0 ,CRYPTO_ALG_ASYNC ); +if (IS_ERR (tfm)) { +printk (KERN_INFO "%s: failed to load %s transform: %ld\n" , + __func__, ima_hash,PTR_ERR (tfm)); +return -ENOSYS ; + }Similarly, why not propagate the actual error ?
(This kind of thing happens quite a lot in the code).
Quoted 7 lines
security/integrity/ima/ima_main.c new file +7
-0+static int __init init_ima (void ) +{ +int error; + tfm_hash =crypto_alloc_hash (ima_hash,0 ,CRYPTO_ALG_ASYNC ); + + error =ima_init (); +if (error)security/integrity/ima/ima_main.c line 405
Quoted 10 lines
security/integrity/ima/ima_main.c new file +10
-0+ goto out; +ima_fixup_inodes (); +if (ima_base_hooks) + error =register_integrity (&ima_base_ops); +else + error =register_integrity (&ima_integrity_ops); +register_template ("ima" , &ima_template_ops); +out: +return error; +}What if
crypto_alloc_hash()fails ? Actually, where is it used?- James