aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--security/integrity/ima/ima_main.c54
1 files changed, 33 insertions, 21 deletions
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index 2191b36ad1da..03bb52ecf490 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -77,21 +77,19 @@ __setup("ima_hash=", hash_setup);
77 * could result in a file measurement error. 77 * could result in a file measurement error.
78 * 78 *
79 */ 79 */
80static void ima_rdwr_violation_check(struct file *file) 80static void ima_rdwr_violation_check(struct file *file,
81 struct integrity_iint_cache *iint,
82 char **pathbuf,
83 const char **pathname)
81{ 84{
82 struct inode *inode = file_inode(file); 85 struct inode *inode = file_inode(file);
83 fmode_t mode = file->f_mode; 86 fmode_t mode = file->f_mode;
84 bool send_tomtou = false, send_writers = false; 87 bool send_tomtou = false, send_writers = false;
85 char *pathbuf = NULL;
86 const char *pathname;
87
88 if (!S_ISREG(inode->i_mode) || !(ima_policy_flag & IMA_MEASURE))
89 return;
90 88
91 if (mode & FMODE_WRITE) { 89 if (mode & FMODE_WRITE) {
92 if (atomic_read(&inode->i_readcount) && IS_IMA(inode)) { 90 if (atomic_read(&inode->i_readcount) && IS_IMA(inode)) {
93 struct integrity_iint_cache *iint; 91 if (!iint)
94 iint = integrity_iint_find(inode); 92 iint = integrity_iint_find(inode);
95 /* IMA_MEASURE is set from reader side */ 93 /* IMA_MEASURE is set from reader side */
96 if (iint && (iint->flags & IMA_MEASURE)) 94 if (iint && (iint->flags & IMA_MEASURE))
97 send_tomtou = true; 95 send_tomtou = true;
@@ -105,14 +103,13 @@ static void ima_rdwr_violation_check(struct file *file)
105 if (!send_tomtou && !send_writers) 103 if (!send_tomtou && !send_writers)
106 return; 104 return;
107 105
108 pathname = ima_d_path(&file->f_path, &pathbuf); 106 *pathname = ima_d_path(&file->f_path, pathbuf);
109 107
110 if (send_tomtou) 108 if (send_tomtou)
111 ima_add_violation(file, pathname, "invalid_pcr", "ToMToU"); 109 ima_add_violation(file, *pathname, "invalid_pcr", "ToMToU");
112 if (send_writers) 110 if (send_writers)
113 ima_add_violation(file, pathname, 111 ima_add_violation(file, *pathname,
114 "invalid_pcr", "open_writers"); 112 "invalid_pcr", "open_writers");
115 kfree(pathbuf);
116} 113}
117 114
118static void ima_check_last_writer(struct integrity_iint_cache *iint, 115static void ima_check_last_writer(struct integrity_iint_cache *iint,
@@ -160,13 +157,14 @@ static int process_measurement(struct file *file, int mask, int function,
160 int opened) 157 int opened)
161{ 158{
162 struct inode *inode = file_inode(file); 159 struct inode *inode = file_inode(file);
163 struct integrity_iint_cache *iint; 160 struct integrity_iint_cache *iint = NULL;
164 struct ima_template_desc *template_desc; 161 struct ima_template_desc *template_desc;
165 char *pathbuf = NULL; 162 char *pathbuf = NULL;
166 const char *pathname = NULL; 163 const char *pathname = NULL;
167 int rc = -ENOMEM, action, must_appraise; 164 int rc = -ENOMEM, action, must_appraise;
168 struct evm_ima_xattr_data *xattr_value = NULL, **xattr_ptr = NULL; 165 struct evm_ima_xattr_data *xattr_value = NULL, **xattr_ptr = NULL;
169 int xattr_len = 0; 166 int xattr_len = 0;
167 bool violation_check;
170 168
171 if (!ima_policy_flag || !S_ISREG(inode->i_mode)) 169 if (!ima_policy_flag || !S_ISREG(inode->i_mode))
172 return 0; 170 return 0;
@@ -176,7 +174,9 @@ static int process_measurement(struct file *file, int mask, int function,
176 * Included is the appraise submask. 174 * Included is the appraise submask.
177 */ 175 */
178 action = ima_get_action(inode, mask, function); 176 action = ima_get_action(inode, mask, function);
179 if (!action) 177 violation_check = (function == FILE_CHECK &&
178 (ima_policy_flag & IMA_MEASURE));
179 if (!action && !violation_check)
180 return 0; 180 return 0;
181 181
182 must_appraise = action & IMA_APPRAISE; 182 must_appraise = action & IMA_APPRAISE;
@@ -187,9 +187,19 @@ static int process_measurement(struct file *file, int mask, int function,
187 187
188 mutex_lock(&inode->i_mutex); 188 mutex_lock(&inode->i_mutex);
189 189
190 iint = integrity_inode_get(inode); 190 if (action) {
191 if (!iint) 191 iint = integrity_inode_get(inode);
192 goto out; 192 if (!iint)
193 goto out;
194 }
195
196 if (violation_check) {
197 ima_rdwr_violation_check(file, iint, &pathbuf, &pathname);
198 if (!action) {
199 rc = 0;
200 goto out_free;
201 }
202 }
193 203
194 /* Determine if already appraised/measured based on bitmask 204 /* Determine if already appraised/measured based on bitmask
195 * (IMA_MEASURE, IMA_MEASURED, IMA_XXXX_APPRAISE, IMA_XXXX_APPRAISED, 205 * (IMA_MEASURE, IMA_MEASURED, IMA_XXXX_APPRAISE, IMA_XXXX_APPRAISED,
@@ -218,7 +228,8 @@ static int process_measurement(struct file *file, int mask, int function,
218 goto out_digsig; 228 goto out_digsig;
219 } 229 }
220 230
221 pathname = ima_d_path(&file->f_path, &pathbuf); 231 if (!pathname) /* ima_rdwr_violation possibly pre-fetched */
232 pathname = ima_d_path(&file->f_path, &pathbuf);
222 233
223 if (action & IMA_MEASURE) 234 if (action & IMA_MEASURE)
224 ima_store_measurement(iint, file, pathname, 235 ima_store_measurement(iint, file, pathname,
@@ -228,13 +239,15 @@ static int process_measurement(struct file *file, int mask, int function,
228 xattr_value, xattr_len, opened); 239 xattr_value, xattr_len, opened);
229 if (action & IMA_AUDIT) 240 if (action & IMA_AUDIT)
230 ima_audit_measurement(iint, pathname); 241 ima_audit_measurement(iint, pathname);
231 kfree(pathbuf); 242
232out_digsig: 243out_digsig:
233 if ((mask & MAY_WRITE) && (iint->flags & IMA_DIGSIG)) 244 if ((mask & MAY_WRITE) && (iint->flags & IMA_DIGSIG))
234 rc = -EACCES; 245 rc = -EACCES;
246 kfree(xattr_value);
247out_free:
248 kfree(pathbuf);
235out: 249out:
236 mutex_unlock(&inode->i_mutex); 250 mutex_unlock(&inode->i_mutex);
237 kfree(xattr_value);
238 if ((rc && must_appraise) && (ima_appraise & IMA_APPRAISE_ENFORCE)) 251 if ((rc && must_appraise) && (ima_appraise & IMA_APPRAISE_ENFORCE))
239 return -EACCES; 252 return -EACCES;
240 return 0; 253 return 0;
@@ -288,7 +301,6 @@ int ima_bprm_check(struct linux_binprm *bprm)
288 */ 301 */
289int ima_file_check(struct file *file, int mask, int opened) 302int ima_file_check(struct file *file, int mask, int opened)
290{ 303{
291 ima_rdwr_violation_check(file);
292 return process_measurement(file, 304 return process_measurement(file,
293 mask & (MAY_READ | MAY_WRITE | MAY_EXEC), 305 mask & (MAY_READ | MAY_WRITE | MAY_EXEC),
294 FILE_CHECK, opened); 306 FILE_CHECK, opened);