diff options
author | Mimi Zohar <zohar@linux.vnet.ibm.com> | 2010-11-02 10:13:07 -0400 |
---|---|---|
committer | Mimi Zohar <zohar@linux.vnet.ibm.com> | 2011-02-10 07:51:44 -0500 |
commit | 890275b5eb79e9933d12290473eab9ac38da0051 (patch) | |
tree | 8fa529a6fdfa7647ed4e14287658b71df8636ddd /security/integrity/ima | |
parent | a5c96ebf1d71df0c5fb77ab58c9aeb307cf02372 (diff) |
IMA: maintain i_readcount in the VFS layer
ima_counts_get() updated the readcount and invalidated the PCR,
as necessary. Only update the i_readcount in the VFS layer.
Move the PCR invalidation checks to ima_file_check(), where it
belongs.
Maintaining the i_readcount in the VFS layer, will allow other
subsystems to use i_readcount.
Signed-off-by: Mimi Zohar <zohar@us.ibm.com>
Acked-by: Eric Paris <eparis@redhat.com>
Diffstat (limited to 'security/integrity/ima')
-rw-r--r-- | security/integrity/ima/ima_iint.c | 2 | ||||
-rw-r--r-- | security/integrity/ima/ima_main.c | 25 |
2 files changed, 8 insertions, 19 deletions
diff --git a/security/integrity/ima/ima_iint.c b/security/integrity/ima/ima_iint.c index f0053552fd5..68efe3b8d99 100644 --- a/security/integrity/ima/ima_iint.c +++ b/security/integrity/ima/ima_iint.c @@ -141,8 +141,6 @@ void ima_inode_free(struct inode *inode) printk(KERN_INFO "%s: readcount: %u\n", __func__, atomic_read(&inode->i_readcount)); - atomic_set(&inode->i_readcount, 0); - if (!IS_IMA(inode)) return; diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index 6e8cb931b8f..69b4856af4d 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c @@ -86,17 +86,16 @@ out: } /* - * ima_counts_get - increment file counts + * ima_rdwr_violation_check * - * Maintain read/write counters for all files, but only - * invalidate the PCR for measured files: + * 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. * */ -void ima_counts_get(struct file *file) +static void ima_rdwr_violation_check(struct file *file) { struct dentry *dentry = file->f_path.dentry; struct inode *inode = dentry->d_inode; @@ -104,13 +103,10 @@ void ima_counts_get(struct file *file) int rc; bool send_tomtou = false, send_writers = false; - if (!S_ISREG(inode->i_mode)) + if (!S_ISREG(inode->i_mode) || !ima_initialized) return; - spin_lock(&inode->i_lock); - - if (!ima_initialized) - goto out; + mutex_lock(&inode->i_mutex); /* file metadata: permissions, xattr */ if (mode & FMODE_WRITE) { if (atomic_read(&inode->i_readcount) && IS_IMA(inode)) @@ -125,11 +121,7 @@ void ima_counts_get(struct file *file) if (atomic_read(&inode->i_writecount) > 0) send_writers = true; out: - /* remember the vfs deals with i_writecount */ - if ((mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) - atomic_inc(&inode->i_readcount); - - spin_unlock(&inode->i_lock); + mutex_unlock(&inode->i_mutex); if (send_tomtou) ima_add_violation(inode, dentry->d_name.name, "invalid_pcr", @@ -158,7 +150,6 @@ static void ima_dec_counts(struct inode *inode, struct file *file) } return; } - atomic_dec(&inode->i_readcount); } } @@ -203,8 +194,7 @@ static void ima_file_free_noiint(struct inode *inode, struct file *file) * ima_file_free - called on __fput() * @file: pointer to file structure being freed * - * Flag files that changed, based on i_version; - * and decrement the i_readcount. + * Flag files that changed, based on i_version */ void ima_file_free(struct file *file) { @@ -318,6 +308,7 @@ int ima_file_check(struct file *file, int mask) { int rc; + ima_rdwr_violation_check(file); rc = process_measurement(file, file->f_dentry->d_name.name, mask & (MAY_READ | MAY_WRITE | MAY_EXEC), FILE_CHECK); |