path: root/security/integrity/ima/ima_main.c
Commit message (Collapse)AuthorAgeFilesLines
* IMA: fix the ToMToU logicEric Paris2010-10-261-5/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Current logic looks like this: rc = ima_must_measure(NULL, inode, MAY_READ, FILE_CHECK); if (rc < 0) goto out; if (mode & FMODE_WRITE) { if (inode->i_readcount) send_tomtou = true; goto out; } if (atomic_read(&inode->i_writecount) > 0) send_writers = true; Lets assume we have a policy which states that all files opened for read by root must be measured. Lets assume the file has permissions 777. Lets assume that root has the given file open for read. Lets assume that a non-root process opens the file write. The non-root process will get to ima_counts_get() and will check the ima_must_measure(). Since it is not supposed to measure it will goto out. We should check the i_readcount no matter what since we might be causing a ToMToU voilation! This is close to correct, but still not quite perfect. The situation could have been that root, which was interested in the mesurement opened and closed the file and another process which is not interested in the measurement is the one holding the i_readcount ATM. This is just overly strict on ToMToU violations, which is better than not strict enough... Signed-off-by: Eric Paris <eparis@redhat.com> Acked-by: Mimi Zohar <zohar@linux.vnet.ibm.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* IMA: explicit IMA i_flag to remove global lock on inode_deleteEric Paris2010-10-261-0/+1
| | | | | | | | | | | Currently for every removed inode IMA must take a global lock and search the IMA rbtree looking for an associated integrity structure. Instead we explicitly mark an inode when we add an integrity structure so we only have to take the global lock and do the removal if it exists. Signed-off-by: Eric Paris <eparis@redhat.com> Acked-by: Mimi Zohar <zohar@linux.vnet.ibm.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* IMA: drop refcnt from ima_iint_cache since it isn't neededEric Paris2010-10-261-5/+2
| | | | | | | | | | | | | Since finding a struct ima_iint_cache requires a valid struct inode, and the struct ima_iint_cache is supposed to have the same lifetime as a struct inode (technically they die together but don't need to be created at the same time) we don't have to worry about the ima_iint_cache outliving or dieing before the inode. So the refcnt isn't useful. Just get rid of it and free the structure when the inode is freed. Signed-off-by: Eric Paris <eapris@redhat.com> Acked-by: Mimi Zohar <zohar@linux.vnet.ibm.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* IMA: only allocate iint when neededEric Paris2010-10-261-30/+64
| | | | | | | | | | | | | IMA always allocates an integrity structure to hold information about every inode, but only needed this structure to track the number of readers and writers currently accessing a given inode. Since that information was moved into struct inode instead of the integrity struct this patch stops allocating the integrity stucture until it is needed. Thus greatly reducing memory usage. Signed-off-by: Eric Paris <eparis@redhat.com> Acked-by: Mimi Zohar <zohar@linux.vnet.ibm.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* IMA: move read counter into struct inodeEric Paris2010-10-261-25/+10
| | | | | | | | | | | | | | | | | | | | | IMA currently allocated an inode integrity structure for every inode in core. This stucture is about 120 bytes long. Most files however (especially on a system which doesn't make use of IMA) will never need any of this space. The problem is that if IMA is enabled we need to know information about the number of readers and the number of writers for every inode on the box. At the moment we collect that information in the per inode iint structure and waste the rest of the space. This patch moves those counters into the struct inode so we can eventually stop allocating an IMA integrity structure except when absolutely needed. This patch does the minimum needed to move the location of the data. Further cleanups, especially the location of counter updates, may still be possible. Signed-off-by: Eric Paris <eparis@redhat.com> Acked-by: Mimi Zohar <zohar@linux.vnet.ibm.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* IMA: use i_writecount rather than a private counterEric Paris2010-10-261-10/+6
| | | | | | | | | | | | | | | | | | | | | | | | | IMA tracks the number of struct files which are holding a given inode readonly and the number which are holding the inode write or r/w. It needs this information so when a new reader or writer comes in it can tell if this new file will be able to invalidate results it already made about existing files. aka if a task is holding a struct file open RO, IMA measured the file and recorded those measurements and then a task opens the file RW IMA needs to note in the logs that the old measurement may not be correct. It's called a "Time of Measure Time of Use" (ToMToU) issue. The same is true is a RO file is opened to an inode which has an open writer. We cannot, with any validity, measure the file in question since it could be changing. This patch attempts to use the i_writecount field to track writers. The i_writecount field actually embeds more information in it's value than IMA needs but it should work for our purposes and allow us to shrink the struct inode even more. Signed-off-by: Eric Paris <eparis@redhat.com> Acked-by: Mimi Zohar <zohar@linux.vnet.ibm.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* IMA: use inode->i_lock to protect read and write countersEric Paris2010-10-261-34/+23
| | | | | | | | | | Currently IMA used the iint->mutex to protect the i_readcount and i_writecount. This patch uses the inode->i_lock since we are going to start using in inode objects and that is the most appropriate lock. Signed-off-by: Eric Paris <eparis@redhat.com> Acked-by: Mimi Zohar <zohar@linux.vnet.ibm.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* IMA: use unsigned int instead of long for countersEric Paris2010-10-261-5/+10
| | | | | | | | | | | Currently IMA uses 2 longs in struct inode. To save space (and as it seems impossible to overflow 32 bits) we switch these to unsigned int. The switch to unsigned does require slightly different checks for underflow, but it isn't complex. Signed-off-by: Eric Paris <eparis@redhat.com> Acked-by: Mimi Zohar <zohar@linux.vnet.ibm.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* IMA: drop the inode opencount since it isn't needed for operationEric Paris2010-10-261-7/+3
| | | | | | | | | | | | The opencount was used to help debugging to make sure that everything which created a struct file also correctly made the IMA calls. Since we moved all of that into the VFS this isn't as necessary. We should be able to get the same amount of debugging out of just the reader and write count. Signed-off-by: Eric Paris <eparis@redhat.com> Acked-by: Mimi Zohar <zohar@linux.vnet.ibm.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* ima: always maintain countersMimi Zohar2010-09-081-3/+5
| | | | | | | | | | | | | | | | | | commit 8262bb85da allocated the inode integrity struct (iint) before any inodes were created. Only after IMA was initialized in late_initcall were the counters updated. This patch updates the counters, whether or not IMA has been initialized, to resolve 'imbalance' messages. This patch fixes the bug as reported in bugzilla: 15673. When the i915 is builtin, the ring_buffer is initialized before IMA, causing the imbalance message on suspend. Reported-by: Thomas Meyer <thomas@m3y3r.de> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com> Tested-by: Thomas Meyer <thomas@m3y3r.de> Tested-by: David Safford<safford@watson.ibm.com> Cc: Stable Kernel <stable@kernel.org> Signed-off-by: James Morris <jmorris@namei.org>
* Merge branch 'master' into nextJames Morris2010-05-061-0/+1
| * include cleanup: Update gfp.h and slab.h includes to prepare for breaking ↵Tejun Heo2010-03-301-0/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | implicit slab.h inclusion from percpu.h percpu.h is included by sched.h and module.h and thus ends up being included when building most .c files. percpu.h includes slab.h which in turn includes gfp.h making everything defined by the two files universally available and complicating inclusion dependencies. percpu.h -> slab.h dependency is about to be removed. Prepare for this change by updating users of gfp and slab facilities include those headers directly instead of assuming availability. As this conversion needs to touch large number of source files, the following script is used as the basis of conversion. http://userweb.kernel.org/~tj/misc/slabh-sweep.py The script does the followings. * Scan files for gfp and slab usages and update includes such that only the necessary includes are there. ie. if only gfp is used, gfp.h, if slab is used, slab.h. * When the script inserts a new include, it looks at the include blocks and try to put the new include such that its order conforms to its surrounding. It's put in the include block which contains core kernel includes, in the same order that the rest are ordered - alphabetical, Christmas tree, rev-Xmas-tree or at the end if there doesn't seem to be any matching order. * If the script can't find a place to put a new include (mostly because the file doesn't have fitting include block), it prints out an error message indicating which .h file needs to be added to the file. The conversion was done in the following steps. 1. The initial automatic conversion of all .c files updated slightly over 4000 files, deleting around 700 includes and adding ~480 gfp.h and ~3000 slab.h inclusions. The script emitted errors for ~400 files. 2. Each error was manually checked. Some didn't need the inclusion, some needed manual addition while adding it to implementation .h or embedding .c file was more appropriate for others. This step added inclusions to around 150 files. 3. The script was run again and the output was compared to the edits from #2 to make sure no file was left behind. 4. Several build tests were done and a couple of problems were fixed. e.g. lib/decompress_*.c used malloc/free() wrappers around slab APIs requiring slab.h to be added manually. 5. The script was run on all .h files but without automatically editing them as sprinkling gfp.h and slab.h inclusions around .h files could easily lead to inclusion dependency hell. Most gfp.h inclusion directives were ignored as stuff from gfp.h was usually wildly available and often used in preprocessor macros. Each slab.h inclusion directive was examined and added manually as necessary. 6. percpu.h was updated not to include slab.h. 7. Build test were done on the following configurations and failures were fixed. CONFIG_GCOV_KERNEL was turned off for all tests (as my distributed build env didn't work with gcov compiles) and a few more options had to be turned off depending on archs to make things build (like ipr on powerpc/64 which failed due to missing writeq). * x86 and x86_64 UP and SMP allmodconfig and a custom test config. * powerpc and powerpc64 SMP allmodconfig * sparc and sparc64 SMP allmodconfig * ia64 SMP allmodconfig * s390 SMP allmodconfig * alpha SMP allmodconfig * um on x86_64 SMP allmodconfig 8. percpu.h modifications were reverted so that it could be applied as a separate patch and serve as bisection point. Given the fact that I had only a couple of failures from tests on step 6, I'm fairly confident about the coverage of this conversion patch. If there is a breakage, it's likely to be something in one of the arch headers which should be easily discoverable easily on most builds of the specific arch. Signed-off-by: Tejun Heo <tj@kernel.org> Guess-its-ok-by: Christoph Lameter <cl@linux-foundation.org> Cc: Ingo Molnar <mingo@redhat.com> Cc: Lee Schermerhorn <Lee.Schermerhorn@hp.com>
* | security/ima: replace gcc specific __FUNCTION__ with __func__H Hartley Sweeten2010-03-101-1/+1
|/ | | | | | | | As noted by checkpatch.pl, __func__ should be used instead of gcc specific __FUNCTION__. Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: James Morris <jmorris@namei.org>
* ima: rename PATH_CHECK to FILE_CHECKMimi Zohar2010-02-071-2/+2
| | | | | | | | | | With the movement of the ima hooks functions were renamed from *path* to *file* since they always deal with struct file. This patch renames some of the ima internal flags to make them consistent with the rest of the code. Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com> Signed-off-by: Eric Paris <eparis@redhat.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* ima: rename ima_path_check to ima_file_checkMimi Zohar2010-02-071-3/+3
| | | | | | | | ima_path_check actually deals with files! call it ima_file_check instead. Signed-off-by: Eric Paris <eparis@redhat.com> Acked-by: Mimi Zohar <zohar@linux.vnet.ibm.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* ima: initialize ima before inodes can be allocatedEric Paris2010-02-071-1/+0
| | | | | | | | | | | | | | ima wants to create an inode information struct (iint) when inodes are allocated. This means that at least the part of ima which does this allocation (the allocation is filled with information later) should before any inodes are created. To accomplish this we split the ima initialization routine placing the kmem cache allocator inside a security_initcall() function. Since this makes use of radix trees we also need to make sure that is initialized before security_initcall(). Signed-off-by: Eric Paris <eparis@redhat.com> Acked-by: Mimi Zohar <zohar@linux.vnet.ibm.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* fix ima breakageMimi Zohar2010-02-071-144/+92
| | | | | | | | | | | | | | | | The "Untangling ima mess, part 2 with counters" patch messed up the counters. Based on conversations with Al Viro, this patch streamlines ima_path_check() by removing the counter maintaince. The counters are now updated independently, from measuring the file, in __dentry_open() and alloc_file() by calling ima_counts_get(). ima_path_check() is called from nfsd and do_filp_open(). It also did not measure all files that should have been measured. Reason: ima_path_check() got bogus value passed as mask. [AV: mea culpa] [AV: add missing nfsd bits] Signed-off-by: Mimi Zohar <zohar@us.ibm.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* ima: limit imbalance msgMimi Zohar2009-12-161-9/+53
| | | | | | | | | Limit the number of imbalance messages to once per filesystem type instead of once per system boot. (it's actually slightly racy and could give you a couple per fs, but this isn't a real issue) Signed-off-by: Mimi Zohar <zohar@us.ibm.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* Untangling ima mess, part 3: kill dead code in imaAl Viro2009-12-161-48/+4
| | | | | | | | | | | | | Kill the 'update' argument of ima_path_check(), kill dead code in ima. Current rules: ima counters are bumped at the same time when the file switches from put_filp() fodder to fput() one. Which happens exactly in two places - alloc_file() and __dentry_open(). Nothing else needs to do that at all. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* IMA: clean up the IMA counts updating codeEric Paris2009-12-161-48/+70
| | | | | | | | | We currently have a lot of duplicated code around ima file counts. Clean that all up. Signed-off-by: Eric Paris <eparis@redhat.com> Acked-by: Serge Hallyn <serue@us.ibm.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* ima: only insert at inode creation timeEric Paris2009-12-161-4/+4
| | | | | | | | | | | iints are supposed to be allocated when an inode is allocated (during security_inode_alloc()) But we have code which will attempt to allocate an iint during measurement calls. If we couldn't allocate the iint and we cared, we should have died during security_inode_alloc(). Not make the code more complex and less efficient. Signed-off-by: Eric Paris <eparis@redhat.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* IMA: update ima_counts_putMimi Zohar2009-09-071-1/+5
| | | | | | | | | | | | | | - As ima_counts_put() may be called after the inode has been freed, verify that the inode is not NULL, before dereferencing it. - Maintain the IMA file counters in may_open() properly, decrementing any counter increments on subsequent errors. Reported-by: Ciprian Docan <docan@eden.rutgers.edu> Reported-by: J.R. Okajima <hooanon05@yahoo.co.jp> Signed-off-by: Mimi Zohar <zohar@us.ibm.com> Acked-by: Eric Paris <eparis@redhat.com Signed-off-by: James Morris <jmorris@namei.org>
* IMA: iint put in ima_counts_get and putEric Paris2009-08-271-0/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | ima_counts_get() calls ima_iint_find_insert_get() which takes a reference to the iint in question, but does not put that reference at the end of the function. This can lead to a nasty memory leak. Easy enough to reproduce: #include <sys/mman.h> #include <stdio.h> int main (void) { int i; void *ptr; for (i=0; i < 100000; i++) { ptr = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0); if (ptr == MAP_FAILED) return 2; munmap(ptr, 4096); } return 0; } Signed-off-by: Eric Paris <eparis@redhat.com> Signed-off-by: James Morris <jmorris@namei.org>
* integrity: add ima_counts_put (updated)Mimi Zohar2009-06-291-1/+28
| | | | | | | | | | | This patch fixes an imbalance message as reported by J.R. Okajima. The IMA file counters are incremented in ima_path_check. If the actual open fails, such as ETXTBSY, decrement the counters to prevent unnecessary imbalance messages. Reported-by: J.R. Okajima <hooanon05@yahoo.co.jp> Signed-off-by: Mimi Zohar <zohar@us.ibm.com> Signed-off-by: James Morris <jmorris@namei.org>
* integrity: ima audit dentry_open failureMimi Zohar2009-06-051-4/+9
| | | | | | | | | | | | Until we start appraising measurements, the ima_path_check() return code should always be 0. - Update the ima_path_check() return code comment - Instead of the pr_info, audit the dentry_open failure Signed-off-by: Mimi Zohar <zohar@us.ibm.com> Acked-by: Eric Paris <eparis@redhat.com> Signed-off-by: James Morris <jmorris@namei.org>
* integrity: path_check updateMimi Zohar2009-05-221-19/+29
| | | | | | | | | | | - Add support in ima_path_check() for integrity checking without incrementing the counts. (Required for nfsd.) - rename and export opencount_get to ima_counts_get - replace ima_shm_check calls with ima_counts_get - export ima_path_check Signed-off-by: Mimi Zohar <zohar@us.ibm.com> Signed-off-by: James Morris <jmorris@namei.org>
* IMA: open all files O_LARGEFILEEric Paris2009-05-121-1/+2
| | | | | | | | | | If IMA tried to measure a file which was larger than 4G dentry_open would fail with -EOVERFLOW since IMA wasn't passing O_LARGEFILE. This patch passes O_LARGEFILE to all IMA opens to avoid this problem. Signed-off-by: Eric Paris <eparis@redhat.com> Acked-by: Mimi Zohar <zohar@us.ibm.com> Signed-off-by: James Morris <jmorris@namei.org>
* IMA: Handle dentry_open failuresEric Paris2009-05-121-4/+6
| | | | | | | | | | Currently IMA does not handle failures from dentry_open(). This means that we leave a pointer set to ERR_PTR(errno) and then try to use it just a few lines later in fput(). Oops. Signed-off-by: Eric Paris <eparis@redhat.com> Acked-by: Mimi Zohar <zohar@us.ibm.com> Signed-off-by: James Morris <jmorris@namei.org>
* IMA: use current_cred() instead of current->credEric Paris2009-05-121-1/+1
| | | | | | | | | Proper invocation of the current credentials is to use current_cred() not current->cred. This patches makes IMA use the new method. Signed-off-by: Eric Paris <eparis@redhat.com> Acked-by: Mimi Zohar <zohar@us.ibm.com> Signed-off-by: James Morris <jmorris@namei.org>
* integrity: remove __setup auditing msgsMimi Zohar2009-05-061-14/+2
| | | | | | | Remove integrity audit messages from __setup() Signed-off-by: Mimi Zohar <zohar@us.ibm.com> Signed-off-by: James Morris <jmorris@namei.org>
* Integrity: IMA file free imbalanceMimi Zohar2009-02-061-0/+42
| | | | | | | | | | | | | | | | | | | | | 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> Signed-off-by: James Morris <jmorris@namei.org>
* integrity: IMA displayMimi Zohar2009-02-061-0/+5
| | | | | | | | | 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> Signed-off-by: James Morris <jmorris@namei.org>
* integrity: IMA as an integrity service providerMimi Zohar2009-02-061-0/+280
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> Signed-off-by: James Morris <jmorris@namei.org>