* [PATCH 0/7] integrity
@ 2009-02-04 14:06 Mimi Zohar
2009-02-04 14:06 ` [PATCH 1/7] integrity: IMA hooks Mimi Zohar
` (8 more replies)
0 siblings, 9 replies; 19+ messages in thread
From: Mimi Zohar @ 2009-02-04 14:06 UTC (permalink / raw)
To: linux-kernel
Cc: Mimi Zohar, Andrew Morton, James Morris, David Safford,
Serge Hallyn
This patchset contains the IMA integrity patches. The changes made since
the last integrity posting are based on comments made by James Morris and
Serge Hallyn.
- removed test for NULL return code from securityfs_create_file/dir
- alloc ima_template_entry before calling ima_store_template()
- log ima_add_boot_aggregate failure
- free invalid rule
- add hook to increment opencount for /dev/zero shm
- replaced hard coded string length with #define name
- removed unused IMA_TEMPLATE_NAME_LEN
This patchset is dependent on the tpm-integrity-interface patch, which
has been applied to the security-testing-2.6/#next.
Mimi Zohar (7):
integrity: IMA hooks
integrity: IMA as an integrity service provider
integrity: IMA display
integrity: IMA policy
integrity: IMA policy open
Integrity: IMA file free imbalance
Integrity: IMA update maintainers
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 1/7] integrity: IMA hooks
2009-02-04 14:06 [PATCH 0/7] integrity Mimi Zohar
@ 2009-02-04 14:06 ` Mimi Zohar
2009-02-04 14:06 ` [PATCH 2/7] integrity: IMA as an integrity service provider Mimi Zohar
` (7 subsequent siblings)
8 siblings, 0 replies; 19+ messages in thread
From: Mimi Zohar @ 2009-02-04 14:06 UTC (permalink / raw)
To: linux-kernel
Cc: Mimi Zohar, Andrew Morton, James Morris, David Safford,
Serge Hallyn, Mimi Zohar
This patch replaces the generic integrity hooks, for which IMA registered
itself, with IMA integrity hooks in the appropriate places directly
in the fs directory.
Signed-off-by: Mimi Zohar <zohar@us.ibm.com>
Acked-by: Serge Hallyn <serue@us.ibm.com>
---
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index a2d8805..7c67b94 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -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.
diff --git a/fs/exec.c b/fs/exec.c
index 02d2e12..9c789a5 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -45,6 +45,7 @@
#include <linux/proc_fs.h>
#include <linux/mount.h>
#include <linux/security.h>
+#include <linux/ima.h>
#include <linux/syscalls.h>
#include <linux/tsacct_kern.h>
#include <linux/cn_proc.h>
@@ -130,6 +131,9 @@ asmlinkage long sys_uselib(const char __user * library)
error = vfs_permission(&nd, MAY_READ | MAY_EXEC | MAY_OPEN);
if (error)
goto exit;
+ error = ima_path_check(&nd.path, MAY_READ | MAY_EXEC | MAY_OPEN);
+ if (error)
+ goto exit;
file = nameidata_to_filp(&nd, O_RDONLY|O_LARGEFILE);
error = PTR_ERR(file);
@@ -683,6 +687,9 @@ struct file *open_exec(const char *name)
err = vfs_permission(&nd, MAY_EXEC | MAY_OPEN);
if (err)
goto out_path_put;
+ err = ima_path_check(&nd.path, MAY_EXEC | MAY_OPEN);
+ if (err)
+ goto out_path_put;
file = nameidata_to_filp(&nd, O_RDONLY|O_LARGEFILE);
if (IS_ERR(file))
@@ -1209,6 +1216,9 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
retval = security_bprm_check(bprm);
if (retval)
return retval;
+ retval = ima_bprm_check(bprm);
+ if (retval)
+ return retval;
/* kernel module loader fixup */
/* so we don't try to load run modprobe in kernel space. */
diff --git a/fs/file_table.c b/fs/file_table.c
index 0fbcacc..55895cc 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -13,6 +13,7 @@
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/security.h>
+#include <linux/ima.h>
#include <linux/eventpoll.h>
#include <linux/rcupdate.h>
#include <linux/mount.h>
@@ -276,6 +277,7 @@ void __fput(struct file *file)
if (file->f_op && file->f_op->release)
file->f_op->release(inode, file);
security_file_free(file);
+ ima_file_free(file);
if (unlikely(S_ISCHR(inode->i_mode) && inode->i_cdev != NULL))
cdev_put(inode->i_cdev);
fops_put(file->f_op);
diff --git a/fs/inode.c b/fs/inode.c
index 098a244..ed22b14 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -17,6 +17,7 @@
#include <linux/hash.h>
#include <linux/swap.h>
#include <linux/security.h>
+#include <linux/ima.h>
#include <linux/pagemap.h>
#include <linux/cdev.h>
#include <linux/bootmem.h>
@@ -144,13 +145,13 @@ struct inode *inode_init_always(struct super_block *sb, struct inode *inode)
inode->i_cdev = NULL;
inode->i_rdev = 0;
inode->dirtied_when = 0;
- if (security_inode_alloc(inode)) {
- if (inode->i_sb->s_op->destroy_inode)
- inode->i_sb->s_op->destroy_inode(inode);
- else
- kmem_cache_free(inode_cachep, (inode));
- return NULL;
- }
+
+ if (security_inode_alloc(inode))
+ goto out_free_inode;
+
+ /* allocate and initialize an i_integrity */
+ if (ima_inode_alloc(inode))
+ goto out_free_security;
spin_lock_init(&inode->i_lock);
lockdep_set_class(&inode->i_lock, &sb->s_type->i_lock_key);
@@ -186,6 +187,15 @@ struct inode *inode_init_always(struct super_block *sb, struct inode *inode)
inode->i_mapping = mapping;
return inode;
+
+out_free_security:
+ security_inode_free(inode);
+out_free_inode:
+ if (inode->i_sb->s_op->destroy_inode)
+ inode->i_sb->s_op->destroy_inode(inode);
+ else
+ kmem_cache_free(inode_cachep, (inode));
+ return NULL;
}
EXPORT_SYMBOL(inode_init_always);
diff --git a/fs/namei.c b/fs/namei.c
index af3783f..d4654ce 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -24,6 +24,7 @@
#include <linux/fsnotify.h>
#include <linux/personality.h>
#include <linux/security.h>
+#include <linux/ima.h>
#include <linux/syscalls.h>
#include <linux/mount.h>
#include <linux/audit.h>
@@ -860,6 +861,8 @@ static int __link_path_walk(const char *name, struct nameidata *nd)
err = exec_permission_lite(inode);
if (err == -EAGAIN)
err = vfs_permission(nd, MAY_EXEC);
+ if (!err)
+ err = ima_path_check(&nd->path, MAY_EXEC);
if (err)
break;
@@ -1525,6 +1528,11 @@ int may_open(struct nameidata *nd, int acc_mode, int flag)
error = vfs_permission(nd, acc_mode);
if (error)
return error;
+
+ error = ima_path_check(&nd->path,
+ acc_mode & (MAY_READ | MAY_WRITE | MAY_EXEC));
+ if (error)
+ return error;
/*
* An append-only file must be opened in append mode for writing.
*/
diff --git a/include/linux/ima.h b/include/linux/ima.h
new file mode 100644
index 0000000..4ed1e4d
--- /dev/null
+++ b/include/linux/ima.h
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+
+#include <linux/fs.h>
+
+#ifndef _LINUX_IMA_H
+#define _LINUX_IMA_H
+
+static inline int ima_bprm_check(struct linux_binprm *bprm)
+{
+ return 0;
+}
+
+static inline int ima_inode_alloc(struct inode *inode)
+{
+ return 0;
+}
+
+static inline void ima_inode_free(struct inode *inode)
+{
+ return;
+}
+
+static inline int ima_path_check(struct path *path, int mask)
+{
+ return 0;
+}
+
+static inline void ima_file_free(struct file *file)
+{
+ return;
+}
+
+static inline int ima_file_mmap(struct file *file, unsigned long prot)
+{
+ return 0;
+}
+#endif /* _LINUX_IMA_H */
diff --git a/mm/mmap.c b/mm/mmap.c
index d4855a6..c3647f3 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -20,6 +20,7 @@
#include <linux/fs.h>
#include <linux/personality.h>
#include <linux/security.h>
+#include <linux/ima.h>
#include <linux/hugetlb.h>
#include <linux/profile.h>
#include <linux/module.h>
@@ -1050,6 +1051,9 @@ unsigned long do_mmap_pgoff(struct file * file, unsigned long addr,
error = security_file_mmap(file, reqprot, prot, flags, addr, 0);
if (error)
return error;
+ error = ima_file_mmap(file, prot);
+ if (error)
+ return error;
return mmap_region(file, addr, len, flags, vm_flags, pgoff,
accountable);
--
1.5.6.6
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 2/7] integrity: IMA as an integrity service provider
2009-02-04 14:06 [PATCH 0/7] integrity Mimi Zohar
2009-02-04 14:06 ` [PATCH 1/7] integrity: IMA hooks Mimi Zohar
@ 2009-02-04 14:06 ` Mimi Zohar
2009-02-06 20:31 ` Serge E. Hallyn
2009-02-10 20:23 ` Pavel Machek
2009-02-04 14:06 ` [PATCH 3/7] integrity: IMA display Mimi Zohar
` (6 subsequent siblings)
8 siblings, 2 replies; 19+ messages in thread
From: Mimi Zohar @ 2009-02-04 14:06 UTC (permalink / raw)
To: linux-kernel
Cc: Mimi Zohar, Andrew Morton, James Morris, David Safford,
Serge Hallyn, Mimi Zohar
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 <zohar@us.ibm.com>
---
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 7c67b94..31e0c2c 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -895,6 +895,15 @@ and is between 256 and 4096 characters. It is defined in the file
ihash_entries= [KNL]
Set number of hash buckets for inode cache.
+ ima_audit= [IMA]
+ Format: { "0" | "1" }
+ 0 -- integrity auditing messages. (Default)
+ 1 -- enable informational integrity auditing messages.
+
+ ima_hash= [IMA]
+ Formt: { "sha1" | "md5" }
+ default: "sha1"
+
in2000= [HW,SCSI]
See header of drivers/scsi/in2000.c.
diff --git a/include/linux/audit.h b/include/linux/audit.h
index 26c4f6f..8d1f677 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -125,6 +125,11 @@
#define AUDIT_LAST_KERN_ANOM_MSG 1799
#define AUDIT_ANOM_PROMISCUOUS 1700 /* Device changed promiscuous mode */
#define AUDIT_ANOM_ABEND 1701 /* Process ended abnormally */
+#define AUDIT_INTEGRITY_DATA 1800 /* Data integrity verification */
+#define AUDIT_INTEGRITY_METADATA 1801 /* Metadata integrity verification */
+#define AUDIT_INTEGRITY_STATUS 1802 /* Integrity enable status */
+#define AUDIT_INTEGRITY_HASH 1803 /* Integrity HASH type */
+#define AUDIT_INTEGRITY_PCR 1804 /* PCR invalidation msgs */
#define AUDIT_KERNEL 2000 /* Asynchronous audit record. NOT A REQUEST. */
diff --git a/include/linux/ima.h b/include/linux/ima.h
index 4ed1e4d..dcc3664 100644
--- a/include/linux/ima.h
+++ b/include/linux/ima.h
@@ -12,6 +12,15 @@
#ifndef _LINUX_IMA_H
#define _LINUX_IMA_H
+#ifdef CONFIG_IMA
+extern int ima_bprm_check(struct linux_binprm *bprm);
+extern int ima_inode_alloc(struct inode *inode);
+extern void ima_inode_free(struct inode *inode);
+extern int ima_path_check(struct path *path, int mask);
+extern void ima_file_free(struct file *file);
+extern int ima_file_mmap(struct file *file, unsigned long prot);
+
+#else
static inline int ima_bprm_check(struct linux_binprm *bprm)
{
return 0;
@@ -41,4 +50,5 @@ static inline int ima_file_mmap(struct file *file, unsigned long prot)
{
return 0;
}
+#endif /* CONFIG_IMA_H */
#endif /* _LINUX_IMA_H */
diff --git a/security/Kconfig b/security/Kconfig
index d9f47ce..a79b23f 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -55,7 +55,8 @@ config SECURITYFS
bool "Enable the securityfs filesystem"
help
This will build the securityfs filesystem. It is currently used by
- the TPM bios character driver. It is not used by SELinux or SMACK.
+ the TPM bios character driver and IMA, an integrity provider. It is
+ not used by SELinux or SMACK.
If you are unsure how to answer this question, answer N.
@@ -126,5 +127,7 @@ config SECURITY_DEFAULT_MMAP_MIN_ADDR
source security/selinux/Kconfig
source security/smack/Kconfig
+source security/integrity/ima/Kconfig
+
endmenu
diff --git a/security/Makefile b/security/Makefile
index c05c127..595536c 100644
--- a/security/Makefile
+++ b/security/Makefile
@@ -17,3 +17,7 @@ obj-$(CONFIG_SECURITY_SELINUX) += selinux/built-in.o
obj-$(CONFIG_SECURITY_SMACK) += smack/built-in.o
obj-$(CONFIG_SECURITY_ROOTPLUG) += root_plug.o
obj-$(CONFIG_CGROUP_DEVICE) += device_cgroup.o
+
+# Object integrity file lists
+subdir-$(CONFIG_IMA) += integrity/ima
+obj-$(CONFIG_IMA) += integrity/ima/built-in.o
diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig
new file mode 100644
index 0000000..2a761c8
--- /dev/null
+++ b/security/integrity/ima/Kconfig
@@ -0,0 +1,49 @@
+# IBM Integrity Measurement Architecture
+#
+config IMA
+ bool "Integrity Measurement Architecture(IMA)"
+ depends on ACPI
+ select SECURITYFS
+ select CRYPTO
+ select CRYPTO_HMAC
+ select CRYPTO_MD5
+ select CRYPTO_SHA1
+ select TCG_TPM
+ select TCG_TIS
+ help
+ The Trusted Computing Group(TCG) runtime Integrity
+ Measurement Architecture(IMA) maintains a list of hash
+ values of executables and other sensitive system files,
+ as they are read or executed. If an attacker manages
+ to change the contents of an important system file
+ being measured, we can tell.
+
+ If your system has a TPM chip, then IMA also maintains
+ an aggregate integrity value over this list inside the
+ TPM hardware, so that the TPM can prove to a third party
+ whether or not critical system files have been modified.
+ Read <http://www.usenix.org/events/sec04/tech/sailer.html>
+ to learn more about IMA.
+ If unsure, say N.
+
+config IMA_MEASURE_PCR_IDX
+ int
+ depends on IMA
+ 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_AUDIT
+ bool
+ depends on IMA
+ default y
+ help
+ This option adds a kernel parameter 'ima_audit', which
+ allows informational auditing messages to be enabled
+ at boot. If this option is selected, informational integrity
+ auditing messages can be enabled with 'ima_audit=1' on
+ the kernel command line.
+
diff --git a/security/integrity/ima/Makefile b/security/integrity/ima/Makefile
new file mode 100644
index 0000000..9d6bf97
--- /dev/null
+++ b/security/integrity/ima/Makefile
@@ -0,0 +1,9 @@
+#
+# Makefile for building Trusted Computing Group's(TCG) runtime Integrity
+# Measurement Architecture(IMA).
+#
+
+obj-$(CONFIG_IMA) += ima.o
+
+ima-y := ima_queue.o ima_init.o ima_main.o ima_crypto.o ima_api.o \
+ ima_policy.o ima_iint.o ima_audit.o
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
new file mode 100644
index 0000000..bfa72ed
--- /dev/null
+++ b/security/integrity/ima/ima.h
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2005,2006,2007,2008 IBM Corporation
+ *
+ * Authors:
+ * Reiner Sailer <sailer@watson.ibm.com>
+ * 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.
+ *
+ * File: ima.h
+ * internal Integrity Measurement Architecture (IMA) definitions
+ */
+
+#ifndef __LINUX_IMA_H
+#define __LINUX_IMA_H
+
+#include <linux/types.h>
+#include <linux/crypto.h>
+#include <linux/security.h>
+#include <linux/hash.h>
+#include <linux/tpm.h>
+#include <linux/audit.h>
+
+enum ima_show_type { IMA_SHOW_BINARY, IMA_SHOW_ASCII };
+enum tpm_pcrs { TPM_PCR0 = 0, TPM_PCR8 = 8 };
+
+/* digest size for IMA, fits SHA1 or MD5 */
+#define IMA_DIGEST_SIZE 20
+#define IMA_EVENT_NAME_LEN_MAX 255
+
+#define IMA_HASH_BITS 9
+#define IMA_MEASURE_HTABLE_SIZE (1 << IMA_HASH_BITS)
+
+/* set during initialization */
+extern int ima_initialized;
+extern int ima_used_chip;
+extern char *ima_hash;
+
+/* IMA inode template definition */
+struct ima_template_data {
+ u8 digest[IMA_DIGEST_SIZE]; /* sha1/md5 measurement hash */
+ char file_name[IMA_EVENT_NAME_LEN_MAX + 1]; /* name + \0 */
+};
+
+struct ima_template_entry {
+ u8 digest[IMA_DIGEST_SIZE]; /* sha1 or md5 measurement hash */
+ char *template_name;
+ int template_len;
+ struct ima_template_data template;
+};
+
+struct ima_queue_entry {
+ struct hlist_node hnext; /* place in hash collision list */
+ struct list_head later; /* place in ima_measurements list */
+ struct ima_template_entry *entry;
+};
+extern struct list_head ima_measurements; /* list of all measurements */
+
+/* declarations */
+void integrity_audit_msg(int audit_msgno, struct inode *inode,
+ const unsigned char *fname, const char *op,
+ const char *cause, int result, int info);
+
+/* Internal IMA function definitions */
+void ima_iintcache_init(void);
+int ima_init(void);
+int ima_add_template_entry(struct ima_template_entry *entry, int violation,
+ const char *op, struct inode *inode);
+int ima_calc_hash(struct file *file, char *digest);
+int ima_calc_template_hash(int template_len, void *template, char *digest);
+int ima_calc_boot_aggregate(char *digest);
+void ima_add_violation(struct inode *inode, const unsigned char *filename,
+ const char *op, const char *cause);
+
+/*
+ * used to protect h_table and sha_table
+ */
+extern spinlock_t ima_queue_lock;
+
+struct ima_h_table {
+ atomic_long_t len; /* number of stored measurements in the list */
+ atomic_long_t violations;
+ struct hlist_head queue[IMA_MEASURE_HTABLE_SIZE];
+};
+extern struct ima_h_table ima_htable;
+
+static inline unsigned long ima_hash_key(u8 *digest)
+{
+ return hash_long(*digest, IMA_HASH_BITS);
+}
+
+/* iint cache flags */
+#define IMA_MEASURED 1
+
+/* integrity data associated with an inode */
+struct ima_iint_cache {
+ u64 version; /* track inode changes */
+ unsigned long flags;
+ u8 digest[IMA_DIGEST_SIZE];
+ struct mutex mutex; /* protects: version, flags, digest */
+ long readcount; /* measured files readcount */
+ long writecount; /* measured files writecount */
+ struct kref refcount; /* ima_iint_cache reference count */
+ struct rcu_head rcu;
+};
+
+/* LIM API function definitions */
+int ima_must_measure(struct ima_iint_cache *iint, struct inode *inode,
+ int mask, int function);
+int ima_collect_measurement(struct ima_iint_cache *iint, struct file *file);
+void ima_store_measurement(struct ima_iint_cache *iint, struct file *file,
+ const unsigned char *filename);
+int ima_store_template(struct ima_template_entry *entry, int violation,
+ struct inode *inode);
+
+/* radix tree calls to lookup, insert, delete
+ * integrity data associated with an inode.
+ */
+struct ima_iint_cache *ima_iint_insert(struct inode *inode);
+struct ima_iint_cache *ima_iint_find_get(struct inode *inode);
+struct ima_iint_cache *ima_iint_find_insert_get(struct inode *inode);
+void ima_iint_delete(struct inode *inode);
+void iint_free(struct kref *kref);
+void iint_rcu_free(struct rcu_head *rcu);
+
+/* IMA policy related functions */
+enum ima_hooks { PATH_CHECK = 1, FILE_MMAP, BPRM_CHECK };
+
+int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask);
+void ima_init_policy(void);
+void ima_update_policy(void);
+#endif
diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
new file mode 100644
index 0000000..a148a25
--- /dev/null
+++ b/security/integrity/ima/ima_api.c
@@ -0,0 +1,190 @@
+/*
+ * 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.
+ *
+ * File: ima_api.c
+ * Implements must_measure, collect_measurement, store_measurement,
+ * and store_template.
+ */
+#include <linux/module.h>
+
+#include "ima.h"
+static char *IMA_TEMPLATE_NAME = "ima";
+
+/*
+ * ima_store_template - store ima template measurements
+ *
+ * Calculate the hash of a template entry, add the template entry
+ * to an ordered list of measurement entries maintained inside the kernel,
+ * and also update the aggregate integrity value (maintained inside the
+ * configured TPM PCR) over the hashes of the current list of measurement
+ * entries.
+ *
+ * Applications retrieve the current kernel-held measurement list through
+ * the securityfs entries in /sys/kernel/security/ima. The signed aggregate
+ * TPM PCR (called quote) can be retrieved using a TPM user space library
+ * and is used to validate the measurement list.
+ *
+ * Returns 0 on success, error code otherwise
+ */
+int ima_store_template(struct ima_template_entry *entry,
+ int violation, struct inode *inode)
+{
+ const char *op = "add_template_measure";
+ const char *audit_cause = "hashing_error";
+ int result;
+
+ memset(entry->digest, 0, sizeof(entry->digest));
+ entry->template_name = IMA_TEMPLATE_NAME;
+ entry->template_len = sizeof(entry->template);
+
+ if (!violation) {
+ result = ima_calc_template_hash(entry->template_len,
+ &entry->template,
+ entry->digest);
+ if (result < 0) {
+ integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode,
+ entry->template_name, op,
+ audit_cause, result, 0);
+ return result;
+ }
+ }
+ result = ima_add_template_entry(entry, violation, op, inode);
+ return result;
+}
+
+/*
+ * ima_add_violation - add violation to measurement list.
+ *
+ * Violations are flagged in the measurement list with zero hash values.
+ * By extending the PCR with 0xFF's instead of with zeroes, the PCR
+ * value is invalidated.
+ */
+void ima_add_violation(struct inode *inode, const unsigned char *filename,
+ const char *op, const char *cause)
+{
+ struct ima_template_entry *entry;
+ int violation = 1;
+ int result;
+
+ /* can overflow, only indicator */
+ atomic_long_inc(&ima_htable.violations);
+
+ entry = kmalloc(sizeof(*entry), GFP_KERNEL);
+ if (!entry) {
+ result = -ENOMEM;
+ goto err_out;
+ }
+ memset(&entry->template, 0, sizeof(entry->template));
+ strncpy(entry->template.file_name, filename, IMA_EVENT_NAME_LEN_MAX);
+ result = ima_store_template(entry, violation, inode);
+ if (result < 0)
+ kfree(entry);
+err_out:
+ integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, filename,
+ op, cause, result, 0);
+}
+
+/**
+ * ima_must_measure - 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 (PATH_CHECK, BPRM_CHECK, FILE_MMAP)
+ *
+ * The policy is defined in terms of keypairs:
+ * subj=, obj=, type=, func=, mask=, fsmagic=
+ * subj,obj, and type: are LSM specific.
+ * func: PATH_CHECK | BPRM_CHECK | FILE_MMAP
+ * mask: contains the permission mask
+ * fsmagic: hex value
+ *
+ * Must be called with iint->mutex held.
+ *
+ * Return 0 to measure. Return 1 if already measured.
+ * For matching a DONT_MEASURE policy, no policy, or other
+ * error, return an error code.
+*/
+int ima_must_measure(struct ima_iint_cache *iint, struct inode *inode,
+ int mask, int function)
+{
+ int must_measure;
+
+ if (iint->flags & IMA_MEASURED)
+ return 1;
+
+ must_measure = ima_match_policy(inode, function, mask);
+ return must_measure ? 0 : -EACCES;
+}
+
+/*
+ * ima_collect_measurement - collect file measurement
+ *
+ * Calculate the file hash, if it doesn't already exist,
+ * storing the measurement and i_version in the iint.
+ *
+ * Must be called with iint->mutex held.
+ *
+ * Return 0 on success, error code otherwise
+ */
+int ima_collect_measurement(struct ima_iint_cache *iint, struct file *file)
+{
+ int result = -EEXIST;
+
+ if (!(iint->flags & IMA_MEASURED)) {
+ 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)
+ iint->version = i_version;
+ }
+ return result;
+}
+
+/*
+ * ima_store_measurement - store file measurement
+ *
+ * Create an "ima" template and then store the template by calling
+ * ima_store_template.
+ *
+ * We only get here if the inode has not already been measured,
+ * but the measurement could already exist:
+ * - multiple copies of the same file on either the same or
+ * different filesystems.
+ * - the inode was previously flushed as well as the iint info,
+ * containing the hashing info.
+ *
+ * Must be called with iint->mutex held.
+ */
+void ima_store_measurement(struct ima_iint_cache *iint, struct file *file,
+ const unsigned char *filename)
+{
+ const char *op = "add_template_measure";
+ const char *audit_cause = "ENOMEM";
+ int result = -ENOMEM;
+ struct inode *inode = file->f_dentry->d_inode;
+ struct ima_template_entry *entry;
+ int violation = 0;
+
+ entry = kmalloc(sizeof(*entry), GFP_KERNEL);
+ if (!entry) {
+ integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, filename,
+ op, audit_cause, result, 0);
+ return;
+ }
+ memset(&entry->template, 0, sizeof(entry->template));
+ memcpy(entry->template.digest, iint->digest, IMA_DIGEST_SIZE);
+ strncpy(entry->template.file_name, filename, IMA_EVENT_NAME_LEN_MAX);
+
+ result = ima_store_template(entry, violation, inode);
+ if (!result)
+ iint->flags |= IMA_MEASURED;
+ else
+ kfree(entry);
+}
diff --git a/security/integrity/ima/ima_audit.c b/security/integrity/ima/ima_audit.c
new file mode 100644
index 0000000..8a0f1e2
--- /dev/null
+++ b/security/integrity/ima/ima_audit.c
@@ -0,0 +1,78 @@
+/*
+ * 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.
+ *
+ * File: integrity_audit.c
+ * Audit calls for the integrity subsystem
+ */
+
+#include <linux/fs.h>
+#include <linux/audit.h>
+#include "ima.h"
+
+static int ima_audit;
+
+#ifdef CONFIG_IMA_AUDIT
+
+/* ima_audit_setup - enable informational auditing messages */
+static int __init ima_audit_setup(char *str)
+{
+ unsigned long audit;
+ int rc;
+ char *op;
+
+ rc = strict_strtoul(str, 0, &audit);
+ if (rc || audit > 1)
+ printk(KERN_INFO "ima: invalid ima_audit value\n");
+ else
+ ima_audit = audit;
+ op = ima_audit ? "ima_audit_enabled" : "ima_audit_not_enabled";
+ integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL, NULL, NULL, op, 0, 0);
+ return 1;
+}
+__setup("ima_audit=", ima_audit_setup);
+#endif
+
+void integrity_audit_msg(int audit_msgno, struct inode *inode,
+ const unsigned char *fname, const char *op,
+ const char *cause, int result, int audit_info)
+{
+ struct audit_buffer *ab;
+
+ if (!ima_audit && audit_info == 1) /* Skip informational messages */
+ return;
+
+ ab = audit_log_start(current->audit_context, GFP_KERNEL, audit_msgno);
+ audit_log_format(ab, "integrity: pid=%d uid=%u auid=%u",
+ current->pid, current->cred->uid,
+ audit_get_loginuid(current));
+ audit_log_task_context(ab);
+ switch (audit_msgno) {
+ case AUDIT_INTEGRITY_DATA:
+ case AUDIT_INTEGRITY_METADATA:
+ case AUDIT_INTEGRITY_PCR:
+ audit_log_format(ab, " op=%s cause=%s", op, cause);
+ break;
+ case AUDIT_INTEGRITY_HASH:
+ audit_log_format(ab, " op=%s hash=%s", op, cause);
+ break;
+ case AUDIT_INTEGRITY_STATUS:
+ default:
+ audit_log_format(ab, " op=%s", op);
+ }
+ audit_log_format(ab, " comm=");
+ audit_log_untrustedstring(ab, current->comm);
+ if (fname) {
+ audit_log_format(ab, " name=");
+ audit_log_untrustedstring(ab, fname);
+ }
+ if (inode)
+ audit_log_format(ab, " dev=%s ino=%lu",
+ inode->i_sb->s_id, inode->i_ino);
+ audit_log_format(ab, " res=%d", result);
+ audit_log_end(ab);
+}
diff --git a/security/integrity/ima/ima_crypto.c b/security/integrity/ima/ima_crypto.c
new file mode 100644
index 0000000..c2a46e4
--- /dev/null
+++ b/security/integrity/ima/ima_crypto.c
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2005,2006,2007,2008 IBM Corporation
+ *
+ * Authors:
+ * Mimi Zohar <zohar@us.ibm.com>
+ * Kylene Hall <kjhall@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.
+ *
+ * File: ima_crypto.c
+ * Calculates md5/sha1 file hash, template hash, boot-aggreate hash
+ */
+
+#include <linux/kernel.h>
+#include <linux/file.h>
+#include <linux/crypto.h>
+#include <linux/scatterlist.h>
+#include <linux/err.h>
+#include "ima.h"
+
+static int init_desc(struct hash_desc *desc)
+{
+ int rc;
+
+ desc->tfm = crypto_alloc_hash(ima_hash, 0, CRYPTO_ALG_ASYNC);
+ if (IS_ERR(desc->tfm)) {
+ pr_info("failed to load %s transform: %ld\n",
+ ima_hash, PTR_ERR(desc->tfm));
+ rc = PTR_ERR(desc->tfm);
+ return rc;
+ }
+ desc->flags = 0;
+ rc = crypto_hash_init(desc);
+ if (rc)
+ crypto_free_hash(desc->tfm);
+ return rc;
+}
+
+/*
+ * Calculate the MD5/SHA1 file digest
+ */
+int ima_calc_hash(struct file *file, char *digest)
+{
+ struct hash_desc desc;
+ struct scatterlist sg[1];
+ loff_t i_size;
+ char *rbuf;
+ int rc, offset = 0;
+
+ rc = init_desc(&desc);
+ if (rc != 0)
+ return rc;
+
+ rbuf = kzalloc(PAGE_SIZE, GFP_KERNEL);
+ if (!rbuf) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ i_size = i_size_read(file->f_dentry->d_inode);
+ while (offset < i_size) {
+ int rbuf_len;
+
+ rbuf_len = kernel_read(file, offset, rbuf, PAGE_SIZE);
+ if (rbuf_len < 0) {
+ rc = rbuf_len;
+ break;
+ }
+ offset += rbuf_len;
+ sg_set_buf(sg, rbuf, rbuf_len);
+
+ rc = crypto_hash_update(&desc, sg, rbuf_len);
+ if (rc)
+ break;
+ }
+ kfree(rbuf);
+ if (!rc)
+ rc = crypto_hash_final(&desc, digest);
+out:
+ crypto_free_hash(desc.tfm);
+ return rc;
+}
+
+/*
+ * Calculate the hash of a given template
+ */
+int ima_calc_template_hash(int template_len, void *template, char *digest)
+{
+ struct hash_desc desc;
+ struct scatterlist sg[1];
+ int rc;
+
+ rc = init_desc(&desc);
+ if (rc != 0)
+ return rc;
+
+ sg_set_buf(sg, template, template_len);
+ rc = crypto_hash_update(&desc, sg, template_len);
+ if (!rc)
+ rc = crypto_hash_final(&desc, digest);
+ crypto_free_hash(desc.tfm);
+ return rc;
+}
+
+static void ima_pcrread(int idx, u8 *pcr)
+{
+ if (!ima_used_chip)
+ return;
+
+ if (tpm_pcr_read(TPM_ANY_NUM, idx, pcr) != 0)
+ pr_err("Error Communicating to TPM chip\n");
+}
+
+/*
+ * Calculate the boot aggregate hash
+ */
+int ima_calc_boot_aggregate(char *digest)
+{
+ struct hash_desc desc;
+ struct scatterlist sg;
+ u8 pcr_i[IMA_DIGEST_SIZE];
+ int rc, i;
+
+ rc = init_desc(&desc);
+ if (rc != 0)
+ return rc;
+
+ /* cumulative sha1 over tpm registers 0-7 */
+ for (i = TPM_PCR0; i < TPM_PCR8; i++) {
+ ima_pcrread(i, pcr_i);
+ /* now accumulate with current aggregate */
+ sg_init_one(&sg, pcr_i, IMA_DIGEST_SIZE);
+ rc = crypto_hash_update(&desc, &sg, IMA_DIGEST_SIZE);
+ }
+ if (!rc)
+ crypto_hash_final(&desc, digest);
+ crypto_free_hash(desc.tfm);
+ return rc;
+}
diff --git a/security/integrity/ima/ima_iint.c b/security/integrity/ima/ima_iint.c
new file mode 100644
index 0000000..750db3c
--- /dev/null
+++ b/security/integrity/ima/ima_iint.c
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2008 IBM Corporation
+ *
+ * Authors:
+ * 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.
+ *
+ * File: ima_iint.c
+ * - implements the IMA hooks: ima_inode_alloc, ima_inode_free
+ * - cache integrity information associated with an inode
+ * using a radix tree.
+ */
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/radix-tree.h>
+#include "ima.h"
+
+#define ima_iint_delete ima_inode_free
+
+RADIX_TREE(ima_iint_store, GFP_ATOMIC);
+DEFINE_SPINLOCK(ima_iint_lock);
+
+static struct kmem_cache *iint_cache __read_mostly;
+
+/* ima_iint_find_get - return the iint associated with an inode
+ *
+ * ima_iint_find_get gets a reference to the iint. Caller must
+ * remember to put the iint reference.
+ */
+struct ima_iint_cache *ima_iint_find_get(struct inode *inode)
+{
+ struct ima_iint_cache *iint;
+
+ rcu_read_lock();
+ iint = radix_tree_lookup(&ima_iint_store, (unsigned long)inode);
+ if (!iint)
+ goto out;
+ kref_get(&iint->refcount);
+out:
+ rcu_read_unlock();
+ return iint;
+}
+
+/* Allocate memory for the iint associated with the inode
+ * from the iint_cache slab, initialize the iint, and
+ * insert it into the radix tree.
+ *
+ * On success return a pointer to the iint; on failure return NULL.
+ */
+struct ima_iint_cache *ima_iint_insert(struct inode *inode)
+{
+ struct ima_iint_cache *iint = NULL;
+ int rc = 0;
+
+ if (!ima_initialized)
+ return iint;
+ iint = kmem_cache_alloc(iint_cache, GFP_KERNEL);
+ if (!iint)
+ return iint;
+
+ rc = radix_tree_preload(GFP_KERNEL);
+ if (rc < 0)
+ goto out;
+
+ spin_lock(&ima_iint_lock);
+ rc = radix_tree_insert(&ima_iint_store, (unsigned long)inode, iint);
+ spin_unlock(&ima_iint_lock);
+out:
+ if (rc < 0) {
+ kmem_cache_free(iint_cache, iint);
+ if (rc == -EEXIST) {
+ iint = radix_tree_lookup(&ima_iint_store,
+ (unsigned long)inode);
+ } else
+ iint = NULL;
+ }
+ radix_tree_preload_end();
+ return iint;
+}
+
+/**
+ * ima_inode_alloc - allocate an iint associated with an inode
+ * @inode: pointer to the inode
+ *
+ * Return 0 on success, 1 on failure.
+ */
+int ima_inode_alloc(struct inode *inode)
+{
+ struct ima_iint_cache *iint;
+
+ if (!ima_initialized)
+ return 0;
+
+ iint = ima_iint_insert(inode);
+ if (!iint)
+ return 1;
+ return 0;
+}
+
+/* ima_iint_find_insert_get - get the iint associated with an inode
+ *
+ * Most insertions are done at inode_alloc, except those allocated
+ * before late_initcall. When the iint does not exist, allocate it,
+ * initialize and insert it, and increment the iint refcount.
+ *
+ * (Can't initialize at security_initcall before any inodes are
+ * allocated, got to wait at least until proc_init.)
+ *
+ * Return the iint.
+ */
+struct ima_iint_cache *ima_iint_find_insert_get(struct inode *inode)
+{
+ struct ima_iint_cache *iint = NULL;
+
+ iint = ima_iint_find_get(inode);
+ if (iint)
+ return iint;
+
+ iint = ima_iint_insert(inode);
+ if (iint)
+ kref_get(&iint->refcount);
+
+ return iint;
+}
+
+/* iint_free - called when the iint refcount goes to zero */
+void iint_free(struct kref *kref)
+{
+ struct ima_iint_cache *iint = container_of(kref, struct ima_iint_cache,
+ refcount);
+ iint->version = 0;
+ iint->flags = 0UL;
+ kref_set(&iint->refcount, 1);
+ kmem_cache_free(iint_cache, iint);
+}
+
+void iint_rcu_free(struct rcu_head *rcu_head)
+{
+ struct ima_iint_cache *iint = container_of(rcu_head,
+ struct ima_iint_cache, rcu);
+ kref_put(&iint->refcount, iint_free);
+}
+
+/**
+ * ima_iint_delete - called on integrity_inode_free
+ * @inode: pointer to the inode
+ *
+ * Free the integrity information(iint) associated with an inode.
+ */
+void ima_iint_delete(struct inode *inode)
+{
+ struct ima_iint_cache *iint;
+
+ if (!ima_initialized)
+ return;
+ spin_lock(&ima_iint_lock);
+ iint = radix_tree_delete(&ima_iint_store, (unsigned long)inode);
+ spin_unlock(&ima_iint_lock);
+ if (iint)
+ call_rcu(&iint->rcu, iint_rcu_free);
+}
+
+static void init_once(void *foo)
+{
+ struct ima_iint_cache *iint = foo;
+
+ memset(iint, 0, sizeof *iint);
+ iint->version = 0;
+ iint->flags = 0UL;
+ mutex_init(&iint->mutex);
+ iint->readcount = 0;
+ iint->writecount = 0;
+ kref_set(&iint->refcount, 1);
+}
+
+void ima_iintcache_init(void)
+{
+ iint_cache =
+ kmem_cache_create("iint_cache", sizeof(struct ima_iint_cache), 0,
+ SLAB_PANIC, init_once);
+}
diff --git a/security/integrity/ima/ima_init.c b/security/integrity/ima/ima_init.c
new file mode 100644
index 0000000..e0f02e3
--- /dev/null
+++ b/security/integrity/ima/ima_init.c
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2005,2006,2007,2008 IBM Corporation
+ *
+ * Authors:
+ * Reiner Sailer <sailer@watson.ibm.com>
+ * Leendert van Doorn <leendert@watson.ibm.com>
+ * 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.
+ *
+ * File: ima_init.c
+ * initialization and cleanup functions
+ */
+#include <linux/module.h>
+#include <linux/scatterlist.h>
+#include <linux/err.h>
+#include "ima.h"
+
+/* name for boot aggregate entry */
+static char *boot_aggregate_name = "boot_aggregate";
+int ima_used_chip;
+
+/* Add the boot aggregate to the IMA measurement list and extend
+ * the PCR register.
+ *
+ * Calculate the boot aggregate, a SHA1 over tpm registers 0-7,
+ * assuming a TPM chip exists, and zeroes if the TPM chip does not
+ * exist. Add the boot aggregate measurement to the measurement
+ * list and extend the PCR register.
+ *
+ * If a tpm chip does not exist, indicate the core root of trust is
+ * not hardware based by invalidating the aggregate PCR value.
+ * (The aggregate PCR value is invalidated by adding one value to
+ * the measurement list and extending the aggregate PCR value with
+ * a different value.) Violations add a zero entry to the measurement
+ * list and extend the aggregate PCR value with ff...ff's.
+ */
+static void ima_add_boot_aggregate(void)
+{
+ struct ima_template_entry *entry;
+ const char *op = "add_boot_aggregate";
+ const char *audit_cause = "ENOMEM";
+ int result = -ENOMEM;
+ int violation = 1;
+
+ entry = kmalloc(sizeof(*entry), GFP_KERNEL);
+ if (!entry)
+ goto err_out;
+
+ memset(&entry->template, 0, sizeof(entry->template));
+ strncpy(entry->template.file_name, boot_aggregate_name,
+ IMA_EVENT_NAME_LEN_MAX);
+ if (ima_used_chip) {
+ violation = 0;
+ result = ima_calc_boot_aggregate(entry->template.digest);
+ if (result < 0) {
+ audit_cause = "hashing_error";
+ kfree(entry);
+ goto err_out;
+ }
+ }
+ result = ima_store_template(entry, violation, NULL);
+ if (result < 0)
+ kfree(entry);
+ return;
+err_out:
+ integrity_audit_msg(AUDIT_INTEGRITY_PCR, NULL, boot_aggregate_name, op,
+ audit_cause, result, 0);
+}
+
+int ima_init(void)
+{
+ u8 pcr_i[IMA_DIGEST_SIZE];
+ int rc;
+
+ ima_used_chip = 0;
+ rc = tpm_pcr_read(TPM_ANY_NUM, 0, pcr_i);
+ if (rc == 0)
+ ima_used_chip = 1;
+
+ if (!ima_used_chip)
+ pr_info("No TPM chip found, activating TPM-bypass!\n");
+
+ ima_add_boot_aggregate(); /* boot aggregate must be first entry */
+ ima_init_policy();
+ return 0;
+}
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
new file mode 100644
index 0000000..53cee4c
--- /dev/null
+++ b/security/integrity/ima/ima_main.c
@@ -0,0 +1,280 @@
+/*
+ * Copyright (C) 2005,2006,2007,2008 IBM Corporation
+ *
+ * Authors:
+ * Reiner Sailer <sailer@watson.ibm.com>
+ * Serge Hallyn <serue@us.ibm.com>
+ * Kylene Hall <kylene@us.ibm.com>
+ * 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.
+ *
+ * File: ima_main.c
+ * implements the IMA hooks: ima_bprm_check, ima_file_mmap,
+ * and ima_path_check.
+ */
+#include <linux/module.h>
+#include <linux/file.h>
+#include <linux/binfmts.h>
+#include <linux/mount.h>
+#include <linux/mman.h>
+
+#include "ima.h"
+
+int ima_initialized;
+
+char *ima_hash = "sha1";
+static int __init hash_setup(char *str)
+{
+ const char *op = "hash_setup";
+ const char *hash = "sha1";
+ int result = 0;
+ int audit_info = 0;
+
+ if (strncmp(str, "md5", 3) == 0) {
+ hash = "md5";
+ ima_hash = str;
+ } else if (strncmp(str, "sha1", 4) != 0) {
+ hash = "invalid_hash_type";
+ result = 1;
+ }
+ integrity_audit_msg(AUDIT_INTEGRITY_HASH, NULL, NULL, op, hash,
+ result, audit_info);
+ return 1;
+}
+__setup("ima_hash=", hash_setup);
+
+/**
+ * ima_file_free - called on __fput()
+ * @file: pointer to file structure being freed
+ *
+ * Flag files that changed, based on i_version;
+ * and decrement the iint readcount/writecount.
+ */
+void ima_file_free(struct file *file)
+{
+ struct inode *inode = file->f_dentry->d_inode;
+ struct ima_iint_cache *iint;
+
+ if (!ima_initialized || !S_ISREG(inode->i_mode))
+ return;
+ iint = ima_iint_find_get(inode);
+ if (!iint)
+ return;
+
+ mutex_lock(&iint->mutex);
+ if ((file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
+ iint->readcount--;
+
+ if (file->f_mode & FMODE_WRITE) {
+ iint->writecount--;
+ if (iint->writecount == 0) {
+ if (iint->version != inode->i_version)
+ iint->flags &= ~IMA_MEASURED;
+ }
+ }
+ mutex_unlock(&iint->mutex);
+ kref_put(&iint->refcount, iint_free);
+}
+
+/* ima_read_write_check - reflect possible reading/writing errors in the PCR.
+ *
+ * When opening a file for read, if the file is already open for write,
+ * the file could change, resulting in a file measurement error.
+ *
+ * Opening a file for write, if the file is already open for read, results
+ * in a time of measure, time of use (ToMToU) error.
+ *
+ * In either case invalidate the PCR.
+ */
+enum iint_pcr_error { TOMTOU, OPEN_WRITERS };
+static void ima_read_write_check(enum iint_pcr_error error,
+ struct ima_iint_cache *iint,
+ struct inode *inode,
+ const unsigned char *filename)
+{
+ switch (error) {
+ case TOMTOU:
+ if (iint->readcount > 0)
+ ima_add_violation(inode, filename, "invalid_pcr",
+ "ToMToU");
+ break;
+ case OPEN_WRITERS:
+ if (iint->writecount > 0)
+ ima_add_violation(inode, filename, "invalid_pcr",
+ "open_writers");
+ break;
+ }
+}
+
+static int get_path_measurement(struct ima_iint_cache *iint, struct file *file,
+ const unsigned char *filename)
+{
+ int rc = 0;
+
+ if (IS_ERR(file)) {
+ pr_info("%s dentry_open failed\n", filename);
+ return rc;
+ }
+ iint->readcount++;
+
+ rc = ima_collect_measurement(iint, file);
+ if (!rc)
+ ima_store_measurement(iint, file, filename);
+ return rc;
+}
+
+/**
+ * ima_path_check - based on policy, collect/store measurement.
+ * @path: contains a pointer to the path to be measured
+ * @mask: contains MAY_READ, MAY_WRITE or MAY_EXECUTE
+ *
+ * Measure the file being open for readonly, based on the
+ * ima_must_measure() policy decision.
+ *
+ * Keep read/write counters for all files, but only
+ * invalidate the PCR for measured files:
+ * - Opening a file for write when already open for read,
+ * results in a time of measure, time of use (ToMToU) error.
+ * - Opening a file for read when already open for write,
+ * could result in a file measurement error.
+ *
+ * Return 0 on success, an error code on failure.
+ * (Based on the results of appraise_measurement().)
+ */
+int ima_path_check(struct path *path, int mask)
+{
+ struct inode *inode = path->dentry->d_inode;
+ struct ima_iint_cache *iint;
+ struct file *file = NULL;
+ int rc;
+
+ if (!ima_initialized || !S_ISREG(inode->i_mode))
+ return 0;
+ iint = ima_iint_find_insert_get(inode);
+ if (!iint)
+ return 0;
+
+ mutex_lock(&iint->mutex);
+ if ((mask & MAY_WRITE) || (mask == 0))
+ iint->writecount++;
+ else if (mask & (MAY_READ | MAY_EXEC))
+ iint->readcount++;
+
+ rc = ima_must_measure(iint, inode, MAY_READ, PATH_CHECK);
+ if (rc < 0)
+ goto out;
+
+ if ((mask & MAY_WRITE) || (mask == 0))
+ ima_read_write_check(TOMTOU, iint, inode,
+ path->dentry->d_name.name);
+
+ if ((mask & (MAY_WRITE | MAY_READ | MAY_EXEC)) != MAY_READ)
+ goto out;
+
+ ima_read_write_check(OPEN_WRITERS, iint, inode,
+ path->dentry->d_name.name);
+ if (!(iint->flags & IMA_MEASURED)) {
+ struct dentry *dentry = dget(path->dentry);
+ struct vfsmount *mnt = mntget(path->mnt);
+
+ file = dentry_open(dentry, mnt, O_RDONLY, current->cred);
+ rc = get_path_measurement(iint, file, dentry->d_name.name);
+ }
+out:
+ mutex_unlock(&iint->mutex);
+ if (file)
+ fput(file);
+ kref_put(&iint->refcount, iint_free);
+ return 0;
+}
+
+static int process_measurement(struct file *file, const unsigned char *filename,
+ int mask, int function)
+{
+ struct inode *inode = file->f_dentry->d_inode;
+ struct ima_iint_cache *iint;
+ int rc;
+
+ if (!ima_initialized || !S_ISREG(inode->i_mode))
+ return 0;
+ iint = ima_iint_find_insert_get(inode);
+ if (!iint)
+ return -ENOMEM;
+
+ mutex_lock(&iint->mutex);
+ rc = ima_must_measure(iint, inode, mask, function);
+ if (rc != 0)
+ goto out;
+
+ rc = ima_collect_measurement(iint, file);
+ if (!rc)
+ ima_store_measurement(iint, file, filename);
+out:
+ mutex_unlock(&iint->mutex);
+ kref_put(&iint->refcount, iint_free);
+ return rc;
+}
+
+/**
+ * ima_file_mmap - based on policy, collect/store measurement.
+ * @file: pointer to the file to be measured (May be NULL)
+ * @prot: contains the protection that will be applied by the kernel.
+ *
+ * Measure files being mmapped executable based on the ima_must_measure()
+ * policy decision.
+ *
+ * Return 0 on success, an error code on failure.
+ * (Based on the results of appraise_measurement().)
+ */
+int ima_file_mmap(struct file *file, unsigned long prot)
+{
+ int rc;
+
+ if (!file)
+ return 0;
+ if (prot & PROT_EXEC)
+ rc = process_measurement(file, file->f_dentry->d_name.name,
+ MAY_EXEC, FILE_MMAP);
+ return 0;
+}
+
+/**
+ * ima_bprm_check - based on policy, collect/store measurement.
+ * @bprm: contains the linux_binprm structure
+ *
+ * The OS protects against an executable file, already open for write,
+ * from being executed in deny_write_access() and an executable file,
+ * already open for execute, from being modified in get_write_access().
+ * So we can be certain that what we verify and measure here is actually
+ * what is being executed.
+ *
+ * Return 0 on success, an error code on failure.
+ * (Based on the results of appraise_measurement().)
+ */
+int ima_bprm_check(struct linux_binprm *bprm)
+{
+ int rc;
+
+ rc = process_measurement(bprm->file, bprm->filename,
+ MAY_EXEC, BPRM_CHECK);
+ return 0;
+}
+
+static int __init init_ima(void)
+{
+ int error;
+
+ ima_iintcache_init();
+ error = ima_init();
+ ima_initialized = 1;
+ return error;
+}
+
+late_initcall(init_ima); /* Start IMA after the TPM is available */
+
+MODULE_DESCRIPTION("Integrity Measurement Architecture");
+MODULE_LICENSE("GPL");
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
new file mode 100644
index 0000000..7c3d1ff
--- /dev/null
+++ b/security/integrity/ima/ima_policy.c
@@ -0,0 +1,126 @@
+/*
+ * 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.
+ *
+ * ima_policy.c
+ * - initialize default measure policy rules
+ *
+ */
+#include <linux/module.h>
+#include <linux/list.h>
+#include <linux/audit.h>
+#include <linux/security.h>
+#include <linux/magic.h>
+
+#include "ima.h"
+
+/* flags definitions */
+#define IMA_FUNC 0x0001
+#define IMA_MASK 0x0002
+#define IMA_FSMAGIC 0x0004
+#define IMA_UID 0x0008
+
+enum ima_action { DONT_MEASURE, MEASURE };
+
+struct ima_measure_rule_entry {
+ struct list_head list;
+ enum ima_action action;
+ unsigned int flags;
+ enum ima_hooks func;
+ int mask;
+ unsigned long fsmagic;
+ uid_t uid;
+};
+
+static struct ima_measure_rule_entry default_rules[] = {
+ {.action = DONT_MEASURE,.fsmagic = PROC_SUPER_MAGIC,
+ .flags = IMA_FSMAGIC},
+ {.action = DONT_MEASURE,.fsmagic = SYSFS_MAGIC,.flags = IMA_FSMAGIC},
+ {.action = DONT_MEASURE,.fsmagic = DEBUGFS_MAGIC,.flags = IMA_FSMAGIC},
+ {.action = DONT_MEASURE,.fsmagic = TMPFS_MAGIC,.flags = IMA_FSMAGIC},
+ {.action = DONT_MEASURE,.fsmagic = SECURITYFS_MAGIC,
+ .flags = IMA_FSMAGIC},
+ {.action = DONT_MEASURE,.fsmagic = 0xF97CFF8C,.flags = IMA_FSMAGIC},
+ {.action = MEASURE,.func = FILE_MMAP,.mask = MAY_EXEC,
+ .flags = IMA_FUNC | IMA_MASK},
+ {.action = MEASURE,.func = BPRM_CHECK,.mask = MAY_EXEC,
+ .flags = IMA_FUNC | IMA_MASK},
+ {.action = MEASURE,.func = PATH_CHECK,.mask = MAY_READ,.uid = 0,
+ .flags = IMA_FUNC | IMA_MASK | IMA_UID}
+};
+
+static LIST_HEAD(measure_default_rules);
+static struct list_head *ima_measure;
+
+/**
+ * ima_match_rules - determine whether an inode matches the measure rule.
+ * @rule: a pointer to a rule
+ * @inode: a pointer to an inode
+ * @func: LIM hook identifier
+ * @mask: requested action (MAY_READ | MAY_WRITE | MAY_APPEND | MAY_EXEC)
+ *
+ * Returns true on rule match, false on failure.
+ */
+static bool ima_match_rules(struct ima_measure_rule_entry *rule,
+ struct inode *inode, enum ima_hooks func, int mask)
+{
+ struct task_struct *tsk = current;
+
+ if ((rule->flags & IMA_FUNC) && rule->func != func)
+ return false;
+ if ((rule->flags & IMA_MASK) && rule->mask != mask)
+ return false;
+ if ((rule->flags & IMA_FSMAGIC)
+ && rule->fsmagic != inode->i_sb->s_magic)
+ return false;
+ if ((rule->flags & IMA_UID) && rule->uid != tsk->cred->uid)
+ return false;
+ return true;
+}
+
+/**
+ * ima_match_policy - decision based on LSM and other conditions
+ * @inode: pointer to an inode for which the policy decision is being made
+ * @func: IMA hook identifier
+ * @mask: requested action (MAY_READ | MAY_WRITE | MAY_APPEND | MAY_EXEC)
+ *
+ * Measure decision based on func/mask/fsmagic and LSM(subj/obj/type)
+ * conditions.
+ *
+ * (There is no need for locking when walking the policy list,
+ * as elements in the list are never deleted, nor does the list
+ * change.)
+ */
+int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask)
+{
+ struct ima_measure_rule_entry *entry;
+
+ list_for_each_entry(entry, ima_measure, list) {
+ bool rc;
+
+ rc = ima_match_rules(entry, inode, func, mask);
+ if (rc)
+ return entry->action;
+ }
+ return 0;
+}
+
+/**
+ * ima_init_policy - initialize the default measure rules.
+ *
+ * (Could use the default_rules directly, but in policy patch
+ * ima_measure points to either the measure_default_rules or the
+ * the new measure_policy_rules.)
+ */
+void ima_init_policy(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(default_rules); i++)
+ list_add_tail(&default_rules[i].list, &measure_default_rules);
+ ima_measure = &measure_default_rules;
+}
diff --git a/security/integrity/ima/ima_queue.c b/security/integrity/ima/ima_queue.c
new file mode 100644
index 0000000..7ec9431
--- /dev/null
+++ b/security/integrity/ima/ima_queue.c
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2005,2006,2007,2008 IBM Corporation
+ *
+ * Authors:
+ * Serge Hallyn <serue@us.ibm.com>
+ * Reiner Sailer <sailer@watson.ibm.com>
+ * 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.
+ *
+ * File: ima_queue.c
+ * Implements queues that store template measurements and
+ * maintains aggregate over the stored measurements
+ * in the pre-configured TPM PCR (if available).
+ * The measurement list is append-only. No entry is
+ * ever removed or changed during the boot-cycle.
+ */
+#include <linux/module.h>
+#include <linux/rculist.h>
+#include "ima.h"
+
+LIST_HEAD(ima_measurements); /* list of all measurements */
+
+/* key: inode (before secure-hashing a file) */
+struct ima_h_table ima_htable = {
+ .len = ATOMIC_LONG_INIT(0),
+ .violations = ATOMIC_LONG_INIT(0),
+ .queue[0 ... IMA_MEASURE_HTABLE_SIZE - 1] = HLIST_HEAD_INIT
+};
+
+/* mutex protects atomicity of extending measurement list
+ * and extending the TPM PCR aggregate. Since tpm_extend can take
+ * long (and the tpm driver uses a mutex), we can't use the spinlock.
+ */
+static DEFINE_MUTEX(ima_extend_list_mutex);
+
+/* lookup up the digest value in the hash table, and return the entry */
+static struct ima_queue_entry *ima_lookup_digest_entry(u8 *digest_value)
+{
+ struct ima_queue_entry *qe, *ret = NULL;
+ unsigned int key;
+ struct hlist_node *pos;
+ int rc;
+
+ key = ima_hash_key(digest_value);
+ rcu_read_lock();
+ hlist_for_each_entry_rcu(qe, pos, &ima_htable.queue[key], hnext) {
+ rc = memcmp(qe->entry->digest, digest_value, IMA_DIGEST_SIZE);
+ if (rc == 0) {
+ ret = qe;
+ break;
+ }
+ }
+ rcu_read_unlock();
+ return ret;
+}
+
+/* ima_add_template_entry helper function:
+ * - Add template entry to measurement list and hash table.
+ *
+ * (Called with ima_extend_list_mutex held.)
+ */
+static int ima_add_digest_entry(struct ima_template_entry *entry)
+{
+ struct ima_queue_entry *qe;
+ unsigned int key;
+
+ qe = kmalloc(sizeof(*qe), GFP_KERNEL);
+ if (qe == NULL) {
+ pr_err("OUT OF MEMORY ERROR creating queue entry.\n");
+ return -ENOMEM;
+ }
+ qe->entry = entry;
+
+ INIT_LIST_HEAD(&qe->later);
+ list_add_tail_rcu(&qe->later, &ima_measurements);
+
+ atomic_long_inc(&ima_htable.len);
+ key = ima_hash_key(entry->digest);
+ hlist_add_head_rcu(&qe->hnext, &ima_htable.queue[key]);
+ return 0;
+}
+
+static int ima_pcr_extend(const u8 *hash)
+{
+ int result = 0;
+
+ if (!ima_used_chip)
+ return result;
+
+ result = tpm_pcr_extend(TPM_ANY_NUM, CONFIG_IMA_MEASURE_PCR_IDX, hash);
+ if (result != 0)
+ pr_err("Error Communicating to TPM chip\n");
+ return result;
+}
+
+/* Add template entry to the measurement list and hash table,
+ * and extend the pcr.
+ */
+int ima_add_template_entry(struct ima_template_entry *entry, int violation,
+ const char *op, struct inode *inode)
+{
+ u8 digest[IMA_DIGEST_SIZE];
+ const char *audit_cause = "hash_added";
+ int audit_info = 1;
+ int result = 0;
+
+ mutex_lock(&ima_extend_list_mutex);
+ if (!violation) {
+ memcpy(digest, entry->digest, sizeof digest);
+ if (ima_lookup_digest_entry(digest)) {
+ audit_cause = "hash_exists";
+ goto out;
+ }
+ }
+
+ result = ima_add_digest_entry(entry);
+ if (result < 0) {
+ audit_cause = "ENOMEM";
+ audit_info = 0;
+ goto out;
+ }
+
+ if (violation) /* invalidate pcr */
+ memset(digest, 0xff, sizeof digest);
+
+ result = ima_pcr_extend(digest);
+ if (result != 0) {
+ audit_cause = "TPM error";
+ audit_info = 0;
+ }
+out:
+ mutex_unlock(&ima_extend_list_mutex);
+ integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, entry->template_name,
+ op, audit_cause, result, audit_info);
+ return result;
+}
--
1.5.6.6
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 3/7] integrity: IMA display
2009-02-04 14:06 [PATCH 0/7] integrity Mimi Zohar
2009-02-04 14:06 ` [PATCH 1/7] integrity: IMA hooks Mimi Zohar
2009-02-04 14:06 ` [PATCH 2/7] integrity: IMA as an integrity service provider Mimi Zohar
@ 2009-02-04 14:06 ` Mimi Zohar
2009-02-04 14:07 ` [PATCH 4/7] integrity: IMA policy Mimi Zohar
` (5 subsequent siblings)
8 siblings, 0 replies; 19+ messages in thread
From: Mimi Zohar @ 2009-02-04 14:06 UTC (permalink / raw)
To: linux-kernel
Cc: Mimi Zohar, Andrew Morton, James Morris, David Safford,
Serge Hallyn, Mimi Zohar
Make the measurement lists available through securityfs.
- removed test for NULL return code from securityfs_create_file/dir
Signed-off-by: Mimi Zohar <zohar@us.ibm.com>
Acked-by: Serge Hallyn <serue@us.ibm.com>
---
diff --git a/security/integrity/ima/Makefile b/security/integrity/ima/Makefile
index 9d6bf97..787c4cb 100644
--- a/security/integrity/ima/Makefile
+++ b/security/integrity/ima/Makefile
@@ -5,5 +5,5 @@
obj-$(CONFIG_IMA) += ima.o
-ima-y := ima_queue.o ima_init.o ima_main.o ima_crypto.o ima_api.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_iint.o ima_audit.o
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index bfa72ed..9c280cc 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -67,6 +67,9 @@ void integrity_audit_msg(int audit_msgno, struct inode *inode,
/* Internal IMA function definitions */
void ima_iintcache_init(void);
int ima_init(void);
+void ima_cleanup(void);
+int ima_fs_init(void);
+void ima_fs_cleanup(void);
int ima_add_template_entry(struct ima_template_entry *entry, int violation,
const char *op, struct inode *inode);
int ima_calc_hash(struct file *file, char *digest);
@@ -115,6 +118,8 @@ void ima_store_measurement(struct ima_iint_cache *iint, struct file *file,
const unsigned char *filename);
int ima_store_template(struct ima_template_entry *entry, int violation,
struct inode *inode);
+void ima_template_show(struct seq_file *m, void *e,
+ enum ima_show_type show);
/* radix tree calls to lookup, insert, delete
* integrity data associated with an inode.
diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
new file mode 100644
index 0000000..4f25be7
--- /dev/null
+++ b/security/integrity/ima/ima_fs.c
@@ -0,0 +1,296 @@
+/*
+ * Copyright (C) 2005,2006,2007,2008 IBM Corporation
+ *
+ * Authors:
+ * Kylene Hall <kjhall@us.ibm.com>
+ * Reiner Sailer <sailer@us.ibm.com>
+ * 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.
+ *
+ * File: ima_fs.c
+ * implemenents security file system for reporting
+ * current measurement list and IMA statistics
+ */
+#include <linux/module.h>
+#include <linux/seq_file.h>
+#include <linux/rculist.h>
+#include <linux/rcupdate.h>
+
+#include "ima.h"
+
+#define TMPBUFLEN 12
+static ssize_t ima_show_htable_value(char __user *buf, size_t count,
+ loff_t *ppos, atomic_long_t *val)
+{
+ char tmpbuf[TMPBUFLEN];
+ ssize_t len;
+
+ len = scnprintf(tmpbuf, TMPBUFLEN, "%li\n", atomic_long_read(val));
+ return simple_read_from_buffer(buf, count, ppos, tmpbuf, len);
+}
+
+static ssize_t ima_show_htable_violations(struct file *filp,
+ char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ return ima_show_htable_value(buf, count, ppos, &ima_htable.violations);
+}
+
+static struct file_operations ima_htable_violations_ops = {
+ .read = ima_show_htable_violations
+};
+
+static ssize_t ima_show_measurements_count(struct file *filp,
+ char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ return ima_show_htable_value(buf, count, ppos, &ima_htable.len);
+
+}
+
+static struct file_operations ima_measurements_count_ops = {
+ .read = ima_show_measurements_count
+};
+
+/* returns pointer to hlist_node */
+static void *ima_measurements_start(struct seq_file *m, loff_t *pos)
+{
+ loff_t l = *pos;
+ struct ima_queue_entry *qe;
+
+ /* we need a lock since pos could point beyond last element */
+ rcu_read_lock();
+ list_for_each_entry_rcu(qe, &ima_measurements, later) {
+ if (!l--) {
+ rcu_read_unlock();
+ return qe;
+ }
+ }
+ rcu_read_unlock();
+ return NULL;
+}
+
+static void *ima_measurements_next(struct seq_file *m, void *v, loff_t *pos)
+{
+ struct ima_queue_entry *qe = v;
+
+ /* lock protects when reading beyond last element
+ * against concurrent list-extension
+ */
+ rcu_read_lock();
+ qe = list_entry(rcu_dereference(qe->later.next),
+ struct ima_queue_entry, later);
+ rcu_read_unlock();
+ (*pos)++;
+
+ return (&qe->later == &ima_measurements) ? NULL : qe;
+}
+
+static void ima_measurements_stop(struct seq_file *m, void *v)
+{
+}
+
+static void ima_putc(struct seq_file *m, void *data, int datalen)
+{
+ while (datalen--)
+ seq_putc(m, *(char *)data++);
+}
+
+/* print format:
+ * 32bit-le=pcr#
+ * char[20]=template digest
+ * 32bit-le=template name size
+ * char[n]=template name
+ * eventdata[n]=template specific data
+ */
+static int ima_measurements_show(struct seq_file *m, void *v)
+{
+ /* the list never shrinks, so we don't need a lock here */
+ struct ima_queue_entry *qe = v;
+ struct ima_template_entry *e;
+ int namelen;
+ u32 pcr = CONFIG_IMA_MEASURE_PCR_IDX;
+
+ /* get entry */
+ e = qe->entry;
+ if (e == NULL)
+ return -1;
+
+ /*
+ * 1st: PCRIndex
+ * PCR used is always the same (config option) in
+ * little-endian format
+ */
+ ima_putc(m, &pcr, sizeof pcr);
+
+ /* 2nd: template digest */
+ ima_putc(m, e->digest, IMA_DIGEST_SIZE);
+
+ /* 3rd: template name size */
+ namelen = strlen(e->template_name);
+ ima_putc(m, &namelen, sizeof namelen);
+
+ /* 4th: template name */
+ ima_putc(m, e->template_name, namelen);
+
+ /* 5th: template specific data */
+ ima_template_show(m, (struct ima_template_data *)&e->template,
+ IMA_SHOW_BINARY);
+ return 0;
+}
+
+static struct seq_operations ima_measurments_seqops = {
+ .start = ima_measurements_start,
+ .next = ima_measurements_next,
+ .stop = ima_measurements_stop,
+ .show = ima_measurements_show
+};
+
+static int ima_measurements_open(struct inode *inode, struct file *file)
+{
+ return seq_open(file, &ima_measurments_seqops);
+}
+
+static struct file_operations ima_measurements_ops = {
+ .open = ima_measurements_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
+static void ima_print_digest(struct seq_file *m, u8 *digest)
+{
+ int i;
+
+ for (i = 0; i < IMA_DIGEST_SIZE; i++)
+ seq_printf(m, "%02x", *(digest + i));
+}
+
+void ima_template_show(struct seq_file *m, void *e, enum ima_show_type show)
+{
+ struct ima_template_data *entry = e;
+ int namelen;
+
+ switch (show) {
+ case IMA_SHOW_ASCII:
+ ima_print_digest(m, entry->digest);
+ seq_printf(m, " %s\n", entry->file_name);
+ break;
+ case IMA_SHOW_BINARY:
+ ima_putc(m, entry->digest, IMA_DIGEST_SIZE);
+
+ namelen = strlen(entry->file_name);
+ ima_putc(m, &namelen, sizeof namelen);
+ ima_putc(m, entry->file_name, namelen);
+ default:
+ break;
+ }
+}
+
+/* print in ascii */
+static int ima_ascii_measurements_show(struct seq_file *m, void *v)
+{
+ /* the list never shrinks, so we don't need a lock here */
+ struct ima_queue_entry *qe = v;
+ struct ima_template_entry *e;
+
+ /* get entry */
+ e = qe->entry;
+ if (e == NULL)
+ return -1;
+
+ /* 1st: PCR used (config option) */
+ seq_printf(m, "%2d ", CONFIG_IMA_MEASURE_PCR_IDX);
+
+ /* 2nd: SHA1 template hash */
+ ima_print_digest(m, e->digest);
+
+ /* 3th: template name */
+ seq_printf(m, " %s ", e->template_name);
+
+ /* 4th: template specific data */
+ ima_template_show(m, (struct ima_template_data *)&e->template,
+ IMA_SHOW_ASCII);
+ return 0;
+}
+
+static struct seq_operations ima_ascii_measurements_seqops = {
+ .start = ima_measurements_start,
+ .next = ima_measurements_next,
+ .stop = ima_measurements_stop,
+ .show = ima_ascii_measurements_show
+};
+
+static int ima_ascii_measurements_open(struct inode *inode, struct file *file)
+{
+ return seq_open(file, &ima_ascii_measurements_seqops);
+}
+
+static struct file_operations ima_ascii_measurements_ops = {
+ .open = ima_ascii_measurements_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
+static struct dentry *ima_dir;
+static struct dentry *binary_runtime_measurements;
+static struct dentry *ascii_runtime_measurements;
+static struct dentry *runtime_measurements_count;
+static struct dentry *violations;
+
+int ima_fs_init(void)
+{
+ ima_dir = securityfs_create_dir("ima", NULL);
+ if (IS_ERR(ima_dir))
+ return -1;
+
+ binary_runtime_measurements =
+ securityfs_create_file("binary_runtime_measurements",
+ S_IRUSR | S_IRGRP, ima_dir, NULL,
+ &ima_measurements_ops);
+ if (IS_ERR(binary_runtime_measurements))
+ goto out;
+
+ ascii_runtime_measurements =
+ securityfs_create_file("ascii_runtime_measurements",
+ S_IRUSR | S_IRGRP, ima_dir, NULL,
+ &ima_ascii_measurements_ops);
+ if (IS_ERR(ascii_runtime_measurements))
+ goto out;
+
+ runtime_measurements_count =
+ securityfs_create_file("runtime_measurements_count",
+ S_IRUSR | S_IRGRP, ima_dir, NULL,
+ &ima_measurements_count_ops);
+ if (IS_ERR(runtime_measurements_count))
+ goto out;
+
+ violations =
+ securityfs_create_file("violations", S_IRUSR | S_IRGRP,
+ ima_dir, NULL, &ima_htable_violations_ops);
+ if (IS_ERR(violations))
+ goto out;
+
+ return 0;
+
+out:
+ securityfs_remove(runtime_measurements_count);
+ securityfs_remove(ascii_runtime_measurements);
+ securityfs_remove(binary_runtime_measurements);
+ securityfs_remove(ima_dir);
+ return -1;
+}
+
+void __exit ima_fs_cleanup(void)
+{
+ securityfs_remove(violations);
+ securityfs_remove(runtime_measurements_count);
+ securityfs_remove(ascii_runtime_measurements);
+ securityfs_remove(binary_runtime_measurements);
+ securityfs_remove(ima_dir);
+}
diff --git a/security/integrity/ima/ima_init.c b/security/integrity/ima/ima_init.c
index e0f02e3..cf227db 100644
--- a/security/integrity/ima/ima_init.c
+++ b/security/integrity/ima/ima_init.c
@@ -86,5 +86,11 @@ int ima_init(void)
ima_add_boot_aggregate(); /* boot aggregate must be first entry */
ima_init_policy();
- return 0;
+
+ return ima_fs_init();
+}
+
+void __exit ima_cleanup(void)
+{
+ ima_fs_cleanup();
}
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index 53cee4c..871e356 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -274,6 +274,11 @@ static int __init init_ima(void)
return error;
}
+static void __exit cleanup_ima(void)
+{
+ ima_cleanup();
+}
+
late_initcall(init_ima); /* Start IMA after the TPM is available */
MODULE_DESCRIPTION("Integrity Measurement Architecture");
--
1.5.6.6
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 4/7] integrity: IMA policy
2009-02-04 14:06 [PATCH 0/7] integrity Mimi Zohar
` (2 preceding siblings ...)
2009-02-04 14:06 ` [PATCH 3/7] integrity: IMA display Mimi Zohar
@ 2009-02-04 14:07 ` Mimi Zohar
2009-02-04 14:07 ` [PATCH 5/7] integrity: IMA policy open Mimi Zohar
` (4 subsequent siblings)
8 siblings, 0 replies; 19+ messages in thread
From: Mimi Zohar @ 2009-02-04 14:07 UTC (permalink / raw)
To: linux-kernel
Cc: Mimi Zohar, Andrew Morton, James Morris, David Safford,
Serge Hallyn, Mimi Zohar
Support for a user loadable policy through securityfs
with support for LSM specific policy data.
- free invalid rule in ima_parse_add_rule()
Signed-off-by: Mimi Zohar <zohar@us.ibm.com>
Acked-by: Serge Hallyn <serue@us.ibm.com>
---
diff --git a/Documentation/ABI/testing/ima_policy b/Documentation/ABI/testing/ima_policy
new file mode 100644
index 0000000..6434f0d
--- /dev/null
+++ b/Documentation/ABI/testing/ima_policy
@@ -0,0 +1,61 @@
+What: security/ima/policy
+Date: May 2008
+Contact: Mimi Zohar <zohar@us.ibm.com>
+Description:
+ The Trusted Computing Group(TCG) runtime Integrity
+ Measurement Architecture(IMA) maintains a list of hash
+ values of executables and other sensitive system files
+ loaded into the run-time of this system. At runtime,
+ the policy can be constrained based on LSM specific data.
+ Policies are loaded into the securityfs file ima/policy
+ by opening the file, writing the rules one at a time and
+ then closing the file. The new policy takes effect after
+ the file ima/policy is closed.
+
+ rule format: action [condition ...]
+
+ action: measure | dont_measure
+ condition:= base | lsm
+ base: [[func=] [mask=] [fsmagic=] [uid=]]
+ lsm: [[subj_user=] [subj_role=] [subj_type=]
+ [obj_user=] [obj_role=] [obj_type=]]
+
+ base: func:= [BPRM_CHECK][FILE_MMAP][INODE_PERMISSION]
+ mask:= [MAY_READ] [MAY_WRITE] [MAY_APPEND] [MAY_EXEC]
+ fsmagic:= hex value
+ uid:= decimal value
+ lsm: are LSM specific
+
+ default policy:
+ # PROC_SUPER_MAGIC
+ dont_measure fsmagic=0x9fa0
+ # SYSFS_MAGIC
+ dont_measure fsmagic=0x62656572
+ # DEBUGFS_MAGIC
+ dont_measure fsmagic=0x64626720
+ # TMPFS_MAGIC
+ dont_measure fsmagic=0x01021994
+ # SECURITYFS_MAGIC
+ dont_measure fsmagic=0x73636673
+
+ measure func=BPRM_CHECK
+ measure func=FILE_MMAP mask=MAY_EXEC
+ measure func=INODE_PERM mask=MAY_READ uid=0
+
+ The default policy measures all executables in bprm_check,
+ all files mmapped executable in file_mmap, and all files
+ open for read by root in inode_permission.
+
+ Examples of LSM specific definitions:
+
+ SELinux:
+ # SELINUX_MAGIC
+ dont_measure fsmagic=0xF97CFF8C
+
+ dont_measure obj_type=var_log_t
+ dont_measure obj_type=auditd_log_t
+ measure subj_user=system_u func=INODE_PERM mask=MAY_READ
+ measure subj_role=system_r func=INODE_PERM mask=MAY_READ
+
+ Smack:
+ measure subj_user=_ func=INODE_PERM mask=MAY_READ
diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig
index 2a761c8..3d2b6ee 100644
--- a/security/integrity/ima/Kconfig
+++ b/security/integrity/ima/Kconfig
@@ -47,3 +47,9 @@ config IMA_AUDIT
auditing messages can be enabled with 'ima_audit=1' on
the kernel command line.
+config IMA_LSM_RULES
+ bool
+ depends on IMA && (SECURITY_SELINUX || SECURITY_SMACK)
+ default y
+ help
+ Disabling this option will disregard LSM based policy rules
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index 9c280cc..42706b5 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -137,4 +137,28 @@ enum ima_hooks { PATH_CHECK = 1, FILE_MMAP, BPRM_CHECK };
int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask);
void ima_init_policy(void);
void ima_update_policy(void);
+int ima_parse_add_rule(char *);
+void ima_delete_rules(void);
+
+/* LSM based policy rules require audit */
+#ifdef CONFIG_IMA_LSM_RULES
+
+#define security_filter_rule_init security_audit_rule_init
+#define security_filter_rule_match security_audit_rule_match
+
+#else
+
+static inline int security_filter_rule_init(u32 field, u32 op, char *rulestr,
+ void **lsmrule)
+{
+ return -EINVAL;
+}
+
+static inline int security_filter_rule_match(u32 secid, u32 field, u32 op,
+ void *lsmrule,
+ struct audit_context *actx)
+{
+ return -EINVAL;
+}
+#endif /* CONFIG_IMA_LSM_RULES */
#endif
diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
index 4f25be7..95ef1ca 100644
--- a/security/integrity/ima/ima_fs.c
+++ b/security/integrity/ima/ima_fs.c
@@ -19,9 +19,11 @@
#include <linux/seq_file.h>
#include <linux/rculist.h>
#include <linux/rcupdate.h>
+#include <linux/parser.h>
#include "ima.h"
+static int valid_policy = 1;
#define TMPBUFLEN 12
static ssize_t ima_show_htable_value(char __user *buf, size_t count,
loff_t *ppos, atomic_long_t *val)
@@ -237,11 +239,66 @@ static struct file_operations ima_ascii_measurements_ops = {
.release = seq_release,
};
+static ssize_t ima_write_policy(struct file *file, const char __user *buf,
+ size_t datalen, loff_t *ppos)
+{
+ char *data;
+ int rc;
+
+ if (datalen >= PAGE_SIZE)
+ return -ENOMEM;
+ if (*ppos != 0) {
+ /* No partial writes. */
+ return -EINVAL;
+ }
+ data = kmalloc(datalen + 1, GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ if (copy_from_user(data, buf, datalen)) {
+ kfree(data);
+ return -EFAULT;
+ }
+ *(data + datalen) = '\0';
+ rc = ima_parse_add_rule(data);
+ if (rc < 0) {
+ datalen = -EINVAL;
+ valid_policy = 0;
+ }
+
+ kfree(data);
+ return datalen;
+}
+
static struct dentry *ima_dir;
static struct dentry *binary_runtime_measurements;
static struct dentry *ascii_runtime_measurements;
static struct dentry *runtime_measurements_count;
static struct dentry *violations;
+static struct dentry *ima_policy;
+
+/*
+ * ima_release_policy - start using the new measure policy rules.
+ *
+ * Initially, ima_measure points to the default policy rules, now
+ * point to the new policy rules, and remove the securityfs policy file.
+ */
+static int ima_release_policy(struct inode *inode, struct file *file)
+{
+ if (!valid_policy) {
+ ima_delete_rules();
+ return 0;
+ }
+ ima_update_policy();
+ securityfs_remove(ima_policy);
+ ima_policy = NULL;
+ return 0;
+}
+
+static struct file_operations ima_measure_policy_ops = {
+ .write = ima_write_policy,
+ .release = ima_release_policy
+};
int ima_fs_init(void)
{
@@ -276,13 +333,20 @@ int ima_fs_init(void)
if (IS_ERR(violations))
goto out;
- return 0;
+ ima_policy = securityfs_create_file("policy",
+ S_IRUSR | S_IRGRP | S_IWUSR,
+ ima_dir, NULL,
+ &ima_measure_policy_ops);
+ if (IS_ERR(ima_policy))
+ goto out;
+ return 0;
out:
securityfs_remove(runtime_measurements_count);
securityfs_remove(ascii_runtime_measurements);
securityfs_remove(binary_runtime_measurements);
securityfs_remove(ima_dir);
+ securityfs_remove(ima_policy);
return -1;
}
@@ -293,4 +357,5 @@ void __exit ima_fs_cleanup(void)
securityfs_remove(ascii_runtime_measurements);
securityfs_remove(binary_runtime_measurements);
securityfs_remove(ima_dir);
+ securityfs_remove(ima_policy);
}
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index 7c3d1ff..bd45360 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -15,6 +15,7 @@
#include <linux/audit.h>
#include <linux/security.h>
#include <linux/magic.h>
+#include <linux/parser.h>
#include "ima.h"
@@ -24,7 +25,12 @@
#define IMA_FSMAGIC 0x0004
#define IMA_UID 0x0008
-enum ima_action { DONT_MEASURE, MEASURE };
+enum ima_action { UNKNOWN = -1, DONT_MEASURE = 0, MEASURE };
+
+#define MAX_LSM_RULES 6
+enum lsm_rule_types { LSM_OBJ_USER, LSM_OBJ_ROLE, LSM_OBJ_TYPE,
+ LSM_SUBJ_USER, LSM_SUBJ_ROLE, LSM_SUBJ_TYPE
+};
struct ima_measure_rule_entry {
struct list_head list;
@@ -34,8 +40,15 @@ struct ima_measure_rule_entry {
int mask;
unsigned long fsmagic;
uid_t uid;
+ struct {
+ void *rule; /* LSM file metadata specific */
+ int type; /* audit type */
+ } lsm[MAX_LSM_RULES];
};
+/* Without LSM specific knowledge, the default policy can only be
+ * written in terms of .action, .func, .mask, .fsmagic, and .uid
+ */
static struct ima_measure_rule_entry default_rules[] = {
{.action = DONT_MEASURE,.fsmagic = PROC_SUPER_MAGIC,
.flags = IMA_FSMAGIC},
@@ -54,8 +67,11 @@ static struct ima_measure_rule_entry default_rules[] = {
};
static LIST_HEAD(measure_default_rules);
+static LIST_HEAD(measure_policy_rules);
static struct list_head *ima_measure;
+static DEFINE_MUTEX(ima_measure_mutex);
+
/**
* ima_match_rules - determine whether an inode matches the measure rule.
* @rule: a pointer to a rule
@@ -69,6 +85,7 @@ static bool ima_match_rules(struct ima_measure_rule_entry *rule,
struct inode *inode, enum ima_hooks func, int mask)
{
struct task_struct *tsk = current;
+ int i;
if ((rule->flags & IMA_FUNC) && rule->func != func)
return false;
@@ -79,6 +96,39 @@ static bool ima_match_rules(struct ima_measure_rule_entry *rule,
return false;
if ((rule->flags & IMA_UID) && rule->uid != tsk->cred->uid)
return false;
+ for (i = 0; i < MAX_LSM_RULES; i++) {
+ int rc;
+ u32 osid, sid;
+
+ if (!rule->lsm[i].rule)
+ continue;
+
+ switch (i) {
+ case LSM_OBJ_USER:
+ case LSM_OBJ_ROLE:
+ case LSM_OBJ_TYPE:
+ security_inode_getsecid(inode, &osid);
+ rc = security_filter_rule_match(osid,
+ rule->lsm[i].type,
+ AUDIT_EQUAL,
+ rule->lsm[i].rule,
+ NULL);
+ break;
+ case LSM_SUBJ_USER:
+ case LSM_SUBJ_ROLE:
+ case LSM_SUBJ_TYPE:
+ security_task_getsecid(tsk, &sid);
+ rc = security_filter_rule_match(sid,
+ rule->lsm[i].type,
+ AUDIT_EQUAL,
+ rule->lsm[i].rule,
+ NULL);
+ default:
+ break;
+ }
+ if (!rc)
+ return false;
+ }
return true;
}
@@ -112,9 +162,8 @@ int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask)
/**
* ima_init_policy - initialize the default measure rules.
*
- * (Could use the default_rules directly, but in policy patch
* ima_measure points to either the measure_default_rules or the
- * the new measure_policy_rules.)
+ * the new measure_policy_rules.
*/
void ima_init_policy(void)
{
@@ -124,3 +173,241 @@ void ima_init_policy(void)
list_add_tail(&default_rules[i].list, &measure_default_rules);
ima_measure = &measure_default_rules;
}
+
+/**
+ * ima_update_policy - update default_rules with new measure rules
+ *
+ * Called on file .release to update the default rules with a complete new
+ * policy. Once updated, the policy is locked, no additional rules can be
+ * added to the policy.
+ */
+void ima_update_policy(void)
+{
+ const char *op = "policy_update";
+ const char *cause = "already exists";
+ int result = 1;
+ int audit_info = 0;
+
+ if (ima_measure == &measure_default_rules) {
+ ima_measure = &measure_policy_rules;
+ cause = "complete";
+ result = 0;
+ }
+ integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL,
+ NULL, op, cause, result, audit_info);
+}
+
+enum {
+ Opt_err = -1,
+ Opt_measure = 1, Opt_dont_measure,
+ Opt_obj_user, Opt_obj_role, Opt_obj_type,
+ Opt_subj_user, Opt_subj_role, Opt_subj_type,
+ Opt_func, Opt_mask, Opt_fsmagic, Opt_uid
+};
+
+static match_table_t policy_tokens = {
+ {Opt_measure, "measure"},
+ {Opt_dont_measure, "dont_measure"},
+ {Opt_obj_user, "obj_user=%s"},
+ {Opt_obj_role, "obj_role=%s"},
+ {Opt_obj_type, "obj_type=%s"},
+ {Opt_subj_user, "subj_user=%s"},
+ {Opt_subj_role, "subj_role=%s"},
+ {Opt_subj_type, "subj_type=%s"},
+ {Opt_func, "func=%s"},
+ {Opt_mask, "mask=%s"},
+ {Opt_fsmagic, "fsmagic=%s"},
+ {Opt_uid, "uid=%s"},
+ {Opt_err, NULL}
+};
+
+static int ima_lsm_rule_init(struct ima_measure_rule_entry *entry,
+ char *args, int lsm_rule, int audit_type)
+{
+ int result;
+
+ entry->lsm[lsm_rule].type = audit_type;
+ result = security_filter_rule_init(entry->lsm[lsm_rule].type,
+ AUDIT_EQUAL, args,
+ &entry->lsm[lsm_rule].rule);
+ return result;
+}
+
+static int ima_parse_rule(char *rule, struct ima_measure_rule_entry *entry)
+{
+ struct audit_buffer *ab;
+ char *p;
+ int result = 0;
+
+ ab = audit_log_start(current->audit_context, GFP_KERNEL,
+ AUDIT_INTEGRITY_STATUS);
+
+ entry->action = -1;
+ while ((p = strsep(&rule, " \n")) != NULL) {
+ substring_t args[MAX_OPT_ARGS];
+ int token;
+ unsigned long lnum;
+
+ if (result < 0)
+ break;
+ if (!*p)
+ continue;
+ token = match_token(p, policy_tokens, args);
+ switch (token) {
+ case Opt_measure:
+ audit_log_format(ab, "%s ", "measure");
+ entry->action = MEASURE;
+ break;
+ case Opt_dont_measure:
+ audit_log_format(ab, "%s ", "dont_measure");
+ entry->action = DONT_MEASURE;
+ break;
+ case Opt_func:
+ audit_log_format(ab, "func=%s ", args[0].from);
+ if (strcmp(args[0].from, "PATH_CHECK") == 0)
+ entry->func = PATH_CHECK;
+ else if (strcmp(args[0].from, "FILE_MMAP") == 0)
+ entry->func = FILE_MMAP;
+ else if (strcmp(args[0].from, "BPRM_CHECK") == 0)
+ entry->func = BPRM_CHECK;
+ else
+ result = -EINVAL;
+ if (!result)
+ entry->flags |= IMA_FUNC;
+ break;
+ case Opt_mask:
+ audit_log_format(ab, "mask=%s ", args[0].from);
+ if ((strcmp(args[0].from, "MAY_EXEC")) == 0)
+ entry->mask = MAY_EXEC;
+ else if (strcmp(args[0].from, "MAY_WRITE") == 0)
+ entry->mask = MAY_WRITE;
+ else if (strcmp(args[0].from, "MAY_READ") == 0)
+ entry->mask = MAY_READ;
+ else if (strcmp(args[0].from, "MAY_APPEND") == 0)
+ entry->mask = MAY_APPEND;
+ else
+ result = -EINVAL;
+ if (!result)
+ entry->flags |= IMA_MASK;
+ break;
+ case Opt_fsmagic:
+ audit_log_format(ab, "fsmagic=%s ", args[0].from);
+ result = strict_strtoul(args[0].from, 16,
+ &entry->fsmagic);
+ if (!result)
+ entry->flags |= IMA_FSMAGIC;
+ break;
+ case Opt_uid:
+ audit_log_format(ab, "uid=%s ", args[0].from);
+ result = strict_strtoul(args[0].from, 10, &lnum);
+ if (!result) {
+ entry->uid = (uid_t) lnum;
+ if (entry->uid != lnum)
+ result = -EINVAL;
+ else
+ entry->flags |= IMA_UID;
+ }
+ break;
+ case Opt_obj_user:
+ audit_log_format(ab, "obj_user=%s ", args[0].from);
+ result = ima_lsm_rule_init(entry, args[0].from,
+ LSM_OBJ_USER,
+ AUDIT_OBJ_USER);
+ break;
+ case Opt_obj_role:
+ audit_log_format(ab, "obj_role=%s ", args[0].from);
+ result = ima_lsm_rule_init(entry, args[0].from,
+ LSM_OBJ_ROLE,
+ AUDIT_OBJ_ROLE);
+ break;
+ case Opt_obj_type:
+ audit_log_format(ab, "obj_type=%s ", args[0].from);
+ result = ima_lsm_rule_init(entry, args[0].from,
+ LSM_OBJ_TYPE,
+ AUDIT_OBJ_TYPE);
+ break;
+ case Opt_subj_user:
+ audit_log_format(ab, "subj_user=%s ", args[0].from);
+ result = ima_lsm_rule_init(entry, args[0].from,
+ LSM_SUBJ_USER,
+ AUDIT_SUBJ_USER);
+ break;
+ case Opt_subj_role:
+ audit_log_format(ab, "subj_role=%s ", args[0].from);
+ result = ima_lsm_rule_init(entry, args[0].from,
+ LSM_SUBJ_ROLE,
+ AUDIT_SUBJ_ROLE);
+ break;
+ case Opt_subj_type:
+ audit_log_format(ab, "subj_type=%s ", args[0].from);
+ result = ima_lsm_rule_init(entry, args[0].from,
+ LSM_SUBJ_TYPE,
+ AUDIT_SUBJ_TYPE);
+ break;
+ case Opt_err:
+ printk(KERN_INFO "%s: unknown token: %s\n",
+ __FUNCTION__, p);
+ break;
+ }
+ }
+ if (entry->action == UNKNOWN)
+ result = -EINVAL;
+
+ audit_log_format(ab, "res=%d", result);
+ audit_log_end(ab);
+ return result;
+}
+
+/**
+ * ima_parse_add_rule - add a rule to measure_policy_rules
+ * @rule - ima measurement policy rule
+ *
+ * Uses a mutex to protect the policy list from multiple concurrent writers.
+ * Returns 0 on success, an error code on failure.
+ */
+int ima_parse_add_rule(char *rule)
+{
+ const char *op = "add_rule";
+ struct ima_measure_rule_entry *entry;
+ int result = 0;
+ int audit_info = 0;
+
+ /* Prevent installed policy from changing */
+ if (ima_measure != &measure_default_rules) {
+ integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL,
+ NULL, op, "already exists",
+ -EACCES, audit_info);
+ return -EACCES;
+ }
+
+ entry = kzalloc(sizeof(*entry), GFP_KERNEL);
+ if (!entry) {
+ integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL,
+ NULL, op, "-ENOMEM", -ENOMEM, audit_info);
+ return -ENOMEM;
+ }
+
+ INIT_LIST_HEAD(&entry->list);
+
+ result = ima_parse_rule(rule, entry);
+ if (!result) {
+ mutex_lock(&ima_measure_mutex);
+ list_add_tail(&entry->list, &measure_policy_rules);
+ mutex_unlock(&ima_measure_mutex);
+ } else
+ kfree(entry);
+ return result;
+}
+
+/* ima_delete_rules called to cleanup invalid policy */
+void ima_delete_rules()
+{
+ struct ima_measure_rule_entry *entry, *tmp;
+
+ mutex_lock(&ima_measure_mutex);
+ list_for_each_entry_safe(entry, tmp, &measure_policy_rules, list) {
+ list_del(&entry->list);
+ kfree(entry);
+ }
+ mutex_unlock(&ima_measure_mutex);
+}
--
1.5.6.6
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 5/7] integrity: IMA policy open
2009-02-04 14:06 [PATCH 0/7] integrity Mimi Zohar
` (3 preceding siblings ...)
2009-02-04 14:07 ` [PATCH 4/7] integrity: IMA policy Mimi Zohar
@ 2009-02-04 14:07 ` Mimi Zohar
2009-02-04 14:07 ` [PATCH 6/7] Integrity: IMA file free imbalance Mimi Zohar
` (3 subsequent siblings)
8 siblings, 0 replies; 19+ messages in thread
From: Mimi Zohar @ 2009-02-04 14:07 UTC (permalink / raw)
To: linux-kernel
Cc: Mimi Zohar, Andrew Morton, James Morris, David Safford,
Serge Hallyn, Mimi Zohar
Sequentialize access to the policy file
- permit multiple attempts to replace default policy with a valid policy
Signed-off-by: Mimi Zohar <zohar@us.ibm.com>
Acked-by: Serge Hallyn <serue@us.ibm.com>
---
diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
index 95ef1ca..573780c 100644
--- a/security/integrity/ima/ima_fs.c
+++ b/security/integrity/ima/ima_fs.c
@@ -277,16 +277,30 @@ static struct dentry *runtime_measurements_count;
static struct dentry *violations;
static struct dentry *ima_policy;
+static atomic_t policy_opencount = ATOMIC_INIT(1);
+/*
+ * ima_open_policy: sequentialize access to the policy file
+ */
+int ima_open_policy(struct inode * inode, struct file * filp)
+{
+ if (atomic_dec_and_test(&policy_opencount))
+ return 0;
+ return -EBUSY;
+}
+
/*
* ima_release_policy - start using the new measure policy rules.
*
* Initially, ima_measure points to the default policy rules, now
- * point to the new policy rules, and remove the securityfs policy file.
+ * point to the new policy rules, and remove the securityfs policy file,
+ * assuming a valid policy.
*/
static int ima_release_policy(struct inode *inode, struct file *file)
{
if (!valid_policy) {
ima_delete_rules();
+ valid_policy = 1;
+ atomic_set(&policy_opencount, 1);
return 0;
}
ima_update_policy();
@@ -296,6 +310,7 @@ static int ima_release_policy(struct inode *inode, struct file *file)
}
static struct file_operations ima_measure_policy_ops = {
+ .open = ima_open_policy,
.write = ima_write_policy,
.release = ima_release_policy
};
--
1.5.6.6
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 6/7] Integrity: IMA file free imbalance
2009-02-04 14:06 [PATCH 0/7] integrity Mimi Zohar
` (4 preceding siblings ...)
2009-02-04 14:07 ` [PATCH 5/7] integrity: IMA policy open Mimi Zohar
@ 2009-02-04 14:07 ` Mimi Zohar
2009-02-04 14:07 ` [PATCH 7/7] Integrity: IMA update maintainers Mimi Zohar
` (2 subsequent siblings)
8 siblings, 0 replies; 19+ messages in thread
From: Mimi Zohar @ 2009-02-04 14:07 UTC (permalink / raw)
To: linux-kernel
Cc: Mimi Zohar, Andrew Morton, James Morris, David Safford,
Serge Hallyn, Mimi Zohar
The number of calls to ima_path_check()/ima_file_free()
should be balanced. An extra call to fput(), indicates
the file could have been accessed without first being
measured.
Although f_count is incremented/decremented in places other
than fget/fput, like fget_light/fput_light and get_file, the
current task must already hold a file refcnt. The call to
__fput() is delayed until the refcnt becomes 0, resulting
in ima_file_free() flagging any changes.
- add hook to increment opencount for IPC shared memory(SYSV),
shmat files, and /dev/zero
- moved NULL iint test in opencount_get()
Signed-off-by: Mimi Zohar <zohar@us.ibm.com>
Acked-by: Serge Hallyn <serue@us.ibm.com>
---
diff --git a/include/linux/ima.h b/include/linux/ima.h
index dcc3664..6db30a3 100644
--- a/include/linux/ima.h
+++ b/include/linux/ima.h
@@ -19,6 +19,7 @@ extern void ima_inode_free(struct inode *inode);
extern int ima_path_check(struct path *path, int mask);
extern void ima_file_free(struct file *file);
extern int ima_file_mmap(struct file *file, unsigned long prot);
+extern void ima_shm_check(struct file *file);
#else
static inline int ima_bprm_check(struct linux_binprm *bprm)
@@ -50,5 +51,10 @@ static inline int ima_file_mmap(struct file *file, unsigned long prot)
{
return 0;
}
+
+static inline void ima_shm_check(struct file *file)
+{
+ return;
+}
#endif /* CONFIG_IMA_H */
#endif /* _LINUX_IMA_H */
diff --git a/ipc/shm.c b/ipc/shm.c
index 38a0557..d39bd76 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -39,6 +39,7 @@
#include <linux/nsproxy.h>
#include <linux/mount.h>
#include <linux/ipc_namespace.h>
+#include <linux/ima.h>
#include <asm/uaccess.h>
@@ -381,6 +382,7 @@ static int newseg(struct ipc_namespace *ns, struct ipc_params *params)
error = PTR_ERR(file);
if (IS_ERR(file))
goto no_file;
+ ima_shm_check(file);
id = ipc_addid(&shm_ids(ns), &shp->shm_perm, ns->shm_ctlmni);
if (id < 0) {
@@ -888,6 +890,7 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr)
file = alloc_file(path.mnt, path.dentry, f_mode, &shm_file_operations);
if (!file)
goto out_free;
+ ima_shm_check(file);
file->private_data = sfd;
file->f_mapping = shp->shm_file->f_mapping;
diff --git a/mm/shmem.c b/mm/shmem.c
index f1b0d48..dd5588f 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -51,6 +51,7 @@
#include <linux/highmem.h>
#include <linux/seq_file.h>
#include <linux/magic.h>
+#include <linux/ima.h>
#include <asm/uaccess.h>
#include <asm/div64.h>
@@ -2600,6 +2601,7 @@ int shmem_zero_setup(struct vm_area_struct *vma)
if (IS_ERR(file))
return PTR_ERR(file);
+ ima_shm_check(file);
if (vma->vm_file)
fput(vma->vm_file);
vma->vm_file = file;
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index 42706b5..e3c16a2 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -97,6 +97,7 @@ static inline unsigned long ima_hash_key(u8 *digest)
/* iint cache flags */
#define IMA_MEASURED 1
+#define IMA_IINT_DUMP_STACK 512
/* integrity data associated with an inode */
struct ima_iint_cache {
@@ -106,6 +107,7 @@ struct ima_iint_cache {
struct mutex mutex; /* protects: version, flags, digest */
long readcount; /* measured files readcount */
long writecount; /* measured files writecount */
+ long opencount; /* opens reference count */
struct kref refcount; /* ima_iint_cache reference count */
struct rcu_head rcu;
};
diff --git a/security/integrity/ima/ima_iint.c b/security/integrity/ima/ima_iint.c
index 750db3c..1f035e8 100644
--- a/security/integrity/ima/ima_iint.c
+++ b/security/integrity/ima/ima_iint.c
@@ -126,6 +126,7 @@ struct ima_iint_cache *ima_iint_find_insert_get(struct inode *inode)
return iint;
}
+EXPORT_SYMBOL_GPL(ima_iint_find_insert_get);
/* iint_free - called when the iint refcount goes to zero */
void iint_free(struct kref *kref)
@@ -134,6 +135,21 @@ void iint_free(struct kref *kref)
refcount);
iint->version = 0;
iint->flags = 0UL;
+ if (iint->readcount != 0) {
+ printk(KERN_INFO "%s: readcount: %ld\n", __FUNCTION__,
+ iint->readcount);
+ iint->readcount = 0;
+ }
+ if (iint->writecount != 0) {
+ printk(KERN_INFO "%s: writecount: %ld\n", __FUNCTION__,
+ iint->writecount);
+ iint->writecount = 0;
+ }
+ if (iint->opencount != 0) {
+ printk(KERN_INFO "%s: opencount: %ld\n", __FUNCTION__,
+ iint->opencount);
+ iint->opencount = 0;
+ }
kref_set(&iint->refcount, 1);
kmem_cache_free(iint_cache, iint);
}
@@ -174,6 +190,7 @@ static void init_once(void *foo)
mutex_init(&iint->mutex);
iint->readcount = 0;
iint->writecount = 0;
+ iint->opencount = 0;
kref_set(&iint->refcount, 1);
}
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index 871e356..f4e7266 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -66,6 +66,19 @@ void ima_file_free(struct file *file)
return;
mutex_lock(&iint->mutex);
+ if (iint->opencount <= 0) {
+ printk(KERN_INFO
+ "%s: %s open/free imbalance (r:%ld w:%ld o:%ld f:%ld)\n",
+ __FUNCTION__, file->f_dentry->d_name.name,
+ iint->readcount, iint->writecount,
+ iint->opencount, atomic_long_read(&file->f_count));
+ if (!(iint->flags & IMA_IINT_DUMP_STACK)) {
+ dump_stack();
+ iint->flags |= IMA_IINT_DUMP_STACK;
+ }
+ }
+ iint->opencount--;
+
if ((file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
iint->readcount--;
@@ -119,6 +132,7 @@ static int get_path_measurement(struct ima_iint_cache *iint, struct file *file,
pr_info("%s dentry_open failed\n", filename);
return rc;
}
+ iint->opencount++;
iint->readcount++;
rc = ima_collect_measurement(iint, file);
@@ -159,6 +173,7 @@ int ima_path_check(struct path *path, int mask)
return 0;
mutex_lock(&iint->mutex);
+ iint->opencount++;
if ((mask & MAY_WRITE) || (mask == 0))
iint->writecount++;
else if (mask & (MAY_READ | MAY_EXEC))
@@ -219,6 +234,21 @@ out:
return rc;
}
+static void opencount_get(struct file *file)
+{
+ struct inode *inode = file->f_dentry->d_inode;
+ struct ima_iint_cache *iint;
+
+ if (!ima_initialized || !S_ISREG(inode->i_mode))
+ return;
+ iint = ima_iint_find_insert_get(inode);
+ if (!iint)
+ return;
+ mutex_lock(&iint->mutex);
+ iint->opencount++;
+ mutex_unlock(&iint->mutex);
+}
+
/**
* ima_file_mmap - based on policy, collect/store measurement.
* @file: pointer to the file to be measured (May be NULL)
@@ -242,6 +272,18 @@ int ima_file_mmap(struct file *file, unsigned long prot)
return 0;
}
+/*
+ * ima_shm_check - IPC shm and shmat create/fput a file
+ *
+ * Maintain the opencount for these files to prevent unnecessary
+ * imbalance messages.
+ */
+void ima_shm_check(struct file *file)
+{
+ opencount_get(file);
+ return;
+}
+
/**
* ima_bprm_check - based on policy, collect/store measurement.
* @bprm: contains the linux_binprm structure
--
1.5.6.6
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 7/7] Integrity: IMA update maintainers
2009-02-04 14:06 [PATCH 0/7] integrity Mimi Zohar
` (5 preceding siblings ...)
2009-02-04 14:07 ` [PATCH 6/7] Integrity: IMA file free imbalance Mimi Zohar
@ 2009-02-04 14:07 ` Mimi Zohar
2009-02-04 23:16 ` [PATCH 0/7] integrity James Morris
2009-02-05 22:37 ` James Morris
8 siblings, 0 replies; 19+ messages in thread
From: Mimi Zohar @ 2009-02-04 14:07 UTC (permalink / raw)
To: linux-kernel
Cc: Mimi Zohar, Andrew Morton, James Morris, David Safford,
Serge Hallyn, Mimi Zohar
Signed-off-by: Mimi Zohar <zohar@us.ibm.com>
---
diff --git a/MAINTAINERS b/MAINTAINERS
index 6bd7d47..12fc280 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2175,6 +2175,11 @@ M: stefanr@s5r6.in-berlin.de
L: linux1394-devel@lists.sourceforge.net
S: Maintained
+INTEGRITY MEASUREMENT ARCHITECTURE (IMA)
+P: Mimi Zohar
+M: zohar@us.ibm.com
+S: Supported
+
IMS TWINTURBO FRAMEBUFFER DRIVER
L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
S: Orphan
--
1.5.6.6
^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH 0/7] integrity
2009-02-04 14:06 [PATCH 0/7] integrity Mimi Zohar
` (6 preceding siblings ...)
2009-02-04 14:07 ` [PATCH 7/7] Integrity: IMA update maintainers Mimi Zohar
@ 2009-02-04 23:16 ` James Morris
2009-02-05 0:38 ` Mimi Zohar
2009-02-05 22:37 ` James Morris
8 siblings, 1 reply; 19+ messages in thread
From: James Morris @ 2009-02-04 23:16 UTC (permalink / raw)
To: Mimi Zohar; +Cc: linux-kernel, Andrew Morton, David Safford, Serge Hallyn
I get an oops on boot with this.
Do you have lock and list debugging enabled?
[ 2.244280] ------------[ cut here ]------------
[ 2.245261] WARNING: at kernel/mutex.c:135 mutex_lock_nested+0x325/0x380()
[ 2.245261] Hardware name: PowerEdge T105
[ 2.245261] Modules linked in:
[ 2.245261] Pid: 1, comm: swapper Not tainted 2.6.28 #37
[ 2.245261] Call Trace:
[ 2.245261] [<ffffffff8104f15f>] warn_slowpath+0xaf/0x110
[ 2.245261] [<ffffffff8107986d>] ? __lock_acquire+0x58d/0x1b80
[ 2.245261] [<ffffffff8107986d>] ? __lock_acquire+0x58d/0x1b80
[ 2.245261] [<ffffffff81383f75>] mutex_lock_nested+0x325/0x380
[ 2.245261] [<ffffffff810418fe>] ? __wake_up+0x4e/0x70
[ 2.245261] [<ffffffff81385c4d>] ? _spin_unlock_irqrestore+0x6d/0x90
[ 2.245261] [<ffffffff81078752>] ? trace_hardirqs_on_caller+0x172/0x1d0
[ 2.245261] [<ffffffff8125b7db>] tpm_transmit+0x5b/0x270
[ 2.245261] [<ffffffff8125ba64>] transmit_cmd+0x14/0x50
[ 2.245261] [<ffffffff8125baef>] __tpm_pcr_read+0x4f/0x80
[ 2.245261] [<ffffffff810e9f07>] ? kfree+0xc7/0x140
[ 2.245261] [<ffffffff81078752>] ? trace_hardirqs_on_caller+0x172/0x1d0
[ 2.245261] [<ffffffff810787bd>] ? trace_hardirqs_on+0xd/0x10
[ 2.245261] [<ffffffff811b342f>] ? kobject_uevent_env+0x11f/0x3f0
[ 2.245261] [<ffffffff810a3e85>] ? __rcu_read_lock+0xc5/0xf0
[ 2.245261] [<ffffffff810a3d8b>] ? __rcu_read_unlock+0xbb/0xf0
[ 2.245261] [<ffffffff81078752>] ? trace_hardirqs_on_caller+0x172/0x1d0
[ 2.245261] [<ffffffff810787bd>] ? trace_hardirqs_on+0xd/0x10
[ 2.245261] [<ffffffff8125c6b5>] ? tpm_chip_find_get+0xd5/0xf0
[ 2.245261] [<ffffffff8125c7d2>] tpm_pcr_read+0x42/0x70
[ 2.245261] [<ffffffff815f5dca>] ? init_ima+0x0/0x1a
[ 2.245261] [<ffffffff8118d8b7>] ima_init+0x27/0x160
[ 2.245261] [<ffffffff815f5dca>] ? init_ima+0x0/0x1a
[ 2.245261] [<ffffffff815f5dca>] ? init_ima+0x0/0x1a
[ 2.245261] [<ffffffff815f5dd8>] init_ima+0xe/0x1a
[ 2.245261] [<ffffffff8100a03c>] do_one_initcall+0x3c/0x180
[ 2.245261] [<ffffffff810a2a3e>] ? register_irq_proc+0xbe/0xe0
[ 2.245261] [<ffffffff81140000>] ? v2_read_dquot+0x240/0x2a0
[ 2.245261] [<ffffffff815ce703>] kernel_init+0x14d/0x1a3
[ 2.245261] [<ffffffff813855a6>] ? trace_hardirqs_on_thunk+0x3a/0x3f
[ 2.245261] [<ffffffff81015ada>] child_rip+0xa/0x20
[ 2.245261] [<ffffffff810153be>] ? restore_args+0x0/0x30
[ 2.245261] [<ffffffff815ce5b6>] ? kernel_init+0x0/0x1a3
[ 2.245261] [<ffffffff81015ad0>] ? child_rip+0x0/0x20
[ 2.245261] ---[ end trace 9947c764f5d88c86 ]---
[ 2.245261] BUG: unable to handle kernel paging request at ffffffff00060000
[ 2.245261] IP: [<ffffffff811cac36>] __list_add+0x26/0xa0
[ 2.245261] PGD 203067 PUD 0
[ 2.245261] Oops: 0000 [#1] PREEMPT SMP
[ 2.245261] last sysfs file:
[ 2.245261] CPU 0
[ 2.245261] Modules linked in:
[ 2.245261] Pid: 1, comm: swapper Tainted: G W 2.6.28 #37
[ 2.245261] RIP: 0010:[<ffffffff811cac36>] [<ffffffff811cac36>] __list_add+0x26/0xa0
[ 2.245261] RSP: 0018:ffff88012fa7fb80 EFLAGS: 00010046
[ 2.245261] RAX: ffffffff00060000 RBX: ffffffff81559ce8 RCX: 0000000000000000
[ 2.245261] RDX: ffffffff81559ce8 RSI: ffffffff00060000 RDI: ffff88012fa7fbd0
[ 2.245261] RBP: ffff88012fa7fba0 R08: 0000000000000002 R09: 0000000000000001
[ 2.245261] R10: ffff8801afa7f95f R11: ffff88012fa7f8e0 R12: ffffffff00060000
[ 2.245261] R13: ffff88012fa7fbd0 R14: ffff88012fa80000 R15: ffffffff8125b7db
[ 2.245261] FS: 0000000000000000(0000) GS:ffffffff8159fe00(0000) knlGS:0000000000000000
[ 2.245261] CS: 0010 DS: 0018 ES: 0018 CR0: 000000008005003b
[ 2.245261] CR2: ffffffff00060000 CR3: 0000000000201000 CR4: 00000000000006e0
[ 2.245261] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[ 2.245261] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
[ 2.245261] Process swapper (pid: 1, threadinfo ffff88012fa7e000, task ffff88012fa80000)
[ 2.245261] Stack:
[ 2.245261] 0000000000000246 ffffffff81559cb0 0000000000000246 ffffffff81559cb8
[ 2.245261] ffff88012fa7fc30 ffffffff81383d49 ffffffff8125b7db ffffffff810418fe
[ 2.245261] 0000000000000001 ffffffff81559ce8 ffff88012fa7fbd0 ffff88012fa7fbd0
[ 2.245261] Call Trace:
[ 2.245261] [<ffffffff81383d49>] mutex_lock_nested+0xf9/0x380
[ 2.245261] [<ffffffff8125b7db>] ? tpm_transmit+0x5b/0x270
[ 2.245261] [<ffffffff810418fe>] ? __wake_up+0x4e/0x70
[ 2.245261] [<ffffffff8125b7db>] tpm_transmit+0x5b/0x270
[ 2.245261] [<ffffffff8125ba64>] transmit_cmd+0x14/0x50
[ 2.245261] [<ffffffff8125baef>] __tpm_pcr_read+0x4f/0x80
[ 2.245261] [<ffffffff810e9f07>] ? kfree+0xc7/0x140
[ 2.245261] [<ffffffff81078752>] ? trace_hardirqs_on_caller+0x172/0x1d0
[ 2.245261] [<ffffffff810787bd>] ? trace_hardirqs_on+0xd/0x10
[ 2.245261] [<ffffffff811b342f>] ? kobject_uevent_env+0x11f/0x3f0
[ 2.245261] [<ffffffff810a3e85>] ? __rcu_read_lock+0xc5/0xf0
[ 2.245261] [<ffffffff810a3d8b>] ? __rcu_read_unlock+0xbb/0xf0
[ 2.245261] [<ffffffff81078752>] ? trace_hardirqs_on_caller+0x172/0x1d0
[ 2.245261] [<ffffffff810787bd>] ? trace_hardirqs_on+0xd/0x10
[ 2.245261] [<ffffffff8125c6b5>] ? tpm_chip_find_get+0xd5/0xf0
[ 2.245261] [<ffffffff8125c7d2>] tpm_pcr_read+0x42/0x70
[ 2.245261] [<ffffffff815f5dca>] ? init_ima+0x0/0x1a
[ 2.245261] [<ffffffff8118d8b7>] ima_init+0x27/0x160
[ 2.245261] [<ffffffff815f5dca>] ? init_ima+0x0/0x1a
[ 2.245261] [<ffffffff815f5dca>] ? init_ima+0x0/0x1a
[ 2.245261] [<ffffffff815f5dd8>] init_ima+0xe/0x1a
[ 2.245261] [<ffffffff8100a03c>] do_one_initcall+0x3c/0x180
[ 2.245261] [<ffffffff810a2a3e>] ? register_irq_proc+0xbe/0xe0
[ 2.245261] [<ffffffff81140000>] ? v2_read_dquot+0x240/0x2a0
[ 2.245261] [<ffffffff815ce703>] kernel_init+0x14d/0x1a3
[ 2.245261] [<ffffffff813855a6>] ? trace_hardirqs_on_thunk+0x3a/0x3f
[ 2.245261] [<ffffffff81015ada>] child_rip+0xa/0x20
[ 2.245261] [<ffffffff810153be>] ? restore_args+0x0/0x30
[ 2.245261] [<ffffffff815ce5b6>] ? kernel_init+0x0/0x1a3
[ 2.245261] [<ffffffff81015ad0>] ? child_rip+0x0/0x20
[ 2.245261] Code: 98 0f 1f 40 00 55 48 89 e5 48 83 ec 20 48 89 5d e8 4c 89 65 f0 48 89 d3 4c 89 6d f8 48 8b 42 08 49 89 fd 49 89 f4 48 39 f0 75 27 <49> 8b 04 24 48 39 d8 75 43 4c 89 6b 08 49 89 5d 00 4d 89 65 08
[ 2.245261] RIP [<ffffffff811cac36>] __list_add+0x26/0xa0
[ 2.245261] RSP <ffff88012fa7fb80>
[ 2.245261] CR2: ffffffff00060000
[ 2.245261] ---[ end trace 9947c764f5d88c86 ]---
[ 2.822672] Kernel panic - not syncing: Attempted to kill init!
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 0/7] integrity
2009-02-04 23:16 ` [PATCH 0/7] integrity James Morris
@ 2009-02-05 0:38 ` Mimi Zohar
2009-02-05 1:00 ` James Morris
0 siblings, 1 reply; 19+ messages in thread
From: Mimi Zohar @ 2009-02-05 0:38 UTC (permalink / raw)
To: James Morris; +Cc: linux-kernel, Andrew Morton, David Safford, Serge Hallyn
On Thu, 2009-02-05 at 10:16 +1100, James Morris wrote:
> I get an oops on boot with this.
>
> Do you have lock and list debugging enabled?
In the past I had them enabled. Just recompiled now with them enabled
and was able to boot without problems.
CONFIG_DEBUG_SPINLOCK=y
CONFIG_DEBUG_MUTEXES=y
CONFIG_DEBUG_LOCK_ALLOC=y
CONFIG_PROVE_LOCKING=y
CONFIG_LOCKDEP=y
CONFIG_LOCK_STAT=y
CONFIG_DEBUG_LOCKDEP=y
CONFIG_TRACE_IRQFLAGS=y
CONFIG_DEBUG_SPINLOCK_SLEEP=y
# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
CONFIG_STACKTRACE=y
# CONFIG_DEBUG_KOBJECT is not set
CONFIG_DEBUG_HIGHMEM=y
CONFIG_DEBUG_BUGVERBOSE=y
CONFIG_DEBUG_INFO=y
# CONFIG_DEBUG_VM is not set
# CONFIG_DEBUG_VIRTUAL is not set
# CONFIG_DEBUG_WRITECOUNT is not set
CONFIG_DEBUG_MEMORY_INIT=y
CONFIG_DEBUG_LIST=y
> [ 2.244280] ------------[ cut here ]------------
> [ 2.245261] WARNING: at kernel/mutex.c:135 mutex_lock_nested+0x325/0x380()
> [ 2.245261] Hardware name: PowerEdge T105
> [ 2.245261] Modules linked in:
> [ 2.245261] Pid: 1, comm: swapper Not tainted 2.6.28 #37
> [ 2.245261] Call Trace:
> [ 2.245261] [<ffffffff8104f15f>] warn_slowpath+0xaf/0x110
> [ 2.245261] [<ffffffff8107986d>] ? __lock_acquire+0x58d/0x1b80
> [ 2.245261] [<ffffffff8107986d>] ? __lock_acquire+0x58d/0x1b80
> [ 2.245261] [<ffffffff81383f75>] mutex_lock_nested+0x325/0x380
> [ 2.245261] [<ffffffff810418fe>] ? __wake_up+0x4e/0x70
> [ 2.245261] [<ffffffff81385c4d>] ? _spin_unlock_irqrestore+0x6d/0x90
> [ 2.245261] [<ffffffff81078752>] ? trace_hardirqs_on_caller+0x172/0x1d0
> [ 2.245261] [<ffffffff8125b7db>] tpm_transmit+0x5b/0x270
> [ 2.245261] [<ffffffff8125ba64>] transmit_cmd+0x14/0x50
> [ 2.245261] [<ffffffff8125baef>] __tpm_pcr_read+0x4f/0x80
> [ 2.245261] [<ffffffff810e9f07>] ? kfree+0xc7/0x140
> [ 2.245261] [<ffffffff81078752>] ? trace_hardirqs_on_caller+0x172/0x1d0
> [ 2.245261] [<ffffffff810787bd>] ? trace_hardirqs_on+0xd/0x10
> [ 2.245261] [<ffffffff811b342f>] ? kobject_uevent_env+0x11f/0x3f0
> [ 2.245261] [<ffffffff810a3e85>] ? __rcu_read_lock+0xc5/0xf0
> [ 2.245261] [<ffffffff810a3d8b>] ? __rcu_read_unlock+0xbb/0xf0
> [ 2.245261] [<ffffffff81078752>] ? trace_hardirqs_on_caller+0x172/0x1d0
> [ 2.245261] [<ffffffff810787bd>] ? trace_hardirqs_on+0xd/0x10
> [ 2.245261] [<ffffffff8125c6b5>] ? tpm_chip_find_get+0xd5/0xf0
> [ 2.245261] [<ffffffff8125c7d2>] tpm_pcr_read+0x42/0x70
> [ 2.245261] [<ffffffff815f5dca>] ? init_ima+0x0/0x1a
> [ 2.245261] [<ffffffff8118d8b7>] ima_init+0x27/0x160
> [ 2.245261] [<ffffffff815f5dca>] ? init_ima+0x0/0x1a
> [ 2.245261] [<ffffffff815f5dca>] ? init_ima+0x0/0x1a
> [ 2.245261] [<ffffffff815f5dd8>] init_ima+0xe/0x1a
> [ 2.245261] [<ffffffff8100a03c>] do_one_initcall+0x3c/0x180
> [ 2.245261] [<ffffffff810a2a3e>] ? register_irq_proc+0xbe/0xe0
> [ 2.245261] [<ffffffff81140000>] ? v2_read_dquot+0x240/0x2a0
> [ 2.245261] [<ffffffff815ce703>] kernel_init+0x14d/0x1a3
> [ 2.245261] [<ffffffff813855a6>] ? trace_hardirqs_on_thunk+0x3a/0x3f
> [ 2.245261] [<ffffffff81015ada>] child_rip+0xa/0x20
> [ 2.245261] [<ffffffff810153be>] ? restore_args+0x0/0x30
> [ 2.245261] [<ffffffff815ce5b6>] ? kernel_init+0x0/0x1a3
> [ 2.245261] [<ffffffff81015ad0>] ? child_rip+0x0/0x20
> [ 2.245261] ---[ end trace 9947c764f5d88c86 ]---
> [ 2.245261] BUG: unable to handle kernel paging request at ffffffff00060000
> [ 2.245261] IP: [<ffffffff811cac36>] __list_add+0x26/0xa0
> [ 2.245261] PGD 203067 PUD 0
> [ 2.245261] Oops: 0000 [#1] PREEMPT SMP
> [ 2.245261] last sysfs file:
> [ 2.245261] CPU 0
> [ 2.245261] Modules linked in:
> [ 2.245261] Pid: 1, comm: swapper Tainted: G W 2.6.28 #37
> [ 2.245261] RIP: 0010:[<ffffffff811cac36>] [<ffffffff811cac36>] __list_add+0x26/0xa0
> [ 2.245261] RSP: 0018:ffff88012fa7fb80 EFLAGS: 00010046
> [ 2.245261] RAX: ffffffff00060000 RBX: ffffffff81559ce8 RCX: 0000000000000000
> [ 2.245261] RDX: ffffffff81559ce8 RSI: ffffffff00060000 RDI: ffff88012fa7fbd0
> [ 2.245261] RBP: ffff88012fa7fba0 R08: 0000000000000002 R09: 0000000000000001
> [ 2.245261] R10: ffff8801afa7f95f R11: ffff88012fa7f8e0 R12: ffffffff00060000
> [ 2.245261] R13: ffff88012fa7fbd0 R14: ffff88012fa80000 R15: ffffffff8125b7db
> [ 2.245261] FS: 0000000000000000(0000) GS:ffffffff8159fe00(0000) knlGS:0000000000000000
> [ 2.245261] CS: 0010 DS: 0018 ES: 0018 CR0: 000000008005003b
> [ 2.245261] CR2: ffffffff00060000 CR3: 0000000000201000 CR4: 00000000000006e0
> [ 2.245261] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
> [ 2.245261] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
> [ 2.245261] Process swapper (pid: 1, threadinfo ffff88012fa7e000, task ffff88012fa80000)
> [ 2.245261] Stack:
> [ 2.245261] 0000000000000246 ffffffff81559cb0 0000000000000246 ffffffff81559cb8
> [ 2.245261] ffff88012fa7fc30 ffffffff81383d49 ffffffff8125b7db ffffffff810418fe
> [ 2.245261] 0000000000000001 ffffffff81559ce8 ffff88012fa7fbd0 ffff88012fa7fbd0
> [ 2.245261] Call Trace:
> [ 2.245261] [<ffffffff81383d49>] mutex_lock_nested+0xf9/0x380
> [ 2.245261] [<ffffffff8125b7db>] ? tpm_transmit+0x5b/0x270
> [ 2.245261] [<ffffffff810418fe>] ? __wake_up+0x4e/0x70
> [ 2.245261] [<ffffffff8125b7db>] tpm_transmit+0x5b/0x270
> [ 2.245261] [<ffffffff8125ba64>] transmit_cmd+0x14/0x50
> [ 2.245261] [<ffffffff8125baef>] __tpm_pcr_read+0x4f/0x80
> [ 2.245261] [<ffffffff810e9f07>] ? kfree+0xc7/0x140
> [ 2.245261] [<ffffffff81078752>] ? trace_hardirqs_on_caller+0x172/0x1d0
> [ 2.245261] [<ffffffff810787bd>] ? trace_hardirqs_on+0xd/0x10
> [ 2.245261] [<ffffffff811b342f>] ? kobject_uevent_env+0x11f/0x3f0
> [ 2.245261] [<ffffffff810a3e85>] ? __rcu_read_lock+0xc5/0xf0
> [ 2.245261] [<ffffffff810a3d8b>] ? __rcu_read_unlock+0xbb/0xf0
> [ 2.245261] [<ffffffff81078752>] ? trace_hardirqs_on_caller+0x172/0x1d0
> [ 2.245261] [<ffffffff810787bd>] ? trace_hardirqs_on+0xd/0x10
> [ 2.245261] [<ffffffff8125c6b5>] ? tpm_chip_find_get+0xd5/0xf0
> [ 2.245261] [<ffffffff8125c7d2>] tpm_pcr_read+0x42/0x70
> [ 2.245261] [<ffffffff815f5dca>] ? init_ima+0x0/0x1a
> [ 2.245261] [<ffffffff8118d8b7>] ima_init+0x27/0x160
> [ 2.245261] [<ffffffff815f5dca>] ? init_ima+0x0/0x1a
> [ 2.245261] [<ffffffff815f5dca>] ? init_ima+0x0/0x1a
> [ 2.245261] [<ffffffff815f5dd8>] init_ima+0xe/0x1a
> [ 2.245261] [<ffffffff8100a03c>] do_one_initcall+0x3c/0x180
> [ 2.245261] [<ffffffff810a2a3e>] ? register_irq_proc+0xbe/0xe0
> [ 2.245261] [<ffffffff81140000>] ? v2_read_dquot+0x240/0x2a0
> [ 2.245261] [<ffffffff815ce703>] kernel_init+0x14d/0x1a3
> [ 2.245261] [<ffffffff813855a6>] ? trace_hardirqs_on_thunk+0x3a/0x3f
> [ 2.245261] [<ffffffff81015ada>] child_rip+0xa/0x20
> [ 2.245261] [<ffffffff810153be>] ? restore_args+0x0/0x30
> [ 2.245261] [<ffffffff815ce5b6>] ? kernel_init+0x0/0x1a3
> [ 2.245261] [<ffffffff81015ad0>] ? child_rip+0x0/0x20
> [ 2.245261] Code: 98 0f 1f 40 00 55 48 89 e5 48 83 ec 20 48 89 5d e8 4c 89 65 f0 48 89 d3 4c 89 6d f8 48 8b 42 08 49 89 fd 49 89 f4 48 39 f0 75 27 <49> 8b 04 24 48 39 d8 75 43 4c 89 6b 08 49 89 5d 00 4d 89 65 08
> [ 2.245261] RIP [<ffffffff811cac36>] __list_add+0x26/0xa0
> [ 2.245261] RSP <ffff88012fa7fb80>
> [ 2.245261] CR2: ffffffff00060000
> [ 2.245261] ---[ end trace 9947c764f5d88c86 ]---
> [ 2.822672] Kernel panic - not syncing: Attempted to kill init!
>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 0/7] integrity
2009-02-05 0:38 ` Mimi Zohar
@ 2009-02-05 1:00 ` James Morris
2009-02-05 1:11 ` Mimi Zohar
2009-02-05 3:06 ` Mimi Zohar
0 siblings, 2 replies; 19+ messages in thread
From: James Morris @ 2009-02-05 1:00 UTC (permalink / raw)
To: Mimi Zohar; +Cc: linux-kernel, Andrew Morton, David Safford, Serge Hallyn
On Wed, 4 Feb 2009, Mimi Zohar wrote:
> On Thu, 2009-02-05 at 10:16 +1100, James Morris wrote:
> > I get an oops on boot with this.
> >
> > Do you have lock and list debugging enabled?
>
> In the past I had them enabled. Just recompiled now with them enabled
> and was able to boot without problems.
Do you have CONFIG_PREEMPT_RCU and SMP ?
>
> CONFIG_DEBUG_SPINLOCK=y
> CONFIG_DEBUG_MUTEXES=y
> CONFIG_DEBUG_LOCK_ALLOC=y
> CONFIG_PROVE_LOCKING=y
> CONFIG_LOCKDEP=y
> CONFIG_LOCK_STAT=y
> CONFIG_DEBUG_LOCKDEP=y
> CONFIG_TRACE_IRQFLAGS=y
> CONFIG_DEBUG_SPINLOCK_SLEEP=y
> # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
> CONFIG_STACKTRACE=y
> # CONFIG_DEBUG_KOBJECT is not set
> CONFIG_DEBUG_HIGHMEM=y
> CONFIG_DEBUG_BUGVERBOSE=y
> CONFIG_DEBUG_INFO=y
> # CONFIG_DEBUG_VM is not set
> # CONFIG_DEBUG_VIRTUAL is not set
> # CONFIG_DEBUG_WRITECOUNT is not set
> CONFIG_DEBUG_MEMORY_INIT=y
> CONFIG_DEBUG_LIST=y
>
>
> > [ 2.244280] ------------[ cut here ]------------
> > [ 2.245261] WARNING: at kernel/mutex.c:135 mutex_lock_nested+0x325/0x380()
> > [ 2.245261] Hardware name: PowerEdge T105
> > [ 2.245261] Modules linked in:
> > [ 2.245261] Pid: 1, comm: swapper Not tainted 2.6.28 #37
> > [ 2.245261] Call Trace:
> > [ 2.245261] [<ffffffff8104f15f>] warn_slowpath+0xaf/0x110
> > [ 2.245261] [<ffffffff8107986d>] ? __lock_acquire+0x58d/0x1b80
> > [ 2.245261] [<ffffffff8107986d>] ? __lock_acquire+0x58d/0x1b80
> > [ 2.245261] [<ffffffff81383f75>] mutex_lock_nested+0x325/0x380
> > [ 2.245261] [<ffffffff810418fe>] ? __wake_up+0x4e/0x70
> > [ 2.245261] [<ffffffff81385c4d>] ? _spin_unlock_irqrestore+0x6d/0x90
> > [ 2.245261] [<ffffffff81078752>] ? trace_hardirqs_on_caller+0x172/0x1d0
> > [ 2.245261] [<ffffffff8125b7db>] tpm_transmit+0x5b/0x270
> > [ 2.245261] [<ffffffff8125ba64>] transmit_cmd+0x14/0x50
> > [ 2.245261] [<ffffffff8125baef>] __tpm_pcr_read+0x4f/0x80
> > [ 2.245261] [<ffffffff810e9f07>] ? kfree+0xc7/0x140
> > [ 2.245261] [<ffffffff81078752>] ? trace_hardirqs_on_caller+0x172/0x1d0
> > [ 2.245261] [<ffffffff810787bd>] ? trace_hardirqs_on+0xd/0x10
> > [ 2.245261] [<ffffffff811b342f>] ? kobject_uevent_env+0x11f/0x3f0
> > [ 2.245261] [<ffffffff810a3e85>] ? __rcu_read_lock+0xc5/0xf0
> > [ 2.245261] [<ffffffff810a3d8b>] ? __rcu_read_unlock+0xbb/0xf0
> > [ 2.245261] [<ffffffff81078752>] ? trace_hardirqs_on_caller+0x172/0x1d0
> > [ 2.245261] [<ffffffff810787bd>] ? trace_hardirqs_on+0xd/0x10
> > [ 2.245261] [<ffffffff8125c6b5>] ? tpm_chip_find_get+0xd5/0xf0
> > [ 2.245261] [<ffffffff8125c7d2>] tpm_pcr_read+0x42/0x70
> > [ 2.245261] [<ffffffff815f5dca>] ? init_ima+0x0/0x1a
> > [ 2.245261] [<ffffffff8118d8b7>] ima_init+0x27/0x160
> > [ 2.245261] [<ffffffff815f5dca>] ? init_ima+0x0/0x1a
> > [ 2.245261] [<ffffffff815f5dca>] ? init_ima+0x0/0x1a
> > [ 2.245261] [<ffffffff815f5dd8>] init_ima+0xe/0x1a
> > [ 2.245261] [<ffffffff8100a03c>] do_one_initcall+0x3c/0x180
> > [ 2.245261] [<ffffffff810a2a3e>] ? register_irq_proc+0xbe/0xe0
> > [ 2.245261] [<ffffffff81140000>] ? v2_read_dquot+0x240/0x2a0
> > [ 2.245261] [<ffffffff815ce703>] kernel_init+0x14d/0x1a3
> > [ 2.245261] [<ffffffff813855a6>] ? trace_hardirqs_on_thunk+0x3a/0x3f
> > [ 2.245261] [<ffffffff81015ada>] child_rip+0xa/0x20
> > [ 2.245261] [<ffffffff810153be>] ? restore_args+0x0/0x30
> > [ 2.245261] [<ffffffff815ce5b6>] ? kernel_init+0x0/0x1a3
> > [ 2.245261] [<ffffffff81015ad0>] ? child_rip+0x0/0x20
> > [ 2.245261] ---[ end trace 9947c764f5d88c86 ]---
> > [ 2.245261] BUG: unable to handle kernel paging request at ffffffff00060000
> > [ 2.245261] IP: [<ffffffff811cac36>] __list_add+0x26/0xa0
> > [ 2.245261] PGD 203067 PUD 0
> > [ 2.245261] Oops: 0000 [#1] PREEMPT SMP
> > [ 2.245261] last sysfs file:
> > [ 2.245261] CPU 0
> > [ 2.245261] Modules linked in:
> > [ 2.245261] Pid: 1, comm: swapper Tainted: G W 2.6.28 #37
> > [ 2.245261] RIP: 0010:[<ffffffff811cac36>] [<ffffffff811cac36>] __list_add+0x26/0xa0
> > [ 2.245261] RSP: 0018:ffff88012fa7fb80 EFLAGS: 00010046
> > [ 2.245261] RAX: ffffffff00060000 RBX: ffffffff81559ce8 RCX: 0000000000000000
> > [ 2.245261] RDX: ffffffff81559ce8 RSI: ffffffff00060000 RDI: ffff88012fa7fbd0
> > [ 2.245261] RBP: ffff88012fa7fba0 R08: 0000000000000002 R09: 0000000000000001
> > [ 2.245261] R10: ffff8801afa7f95f R11: ffff88012fa7f8e0 R12: ffffffff00060000
> > [ 2.245261] R13: ffff88012fa7fbd0 R14: ffff88012fa80000 R15: ffffffff8125b7db
> > [ 2.245261] FS: 0000000000000000(0000) GS:ffffffff8159fe00(0000) knlGS:0000000000000000
> > [ 2.245261] CS: 0010 DS: 0018 ES: 0018 CR0: 000000008005003b
> > [ 2.245261] CR2: ffffffff00060000 CR3: 0000000000201000 CR4: 00000000000006e0
> > [ 2.245261] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
> > [ 2.245261] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
> > [ 2.245261] Process swapper (pid: 1, threadinfo ffff88012fa7e000, task ffff88012fa80000)
> > [ 2.245261] Stack:
> > [ 2.245261] 0000000000000246 ffffffff81559cb0 0000000000000246 ffffffff81559cb8
> > [ 2.245261] ffff88012fa7fc30 ffffffff81383d49 ffffffff8125b7db ffffffff810418fe
> > [ 2.245261] 0000000000000001 ffffffff81559ce8 ffff88012fa7fbd0 ffff88012fa7fbd0
> > [ 2.245261] Call Trace:
> > [ 2.245261] [<ffffffff81383d49>] mutex_lock_nested+0xf9/0x380
> > [ 2.245261] [<ffffffff8125b7db>] ? tpm_transmit+0x5b/0x270
> > [ 2.245261] [<ffffffff810418fe>] ? __wake_up+0x4e/0x70
> > [ 2.245261] [<ffffffff8125b7db>] tpm_transmit+0x5b/0x270
> > [ 2.245261] [<ffffffff8125ba64>] transmit_cmd+0x14/0x50
> > [ 2.245261] [<ffffffff8125baef>] __tpm_pcr_read+0x4f/0x80
> > [ 2.245261] [<ffffffff810e9f07>] ? kfree+0xc7/0x140
> > [ 2.245261] [<ffffffff81078752>] ? trace_hardirqs_on_caller+0x172/0x1d0
> > [ 2.245261] [<ffffffff810787bd>] ? trace_hardirqs_on+0xd/0x10
> > [ 2.245261] [<ffffffff811b342f>] ? kobject_uevent_env+0x11f/0x3f0
> > [ 2.245261] [<ffffffff810a3e85>] ? __rcu_read_lock+0xc5/0xf0
> > [ 2.245261] [<ffffffff810a3d8b>] ? __rcu_read_unlock+0xbb/0xf0
> > [ 2.245261] [<ffffffff81078752>] ? trace_hardirqs_on_caller+0x172/0x1d0
> > [ 2.245261] [<ffffffff810787bd>] ? trace_hardirqs_on+0xd/0x10
> > [ 2.245261] [<ffffffff8125c6b5>] ? tpm_chip_find_get+0xd5/0xf0
> > [ 2.245261] [<ffffffff8125c7d2>] tpm_pcr_read+0x42/0x70
> > [ 2.245261] [<ffffffff815f5dca>] ? init_ima+0x0/0x1a
> > [ 2.245261] [<ffffffff8118d8b7>] ima_init+0x27/0x160
> > [ 2.245261] [<ffffffff815f5dca>] ? init_ima+0x0/0x1a
> > [ 2.245261] [<ffffffff815f5dca>] ? init_ima+0x0/0x1a
> > [ 2.245261] [<ffffffff815f5dd8>] init_ima+0xe/0x1a
> > [ 2.245261] [<ffffffff8100a03c>] do_one_initcall+0x3c/0x180
> > [ 2.245261] [<ffffffff810a2a3e>] ? register_irq_proc+0xbe/0xe0
> > [ 2.245261] [<ffffffff81140000>] ? v2_read_dquot+0x240/0x2a0
> > [ 2.245261] [<ffffffff815ce703>] kernel_init+0x14d/0x1a3
> > [ 2.245261] [<ffffffff813855a6>] ? trace_hardirqs_on_thunk+0x3a/0x3f
> > [ 2.245261] [<ffffffff81015ada>] child_rip+0xa/0x20
> > [ 2.245261] [<ffffffff810153be>] ? restore_args+0x0/0x30
> > [ 2.245261] [<ffffffff815ce5b6>] ? kernel_init+0x0/0x1a3
> > [ 2.245261] [<ffffffff81015ad0>] ? child_rip+0x0/0x20
> > [ 2.245261] Code: 98 0f 1f 40 00 55 48 89 e5 48 83 ec 20 48 89 5d e8 4c 89 65 f0 48 89 d3 4c 89 6d f8 48 8b 42 08 49 89 fd 49 89 f4 48 39 f0 75 27 <49> 8b 04 24 48 39 d8 75 43 4c 89 6b 08 49 89 5d 00 4d 89 65 08
> > [ 2.245261] RIP [<ffffffff811cac36>] __list_add+0x26/0xa0
> > [ 2.245261] RSP <ffff88012fa7fb80>
> > [ 2.245261] CR2: ffffffff00060000
> > [ 2.245261] ---[ end trace 9947c764f5d88c86 ]---
> > [ 2.822672] Kernel panic - not syncing: Attempted to kill init!
> >
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
>
--
James Morris
<jmorris@namei.org>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 0/7] integrity
2009-02-05 1:00 ` James Morris
@ 2009-02-05 1:11 ` Mimi Zohar
2009-02-05 3:06 ` Mimi Zohar
1 sibling, 0 replies; 19+ messages in thread
From: Mimi Zohar @ 2009-02-05 1:11 UTC (permalink / raw)
To: James Morris; +Cc: linux-kernel, Andrew Morton, David Safford, Serge Hallyn
On Thu, 2009-02-05 at 12:00 +1100, James Morris wrote:
> On Wed, 4 Feb 2009, Mimi Zohar wrote:
>
> > On Thu, 2009-02-05 at 10:16 +1100, James Morris wrote:
> > > I get an oops on boot with this.
> > >
> > > Do you have lock and list debugging enabled?
> >
> > In the past I had them enabled. Just recompiled now with them enabled
> > and was able to boot without problems.
>
> Do you have CONFIG_PREEMPT_RCU and SMP ?
Without PREEMPT_RCU, with SMP. Recompiling...
> >
> > CONFIG_DEBUG_SPINLOCK=y
> > CONFIG_DEBUG_MUTEXES=y
> > CONFIG_DEBUG_LOCK_ALLOC=y
> > CONFIG_PROVE_LOCKING=y
> > CONFIG_LOCKDEP=y
> > CONFIG_LOCK_STAT=y
> > CONFIG_DEBUG_LOCKDEP=y
> > CONFIG_TRACE_IRQFLAGS=y
> > CONFIG_DEBUG_SPINLOCK_SLEEP=y
> > # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
> > CONFIG_STACKTRACE=y
> > # CONFIG_DEBUG_KOBJECT is not set
> > CONFIG_DEBUG_HIGHMEM=y
> > CONFIG_DEBUG_BUGVERBOSE=y
> > CONFIG_DEBUG_INFO=y
> > # CONFIG_DEBUG_VM is not set
> > # CONFIG_DEBUG_VIRTUAL is not set
> > # CONFIG_DEBUG_WRITECOUNT is not set
> > CONFIG_DEBUG_MEMORY_INIT=y
> > CONFIG_DEBUG_LIST=y
> >
> >
> > > [ 2.244280] ------------[ cut here ]------------
> > > [ 2.245261] WARNING: at kernel/mutex.c:135 mutex_lock_nested+0x325/0x380()
> > > [ 2.245261] Hardware name: PowerEdge T105
> > > [ 2.245261] Modules linked in:
> > > [ 2.245261] Pid: 1, comm: swapper Not tainted 2.6.28 #37
> > > [ 2.245261] Call Trace:
> > > [ 2.245261] [<ffffffff8104f15f>] warn_slowpath+0xaf/0x110
> > > [ 2.245261] [<ffffffff8107986d>] ? __lock_acquire+0x58d/0x1b80
> > > [ 2.245261] [<ffffffff8107986d>] ? __lock_acquire+0x58d/0x1b80
> > > [ 2.245261] [<ffffffff81383f75>] mutex_lock_nested+0x325/0x380
> > > [ 2.245261] [<ffffffff810418fe>] ? __wake_up+0x4e/0x70
> > > [ 2.245261] [<ffffffff81385c4d>] ? _spin_unlock_irqrestore+0x6d/0x90
> > > [ 2.245261] [<ffffffff81078752>] ? trace_hardirqs_on_caller+0x172/0x1d0
> > > [ 2.245261] [<ffffffff8125b7db>] tpm_transmit+0x5b/0x270
> > > [ 2.245261] [<ffffffff8125ba64>] transmit_cmd+0x14/0x50
> > > [ 2.245261] [<ffffffff8125baef>] __tpm_pcr_read+0x4f/0x80
> > > [ 2.245261] [<ffffffff810e9f07>] ? kfree+0xc7/0x140
> > > [ 2.245261] [<ffffffff81078752>] ? trace_hardirqs_on_caller+0x172/0x1d0
> > > [ 2.245261] [<ffffffff810787bd>] ? trace_hardirqs_on+0xd/0x10
> > > [ 2.245261] [<ffffffff811b342f>] ? kobject_uevent_env+0x11f/0x3f0
> > > [ 2.245261] [<ffffffff810a3e85>] ? __rcu_read_lock+0xc5/0xf0
> > > [ 2.245261] [<ffffffff810a3d8b>] ? __rcu_read_unlock+0xbb/0xf0
> > > [ 2.245261] [<ffffffff81078752>] ? trace_hardirqs_on_caller+0x172/0x1d0
> > > [ 2.245261] [<ffffffff810787bd>] ? trace_hardirqs_on+0xd/0x10
> > > [ 2.245261] [<ffffffff8125c6b5>] ? tpm_chip_find_get+0xd5/0xf0
> > > [ 2.245261] [<ffffffff8125c7d2>] tpm_pcr_read+0x42/0x70
> > > [ 2.245261] [<ffffffff815f5dca>] ? init_ima+0x0/0x1a
> > > [ 2.245261] [<ffffffff8118d8b7>] ima_init+0x27/0x160
> > > [ 2.245261] [<ffffffff815f5dca>] ? init_ima+0x0/0x1a
> > > [ 2.245261] [<ffffffff815f5dca>] ? init_ima+0x0/0x1a
> > > [ 2.245261] [<ffffffff815f5dd8>] init_ima+0xe/0x1a
> > > [ 2.245261] [<ffffffff8100a03c>] do_one_initcall+0x3c/0x180
> > > [ 2.245261] [<ffffffff810a2a3e>] ? register_irq_proc+0xbe/0xe0
> > > [ 2.245261] [<ffffffff81140000>] ? v2_read_dquot+0x240/0x2a0
> > > [ 2.245261] [<ffffffff815ce703>] kernel_init+0x14d/0x1a3
> > > [ 2.245261] [<ffffffff813855a6>] ? trace_hardirqs_on_thunk+0x3a/0x3f
> > > [ 2.245261] [<ffffffff81015ada>] child_rip+0xa/0x20
> > > [ 2.245261] [<ffffffff810153be>] ? restore_args+0x0/0x30
> > > [ 2.245261] [<ffffffff815ce5b6>] ? kernel_init+0x0/0x1a3
> > > [ 2.245261] [<ffffffff81015ad0>] ? child_rip+0x0/0x20
> > > [ 2.245261] ---[ end trace 9947c764f5d88c86 ]---
> > > [ 2.245261] BUG: unable to handle kernel paging request at ffffffff00060000
> > > [ 2.245261] IP: [<ffffffff811cac36>] __list_add+0x26/0xa0
> > > [ 2.245261] PGD 203067 PUD 0
> > > [ 2.245261] Oops: 0000 [#1] PREEMPT SMP
> > > [ 2.245261] last sysfs file:
> > > [ 2.245261] CPU 0
> > > [ 2.245261] Modules linked in:
> > > [ 2.245261] Pid: 1, comm: swapper Tainted: G W 2.6.28 #37
> > > [ 2.245261] RIP: 0010:[<ffffffff811cac36>] [<ffffffff811cac36>] __list_add+0x26/0xa0
> > > [ 2.245261] RSP: 0018:ffff88012fa7fb80 EFLAGS: 00010046
> > > [ 2.245261] RAX: ffffffff00060000 RBX: ffffffff81559ce8 RCX: 0000000000000000
> > > [ 2.245261] RDX: ffffffff81559ce8 RSI: ffffffff00060000 RDI: ffff88012fa7fbd0
> > > [ 2.245261] RBP: ffff88012fa7fba0 R08: 0000000000000002 R09: 0000000000000001
> > > [ 2.245261] R10: ffff8801afa7f95f R11: ffff88012fa7f8e0 R12: ffffffff00060000
> > > [ 2.245261] R13: ffff88012fa7fbd0 R14: ffff88012fa80000 R15: ffffffff8125b7db
> > > [ 2.245261] FS: 0000000000000000(0000) GS:ffffffff8159fe00(0000) knlGS:0000000000000000
> > > [ 2.245261] CS: 0010 DS: 0018 ES: 0018 CR0: 000000008005003b
> > > [ 2.245261] CR2: ffffffff00060000 CR3: 0000000000201000 CR4: 00000000000006e0
> > > [ 2.245261] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
> > > [ 2.245261] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
> > > [ 2.245261] Process swapper (pid: 1, threadinfo ffff88012fa7e000, task ffff88012fa80000)
> > > [ 2.245261] Stack:
> > > [ 2.245261] 0000000000000246 ffffffff81559cb0 0000000000000246 ffffffff81559cb8
> > > [ 2.245261] ffff88012fa7fc30 ffffffff81383d49 ffffffff8125b7db ffffffff810418fe
> > > [ 2.245261] 0000000000000001 ffffffff81559ce8 ffff88012fa7fbd0 ffff88012fa7fbd0
> > > [ 2.245261] Call Trace:
> > > [ 2.245261] [<ffffffff81383d49>] mutex_lock_nested+0xf9/0x380
> > > [ 2.245261] [<ffffffff8125b7db>] ? tpm_transmit+0x5b/0x270
> > > [ 2.245261] [<ffffffff810418fe>] ? __wake_up+0x4e/0x70
> > > [ 2.245261] [<ffffffff8125b7db>] tpm_transmit+0x5b/0x270
> > > [ 2.245261] [<ffffffff8125ba64>] transmit_cmd+0x14/0x50
> > > [ 2.245261] [<ffffffff8125baef>] __tpm_pcr_read+0x4f/0x80
> > > [ 2.245261] [<ffffffff810e9f07>] ? kfree+0xc7/0x140
> > > [ 2.245261] [<ffffffff81078752>] ? trace_hardirqs_on_caller+0x172/0x1d0
> > > [ 2.245261] [<ffffffff810787bd>] ? trace_hardirqs_on+0xd/0x10
> > > [ 2.245261] [<ffffffff811b342f>] ? kobject_uevent_env+0x11f/0x3f0
> > > [ 2.245261] [<ffffffff810a3e85>] ? __rcu_read_lock+0xc5/0xf0
> > > [ 2.245261] [<ffffffff810a3d8b>] ? __rcu_read_unlock+0xbb/0xf0
> > > [ 2.245261] [<ffffffff81078752>] ? trace_hardirqs_on_caller+0x172/0x1d0
> > > [ 2.245261] [<ffffffff810787bd>] ? trace_hardirqs_on+0xd/0x10
> > > [ 2.245261] [<ffffffff8125c6b5>] ? tpm_chip_find_get+0xd5/0xf0
> > > [ 2.245261] [<ffffffff8125c7d2>] tpm_pcr_read+0x42/0x70
> > > [ 2.245261] [<ffffffff815f5dca>] ? init_ima+0x0/0x1a
> > > [ 2.245261] [<ffffffff8118d8b7>] ima_init+0x27/0x160
> > > [ 2.245261] [<ffffffff815f5dca>] ? init_ima+0x0/0x1a
> > > [ 2.245261] [<ffffffff815f5dca>] ? init_ima+0x0/0x1a
> > > [ 2.245261] [<ffffffff815f5dd8>] init_ima+0xe/0x1a
> > > [ 2.245261] [<ffffffff8100a03c>] do_one_initcall+0x3c/0x180
> > > [ 2.245261] [<ffffffff810a2a3e>] ? register_irq_proc+0xbe/0xe0
> > > [ 2.245261] [<ffffffff81140000>] ? v2_read_dquot+0x240/0x2a0
> > > [ 2.245261] [<ffffffff815ce703>] kernel_init+0x14d/0x1a3
> > > [ 2.245261] [<ffffffff813855a6>] ? trace_hardirqs_on_thunk+0x3a/0x3f
> > > [ 2.245261] [<ffffffff81015ada>] child_rip+0xa/0x20
> > > [ 2.245261] [<ffffffff810153be>] ? restore_args+0x0/0x30
> > > [ 2.245261] [<ffffffff815ce5b6>] ? kernel_init+0x0/0x1a3
> > > [ 2.245261] [<ffffffff81015ad0>] ? child_rip+0x0/0x20
> > > [ 2.245261] Code: 98 0f 1f 40 00 55 48 89 e5 48 83 ec 20 48 89 5d e8 4c 89 65 f0 48 89 d3 4c 89 6d f8 48 8b 42 08 49 89 fd 49 89 f4 48 39 f0 75 27 <49> 8b 04 24 48 39 d8 75 43 4c 89 6b 08 49 89 5d 00 4d 89 65 08
> > > [ 2.245261] RIP [<ffffffff811cac36>] __list_add+0x26/0xa0
> > > [ 2.245261] RSP <ffff88012fa7fb80>
> > > [ 2.245261] CR2: ffffffff00060000
> > > [ 2.245261] ---[ end trace 9947c764f5d88c86 ]---
> > > [ 2.822672] Kernel panic - not syncing: Attempted to kill init!
> > >
> >
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at http://vger.kernel.org/majordomo-info.html
> > Please read the FAQ at http://www.tux.org/lkml/
> >
>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 0/7] integrity
2009-02-05 1:00 ` James Morris
2009-02-05 1:11 ` Mimi Zohar
@ 2009-02-05 3:06 ` Mimi Zohar
2009-02-05 9:12 ` James Morris
1 sibling, 1 reply; 19+ messages in thread
From: Mimi Zohar @ 2009-02-05 3:06 UTC (permalink / raw)
To: James Morris; +Cc: linux-kernel, Andrew Morton, David Safford, Serge Hallyn
On Thu, 2009-02-05 at 12:00 +1100, James Morris wrote:
> On Wed, 4 Feb 2009, Mimi Zohar wrote:
>
> > On Thu, 2009-02-05 at 10:16 +1100, James Morris wrote:
> > > I get an oops on boot with this.
> > >
> > > Do you have lock and list debugging enabled?
> >
> > In the past I had them enabled. Just recompiled now with them enabled
> > and was able to boot without problems.
>
> Do you have CONFIG_PREEMPT_RCU and SMP ?
I've recompiled with both CONFIG_PREEMPT_RCU and SMP and didn't
get the oops. Is your TPM enabled?
> >
> > CONFIG_DEBUG_SPINLOCK=y
> > CONFIG_DEBUG_MUTEXES=y
> > CONFIG_DEBUG_LOCK_ALLOC=y
> > CONFIG_PROVE_LOCKING=y
> > CONFIG_LOCKDEP=y
> > CONFIG_LOCK_STAT=y
> > CONFIG_DEBUG_LOCKDEP=y
> > CONFIG_TRACE_IRQFLAGS=y
> > CONFIG_DEBUG_SPINLOCK_SLEEP=y
> > # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
> > CONFIG_STACKTRACE=y
> > # CONFIG_DEBUG_KOBJECT is not set
> > CONFIG_DEBUG_HIGHMEM=y
> > CONFIG_DEBUG_BUGVERBOSE=y
> > CONFIG_DEBUG_INFO=y
> > # CONFIG_DEBUG_VM is not set
> > # CONFIG_DEBUG_VIRTUAL is not set
> > # CONFIG_DEBUG_WRITECOUNT is not set
> > CONFIG_DEBUG_MEMORY_INIT=y
> > CONFIG_DEBUG_LIST=y
> >
> >
> > > [ 2.244280] ------------[ cut here ]------------
> > > [ 2.245261] WARNING: at kernel/mutex.c:135 mutex_lock_nested+0x325/0x380()
> > > [ 2.245261] Hardware name: PowerEdge T105
> > > [ 2.245261] Modules linked in:
> > > [ 2.245261] Pid: 1, comm: swapper Not tainted 2.6.28 #37
> > > [ 2.245261] Call Trace:
> > > [ 2.245261] [<ffffffff8104f15f>] warn_slowpath+0xaf/0x110
> > > [ 2.245261] [<ffffffff8107986d>] ? __lock_acquire+0x58d/0x1b80
> > > [ 2.245261] [<ffffffff8107986d>] ? __lock_acquire+0x58d/0x1b80
> > > [ 2.245261] [<ffffffff81383f75>] mutex_lock_nested+0x325/0x380
> > > [ 2.245261] [<ffffffff810418fe>] ? __wake_up+0x4e/0x70
> > > [ 2.245261] [<ffffffff81385c4d>] ? _spin_unlock_irqrestore+0x6d/0x90
> > > [ 2.245261] [<ffffffff81078752>] ? trace_hardirqs_on_caller+0x172/0x1d0
> > > [ 2.245261] [<ffffffff8125b7db>] tpm_transmit+0x5b/0x270
> > > [ 2.245261] [<ffffffff8125ba64>] transmit_cmd+0x14/0x50
> > > [ 2.245261] [<ffffffff8125baef>] __tpm_pcr_read+0x4f/0x80
> > > [ 2.245261] [<ffffffff810e9f07>] ? kfree+0xc7/0x140
> > > [ 2.245261] [<ffffffff81078752>] ? trace_hardirqs_on_caller+0x172/0x1d0
> > > [ 2.245261] [<ffffffff810787bd>] ? trace_hardirqs_on+0xd/0x10
> > > [ 2.245261] [<ffffffff811b342f>] ? kobject_uevent_env+0x11f/0x3f0
> > > [ 2.245261] [<ffffffff810a3e85>] ? __rcu_read_lock+0xc5/0xf0
> > > [ 2.245261] [<ffffffff810a3d8b>] ? __rcu_read_unlock+0xbb/0xf0
> > > [ 2.245261] [<ffffffff81078752>] ? trace_hardirqs_on_caller+0x172/0x1d0
> > > [ 2.245261] [<ffffffff810787bd>] ? trace_hardirqs_on+0xd/0x10
> > > [ 2.245261] [<ffffffff8125c6b5>] ? tpm_chip_find_get+0xd5/0xf0
> > > [ 2.245261] [<ffffffff8125c7d2>] tpm_pcr_read+0x42/0x70
> > > [ 2.245261] [<ffffffff815f5dca>] ? init_ima+0x0/0x1a
> > > [ 2.245261] [<ffffffff8118d8b7>] ima_init+0x27/0x160
> > > [ 2.245261] [<ffffffff815f5dca>] ? init_ima+0x0/0x1a
> > > [ 2.245261] [<ffffffff815f5dca>] ? init_ima+0x0/0x1a
> > > [ 2.245261] [<ffffffff815f5dd8>] init_ima+0xe/0x1a
> > > [ 2.245261] [<ffffffff8100a03c>] do_one_initcall+0x3c/0x180
> > > [ 2.245261] [<ffffffff810a2a3e>] ? register_irq_proc+0xbe/0xe0
> > > [ 2.245261] [<ffffffff81140000>] ? v2_read_dquot+0x240/0x2a0
> > > [ 2.245261] [<ffffffff815ce703>] kernel_init+0x14d/0x1a3
> > > [ 2.245261] [<ffffffff813855a6>] ? trace_hardirqs_on_thunk+0x3a/0x3f
> > > [ 2.245261] [<ffffffff81015ada>] child_rip+0xa/0x20
> > > [ 2.245261] [<ffffffff810153be>] ? restore_args+0x0/0x30
> > > [ 2.245261] [<ffffffff815ce5b6>] ? kernel_init+0x0/0x1a3
> > > [ 2.245261] [<ffffffff81015ad0>] ? child_rip+0x0/0x20
> > > [ 2.245261] ---[ end trace 9947c764f5d88c86 ]---
> > > [ 2.245261] BUG: unable to handle kernel paging request at ffffffff00060000
> > > [ 2.245261] IP: [<ffffffff811cac36>] __list_add+0x26/0xa0
> > > [ 2.245261] PGD 203067 PUD 0
> > > [ 2.245261] Oops: 0000 [#1] PREEMPT SMP
> > > [ 2.245261] last sysfs file:
> > > [ 2.245261] CPU 0
> > > [ 2.245261] Modules linked in:
> > > [ 2.245261] Pid: 1, comm: swapper Tainted: G W 2.6.28 #37
> > > [ 2.245261] RIP: 0010:[<ffffffff811cac36>] [<ffffffff811cac36>] __list_add+0x26/0xa0
> > > [ 2.245261] RSP: 0018:ffff88012fa7fb80 EFLAGS: 00010046
> > > [ 2.245261] RAX: ffffffff00060000 RBX: ffffffff81559ce8 RCX: 0000000000000000
> > > [ 2.245261] RDX: ffffffff81559ce8 RSI: ffffffff00060000 RDI: ffff88012fa7fbd0
> > > [ 2.245261] RBP: ffff88012fa7fba0 R08: 0000000000000002 R09: 0000000000000001
> > > [ 2.245261] R10: ffff8801afa7f95f R11: ffff88012fa7f8e0 R12: ffffffff00060000
> > > [ 2.245261] R13: ffff88012fa7fbd0 R14: ffff88012fa80000 R15: ffffffff8125b7db
> > > [ 2.245261] FS: 0000000000000000(0000) GS:ffffffff8159fe00(0000) knlGS:0000000000000000
> > > [ 2.245261] CS: 0010 DS: 0018 ES: 0018 CR0: 000000008005003b
> > > [ 2.245261] CR2: ffffffff00060000 CR3: 0000000000201000 CR4: 00000000000006e0
> > > [ 2.245261] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
> > > [ 2.245261] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
> > > [ 2.245261] Process swapper (pid: 1, threadinfo ffff88012fa7e000, task ffff88012fa80000)
> > > [ 2.245261] Stack:
> > > [ 2.245261] 0000000000000246 ffffffff81559cb0 0000000000000246 ffffffff81559cb8
> > > [ 2.245261] ffff88012fa7fc30 ffffffff81383d49 ffffffff8125b7db ffffffff810418fe
> > > [ 2.245261] 0000000000000001 ffffffff81559ce8 ffff88012fa7fbd0 ffff88012fa7fbd0
> > > [ 2.245261] Call Trace:
> > > [ 2.245261] [<ffffffff81383d49>] mutex_lock_nested+0xf9/0x380
> > > [ 2.245261] [<ffffffff8125b7db>] ? tpm_transmit+0x5b/0x270
> > > [ 2.245261] [<ffffffff810418fe>] ? __wake_up+0x4e/0x70
> > > [ 2.245261] [<ffffffff8125b7db>] tpm_transmit+0x5b/0x270
> > > [ 2.245261] [<ffffffff8125ba64>] transmit_cmd+0x14/0x50
> > > [ 2.245261] [<ffffffff8125baef>] __tpm_pcr_read+0x4f/0x80
> > > [ 2.245261] [<ffffffff810e9f07>] ? kfree+0xc7/0x140
> > > [ 2.245261] [<ffffffff81078752>] ? trace_hardirqs_on_caller+0x172/0x1d0
> > > [ 2.245261] [<ffffffff810787bd>] ? trace_hardirqs_on+0xd/0x10
> > > [ 2.245261] [<ffffffff811b342f>] ? kobject_uevent_env+0x11f/0x3f0
> > > [ 2.245261] [<ffffffff810a3e85>] ? __rcu_read_lock+0xc5/0xf0
> > > [ 2.245261] [<ffffffff810a3d8b>] ? __rcu_read_unlock+0xbb/0xf0
> > > [ 2.245261] [<ffffffff81078752>] ? trace_hardirqs_on_caller+0x172/0x1d0
> > > [ 2.245261] [<ffffffff810787bd>] ? trace_hardirqs_on+0xd/0x10
> > > [ 2.245261] [<ffffffff8125c6b5>] ? tpm_chip_find_get+0xd5/0xf0
> > > [ 2.245261] [<ffffffff8125c7d2>] tpm_pcr_read+0x42/0x70
> > > [ 2.245261] [<ffffffff815f5dca>] ? init_ima+0x0/0x1a
> > > [ 2.245261] [<ffffffff8118d8b7>] ima_init+0x27/0x160
> > > [ 2.245261] [<ffffffff815f5dca>] ? init_ima+0x0/0x1a
> > > [ 2.245261] [<ffffffff815f5dca>] ? init_ima+0x0/0x1a
> > > [ 2.245261] [<ffffffff815f5dd8>] init_ima+0xe/0x1a
> > > [ 2.245261] [<ffffffff8100a03c>] do_one_initcall+0x3c/0x180
> > > [ 2.245261] [<ffffffff810a2a3e>] ? register_irq_proc+0xbe/0xe0
> > > [ 2.245261] [<ffffffff81140000>] ? v2_read_dquot+0x240/0x2a0
> > > [ 2.245261] [<ffffffff815ce703>] kernel_init+0x14d/0x1a3
> > > [ 2.245261] [<ffffffff813855a6>] ? trace_hardirqs_on_thunk+0x3a/0x3f
> > > [ 2.245261] [<ffffffff81015ada>] child_rip+0xa/0x20
> > > [ 2.245261] [<ffffffff810153be>] ? restore_args+0x0/0x30
> > > [ 2.245261] [<ffffffff815ce5b6>] ? kernel_init+0x0/0x1a3
> > > [ 2.245261] [<ffffffff81015ad0>] ? child_rip+0x0/0x20
> > > [ 2.245261] Code: 98 0f 1f 40 00 55 48 89 e5 48 83 ec 20 48 89 5d e8 4c 89 65 f0 48 89 d3 4c 89 6d f8 48 8b 42 08 49 89 fd 49 89 f4 48 39 f0 75 27 <49> 8b 04 24 48 39 d8 75 43 4c 89 6b 08 49 89 5d 00 4d 89 65 08
> > > [ 2.245261] RIP [<ffffffff811cac36>] __list_add+0x26/0xa0
> > > [ 2.245261] RSP <ffff88012fa7fb80>
> > > [ 2.245261] CR2: ffffffff00060000
> > > [ 2.245261] ---[ end trace 9947c764f5d88c86 ]---
> > > [ 2.822672] Kernel panic - not syncing: Attempted to kill init!
> > >
> >
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at http://vger.kernel.org/majordomo-info.html
> > Please read the FAQ at http://www.tux.org/lkml/
> >
>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 0/7] integrity
2009-02-05 3:06 ` Mimi Zohar
@ 2009-02-05 9:12 ` James Morris
2009-02-05 16:05 ` Rajiv Andrade
0 siblings, 1 reply; 19+ messages in thread
From: James Morris @ 2009-02-05 9:12 UTC (permalink / raw)
To: Mimi Zohar; +Cc: linux-kernel, Andrew Morton, David Safford, Serge Hallyn
On Wed, 4 Feb 2009, Mimi Zohar wrote:
> On Thu, 2009-02-05 at 12:00 +1100, James Morris wrote:
> > On Wed, 4 Feb 2009, Mimi Zohar wrote:
> >
> > > On Thu, 2009-02-05 at 10:16 +1100, James Morris wrote:
> > > > I get an oops on boot with this.
> > > >
> > > > Do you have lock and list debugging enabled?
> > >
> > > In the past I had them enabled. Just recompiled now with them enabled
> > > and was able to boot without problems.
> >
> > Do you have CONFIG_PREEMPT_RCU and SMP ?
>
> I've recompiled with both CONFIG_PREEMPT_RCU and SMP and didn't
> get the oops. Is your TPM enabled?
It was disabled in bios, and the system boots ok with it enabled.
--
James Morris
<jmorris@namei.org>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 0/7] integrity
2009-02-05 9:12 ` James Morris
@ 2009-02-05 16:05 ` Rajiv Andrade
0 siblings, 0 replies; 19+ messages in thread
From: Rajiv Andrade @ 2009-02-05 16:05 UTC (permalink / raw)
To: James Morris
Cc: Mimi Zohar, linux-kernel, Andrew Morton, David Safford,
Serge Hallyn
James Morris wrote:
> On Wed, 4 Feb 2009, Mimi Zohar wrote:
>
>
>> On Thu, 2009-02-05 at 12:00 +1100, James Morris wrote:
>>
>>> On Wed, 4 Feb 2009, Mimi Zohar wrote:
>>>
>>>
>>>> On Thu, 2009-02-05 at 10:16 +1100, James Morris wrote:
>>>>
>>>>> I get an oops on boot with this.
>>>>>
>>>>> Do you have lock and list debugging enabled?
>>>>>
>>>> In the past I had them enabled. Just recompiled now with them enabled
>>>> and was able to boot without problems.
>>>>
>>> Do you have CONFIG_PREEMPT_RCU and SMP ?
>>>
>> I've recompiled with both CONFIG_PREEMPT_RCU and SMP and didn't
>> get the oops. Is your TPM enabled?
>>
>
> It was disabled in bios, and the system boots ok with it enabled.
>
>
Hi James, I've just submitted the fix.
Thanks,
Rajiv Andrade
IBM LTC Security Dev.
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 0/7] integrity
2009-02-04 14:06 [PATCH 0/7] integrity Mimi Zohar
` (7 preceding siblings ...)
2009-02-04 23:16 ` [PATCH 0/7] integrity James Morris
@ 2009-02-05 22:37 ` James Morris
8 siblings, 0 replies; 19+ messages in thread
From: James Morris @ 2009-02-05 22:37 UTC (permalink / raw)
To: Mimi Zohar; +Cc: linux-kernel, Andrew Morton, David Safford, Serge Hallyn
On Wed, 4 Feb 2009, Mimi Zohar wrote:
> This patchset contains the IMA integrity patches. The changes made since
> the last integrity posting are based on comments made by James Morris and
> Serge Hallyn.
> - removed test for NULL return code from securityfs_create_file/dir
> - alloc ima_template_entry before calling ima_store_template()
> - log ima_add_boot_aggregate failure
> - free invalid rule
> - add hook to increment opencount for /dev/zero shm
> - replaced hard coded string length with #define name
> - removed unused IMA_TEMPLATE_NAME_LEN
>
> This patchset is dependent on the tpm-integrity-interface patch, which
> has been applied to the security-testing-2.6/#next.
>
> Mimi Zohar (7):
> integrity: IMA hooks
> integrity: IMA as an integrity service provider
> integrity: IMA display
> integrity: IMA policy
> integrity: IMA policy open
> Integrity: IMA file free imbalance
> Integrity: IMA update maintainers
All applied to security-testing.
--
James Morris <jmorris@namei.org>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 2/7] integrity: IMA as an integrity service provider
2009-02-04 14:06 ` [PATCH 2/7] integrity: IMA as an integrity service provider Mimi Zohar
@ 2009-02-06 20:31 ` Serge E. Hallyn
2009-02-10 20:23 ` Pavel Machek
1 sibling, 0 replies; 19+ messages in thread
From: Serge E. Hallyn @ 2009-02-06 20:31 UTC (permalink / raw)
To: Mimi Zohar
Cc: linux-kernel, Andrew Morton, James Morris, David Safford,
Serge Hallyn, Mimi Zohar
Quoting Mimi Zohar (zohar@linux.vnet.ibm.com):
> 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 <zohar@us.ibm.com>
Acked-by: Serge Hallyn <serue@us.ibm.com>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 2/7] integrity: IMA as an integrity service provider
2009-02-04 14:06 ` [PATCH 2/7] integrity: IMA as an integrity service provider Mimi Zohar
2009-02-06 20:31 ` Serge E. Hallyn
@ 2009-02-10 20:23 ` Pavel Machek
2009-02-10 20:49 ` Serge E. Hallyn
1 sibling, 1 reply; 19+ messages in thread
From: Pavel Machek @ 2009-02-10 20:23 UTC (permalink / raw)
To: Mimi Zohar
Cc: linux-kernel, Andrew Morton, James Morris, David Safford,
Serge Hallyn, Mimi Zohar
Hi!
> --- /dev/null
> +++ b/security/integrity/ima/Kconfig
> @@ -0,0 +1,49 @@
> +# IBM Integrity Measurement Architecture
> +#
> +config IMA
> + bool "Integrity Measurement Architecture(IMA)"
> + depends on ACPI
Ugh?
> + select SECURITYFS
> + select CRYPTO
> + select CRYPTO_HMAC
> + select CRYPTO_MD5
> + select CRYPTO_SHA1
> + select TCG_TPM
> + select TCG_TIS
> + help
> + The Trusted Computing Group(TCG) runtime Integrity
> + Measurement Architecture(IMA) maintains a list of hash
> + values of executables and other sensitive system files,
> + as they are read or executed. If an attacker manages
> + to change the contents of an important system file
> + being measured, we can tell.
> +
> + If your system has a TPM chip, then IMA also maintains
> + an aggregate integrity value over this list inside the
> + TPM hardware, so that the TPM can prove to a third party
> + whether or not critical system files have been modified.
Sound like 'well use this so people with homegrown distros can't
access our e-shop'...
> + Read <http://www.usenix.org/events/sec04/tech/sailer.html>
> + to learn more about IMA.
Maybe some basic docs should go into Documentation?
> +config IMA_MEASURE_PCR_IDX
> + int
> + depends on IMA
> + 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.
This is quite ugly. How do you expect enduser to get this right?
How do you expect distro to get it right for all users?
Pavel
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 2/7] integrity: IMA as an integrity service provider
2009-02-10 20:23 ` Pavel Machek
@ 2009-02-10 20:49 ` Serge E. Hallyn
0 siblings, 0 replies; 19+ messages in thread
From: Serge E. Hallyn @ 2009-02-10 20:49 UTC (permalink / raw)
To: Pavel Machek
Cc: Mimi Zohar, linux-kernel, Andrew Morton, James Morris,
David Safford, Mimi Zohar
Quoting Pavel Machek (pavel@suse.cz):
> Hi!
>
> > --- /dev/null
> > +++ b/security/integrity/ima/Kconfig
> > @@ -0,0 +1,49 @@
> > +# IBM Integrity Measurement Architecture
> > +#
> > +config IMA
> > + bool "Integrity Measurement Architecture(IMA)"
> > + depends on ACPI
>
> Ugh?
>
> > + select SECURITYFS
> > + select CRYPTO
> > + select CRYPTO_HMAC
> > + select CRYPTO_MD5
> > + select CRYPTO_SHA1
> > + select TCG_TPM
> > + select TCG_TIS
> > + help
> > + The Trusted Computing Group(TCG) runtime Integrity
> > + Measurement Architecture(IMA) maintains a list of hash
> > + values of executables and other sensitive system files,
> > + as they are read or executed. If an attacker manages
> > + to change the contents of an important system file
> > + being measured, we can tell.
> > +
> > + If your system has a TPM chip, then IMA also maintains
> > + an aggregate integrity value over this list inside the
> > + TPM hardware, so that the TPM can prove to a third party
> > + whether or not critical system files have been modified.
>
> Sound like 'well use this so people with homegrown distros can't
> access our e-shop'...
That would be tough to pull off, as they would have to have your
TPM's public key stored.
So a small shop could pull this off for their employees, I suppose, but
it's not practical for say a bank to do. (And if they did, well, I'll
bank elsewhere.)
> > + Read <http://www.usenix.org/events/sec04/tech/sailer.html>
> > + to learn more about IMA.
>
> Maybe some basic docs should go into Documentation?
>
> > +config IMA_MEASURE_PCR_IDX
> > + int
> > + depends on IMA
> > + 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.
>
> This is quite ugly. How do you expect enduser to get this right?
> How do you expect distro to get it right for all users?
I'd asked about this before, and here's how I understood it:
End-users aren't expected to get this right - note that it's
hidden. If it changes, then that will be because some other
software using TPM (like trousers) uses 10, so it will be
changed in the upstream kernel for everyone.
-serge
^ permalink raw reply [flat|nested] 19+ messages in thread
end of thread, other threads:[~2009-02-10 20:51 UTC | newest]
Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-02-04 14:06 [PATCH 0/7] integrity Mimi Zohar
2009-02-04 14:06 ` [PATCH 1/7] integrity: IMA hooks Mimi Zohar
2009-02-04 14:06 ` [PATCH 2/7] integrity: IMA as an integrity service provider Mimi Zohar
2009-02-06 20:31 ` Serge E. Hallyn
2009-02-10 20:23 ` Pavel Machek
2009-02-10 20:49 ` Serge E. Hallyn
2009-02-04 14:06 ` [PATCH 3/7] integrity: IMA display Mimi Zohar
2009-02-04 14:07 ` [PATCH 4/7] integrity: IMA policy Mimi Zohar
2009-02-04 14:07 ` [PATCH 5/7] integrity: IMA policy open Mimi Zohar
2009-02-04 14:07 ` [PATCH 6/7] Integrity: IMA file free imbalance Mimi Zohar
2009-02-04 14:07 ` [PATCH 7/7] Integrity: IMA update maintainers Mimi Zohar
2009-02-04 23:16 ` [PATCH 0/7] integrity James Morris
2009-02-05 0:38 ` Mimi Zohar
2009-02-05 1:00 ` James Morris
2009-02-05 1:11 ` Mimi Zohar
2009-02-05 3:06 ` Mimi Zohar
2009-02-05 9:12 ` James Morris
2009-02-05 16:05 ` Rajiv Andrade
2009-02-05 22:37 ` James Morris
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox