diff options
Diffstat (limited to 'security/integrity/ima/ima_main.c')
-rw-r--r-- | security/integrity/ima/ima_main.c | 52 |
1 files changed, 25 insertions, 27 deletions
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index 2917f980bf30..673a37e92ba3 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c | |||
@@ -124,11 +124,13 @@ static void ima_check_last_writer(struct integrity_iint_cache *iint, | |||
124 | return; | 124 | return; |
125 | 125 | ||
126 | mutex_lock(&inode->i_mutex); | 126 | mutex_lock(&inode->i_mutex); |
127 | if (atomic_read(&inode->i_writecount) == 1 && | 127 | if (atomic_read(&inode->i_writecount) == 1) { |
128 | iint->version != inode->i_version) { | 128 | if ((iint->version != inode->i_version) || |
129 | iint->flags &= ~IMA_DONE_MASK; | 129 | (iint->flags & IMA_NEW_FILE)) { |
130 | if (iint->flags & IMA_APPRAISE) | 130 | iint->flags &= ~(IMA_DONE_MASK | IMA_NEW_FILE); |
131 | ima_update_xattr(iint, file); | 131 | if (iint->flags & IMA_APPRAISE) |
132 | ima_update_xattr(iint, file); | ||
133 | } | ||
132 | } | 134 | } |
133 | mutex_unlock(&inode->i_mutex); | 135 | mutex_unlock(&inode->i_mutex); |
134 | } | 136 | } |
@@ -154,15 +156,15 @@ void ima_file_free(struct file *file) | |||
154 | ima_check_last_writer(iint, inode, file); | 156 | ima_check_last_writer(iint, inode, file); |
155 | } | 157 | } |
156 | 158 | ||
157 | static int process_measurement(struct file *file, const char *filename, | 159 | static int process_measurement(struct file *file, int mask, int function, |
158 | int mask, int function) | 160 | int opened) |
159 | { | 161 | { |
160 | struct inode *inode = file_inode(file); | 162 | struct inode *inode = file_inode(file); |
161 | struct integrity_iint_cache *iint; | 163 | struct integrity_iint_cache *iint; |
162 | struct ima_template_desc *template_desc; | 164 | struct ima_template_desc *template_desc; |
163 | char *pathbuf = NULL; | 165 | char *pathbuf = NULL; |
164 | const char *pathname = NULL; | 166 | const char *pathname = NULL; |
165 | int rc = -ENOMEM, action, must_appraise, _func; | 167 | int rc = -ENOMEM, action, must_appraise; |
166 | struct evm_ima_xattr_data *xattr_value = NULL, **xattr_ptr = NULL; | 168 | struct evm_ima_xattr_data *xattr_value = NULL, **xattr_ptr = NULL; |
167 | int xattr_len = 0; | 169 | int xattr_len = 0; |
168 | 170 | ||
@@ -180,7 +182,8 @@ static int process_measurement(struct file *file, const char *filename, | |||
180 | must_appraise = action & IMA_APPRAISE; | 182 | must_appraise = action & IMA_APPRAISE; |
181 | 183 | ||
182 | /* Is the appraise rule hook specific? */ | 184 | /* Is the appraise rule hook specific? */ |
183 | _func = (action & IMA_FILE_APPRAISE) ? FILE_CHECK : function; | 185 | if (action & IMA_FILE_APPRAISE) |
186 | function = FILE_CHECK; | ||
184 | 187 | ||
185 | mutex_lock(&inode->i_mutex); | 188 | mutex_lock(&inode->i_mutex); |
186 | 189 | ||
@@ -199,15 +202,13 @@ static int process_measurement(struct file *file, const char *filename, | |||
199 | /* Nothing to do, just return existing appraised status */ | 202 | /* Nothing to do, just return existing appraised status */ |
200 | if (!action) { | 203 | if (!action) { |
201 | if (must_appraise) | 204 | if (must_appraise) |
202 | rc = ima_get_cache_status(iint, _func); | 205 | rc = ima_get_cache_status(iint, function); |
203 | goto out_digsig; | 206 | goto out_digsig; |
204 | } | 207 | } |
205 | 208 | ||
206 | template_desc = ima_template_desc_current(); | 209 | template_desc = ima_template_desc_current(); |
207 | if (strcmp(template_desc->name, IMA_TEMPLATE_IMA_NAME) == 0) { | 210 | if ((action & IMA_APPRAISE_SUBMASK) || |
208 | if (action & IMA_APPRAISE_SUBMASK) | 211 | strcmp(template_desc->name, IMA_TEMPLATE_IMA_NAME) != 0) |
209 | xattr_ptr = &xattr_value; | ||
210 | } else | ||
211 | xattr_ptr = &xattr_value; | 212 | xattr_ptr = &xattr_value; |
212 | 213 | ||
213 | rc = ima_collect_measurement(iint, file, xattr_ptr, &xattr_len); | 214 | rc = ima_collect_measurement(iint, file, xattr_ptr, &xattr_len); |
@@ -217,14 +218,14 @@ static int process_measurement(struct file *file, const char *filename, | |||
217 | goto out_digsig; | 218 | goto out_digsig; |
218 | } | 219 | } |
219 | 220 | ||
220 | pathname = filename ?: ima_d_path(&file->f_path, &pathbuf); | 221 | pathname = ima_d_path(&file->f_path, &pathbuf); |
221 | 222 | ||
222 | if (action & IMA_MEASURE) | 223 | if (action & IMA_MEASURE) |
223 | ima_store_measurement(iint, file, pathname, | 224 | ima_store_measurement(iint, file, pathname, |
224 | xattr_value, xattr_len); | 225 | xattr_value, xattr_len); |
225 | if (action & IMA_APPRAISE_SUBMASK) | 226 | if (action & IMA_APPRAISE_SUBMASK) |
226 | rc = ima_appraise_measurement(_func, iint, file, pathname, | 227 | rc = ima_appraise_measurement(function, iint, file, pathname, |
227 | xattr_value, xattr_len); | 228 | xattr_value, xattr_len, opened); |
228 | if (action & IMA_AUDIT) | 229 | if (action & IMA_AUDIT) |
229 | ima_audit_measurement(iint, pathname); | 230 | ima_audit_measurement(iint, pathname); |
230 | kfree(pathbuf); | 231 | kfree(pathbuf); |
@@ -253,7 +254,7 @@ out: | |||
253 | int ima_file_mmap(struct file *file, unsigned long prot) | 254 | int ima_file_mmap(struct file *file, unsigned long prot) |
254 | { | 255 | { |
255 | if (file && (prot & PROT_EXEC)) | 256 | if (file && (prot & PROT_EXEC)) |
256 | return process_measurement(file, NULL, MAY_EXEC, MMAP_CHECK); | 257 | return process_measurement(file, MAY_EXEC, MMAP_CHECK, 0); |
257 | return 0; | 258 | return 0; |
258 | } | 259 | } |
259 | 260 | ||
@@ -272,10 +273,7 @@ int ima_file_mmap(struct file *file, unsigned long prot) | |||
272 | */ | 273 | */ |
273 | int ima_bprm_check(struct linux_binprm *bprm) | 274 | int ima_bprm_check(struct linux_binprm *bprm) |
274 | { | 275 | { |
275 | return process_measurement(bprm->file, | 276 | return process_measurement(bprm->file, MAY_EXEC, BPRM_CHECK, 0); |
276 | (strcmp(bprm->filename, bprm->interp) == 0) ? | ||
277 | bprm->filename : bprm->interp, | ||
278 | MAY_EXEC, BPRM_CHECK); | ||
279 | } | 277 | } |
280 | 278 | ||
281 | /** | 279 | /** |
@@ -288,12 +286,12 @@ int ima_bprm_check(struct linux_binprm *bprm) | |||
288 | * On success return 0. On integrity appraisal error, assuming the file | 286 | * On success return 0. On integrity appraisal error, assuming the file |
289 | * is in policy and IMA-appraisal is in enforcing mode, return -EACCES. | 287 | * is in policy and IMA-appraisal is in enforcing mode, return -EACCES. |
290 | */ | 288 | */ |
291 | int ima_file_check(struct file *file, int mask) | 289 | int ima_file_check(struct file *file, int mask, int opened) |
292 | { | 290 | { |
293 | ima_rdwr_violation_check(file); | 291 | ima_rdwr_violation_check(file); |
294 | return process_measurement(file, NULL, | 292 | return process_measurement(file, |
295 | mask & (MAY_READ | MAY_WRITE | MAY_EXEC), | 293 | mask & (MAY_READ | MAY_WRITE | MAY_EXEC), |
296 | FILE_CHECK); | 294 | FILE_CHECK, opened); |
297 | } | 295 | } |
298 | EXPORT_SYMBOL_GPL(ima_file_check); | 296 | EXPORT_SYMBOL_GPL(ima_file_check); |
299 | 297 | ||
@@ -316,7 +314,7 @@ int ima_module_check(struct file *file) | |||
316 | #endif | 314 | #endif |
317 | return 0; /* We rely on module signature checking */ | 315 | return 0; /* We rely on module signature checking */ |
318 | } | 316 | } |
319 | return process_measurement(file, NULL, MAY_EXEC, MODULE_CHECK); | 317 | return process_measurement(file, MAY_EXEC, MODULE_CHECK, 0); |
320 | } | 318 | } |
321 | 319 | ||
322 | int ima_fw_from_file(struct file *file, char *buf, size_t size) | 320 | int ima_fw_from_file(struct file *file, char *buf, size_t size) |
@@ -327,7 +325,7 @@ int ima_fw_from_file(struct file *file, char *buf, size_t size) | |||
327 | return -EACCES; /* INTEGRITY_UNKNOWN */ | 325 | return -EACCES; /* INTEGRITY_UNKNOWN */ |
328 | return 0; | 326 | return 0; |
329 | } | 327 | } |
330 | return process_measurement(file, NULL, MAY_EXEC, FIRMWARE_CHECK); | 328 | return process_measurement(file, MAY_EXEC, FIRMWARE_CHECK, 0); |
331 | } | 329 | } |
332 | 330 | ||
333 | static int __init init_ima(void) | 331 | static int __init init_ima(void) |