IMA: don't propagate opened through the entire thing

just check ->f_mode in ima_appraise_measurement()

Acked-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
Al Viro 2018-06-08 13:40:10 -04:00
parent 73a09dd943
commit 6035a27b25
6 changed files with 16 additions and 17 deletions

View File

@ -3400,8 +3400,7 @@ finish_open_created:
if (error) if (error)
goto out; goto out;
opened: opened:
error = ima_file_check(file, op->acc_mode, error = ima_file_check(file, op->acc_mode);
file->f_mode & FMODE_CREATED ? FILE_CREATED : 0);
if (!error && will_truncate) if (!error && will_truncate)
error = handle_truncate(file); error = handle_truncate(file);
out: out:

View File

@ -763,7 +763,7 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type,
goto out_nfserr; goto out_nfserr;
} }
host_err = ima_file_check(file, may_flags, 0); host_err = ima_file_check(file, may_flags);
if (host_err) { if (host_err) {
fput(file); fput(file);
goto out_nfserr; goto out_nfserr;

View File

@ -16,7 +16,7 @@ struct linux_binprm;
#ifdef CONFIG_IMA #ifdef CONFIG_IMA
extern int ima_bprm_check(struct linux_binprm *bprm); extern int ima_bprm_check(struct linux_binprm *bprm);
extern int ima_file_check(struct file *file, int mask, int opened); extern int ima_file_check(struct file *file, int mask);
extern void ima_file_free(struct file *file); extern void ima_file_free(struct file *file);
extern int ima_file_mmap(struct file *file, unsigned long prot); extern int ima_file_mmap(struct file *file, unsigned long prot);
extern int ima_read_file(struct file *file, enum kernel_read_file_id id); extern int ima_read_file(struct file *file, enum kernel_read_file_id id);
@ -34,7 +34,7 @@ static inline int ima_bprm_check(struct linux_binprm *bprm)
return 0; return 0;
} }
static inline int ima_file_check(struct file *file, int mask, int opened) static inline int ima_file_check(struct file *file, int mask)
{ {
return 0; return 0;
} }

View File

