Commit 8f46ff57 authored by Roberto Sassu's avatar Roberto Sassu Committed by Paul Moore

security: Introduce file_post_open hook

In preparation to move IMA and EVM to the LSM infrastructure, introduce the
file_post_open hook. Also, export security_file_post_open() for NFS.

Based on policy, IMA calculates the digest of the file content and
extends the TPM with the digest, verifies the file's integrity based on
the digest, and/or includes the file digest in the audit log.

LSMs could similarly take action depending on the file content and the
access mask requested with open().

The new hook returns a value and can cause the open to be aborted.
Signed-off-by: default avatarRoberto Sassu <roberto.sassu@huawei.com>
Reviewed-by: default avatarStefan Berger <stefanb@linux.ibm.com>
Acked-by: default avatarCasey Schaufler <casey@schaufler-ca.com>
Reviewed-by: default avatarMimi Zohar <zohar@linux.ibm.com>
Acked-by: default avatarChristian Brauner <brauner@kernel.org>
Signed-off-by: default avatarPaul Moore <paul@paul-moore.com>
parent dae52cbf
......@@ -3639,6 +3639,8 @@ static int do_open(struct nameidata *nd,
error = may_open(idmap, &nd->path, acc_mode, open_flag);
if (!error && !(file->f_mode & FMODE_OPENED))
error = vfs_open(&nd->path, file);
if (!error)
error = security_file_post_open(file, op->acc_mode);
if (!error)
error = ima_file_check(file, op->acc_mode);
if (!error && do_truncate)
......
......@@ -877,6 +877,12 @@ __nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type,
goto out;
}
host_err = security_file_post_open(file, may_flags);
if (host_err) {
fput(file);
goto out;
}
host_err = ima_file_check(file, may_flags);
if (host_err) {
fput(file);
......
......@@ -191,6 +191,7 @@ LSM_HOOK(int, 0, file_send_sigiotask, struct task_struct *tsk,
struct fown_struct *fown, int sig)
LSM_HOOK(int, 0, file_receive, struct file *file)
LSM_HOOK(int, 0, file_open, struct file *file)
LSM_HOOK(int, 0, file_post_open, struct file *file, int mask)
LSM_HOOK(int, 0, file_truncate, struct file *file)
LSM_HOOK(int, 0, task_alloc, struct task_struct *task,
unsigned long clone_flags)
......
......@@ -411,6 +411,7 @@ int security_file_send_sigiotask(struct task_struct *tsk,
struct fown_struct *fown, int sig);
int security_file_receive(struct file *file);
int security_file_open(struct file *file);
int security_file_post_open(struct file *file, int mask);
int security_file_truncate(struct file *file);
int security_task_alloc(struct task_struct *task, unsigned long clone_flags);
void security_task_free(struct task_struct *task);
......@@ -1074,6 +1075,11 @@ static inline int security_file_open(struct file *file)
return 0;
}
static inline int security_file_post_open(struct file *file, int mask)
{
return 0;
}
static inline int security_file_truncate(struct file *file)
{
return 0;
......
......@@ -2966,6 +2966,23 @@ int security_file_open(struct file *file)
return fsnotify_open_perm(file);
}
/**
* security_file_post_open() - Evaluate a file after it has been opened
* @file: the file
* @mask: access mask
*
* Evaluate an opened file and the access mask requested with open(). The hook
* is useful for LSMs that require the file content to be available in order to
* make decisions.
*
* Return: Returns 0 if permission is granted.
*/
int security_file_post_open(struct file *file, int mask)
{
return call_int_hook(file_post_open, 0, file, mask);
}
EXPORT_SYMBOL_GPL(security_file_post_open);
/**
* security_file_truncate() - Check if truncating a file is allowed
* @file: file
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment