integrity
Subsystems (10)
cover integrity
Quoted 10 lines
Quoted 2 lines
The integrity patches are in security-testing-2.6/#next and the auditd patch I just posted to linux-audit. How do you suggest we go forward?
We need to go over the event format and make sure its got everything we need in it. We also need to review the code that touches the audit system and make sure its using the audit API the way we intended. I'd like to do this on the linux-audit mail list so there is a record of it in the audit archives.
Thanks,
-Steve
As per Steve's request, I'm posting the integrity patches here. These patches are dependent on the following TPM patches:
http://lkml.org/lkml/2009/2/2/162 http://lkml.org/lkml/2009/2/5/151
The auditd patch was already posted here.
Mimi
James Morris (1):
IMA: fix ima_delete_rules() definition
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
PATCH 1/8 integrity: IMA hooks
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.
---
Documentation/kernel-parameters.txt +1 -0
@@ -44,6 +44,7 @@ parameter is applicable: FB The frame buffer device is enabled. HW Appropriate hardware is enabled. IA-64 IA-64 architecture is enabled. + IMA Integrity measurement architecture is enabled. IOSCHED More than one I/O scheduler is enabled. IP_PNP IP DHCP, BOOTP, or RARP is enabled. ISAPNP ISA PnP code is enabled.
fs/exec.c +10 -0
@@ -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. */
fs/file_table.c +2 -0
@@ -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);
fs/inode.c +17 -7
@@ -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);
fs/namei.c +8 -0
@@ -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. */
include/linux/ima.h new file +44 -0
44 lines not on this page · raw message
mm/mmap.c +4 -0
@@ -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);
Signature · 1 line
1.5.6.6
PATCH 2/8 integrity: IMA as an integrity service provider
In reply to Mimi ZoharIMA 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
---
Documentation/kernel-parameters.txt +9 -0
@@ -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.
include/linux/audit.h +5 -0
@@ -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. */
include/linux/ima.h +10 -0
@@ -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 */
security/Kconfig +4 -1
@@ -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
security/Makefile +4 -0
@@ -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
security/integrity/ima/Kconfig new file +49 -0
49 lines not on this page · raw message
security/integrity/ima/Makefile new file +9 -0
@@ -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
security/integrity/ima/ima.h new file +135 -0
135 lines not on this page · raw message
security/integrity/ima/ima_api.c new file +190 -0
190 lines not on this page · raw message
security/integrity/ima/ima_audit.c new file +78 -0
78 lines not on this page · raw message
security/integrity/ima/ima_crypto.c new file +140 -0
140 lines not on this page · raw message
security/integrity/ima/ima_iint.c new file +185 -0
185 lines not on this page · raw message
security/integrity/ima/ima_init.c new file +90 -0
90 lines not on this page · raw message
security/integrity/ima/ima_main.c new file +280 -0
280 lines not on this page · raw message
security/integrity/ima/ima_policy.c new file +126 -0
126 lines not on this page · raw message
security/integrity/ima/ima_queue.c new file +140 -0
140 lines not on this page · raw message
Signature · 1 line
1.5.6.6
Re: [PATCH 2/8] integrity: IMA as an integrity service provider
Hi,
Thanks for sending the audit piece to the mail list so we could go over the details without bothering the whole lkml. I have some comments in line below.
Quoted 29 lines · Mimi Zohar
(quoted diff) +0
-0
b/Documentation/kernel-parameters.txtindex 7c67b94..31e0c2c 100644Documentation/kernel-parameters.txt +0
-0@@ -895,6 +895,15 @@ and is between 256 and 4096 characters. It is definedin the file ihash_entries= [KNL]
Documentation/kernel-parameters.txt +9
-0Set 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.include/linux/audit.h +0
-0@@ -125,6 +125,11 @@#define AUDIT_LAST_KERN_ANOM_MSG 1799#define AUDIT_ANOM_PROMISCUOUS 1700/* Device changed promiscuous mode */
#defineAUDIT_ANOM_ABEND1701 /* Process ended abnormally */
include/linux/audit.h
Quoted 2 lines
include/linux/audit.h +2
-0+#define AUDIT_INTEGRITY_DATA 1800/* Data integrity verification */ +#define AUDIT_INTEGRITY_METADATA 1801/* Metadata integrity verification
*/
include/linux/audit.h line 132
Quoted 3 lines
include/linux/audit.h +3
-0+#define AUDIT_INTEGRITY_STATUS 1802/* Integrity enable status */ +#define AUDIT_INTEGRITY_HASH 1803/* Integrity HASH type */ +#define AUDIT_INTEGRITY_PCR 1804/* PCR invalidation msgs */
If you are taking this block, I'd like to have the netlink block map around line 39 updated too. Sb something like:
* 1800 - 1899 integrity labels and related events
* 1900 - 1999 future kernel use
Quoted 24 lines
#define
AUDIT_KERNEL2000 /* Asynchronous audit record. NOT A REQUEST. */security/integrity/ima/ima.h new file +15
-0@@ -0,0 +1,135 @@ +/* +* Copyright (C) 2005,2006,2007,2008 IBM Corporation +* +* Authors: +* Reiner Sailer <[email protected]> +* Mimi Zohar <[email protected]> +* +* 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 +*/
security/integrity/ima/ima.h line 25
Quoted 10 lines
security/integrity/ima/ima.h new file +10
-0+ +#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>
So why did you include the audit.h file in this header? I don't see where its used for any function prototype.
Quoted 14 lines
(quoted diff) +0
-0
b/security/integrity/ima/ima_api.cnew file mode 100644 index 0000000..a148a25security/integrity/ima/ima_api.c new file +8
-0@@ -0,0 +1,190 @@ +/* +* Copyright (C) 2008 IBM Corporation +* +* Author: Mimi Zohar <[email protected]> +* +* 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
security/integrity/ima/ima_api.c line 18
Quoted 10 lines
security/integrity/ima/ima_api.c new file +10
-0+* 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" ;
Would this also be a const ?
Quoted 45 lines
(quoted diff) +0
-0
b/security/integrity/ima/ima_audit.cnew file mode 100644 index 0000000..8a0f1e2security/integrity/ima/ima_audit.c new file +39
-0@@ -0,0 +1,78 @@ +/* +* Copyright (C) 2008 IBM Corporation +* Author: Mimi Zohar <[email protected]> +* +* 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 +
security/integrity/ima/ima_audit.c line 49
Quoted 10 lines
security/integrity/ima/ima_audit.c new file +10
-0+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);
Is this a standalone event or would it be an auxiliary record added to a syscall record? IOW, if I have a watch on the same file as was being measured, would the event have the same serial number?
security/integrity/ima/ima_audit.c line 50
Quoted 1 line
security/integrity/ima/ima_audit.c new file +1
-0+ audit_log_format(ab, "integrity: pid=%d uid=%u auid=%u",
The word "integrity:" can be deleted. All the events will have it in the event type.
security/integrity/ima/ima_audit.c line 52
Quoted 2 lines
security/integrity/ima/ima_audit.c new file +2
-0+ current->pid, current->cred->uid, + audit_get_loginuid(current));
After logging the auid, we now require logging ses=%u for sessionid, use audit_get_sessionid() for the value. This is something that has come up in the last year, but we have it in all events now so that if someone logs in multiple times, we know which session it originated in.
If you are depending on a syscall record, it will record much of what's recorded here for itself and you won't need this much. If you wanted this to be standalone, I think the call to audit_ log_start has NULL as the first param so that it cannot be associated with a syscall.
Quoted 14 lines
security/integrity/ima/ima_audit.c new file +14
-0+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); + }
security/integrity/ima/ima_audit.c line 76
Quoted 10 lines
security/integrity/ima/ima_audit.c new file +10
-0+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);
Note that result should only be 0 (success) or 1 (failure). I saw earlier that a result was getting set to -ENOMEM.
Quoted 23 lines
security/integrity/ima/ima_audit.c new file +2
-0+audit_log_end (ab); +}(quoted diff) +0
-0
b/security/integrity/ima/ima_init.cnew file mode 100644 index 0000000..e0f02e3security/integrity/ima/ima_init.c new file +13
-0@@ -0,0 +1,90 @@ +/* +* Copyright (C) 2005,2006,2007,2008 IBM Corporation +* +* Authors: +* Reiner Sailer <[email protected]> +* Leendert van Doorn <[email protected]> +* Mimi Zohar <[email protected]> +* +* 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. +*
security/integrity/ima/ima_init.c line 23
Quoted 10 lines
security/integrity/ima/ima_init.c new file +10
-0+* 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" ;
const ?
Quoted 13 lines
security/integrity/ima/ima_init.c new file +13
-0+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
security/integrity/ima/ima_init.c line 46
Quoted 10 lines
security/integrity/ima/ima_init.c new file +10
-0+* 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 ;
You can't send the audit system this value.
Quoted 5 lines
security/integrity/ima/ima_init.c new file +5
-0+int violation =1 ; + + entry =kmalloc (sizeof (*entry),GFP_KERNEL ); +if (!entry) + goto err_out;
security/integrity/ima/ima_init.c line 61
Quoted 10 lines
security/integrity/ima/ima_init.c new file +10
-0+ +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);
You may want "!!result" so that its changed to a 1 for failure. Or maybe you want to do that in integrity_audit_msg so you only have 1 place to change it.
Quoted 24 lines
security/integrity/ima/ima_init.c new file +12
-0+ 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 ); +} +(quoted diff) +0
-0
b/security/integrity/ima/ima_policy.cnew file mode 100644 index 0000000..7c3d1ffsecurity/integrity/ima/ima_policy.c new file +5
-0@@ -0,0 +1,126 @@ +/* +* Copyright (C) 2008 IBM Corporation +* Author: Mimi Zohar <[email protected]> +* +* This program is free software; you can redistribute it and/or modify
security/integrity/ima/ima_policy.c line 15
Quoted 10 lines
security/integrity/ima/ima_policy.c new file +10
-0+* 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>
Is audit.h really needed here?
I guess the main concern is the value of the result field.
-Steve
Re: [PATCH 2/8] integrity: IMA as an integrity service provider
Quoted 4 lines · Steve Grubb
Hi,
Thanks for sending the audit piece to the mail list so we could go over the details without bothering the whole lkml. I have some comments in line below.
Definitely preferable.
Quoted 40 lines · Mimi Zohar
Quoted 29 lines
(quoted diff) +0
-0
b/Documentation/kernel-parameters.txtindex 7c67b94..31e0c2c 100644Documentation/kernel-parameters.txt +0
-0@@ -895,6 +895,15 @@ and is between 256 and 4096 characters. It is definedin the file ihash_entries= [KNL]
Documentation/kernel-parameters.txt +9
-0Set 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.include/linux/audit.h +0
-0@@ -125,6 +125,11 @@#define AUDIT_LAST_KERN_ANOM_MSG 1799#define AUDIT_ANOM_PROMISCUOUS 1700/* Device changed promiscuous mode */
#defineAUDIT_ANOM_ABEND1701 /* Process ended abnormally */include/linux/audit.h
Quoted 2 lines
include/linux/audit.h +2
-0+#define AUDIT_INTEGRITY_DATA 1800/* Data integrity verification */ +#define AUDIT_INTEGRITY_METADATA 1801/* Metadata integrity verification */
include/linux/audit.h line 132
Quoted 3 lines
include/linux/audit.h +3
-0+#define AUDIT_INTEGRITY_STATUS 1802/* Integrity enable status */ +#define AUDIT_INTEGRITY_HASH 1803/* Integrity HASH type */ +#define AUDIT_INTEGRITY_PCR 1804/* PCR invalidation msgs */ If you are taking this block, I'd like to have the netlink block map around line 39 updated too. Sb something like:
Quoted 4 lines
* 1800 - 1899 integrity labels and related events
* 1900 - 1999 future kernel useQuoted 1 line
#define
AUDIT_KERNEL2000 /* Asynchronous audit record. NOT A REQUEST. */
ok
Quoted 26 lines
Quoted 26 lines
security/integrity/ima/ima.h new file +20
-0@@ -0,0 +1,135 @@ +/* +* Copyright (C) 2005,2006,2007,2008 IBM Corporation +* +* Authors: +* Reiner Sailer <[email protected]> +* Mimi Zohar <[email protected]> +* +* 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>
Quoted 8 lines
security/integrity/ima/ima.h line 25
Quoted 5 lines
security/integrity/ima/ima.h new file +5
-0+#include <linux/crypto.h> +#include <linux/security.h> +#include <linux/hash.h> +#include <linux/tpm.h> +#include <linux/audit.h> So why did you include the
audit.hfile in this header? I don't see where its used for any function prototype.
IMA measures files based on policy, which can be described in terms of LSM specific labels using security_audit_rule_init/match.
Quoted 18 lines
Quoted 18 lines
(quoted diff) +0
-0
b/security/integrity/ima/ima_api.cnew file mode 100644 index 0000000..a148a25security/integrity/ima/ima_api.c new file +12
-0@@ -0,0 +1,190 @@ +/* +* Copyright (C) 2008 IBM Corporation +* +* Author: Mimi Zohar <[email protected]> +* +* 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,
Quoted 8 lines
security/integrity/ima/ima_api.c line 18
Quoted 6 lines
security/integrity/ima/ima_api.c new file +6
-0+* and store_template. +*/ +#include <linux/module.h> + +#include "ima.h" +static char *IMA_TEMPLATE_NAME ="ima" ;Would this also be a const ?
yes
Quoted 51 lines
Quoted 51 lines
(quoted diff) +0
-0
b/security/integrity/ima/ima_audit.cnew file mode 100644 index 0000000..8a0f1e2security/integrity/ima/ima_audit.c new file +45
-0@@ -0,0 +1,78 @@ +/* +* Copyright (C) 2008 IBM Corporation +* Author: Mimi Zohar <[email protected]> +* +* 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; +
Quoted 8 lines
security/integrity/ima/ima_audit.c line 49
Quoted 4 lines
security/integrity/ima/ima_audit.c new file +4
-0+if (!ima_audit && audit_info ==1 )/* Skip informational messages */ +return ; + + ab =audit_log_start (current->audit_context,GFP_KERNEL , audit_msgno);Is this a standalone event or would it be an auxiliary record added to a syscall record? IOW, if I have a watch on the same file as was being measured, would the event have the same serial number?
Having it as an auxiliary record to syscall seems appropriate. There seems to be different behavior if you stop auditd and if it isn't enabled at boot. In the former case the syscall message still goes to /var/log/messages, while in the latter case it doesn't.
Quoted 6 lines
security/integrity/ima/ima_audit.c line 50
Quoted 1 line
security/integrity/ima/ima_audit.c new file +1
-0+ audit_log_format(ab, "integrity: pid=%d uid=%u auid=%u",The word "integrity:" can be deleted. All the events will have it in the event type.
Quoted 7 lines
security/integrity/ima/ima_audit.c line 52
Quoted 2 lines
security/integrity/ima/ima_audit.c new file +2
-0+ current->pid, current->cred->uid, + audit_get_loginuid(current));After logging the auid, we now require logging ses=%u for sessionid, use
audit_get_sessionid()for the value. This is something that has come up in the last year, but we have it in all events now so that if someone logs in multiple times, we know which session it originated in.
ok
Quoted 4 lines
If you are depending on a syscall record, it will record much of what's recorded here for itself and you won't need this much. If you wanted this to be standalone, I think the call to
audit_log_starthas NULL as the first param so that it cannot be associated with a syscall.
yes that works. Some of the messages don't need the syscall info, like in ima_parse_rules().
Quoted 11 lines
Quoted 11 lines
security/integrity/ima/ima_audit.c new file +11
-0+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 :
Quoted 8 lines
security/integrity/ima/ima_audit.c line 71
Quoted 8 lines
security/integrity/ima/ima_audit.c new file +8
-0+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);
Sure would be nice to be able to print the full pathname.
Quoted 8 lines
security/integrity/ima/ima_audit.c line 76
Quoted 5 lines
security/integrity/ima/ima_audit.c new file +5
-0+ } +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);Note that result should only be 0 (success) or 1 (failure). I saw earlier that a result was getting set to
-ENOMEM.
ok.
Quoted 27 lines
Quoted 27 lines
security/integrity/ima/ima_audit.c new file +2
-0+audit_log_end (ab); +}(quoted diff) +0
-0
b/security/integrity/ima/ima_init.cnew file mode 100644 index 0000000..e0f02e3security/integrity/ima/ima_init.c new file +17
-0@@ -0,0 +1,90 @@ +/* +* Copyright (C) 2005,2006,2007,2008 IBM Corporation +* +* Authors: +* Reiner Sailer <[email protected]> +* Leendert van Doorn <[email protected]> +* Mimi Zohar <[email protected]> +* +* 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>
Quoted 8 lines
security/integrity/ima/ima_init.c line 23
Quoted 6 lines
security/integrity/ima/ima_init.c new file +6
-0+#include <linux/scatterlist.h> +#include <linux/err.h> +#include "ima.h" + +/* name for boot aggregate entry */ +static char *boot_aggregate_name ="boot_aggregate" ;const ?
yes
Quoted 17 lines
Quoted 17 lines
security/integrity/ima/ima_init.c new file +17
-0+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. +*/
Quoted 8 lines
security/integrity/ima/ima_init.c line 46
Quoted 6 lines
security/integrity/ima/ima_init.c new file +6
-0+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 ;You can't send the audit system this value.
ok.
Quoted 48 lines
Quoted 6 lines
security/integrity/ima/ima_init.c new file +5
-0+int violation =1 ; + + entry =kmalloc (sizeof (*entry),GFP_KERNEL ); +if (!entry) + goto err_out;security/integrity/ima/ima_init.c line 61
Quoted 10 lines
security/integrity/ima/ima_init.c new file +10
-0+ +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);You may want "!!result" so that its changed to a 1 for failure. Or maybe you want to do that in
integrity_audit_msgso you only have 1 place to change it.Quoted 28 lines
security/integrity/ima/ima_init.c new file +12
-0+ 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 ); +} +(quoted diff) +0
-0
b/security/integrity/ima/ima_policy.cnew file mode 100644 index 0000000..7c3d1ffsecurity/integrity/ima/ima_policy.c new file +9
-0@@ -0,0 +1,126 @@ +/* +* Copyright (C) 2008 IBM Corporation +* Author: Mimi Zohar <[email protected]> +* +* 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
Quoted 8 lines
security/integrity/ima/ima_policy.c line 15
Quoted 6 lines
security/integrity/ima/ima_policy.c new file +6
-0+* - initialize default measure policy rules +* +*/ +#include <linux/module.h> +#include <linux/list.h> +#include <linux/audit.h> Is
audit.hreally needed here?
As it is already defined in ima.h, it isn't needed here.
Quoted 3 lines
I guess the main concern is the value of the result field.
-Steve
Ok.
Mimi
Re: [PATCH 2/8] integrity: IMA as an integrity service provider
Quoted 21 lines · Mimi Zohar
Quoted 12 lines
Quoted 12 lines
(quoted diff) +0
-0
b/security/integrity/ima/ima_audit.cnew file mode 100644 index 0000000..8a0f1e2security/integrity/ima/ima_audit.c new file +7
-0+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 */ Quoted 8 lines
Quoted 4 lines
security/integrity/ima/ima_audit.c new file +3
-0+return ; + + ab = audit_log_start(current->audit_context, GFP_KERNEL,
audit_msgno);Is this a standalone event or would it be an auxiliary record added to a syscall record? IOW, if I have a watch on the same file as was being measured, would the event have the same serial number?
Quoted 1 line
Having it as an auxiliary record to syscall seems appropriate.
OK. There are are three options then.
1) The first is to just supplement the syscall record whether its there or not. This is kind of what AVCs do. In that case, everything you are logging is fine.
2) Change the audit event really be an auxiliary record that is output at syscall exit only if an audit event has triggered the event. This is more like what the PATH, CWD, or EXECVE records do.
3) The last approach is to cause a syscall audit record to be emitted. This is what the MAC_STATUS does. For this case and #2 above, we could shorten the data collected since the syscall record duplicates many fields.
Quoted 3 lines
There seems to be different behavior if you stop auditd and if it isn't enabled at boot. In the former case the syscall message still goes to
/var/log/messages, while in the latter case it doesn't.
It all depends on if the audit system is enabled. If its enabled, events go to either the daemon or syslog. If the audit system is not enabled, then the admin didn't want any notification.
Quoted 7 lines
Quoted 4 lines
If you are depending on a syscall record, it will record much of what's recorded here for itself and you won't need this much. If you wanted this to be standalone, I think the call to
audit_log_starthas NULL as the first param so that it cannot be associated with a syscall.yes that works. Some of the messages don't need the syscall info, like in
ima_parse_rules().
The perhaps you want 2 logging functions? Or maybe pass something to the function that determines if it should be related to an existing event or its entirely async.
Quoted 13 lines
Quoted 13 lines
Quoted 13 lines
security/integrity/ima/ima_audit.c new file +13
-0+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);
Quoted 8 lines
Quoted 6 lines
security/integrity/ima/ima_audit.c line 71
Quoted 6 lines
security/integrity/ima/ima_audit.c new file +6
-0+ } +audit_log_format (ab," comm=" ); +audit_log_untrustedstring (ab, current->comm); +if (fname) { +audit_log_format (ab," name=" ); +audit_log_untrustedstring (ab, fname);Sure would be nice to be able to print the full pathname.
There is an AUDIT_PATH record that should have the whole path. Its an auxiliary record emitted with the syscall.
Maybe we should talk a little about when the different events would be emitted. Would it be just on creation of the hash? Would it be just on a miscompare? IOW, how many records are likely to be created during a typical session?
Thanks,
-Steve
Re: [PATCH 2/8] integrity: IMA as an integrity service provider
Quoted 26 lines · Steve Grubb
Quoted 21 lines · Mimi Zohar
Quoted 12 lines
Quoted 12 lines
(quoted diff) +0
-0
b/security/integrity/ima/ima_audit.cnew file mode 100644 index 0000000..8a0f1e2security/integrity/ima/ima_audit.c new file +7
-0+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 */ Quoted 8 lines
Quoted 4 lines
security/integrity/ima/ima_audit.c new file +3
-0+return ; + + ab = audit_log_start(current->audit_context, GFP_KERNEL,
audit_msgno);Is this a standalone event or would it be an auxiliary record added to a syscall record? IOW, if I have a watch on the same file as was being measured, would the event have the same serial number?
Quoted 1 line
Having it as an auxiliary record to syscall seems appropriate.
OK. There are are three options then.
Quoted 9 lines
1) The first is to just supplement the syscall record whether its there or not. This is kind of what AVCs do. In that case, everything you are logging is fine.
2) Change the audit event really be an auxiliary record that is output at syscall exit only if an audit event has triggered the event. This is more like what the PATH, CWD, or EXECVE records do.
3) The last approach is to cause a syscall audit record to be emitted. This is what theMAC_STATUSdoes. For this case and #2 above, we could shorten the data collected since the syscall record duplicates many fields.
Seems like the first option is applicable here.
Quoted 13 lines
Quoted 3 lines
There seems to be different behavior if you stop auditd and if it isn't enabled at boot. In the former case the syscall message still goes to
/var/log/messages, while in the latter case it doesn't.It all depends on if the audit system is enabled. If its enabled, events go to either the daemon or syslog. If the audit system is not enabled, then the admin didn't want any notification.
Quoted 5 lines
Quoted 4 lines
If you are depending on a syscall record, it will record much of what's recorded here for itself and you won't need this much. If you wanted this to be standalone, I think the call to
audit_log_starthas NULL as the first param so that it cannot be associated with a syscall.
Quoted 6 lines
Quoted 2 lines
yes that works. Some of the messages don't need the syscall info, like in
ima_parse_rules().The perhaps you want 2 logging functions? Or maybe pass something to the function that determines if it should be related to an existing event or its entirely async.
Ok, I've added a new integrity audit message type for policy rules. The individual policy rules don't require the syscall information. If the policy contains an invalid rule, in addition to the auditing the policy rule, audit integrity status and syscall messages are emitted.
Quoted 22 lines
Quoted 13 lines
Quoted 13 lines
Quoted 13 lines
security/integrity/ima/ima_audit.c new file +13
-0+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);Quoted 8 lines
Quoted 6 lines
security/integrity/ima/ima_audit.c line 71
Quoted 6 lines
security/integrity/ima/ima_audit.c new file +6
-0+ } +audit_log_format (ab," comm=" ); +audit_log_untrustedstring (ab, current->comm); +if (fname) { +audit_log_format (ab," name=" ); +audit_log_untrustedstring (ab, fname);Sure would be nice to be able to print the full pathname.
Quoted 2 lines
There is an
AUDIT_PATHrecord that should have the whole path. Its an auxiliary record emitted with the syscall.
Yes, I'm seeing them now. I had forgotten to add a auditctl syscall rule. Thanks.
Quoted 7 lines
Maybe we should talk a little about when the different events would be emitted. Would it be just on creation of the hash? Would it be just on a miscompare? IOW, how many records are likely to be created during a typical session?
Thanks,
-Steve
IMA measures files, maintains a list of these measurements, and extends the PCR. These measurements are not audited, only failure to calculate the measurement, add an entry to the measurement list, or extend the PCR is audited.
Other audit messages include, runtime kernel options, updating the measurement policy, and measurement violations. The measurement violations are caused either by opening a file for write, that is already open for read (ToMToU), or by opening a file for read, that is already open for write (open_writer). The number of these errors is application dependent.
Mimi
Eric Paris
maintainerRe: [PATCH 2/8] integrity: IMA as an integrity service provider
In reply to Mimi ZoharI'm very slow to the game, I know, but today was the first kernel that I built from linux-next with IMA on. I have a comment, and hopefully more to come....
Quoted 9 lines · Mimi Zohar
security/integrity/ima/ima_audit.c new file +9
-0+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 ; +
security/integrity/ima/ima_audit.c line 58
Quoted 10 lines
security/integrity/ima/ima_audit.c new file +10
-0+ 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);
There are cases where (at least) cause can be a multiword string. These should be using audit_log_string() instead of %s. I'm starting to frown on %s in audit log more and more heavily these days, actually I don't think I should let any more users of %s in at all. If you want I'll go through and change all of these, but I want to make sure that you will be ok with multiword string being either "" or translated. An example of the problem I see would be in say ima_update_policy() where you have const char *cause = "already exists"; Currently that record will get emitted like:
blah cause=already exists blah
which screws up parsers. It should be:
blah cause="already exists" blah
make sense?
Quoted 19 lines
security/integrity/ima/ima_audit.c new file +19
-0+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);
Re: [PATCH 2/8] integrity: IMA as an integrity service provider
Quoted 3 lines · Eric Paris
I'm very slow to the game, I know, but today was the first kernel that I built from linux-next with IMA on. I have a comment, and hopefully more to come....
np
Quoted 31 lines · Mimi Zohar
Quoted 9 lines
security/integrity/ima/ima_audit.c new file +9
-0+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 ; +security/integrity/ima/ima_audit.c line 58
Quoted 10 lines
security/integrity/ima/ima_audit.c new file +10
-0+ 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);There are cases where (at least) cause can be a multiword string. These should be using
audit_log_string()instead of %s. I'm starting to frown on %s in audit log more and more heavily these days, actually I don't think I should let any more users of %s in at all. If you want I'll go through and change all of these, but I want to make sure that you will be ok with multiword string being either "" or translated. An example of the problem I see would be in sayima_update_policy()where you have const char *cause = "already exists"; Currently that record will get emitted like:
Quoted 7 lines
blah cause=already exists blah
which screws up parsers. It should be:
blah cause="already exists" blah
make sense?
Oops, that should have been hyphenated, like "open_writers" below, but quoting it, and "open writers", definitely makes more sense.
type=INTEGRITY_PCR msg=audit(1235867814.206:6): integrity: pid=2089 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:initrc_t:s0 op=invalid_pcr cause=open_writers comm="update-reader.c" name="sh-thd-1235847728" dev=sda6 ino=1635223 res=0
Quoted 4 lines
Quoted 3 lines
security/integrity/ima/ima_audit.c new file +3
-0+break ; +case AUDIT_INTEGRITY_HASH : +audit_log_format (ab," op=%s hash=%s" , op, cause);
Quoted 16 lines
Quoted 6 lines
security/integrity/ima/ima_audit.c new file +6
-0+break ; +case AUDIT_INTEGRITY_STATUS : +default : +audit_log_format (ab," op=%s" , op); + } +audit_log_format (ab," comm=" );security/integrity/ima/ima_audit.c line 77
Quoted 10 lines
security/integrity/ima/ima_audit.c new file +10
-0+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);
Thanks,
Mimi
PATCH 3/8 integrity: IMA display
In reply to Mimi ZoharMake the measurement lists available through securityfs.
- removed test for NULL return code from securityfs_create_file/dir
---
security/integrity/ima/Makefile +1 -1
@@ -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
security/integrity/ima/ima.h +5 -0
@@ -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.
security/integrity/ima/ima_fs.c new file +296 -0
296 lines not on this page · raw message
security/integrity/ima/ima_init.c +7 -1
@@ -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 (); }
security/integrity/ima/ima_main.c +5 -0
@@ -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" );
Signature · 1 line
1.5.6.6
PATCH 4/8 integrity: IMA policy
In reply to Mimi ZoharSupport for a user loadable policy through securityfs with support for LSM specific policy data.
- free invalid rule in ima_parse_add_rule()
---
Documentation/ABI/testing/ima_policy new file +61 -0
@@ -0,0 +1,61 @@ +What: security/ima/policy +Date: May 2008 +Contact: Mimi Zohar <[email protected]> +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
security/integrity/ima/Kconfig +6 -0
@@ -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
security/integrity/ima/ima.h +24 -0
@@ -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
security/integrity/ima/ima_fs.c +66 -1
103 lines not on this page · raw message
security/integrity/ima/ima_policy.c +290 -3
343 lines not on this page · raw message
Signature · 1 line
1.5.6.6
PATCH 5/8 integrity: IMA policy open
In reply to Mimi ZoharSequentialize access to the policy file
- permit multiple attempts to replace default policy with a valid policy
---
security/integrity/ima/ima_fs.c +16 -1
@@ -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 };
Signature · 1 line
1.5.6.6
PATCH 6/8 Integrity: IMA file free imbalance
In reply to Mimi ZoharThe 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()
---
include/linux/ima.h +6 -0
@@ -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 */
ipc/shm.c +3 -0
@@ -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;
mm/shmem.c +2 -0
@@ -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;
security/integrity/ima/ima.h +2 -0
@@ -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; };
security/integrity/ima/ima_iint.c +17 -0
@@ -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 ); }
security/integrity/ima/ima_main.c +42 -0
72 lines not on this page · raw message
Signature · 1 line
1.5.6.6
PATCH 7/8 Integrity: IMA update maintainers
In reply to Mimi Zohar---
MAINTAINERS +5 -0
@@ -2175,6 +2175,11 @@ M: [email protected] L: [email protected] S: Maintained +INTEGRITY MEASUREMENT ARCHITECTURE (IMA) +P: Mimi Zohar +M: [email protected] +S: Supported + IMS TWINTURBO FRAMEBUFFER DRIVER L: [email protected] (moderated for non-subscribers) S: Orphan
Signature · 1 line
1.5.6.6
PATCH 8/8 IMA: fix ima_delete_rules() definition
In reply to Mimi ZoharFrom: James Morris <[email protected]>
Fix ima_delete_rules() definition so sparse doesn't complain.
---
security/integrity/ima/ima_policy.c +1 -1
@@ -400,7 +400,7 @@ int ima_parse_add_rule(char *rule) }/* ima_delete_rules called to cleanup invalid policy */ -void ima_delete_rules () +void ima_delete_rules (void ) {struct ima_measure_rule_entry *entry, *tmp;
Signature · 1 line
1.5.6.6