@ -238,7 +238,7 @@ int ima_appraise_measurement(enum ima_hooks func,
struct integrity_iint_cache *iint, struct integrity_iint_cache *iint,
struct file *file, const unsigned char *filename, struct file *file, const unsigned char *filename,
struct evm_ima_xattr_data *xattr_value, struct evm_ima_xattr_data *xattr_value,
int xattr_len, int opened); int xattr_len);
int ima_must_appraise(struct inode *inode, int mask, enum ima_hooks func); int ima_must_appraise(struct inode *inode, int mask, enum ima_hooks func);
void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file); void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file);
enum integrity_status ima_get_cache_status(struct integrity_iint_cache *iint, enum integrity_status ima_get_cache_status(struct integrity_iint_cache *iint,
@ -254,7 +254,7 @@ static inline int ima_appraise_measurement(enum ima_hooks func,
struct file *file, struct file *file,
const unsigned char *filename, const unsigned char *filename,
struct evm_ima_xattr_data *xattr_value, struct evm_ima_xattr_data *xattr_value,
int xattr_len, int opened) int xattr_len)
{ {
return INTEGRITY_UNKNOWN; return INTEGRITY_UNKNOWN;
} }

View File

@ -212,7 +212,7 @@ int ima_appraise_measurement(enum ima_hooks func,
struct integrity_iint_cache *iint, struct integrity_iint_cache *iint,
struct file *file, const unsigned char *filename, struct file *file, const unsigned char *filename,
struct evm_ima_xattr_data *xattr_value, struct evm_ima_xattr_data *xattr_value,
int xattr_len, int opened) int xattr_len)
{ {
static const char op[] = "appraise_data"; static const char op[] = "appraise_data";
const char *cause = "unknown"; const char *cause = "unknown";
@ -231,7 +231,7 @@ int ima_appraise_measurement(enum ima_hooks func,
cause = iint->flags & IMA_DIGSIG_REQUIRED ? cause = iint->flags & IMA_DIGSIG_REQUIRED ?
"IMA-signature-required" : "missing-hash"; "IMA-signature-required" : "missing-hash";
status = INTEGRITY_NOLABEL; status = INTEGRITY_NOLABEL;
if (opened & FILE_CREATED) if (file->f_mode & FMODE_CREATED)
iint->flags |= IMA_NEW_FILE; iint->flags |= IMA_NEW_FILE;
if ((iint->flags & IMA_NEW_FILE) && if ((iint->flags & IMA_NEW_FILE) &&
(!(iint->flags & IMA_DIGSIG_REQUIRED) || (!(iint->flags & IMA_DIGSIG_REQUIRED) ||

View File

@ -168,7 +168,7 @@ void ima_file_free(struct file *file)
static int process_measurement(struct file *file, const struct cred *cred, static int process_measurement(struct file *file, const struct cred *cred,
u32 secid, char *buf, loff_t size, int mask, u32 secid, char *buf, loff_t size, int mask,
enum ima_hooks func, int opened) enum ima_hooks func)
{ {
struct inode *inode = file_inode(file); struct inode *inode = file_inode(file);
struct integrity_iint_cache *iint = NULL; struct integrity_iint_cache *iint = NULL;
@ -294,7 +294,7 @@ static int process_measurement(struct file *file, const struct cred *cred,
if (rc == 0 && (action & IMA_APPRAISE_SUBMASK)) { if (rc == 0 && (action & IMA_APPRAISE_SUBMASK)) {
inode_lock(inode); inode_lock(inode);
rc = ima_appraise_measurement(func, iint, file, pathname, rc = ima_appraise_measurement(func, iint, file, pathname,
xattr_value, xattr_len, opened); xattr_value, xattr_len);
inode_unlock(inode); inode_unlock(inode);
} }
if (action & IMA_AUDIT) if (action & IMA_AUDIT)
@ -338,7 +338,7 @@ int ima_file_mmap(struct file *file, unsigned long prot)
if (file && (prot & PROT_EXEC)) { if (file && (prot & PROT_EXEC)) {
security_task_getsecid(current, &secid); security_task_getsecid(current, &secid);
return process_measurement(file, current_cred(), secid, NULL, return process_measurement(file, current_cred(), secid, NULL,
0, MAY_EXEC, MMAP_CHECK, 0); 0, MAY_EXEC, MMAP_CHECK);
} }
return 0; return 0;
@ -364,13 +364,13 @@ int ima_bprm_check(struct linux_binprm *bprm)
security_task_getsecid(current, &secid); security_task_getsecid(current, &secid);
ret = process_measurement(bprm->file, current_cred(), secid, NULL, 0, ret = process_measurement(bprm->file, current_cred(), secid, NULL, 0,
MAY_EXEC, BPRM_CHECK, 0); MAY_EXEC, BPRM_CHECK);
if (ret) if (ret)
return ret; return ret;
security_cred_getsecid(bprm->cred, &secid); security_cred_getsecid(bprm->cred, &secid);
return process_measurement(bprm->file, bprm->cred, secid, NULL, 0, return process_measurement(bprm->file, bprm->cred, secid, NULL, 0,
MAY_EXEC, CREDS_CHECK, 0); MAY_EXEC, CREDS_CHECK);
} }
/** /**
@ -383,14 +383,14 @@ int ima_bprm_check(struct linux_binprm *bprm)
* On success return 0. On integrity appraisal error, assuming the file * On success return 0. On integrity appraisal error, assuming the file
* is in policy and IMA-appraisal is in enforcing mode, return -EACCES. * is in policy and IMA-appraisal is in enforcing mode, return -EACCES.
*/ */
int ima_file_check(struct file *file, int mask, int opened) int ima_file_check(struct file *file, int mask)
{ {
u32 secid; u32 secid;
security_task_getsecid(current, &secid); security_task_getsecid(current, &secid);
return process_measurement(file, current_cred(), secid, NULL, 0, return process_measurement(file, current_cred(), secid, NULL, 0,
mask & (MAY_READ | MAY_WRITE | MAY_EXEC | mask & (MAY_READ | MAY_WRITE | MAY_EXEC |
MAY_APPEND), FILE_CHECK, opened); MAY_APPEND), FILE_CHECK);
} }
EXPORT_SYMBOL_GPL(ima_file_check); EXPORT_SYMBOL_GPL(ima_file_check);
@ -493,7 +493,7 @@ int ima_post_read_file(struct file *file, void *buf, loff_t size,
func = read_idmap[read_id] ?: FILE_CHECK; func = read_idmap[read_id] ?: FILE_CHECK;
security_task_getsecid(current, &secid); security_task_getsecid(current, &secid);
return process_measurement(file, current_cred(), secid, buf, size, return process_measurement(file, current_cred(), secid, buf, size,
MAY_READ, func, 0); MAY_READ, func);
} }
static int __init init_ima(void) static int __init init_ima(void)