When policy file is written and write-once is enabled, the policy file must be deleted. Select the namespace policy structure to get the correct policy file descriptor. Signed-off-by: Guilherme Magalhaes <guilherme.magalhaes@xxxxxxx> --- security/integrity/ima/ima_fs.c | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c index 65c43e7..94e89fe 100644 --- a/security/integrity/ima/ima_fs.c +++ b/security/integrity/ima/ima_fs.c @@ -575,6 +575,7 @@ static int ima_open_policy(struct inode *inode, struct file *filp) static int ima_release_policy(struct inode *inode, struct file *file) { const char *cause = valid_policy ? "completed" : "failed"; + struct ima_ns_policy *ins; if ((file->f_flags & O_ACCMODE) == O_RDONLY) return seq_release(inode, file); @@ -595,15 +596,37 @@ static int ima_release_policy(struct inode *inode, struct file *file) return 0; } + /* get the namespace id from file->inode (policy file inode). + * We also need to synchronize this operation with concurrent namespace + * releasing. */ + ima_namespace_lock(); + ins = ima_get_namespace_policy_from_inode(inode); + if (!ins) { + /* the namespace is not valid anymore, discard new policy + * rules and exit */ + ima_delete_rules(); + valid_policy = 1; + clear_bit(IMA_FS_BUSY, &ima_fs_flags); + ima_namespace_unlock(); + return 0; + } + ima_update_policy(); #ifndef CONFIG_IMA_WRITE_POLICY - securityfs_remove(ima_policy_initial_ns); - ima_policy = NULL; + if (ins == &ima_initial_namespace_policy) { + securityfs_remove(ima_policy_initial_ns); + ima_policy_initial_ns = NULL; + } else { + securityfs_remove(ins->policy_dentry); + ins->policy_dentry = NULL; + } #endif /* always clear the busy flag so other namespaces can use it */ clear_bit(IMA_FS_BUSY, &ima_fs_flags); + ima_namespace_unlock(); + return 0; } -- 2.7.4