提交 3c90937e 编写于 作者: R Roberto Sassu 提交者: Zheng Zengkai

ima: Generalize policy file operations

hulk inclusion
category: feature
feature: IMA Digest Lists extension
bugzilla: 46797

-------------------------------------------------

This patch renames ima_open_policy() and ima_release_policy() respectively
to ima_open_data_upload() and ima_release_data_upload(). They will be used
to implement file operations for interfaces allowing to load data from user
space.

A new flag (IMA_POLICY_BUSY) has been defined to prevent concurrent policy
upload.
Signed-off-by: NRoberto Sassu <roberto.sassu@huawei.com>
Signed-off-by: NTianxing Zhang <zhangtianxing3@huawei.com>
Reviewed-by: NJason Yan <yanaijie@huawei.com>
Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
上级 1ebe743e
...@@ -395,9 +395,20 @@ static ssize_t ima_write_data(struct file *file, const char __user *buf, ...@@ -395,9 +395,20 @@ static ssize_t ima_write_data(struct file *file, const char __user *buf,
} }
enum ima_fs_flags { enum ima_fs_flags {
IMA_POLICY_BUSY,
IMA_FS_BUSY, IMA_FS_BUSY,
}; };
static enum ima_fs_flags ima_get_dentry_flag(struct dentry *dentry)
{
enum ima_fs_flags flag = IMA_FS_BUSY;
if (dentry == ima_policy)
flag = IMA_POLICY_BUSY;
return flag;
}
static unsigned long ima_fs_flags; static unsigned long ima_fs_flags;
#ifdef CONFIG_IMA_READ_POLICY #ifdef CONFIG_IMA_READ_POLICY
...@@ -410,40 +421,57 @@ static const struct seq_operations ima_policy_seqops = { ...@@ -410,40 +421,57 @@ static const struct seq_operations ima_policy_seqops = {
#endif #endif
/* /*
* ima_open_policy: sequentialize access to the policy file * ima_open_data_upload: sequentialize access to the data upload interface
*/ */
static int ima_open_policy(struct inode *inode, struct file *filp) static int ima_open_data_upload(struct inode *inode, struct file *filp)
{ {
struct dentry *dentry = file_dentry(filp);
const struct seq_operations *seq_ops = NULL;
enum ima_fs_flags flag = ima_get_dentry_flag(dentry);
bool read_allowed = false;
if (dentry == ima_policy) {
#ifdef CONFIG_IMA_READ_POLICY
read_allowed = true;
seq_ops = &ima_policy_seqops;
#endif
}
if (!(filp->f_flags & O_WRONLY)) { if (!(filp->f_flags & O_WRONLY)) {
#ifndef CONFIG_IMA_READ_POLICY if (!read_allowed)
return -EACCES; return -EACCES;
#else
if ((filp->f_flags & O_ACCMODE) != O_RDONLY) if ((filp->f_flags & O_ACCMODE) != O_RDONLY)
return -EACCES; return -EACCES;
if (!capable(CAP_SYS_ADMIN)) if (!capable(CAP_SYS_ADMIN))
return -EPERM; return -EPERM;
return seq_open(filp, &ima_policy_seqops); return seq_open(filp, seq_ops);
#endif
} }
if (test_and_set_bit(IMA_FS_BUSY, &ima_fs_flags)) if (test_and_set_bit(flag, &ima_fs_flags))
return -EBUSY; return -EBUSY;
return 0; return 0;
} }
/* /*
* ima_release_policy - start using the new measure policy rules. * ima_release_data_upload - start using the new measure policy rules.
* *
* Initially, ima_measure points to the default policy rules, now * Initially, ima_measure points to the default policy rules, now
* point to the new policy rules, and remove the securityfs policy file, * point to the new policy rules, and remove the securityfs policy file,
* assuming a valid policy. * assuming a valid policy.
*/ */
static int ima_release_policy(struct inode *inode, struct file *file) static int ima_release_data_upload(struct inode *inode, struct file *file)
{ {
struct dentry *dentry = file_dentry(file);
const char *cause = valid_policy ? "completed" : "failed"; const char *cause = valid_policy ? "completed" : "failed";
enum ima_fs_flags flag = ima_get_dentry_flag(dentry);
if ((file->f_flags & O_ACCMODE) == O_RDONLY) if ((file->f_flags & O_ACCMODE) == O_RDONLY)
return seq_release(inode, file); return seq_release(inode, file);
if (dentry != ima_policy) {
clear_bit(flag, &ima_fs_flags);
return 0;
}
if (valid_policy && ima_check_policy() < 0) { if (valid_policy && ima_check_policy() < 0) {
cause = "failed"; cause = "failed";
valid_policy = 0; valid_policy = 0;
...@@ -456,7 +484,7 @@ static int ima_release_policy(struct inode *inode, struct file *file) ...@@ -456,7 +484,7 @@ static int ima_release_policy(struct inode *inode, struct file *file)
if (!valid_policy) { if (!valid_policy) {
ima_delete_rules(); ima_delete_rules();
valid_policy = 1; valid_policy = 1;
clear_bit(IMA_FS_BUSY, &ima_fs_flags); clear_bit(flag, &ima_fs_flags);
return 0; return 0;
} }
...@@ -465,18 +493,18 @@ static int ima_release_policy(struct inode *inode, struct file *file) ...@@ -465,18 +493,18 @@ static int ima_release_policy(struct inode *inode, struct file *file)
securityfs_remove(ima_policy); securityfs_remove(ima_policy);
ima_policy = NULL; ima_policy = NULL;
#elif defined(CONFIG_IMA_WRITE_POLICY) #elif defined(CONFIG_IMA_WRITE_POLICY)
clear_bit(IMA_FS_BUSY, &ima_fs_flags); clear_bit(flag, &ima_fs_flags);
#elif defined(CONFIG_IMA_READ_POLICY) #elif defined(CONFIG_IMA_READ_POLICY)
inode->i_mode &= ~S_IWUSR; inode->i_mode &= ~S_IWUSR;
#endif #endif
return 0; return 0;
} }
static const struct file_operations ima_measure_policy_ops = { static const struct file_operations ima_data_upload_ops = {
.open = ima_open_policy, .open = ima_open_data_upload,
.write = ima_write_data, .write = ima_write_data,
.read = seq_read, .read = seq_read,
.release = ima_release_policy, .release = ima_release_data_upload,
.llseek = generic_file_llseek, .llseek = generic_file_llseek,
}; };
...@@ -520,7 +548,7 @@ int __init ima_fs_init(void) ...@@ -520,7 +548,7 @@ int __init ima_fs_init(void)
ima_policy = securityfs_create_file("policy", POLICY_FILE_FLAGS, ima_policy = securityfs_create_file("policy", POLICY_FILE_FLAGS,
ima_dir, NULL, ima_dir, NULL,
&ima_measure_policy_ops); &ima_data_upload_ops);
if (IS_ERR(ima_policy)) if (IS_ERR(ima_policy))
goto out; goto out;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册