aboutsummaryrefslogtreecommitdiffstats
path: root/security/integrity/ima
diff options
context:
space:
mode:
authorMimi Zohar <zohar@linux.vnet.ibm.com>2010-11-02 10:13:07 -0400
committerMimi Zohar <zohar@linux.vnet.ibm.com>2011-02-10 07:51:44 -0500
commit890275b5eb79e9933d12290473eab9ac38da0051 (patch)
tree8fa529a6fdfa7647ed4e14287658b71df8636ddd /security/integrity/ima
parenta5c96ebf1d71df0c5fb77ab58c9aeb307cf02372 (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.c2
-rw-r--r--security/integrity/ima/ima_main.c25
2 files changed, 8 insertions, 19 deletions
diff --git a/security/integrity/ima/ima_iint.c b/security/integrity/ima/ima_iint.c
index f0053552fd58..68efe3b8d993 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)
141 printk(KERN_INFO "%s: readcount: %u\n", __func__, 141 printk(KERN_INFO "%s: readcount: %u\n", __func__,
142 atomic_read(&inode->i_readcount)); 142 atomic_read(&inode->i_readcount));
143 143
144 atomic_set(&inode->i_readcount, 0);
145
146 if (!IS_IMA(inode)) 144 if (!IS_IMA(inode))
147 return; 145 return;
148 146
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index 6e8cb931b8f1..69b4856af4da 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -86,17 +86,16 @@ out:
86} 86}
87 87
88/* 88/*
89 * ima_counts_get - increment file counts 89 * ima_rdwr_violation_check
90 * 90 *
91 * Maintain read/write counters for all files, but only 91 * Only invalidate the PCR for measured files:
92 * invalidate the PCR for measured files:
93 * - Opening a file for write when already open for read, 92 * - Opening a file for write when already open for read,
94 * results in a time of measure, time of use (ToMToU) error. 93 * results in a time of measure, time of use (ToMToU) error.
95 * - Opening a file for read when already open for write, 94 * - Opening a file for read when already open for write,
96 * could result in a file measurement error. 95 * could result in a file measurement error.
97 * 96 *
98 */ 97 */
99void ima_counts_get(struct file *file) 98static void ima_rdwr_violation_check(struct file *file)
100{ 99{
101 struct dentry *dentry = file->f_path.dentry; 100 struct dentry *dentry = file->f_path.dentry;
102 struct inode *inode = dentry->d_inode; 101 struct inode *inode = dentry->d_inode;
@@ -104,13 +103,10 @@ void ima_counts_get(struct file *file)
104 int rc; 103 int rc;
105 bool send_tomtou = false, send_writers = false; 104 bool send_tomtou = false, send_writers = false;
106 105
107 if (!S_ISREG(inode->i_mode)) 106 if (!S_ISREG(inode->i_mode) || !ima_initialized)
108 return; 107 return;
109 108
110 spin_lock(&inode->i_lock); 109 mutex_lock(&inode->i_mutex); /* file metadata: permissions, xattr */
111
112 if (!ima_initialized)
113 goto out;
114 110
115 if (mode & FMODE_WRITE) { 111 if (mode & FMODE_WRITE) {
116 if (atomic_read(&inode->i_readcount) && IS_IMA(inode)) 112 if (atomic_read(&inode->i_readcount) && IS_IMA(inode))
@@ -125,11 +121,7 @@ void ima_counts_get(struct file *file)
125 if (atomic_read(&inode->i_writecount) > 0) 121 if (atomic_read(&inode->i_writecount) > 0)
126 send_writers = true; 122 send_writers = true;
127out: 123out:
128 /* remember the vfs deals with i_writecount */ 124 mutex_unlock(&inode->i_mutex);
129 if ((mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
130 atomic_inc(&inode->i_readcount);
131
132 spin_unlock(&inode->i_lock);
133 125
134 if (send_tomtou) 126 if (send_tomtou)
135 ima_add_violation(inode, dentry->d_name.name, "invalid_pcr", 127 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)
158 } 150 }
159 return; 151 return;
160 } 152 }
161 atomic_dec(&inode->i_readcount);
162 } 153 }
163} 154}
164 155
@@ -203,8 +194,7 @@ static void ima_file_free_noiint(struct inode *inode, struct file *file)
203 * ima_file_free - called on __fput() 194 * ima_file_free - called on __fput()
204 * @file: pointer to file structure being freed 195 * @file: pointer to file structure being freed
205 * 196 *
206 * Flag files that changed, based on i_version; 197 * Flag files that changed, based on i_version
207 * and decrement the i_readcount.
208 */ 198 */
209void ima_file_free(struct file *file) 199void ima_file_free(struct file *file)
210{ 200{
@@ -318,6 +308,7 @@ int ima_file_check(struct file *file, int mask)
318{ 308{
319 int rc; 309 int rc;
320 310
311 ima_rdwr_violation_check(file);
321 rc = process_measurement(file, file->f_dentry->d_name.name, 312 rc = process_measurement(file, file->f_dentry->d_name.name,
322 mask & (MAY_READ | MAY_WRITE | MAY_EXEC), 313 mask & (MAY_READ | MAY_WRITE | MAY_EXEC),
323 FILE_CHECK); 314 FILE_CHECK);