Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ima: pass 'opened' flag to identify newly created files

Empty files and missing xattrs do not guarantee that a file was
just created. This patch passes FILE_CREATED flag to IMA to
reliably identify new files.

Signed-off-by: Dmitry Kasatkin <d.kasatkin@samsung.com>
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
Cc: <stable@vger.kernel.org> 3.14+

authored by

Dmitry Kasatkin and committed by
Mimi Zohar
3034a146 3dcbad52

+16 -16
+1 -1
fs/namei.c
··· 3058 3058 error = open_check_o_direct(file); 3059 3059 if (error) 3060 3060 goto exit_fput; 3061 - error = ima_file_check(file, op->acc_mode); 3061 + error = ima_file_check(file, op->acc_mode, *opened); 3062 3062 if (error) 3063 3063 goto exit_fput; 3064 3064
+1 -1
fs/nfsd/vfs.c
··· 709 709 host_err = PTR_ERR(*filp); 710 710 *filp = NULL; 711 711 } else { 712 - host_err = ima_file_check(*filp, may_flags); 712 + host_err = ima_file_check(*filp, may_flags, 0); 713 713 714 714 if (may_flags & NFSD_MAY_64BIT_COOKIE) 715 715 (*filp)->f_mode |= FMODE_64BITHASH;
+2 -2
include/linux/ima.h
··· 15 15 16 16 #ifdef CONFIG_IMA 17 17 extern int ima_bprm_check(struct linux_binprm *bprm); 18 - extern int ima_file_check(struct file *file, int mask); 18 + extern int ima_file_check(struct file *file, int mask, int opened); 19 19 extern void ima_file_free(struct file *file); 20 20 extern int ima_file_mmap(struct file *file, unsigned long prot); 21 21 extern int ima_module_check(struct file *file); ··· 27 27 return 0; 28 28 } 29 29 30 - static inline int ima_file_check(struct file *file, int mask) 30 + static inline int ima_file_check(struct file *file, int mask, int opened) 31 31 { 32 32 return 0; 33 33 }
+2 -2
security/integrity/ima/ima.h
··· 177 177 int ima_appraise_measurement(int func, struct integrity_iint_cache *iint, 178 178 struct file *file, const unsigned char *filename, 179 179 struct evm_ima_xattr_data *xattr_value, 180 - int xattr_len); 180 + int xattr_len, int opened); 181 181 int ima_must_appraise(struct inode *inode, int mask, enum ima_hooks func); 182 182 void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file); 183 183 enum integrity_status ima_get_cache_status(struct integrity_iint_cache *iint, ··· 193 193 struct file *file, 194 194 const unsigned char *filename, 195 195 struct evm_ima_xattr_data *xattr_value, 196 - int xattr_len) 196 + int xattr_len, int opened) 197 197 { 198 198 return INTEGRITY_UNKNOWN; 199 199 }
+2 -2
security/integrity/ima/ima_appraise.c
··· 183 183 int ima_appraise_measurement(int func, struct integrity_iint_cache *iint, 184 184 struct file *file, const unsigned char *filename, 185 185 struct evm_ima_xattr_data *xattr_value, 186 - int xattr_len) 186 + int xattr_len, int opened) 187 187 { 188 188 static const char op[] = "appraise_data"; 189 189 char *cause = "unknown"; ··· 203 203 204 204 cause = "missing-hash"; 205 205 status = INTEGRITY_NOLABEL; 206 - if (inode->i_size == 0) { 206 + if (opened & FILE_CREATED) { 207 207 iint->flags |= IMA_NEW_FILE; 208 208 status = INTEGRITY_PASS; 209 209 }
+8 -8
security/integrity/ima/ima_main.c
··· 157 157 } 158 158 159 159 static int process_measurement(struct file *file, const char *filename, 160 - int mask, int function) 160 + int mask, int function, int opened) 161 161 { 162 162 struct inode *inode = file_inode(file); 163 163 struct integrity_iint_cache *iint; ··· 226 226 xattr_value, xattr_len); 227 227 if (action & IMA_APPRAISE_SUBMASK) 228 228 rc = ima_appraise_measurement(_func, iint, file, pathname, 229 - xattr_value, xattr_len); 229 + xattr_value, xattr_len, opened); 230 230 if (action & IMA_AUDIT) 231 231 ima_audit_measurement(iint, pathname); 232 232 kfree(pathbuf); ··· 255 255 int ima_file_mmap(struct file *file, unsigned long prot) 256 256 { 257 257 if (file && (prot & PROT_EXEC)) 258 - return process_measurement(file, NULL, MAY_EXEC, MMAP_CHECK); 258 + return process_measurement(file, NULL, MAY_EXEC, MMAP_CHECK, 0); 259 259 return 0; 260 260 } 261 261 ··· 277 277 return process_measurement(bprm->file, 278 278 (strcmp(bprm->filename, bprm->interp) == 0) ? 279 279 bprm->filename : bprm->interp, 280 - MAY_EXEC, BPRM_CHECK); 280 + MAY_EXEC, BPRM_CHECK, 0); 281 281 } 282 282 283 283 /** ··· 290 290 * On success return 0. On integrity appraisal error, assuming the file 291 291 * is in policy and IMA-appraisal is in enforcing mode, return -EACCES. 292 292 */ 293 - int ima_file_check(struct file *file, int mask) 293 + int ima_file_check(struct file *file, int mask, int opened) 294 294 { 295 295 ima_rdwr_violation_check(file); 296 296 return process_measurement(file, NULL, 297 297 mask & (MAY_READ | MAY_WRITE | MAY_EXEC), 298 - FILE_CHECK); 298 + FILE_CHECK, opened); 299 299 } 300 300 EXPORT_SYMBOL_GPL(ima_file_check); 301 301 ··· 318 318 #endif 319 319 return 0; /* We rely on module signature checking */ 320 320 } 321 - return process_measurement(file, NULL, MAY_EXEC, MODULE_CHECK); 321 + return process_measurement(file, NULL, MAY_EXEC, MODULE_CHECK, 0); 322 322 } 323 323 324 324 int ima_fw_from_file(struct file *file, char *buf, size_t size) ··· 329 329 return -EACCES; /* INTEGRITY_UNKNOWN */ 330 330 return 0; 331 331 } 332 - return process_measurement(file, NULL, MAY_EXEC, FIRMWARE_CHECK); 332 + return process_measurement(file, NULL, MAY_EXEC, FIRMWARE_CHECK, 0); 333 333 } 334 334 335 335 static int __init init_ima(void)