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='. Signed-off-by: Mimi Zohar <zohar@us.ibm.com> --- Index: linux-2.6.26-rc3-git2/security/integrity/ima/Kconfig =================================================================== --- /dev/null +++ linux-2.6.26-rc3-git2/security/integrity/ima/Kconfig @@ -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 + ...
kernel-doc notation first line (short description) cannot be continued --- ~Randy --
TCG stands for Trusted Computing Group. (https://www.trustedcomputinggroup.org/faq/) Thank you for reviewing the code. I'll make the kernel doc, Kconfig and Makefile changes and repost. Mimi --
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='. Signed-off-by: Mimi Zohar <zohar@us.ibm.com> --- Index: linux-2.6.26-rc3-git2/security/integrity/ima/Kconfig =================================================================== --- /dev/null +++ linux-2.6.26-rc3-git2/security/integrity/ima/Kconfig @@ -0,0 +1,69 @@ +# +# IBM Integrity Measurement Architecture +# + +config IMA_MEASURE + bool "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 + The Trusted Computing Group(TCG) runtime Integrity + Measurement ...
- I see lots of user file I/O being done from within the kernel. This makes eyebrows raise. Also some other eyebrow-raising file-related things in there. - A complicated-looking in-kernel string parser which is implementing an new and apparently-undocumented user->kernel ABI. - Some GFP_ATOMICs which can hopefully become GFP_KERNEL. - timespec_set() is unneeeded - just use struct assignment (ie: "=") - timespec_recent() looks a bit hacky. The problems which are being solved here should be described in the changelog. Perhaps we can think of a better way, but first we have to know about it. - shouldn't ima_inode_init() initialise tv_usec too? - All the games with mtimes should be described in the changelog too. - All the `static struct integrity_operations' instances could be made const. And lots of other foo_operations too, I expect. That will lead to a constification chase all over the place, but it's probably for the best. This is after all a "security" feature and there is perhaps some benefit in getting your eminently hijackable function pointers into read-only memory. - ima_fixup_inodes looks like it will race and crash against a well-timed unmount. I expect you will need to bump s_count before dropping sb_lock. See writeback_inodes() for an example. - bug: ima_fixup_inodes() does a GFP_KERNEL allocation inside inode->i_lock. This bug shouldn't have got this far. Please always enable all kernel debugging features when testing code. Documentation/SubmitChecklist has useful things. - inode.i_lock is defined as an innermost lock which is used for protecting data internal to the inode. You appear to be using it for way too much stuff in here. - It would be useful to add a comment explaining why late_initcall(init_ima) is using late_initcall() rather than plain old module_init(). Because it is impossible for the reader to determine this information from the implementation. - ...
The amount of I/O is dependent on the number of files being measured.
The default policy measures a whole lot. An LSM specific integrity
policy would cut down on the number of files being measured. For now,
either remove the third rule in default_rules or replace the default
rules with a new policy. To load a new policy execute:
./integrity_load < policy
policy:
#
# Integrity measure policy
#
func=BPRM_CHECK
func=FILE_MMAP mask=MAY_EXEC
#func=INODE_PERMISSION mask=MAY_READ
integrity_load.c:
/*
* integrity_load.c
*
* Strip comments from integrity measurement policy file and load
* policy rules into the kernel by writing to security/ima/policy.
*
*/
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
int fd;
char *policyname = "/sys/kernel/security/ima/policy";
char *line = NULL;
ssize_t len = 0, readcnt;
int rc = 0;
if (argc == 2)
policyname = argv[1];
fd = open(policyname, O_WRONLY);
if (fd == -1) {
perror("opening policy");
exit(EXIT_FAILURE);
}
while ((readcnt = getline(&line, &len, stdin)) != -1) {
if (*line == '#')
continue;
printf("%s", line);
rc = write(fd, line, readcnt);
if (rc == -1) {
perror("write");
break;
}
}
close(fd);
if (line)
free(line);
return (rc == -1) ? EXIT_FAILURE : EXIT_SUCCESS;
Am confused. timespec_set is doing an assignment. Should I
I don't think it matters. timespec_equal checks that the mtime in
the iint and inode are the same. If they are the same then we don't
need to recalculate the hash, unless it's been updated in really
Ok. The timespec_recent and mtime issues are part of the same problem
Yes, one solution is to add policy support so that rules could be
defined instead of actually hard coding each and every fs magic
Ok.
--
The problem is that the code is doing in-kernel user file I/O *at all*. It's a red flag. Look who else is using kernel_read(): just the exec code. Plus struct timespec a, b; What is "initialisation"? During initcalls? Are there even any files in cache at that time? I bet we can arrange for the answer to become "no". --
i_version is now working on my system. It looks good. Is there anything that I need to be concerned about, such as limited filesystem support or the i_version is not updated by file_close for mmaped files? Thanks! Mimi --
On Thu, 29 May 2008 17:50:34 -0400 erk, I'm not an i_version person. It seems that it's only used on directories (to patch up readdir coherency problems) so I guess I misled you there. There's file_struct.f_version, which is no good. i_generation is no good either. We've documented these things so wonderfully! i_writecount looks good? --
No, no. Initially, that's what I thought. I finally found file_update_time() calls inode_inc_iversion(), which updates the i_version. So, it does work. The question is whether --
OK. Before 2.6.17 it wouldn't have worked much at all on MAP_SHARED modifications. After 2.6.17 things will be better - we update the mtime on the clean->dirty transitions of a page. So the first modification after an mmap will update the time. Subsequent modifications via the mmap will not update the file time. Until something (usually pdflush) writes the page out. Then the next modification via mmap will cause another clean->dirty transition on the page, hence another mtime update. So there's a by-default 30-odd second uncertainty with MAP_SHARED alterations. --
Yes, during the initcalls. Is this possible even when using late_initcall(). IMA is dependent on the TPM being available, if it is being used. Mimi --
This is one of the five integrity API calls. Each integrity template
ima_collect_measurement is also one of the five integrity API calls.
Here is a sample template kernel module that measures kernel memory.
Of the five integrity API calls, it implements
integrity_collect_measurement(), integrity_store_measurement(), and
integrity_display_measurement(). It collects and stores measurements
based on data read from security/kmem-template. The format is
"name length address". The name can be any string identifier such as
"proc_root"; the length is the number of bytes to measure; and address
is a kernel memory address, which can be looked up in /proc/kallsyms.
One caveat, the sample program currently does not validate the address.
A userspace application triggers the measurement by writing to
security/kmem-template.
/*
* Copyright (C) 2008 IBM Corporation
* Author: Mimi Zohar <zohar@us.ibm.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 2 of the License.
*
* kmem-template.c
* - defines a kernel memory template
* - reads from security/kmem-template "name length address"
* - collects and stores measurement from address for length bytes
*/
#include <asm/uaccess.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/crypto.h>
#include <linux/scatterlist.h>
#include <linux/notifier.h>
#include <linux/security.h>
#include <linux/debugfs.h>
#include <linux/seq_file.h>
#include <linux/string.h>
#include <linux/proc_fs.h>
#include <linux/security.h>
#include <linux/integrity.h>
#include <linux/ima.h>
#define MY_NAME THIS_MODULE->name
#define IMA_DIGEST_SIZE 20
static int __init init_kmem_template(void);
static void __exit cleanup_kmem_template(void);
struct kmem_data {
char name[25];
char *buf;
int ......also, it would be nice to see explanation 'what is this good for'. Closest explanation I remember was 'it will protect you by making system unbootable if someone stole disk with your /usr filesystem -- but not / filesystem -- added some rootkit, and then stealthily returned it'. That seems a) very unlikely scenario and b) probably better solved by encrypting /usr. Pavel -- (english) http://www.livejournal.com/~pavelmachek (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html --
Sorry about this delayed response - we are about to repost for RFC, and noticed we missed responding to this. You are thinking about a related project, EVM, which HMAC's a file's metadata, to protect against off-line attacks, (which admittedly many users are not concerned about.) This submission, IMA, provides hardware (TPM) based measurement and attestation, which measures all files before they are accessed in any way (on the inode_permission, bprm and mmap hooks), and commits the measurements to the TPM. The TPM can sign these measurement lists, and thus the system can prove to itself and to a third party these measurements in a way that cannot be circumvented by malicious or compromised software. IMA is just one part of integrity detection, as it does not detect purely in-memory attacks, such as worms. dave safford --
And proofing to third party is useful for what....? Given that it can be worked around by modifying files in memory, or by special hardware...? Disney? Pavel -- (english) http://www.livejournal.com/~pavelmachek (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html --
Sorry about this delayed response - we are about to repost for RFC, and noticed we missed responding to this. The Trusted Computing (TPM) model requires that all files be measured, (hashed) and the measurement committed to the hardware TPM before any data of the file is accessed in any way. In addition, if the measurement is incorrect, all access to the file must be denied. This requirement parallels the LSM mandatory access control decisions in the inode_permission, bprm, and mmap hooks, and naturally leads to IMA hooks in the same locations, with similar functionality, but with the addition of hashing the data. The code would have to significantly more complex to do the hashing at these points through userspace. In addition, doing the hashing in userspace gives significantly poorer performance. With in-kernel hashing, at boot time, we typically measure some six thousand files with less than 10% (5 seconds) overhead, which is acceptable to most users. Anything much slower can be annoying enough that users will turn the measurement off. dave safford --
TPM model may require this, but what is the benefit to the user/owner of the machine? Pavel -- (english) http://www.livejournal.com/~pavelmachek (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html --
