diff options
-rw-r--r-- | fs/file_table.c | 5 | ||||
-rw-r--r-- | fs/open.c | 3 | ||||
-rw-r--r-- | include/linux/ima.h | 6 | ||||
-rw-r--r-- | security/integrity/ima/ima_iint.c | 2 | ||||
-rw-r--r-- | security/integrity/ima/ima_main.c | 25 |
5 files changed, 14 insertions, 27 deletions
diff --git a/fs/file_table.c b/fs/file_table.c index c3dee381f1b4..0c724deb46f9 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 | } |
196 | EXPORT_SYMBOL(alloc_file); | 197 | EXPORT_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; |
@@ -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 975837e7d6c0..09e6e62f9953 100644 --- a/include/linux/ima.h +++ b/include/linux/ima.h | |||
@@ -20,7 +20,6 @@ extern void ima_inode_free(struct inode *inode); | |||
20 | extern int ima_file_check(struct file *file, int mask); | 20 | extern int ima_file_check(struct file *file, int mask); |
21 | extern void ima_file_free(struct file *file); | 21 | extern void ima_file_free(struct file *file); |
22 | extern int ima_file_mmap(struct file *file, unsigned long prot); | 22 | extern int ima_file_mmap(struct file *file, unsigned long prot); |
23 | extern void ima_counts_get(struct file *file); | ||
24 | 23 | ||
25 | #else | 24 | #else |
26 | static inline int ima_bprm_check(struct linux_binprm *bprm) | 25 | static 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 | ||
56 | static 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 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 | */ |
99 | void ima_counts_get(struct file *file) | 98 | static 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; |
127 | out: | 123 | out: |
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 | */ |
209 | void ima_file_free(struct file *file) | 199 | void 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); |