aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/file_table.c5
-rw-r--r--fs/open.c3
-rw-r--r--include/linux/ima.h6
-rw-r--r--security/integrity/ima/ima_iint.c2
-rw-r--r--security/integrity/ima/ima_main.c25
5 files changed, 14 insertions, 27 deletions
diff --git a/fs/file_table.c b/fs/file_table.c
index c3dee381f1b..0c724deb46f 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -190,7 +190,8 @@ struct file *alloc_file(struct path *path, fmode_t mode,
190 file_take_write(file); 190 file_take_write(file);
191 WARN_ON(mnt_clone_write(path->mnt)); 191 WARN_ON(mnt_clone_write(path->mnt));
192 } 192 }
193 ima_counts_get(file); 193 if ((mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
194 i_readcount_inc(path->dentry->d_inode);
194 return file; 195 return file;
195} 196}
196EXPORT_SYMBOL(alloc_file); 197EXPORT_SYMBOL(alloc_file);
@@ -251,6 +252,8 @@ static void __fput(struct file *file)
251 fops_put(file->f_op); 252 fops_put(file->f_op);
252 put_pid(file->f_owner.pid); 253 put_pid(file->f_owner.pid);
253 file_sb_list_del(file); 254 file_sb_list_del(file);
255 if ((file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
256 i_readcount_dec(inode);
254 if (file->f_mode & FMODE_WRITE) 257 if (file->f_mode & FMODE_WRITE)
255 drop_file_write_access(file); 258 drop_file_write_access(file);
256 file->f_path.dentry = NULL; 259 file->f_path.dentry = NULL;
diff --git a/fs/open.c b/fs/open.c
index 4197b9ed023..0d485c50bb9 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -688,7 +688,8 @@ static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt,
688 if (error) 688 if (error)
689 goto cleanup_all; 689 goto cleanup_all;
690 } 690 }
691 ima_counts_get(f); 691 if ((f->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
692 i_readcount_inc(inode);
692 693
693 f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC); 694 f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
694 695
diff --git a/include/linux/ima.h b/include/linux/ima.h
index 975837e7d6c..09e6e62f995 100644
--- a/include/linux/ima.h
+++ b/include/linux/ima.h
@@ -20,7 +20,6 @@ extern void ima_inode_free(struct inode *inode);
20extern int ima_file_check(struct file *file, int mask); 20extern int ima_file_check(struct file *file, int mask);
21extern void ima_file_free(struct file *file); 21extern void ima_file_free(struct file *file);
22extern int ima_file_mmap(struct file *file, unsigned long prot); 22extern int ima_file_mmap(struct file *file, unsigned long prot);
23extern void ima_counts_get(struct file *file);
24 23
25#else 24#else
26static inline int ima_bprm_check(struct linux_binprm *bprm) 25static inline int ima_bprm_check(struct linux_binprm *bprm)
@@ -53,10 +52,5 @@ static inline int ima_file_mmap(struct file *file, unsigned long prot)
53 return 0; 52 return 0;
54} 53}
55 54
56static inline void ima_counts_get(struct file *file)
57{
58 return;
59}
60
61#endif /* CONFIG_IMA_H */ 55#endif /* CONFIG_IMA_H */
62#endif /* _LINUX_IMA_H */ 56#endif /* _LINUX_IMA_H */
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)
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 6e8cb931b8f..69b4856af4d 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);