security: switched to stackable model for PFT/PFK module

Moved hooks from SELINUX framework to general SECURITY framework.

Change-Id: I37e701b4925c4993f724c32b258c5088f4dcbe4d
Signed-off-by: Andrey Markovytch <andreym@codeaurora.org>
This commit is contained in:
Andrey Markovytch 2017-01-09 11:23:03 +02:00
parent 33eba0ae11
commit 3eab9b61f3
6 changed files with 12 additions and 114 deletions

View file

@ -292,7 +292,6 @@ 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, const struct cred *cred);
int security_file_close(struct file *file);
int security_task_create(unsigned long clone_flags);
void security_task_free(struct task_struct *task);
int security_cred_alloc_blank(struct cred *cred, gfp_t gfp);
@ -820,11 +819,6 @@ static inline int security_file_open(struct file *file,
return 0;
}
static inline int security_file_close(struct file *file)
{
return 0;
}
static inline int security_task_create(unsigned long clone_flags)
{
return 0;

View file

@ -15,6 +15,7 @@ config PFT
config PFK
bool "Per-File-Key driver"
depends on SECURITY
depends on SECURITY_SELINUX
default n
help
This driver is used for storing eCryptfs information

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -92,56 +92,18 @@ bool pfk_is_ecryptfs_type(const struct inode *inode)
return true;
}
static int pfk_ecryptfs_inode_alloc_security(struct inode *inode)
{
struct inode_security_struct *i_sec = NULL;
if (inode == NULL)
return -EINVAL;
i_sec = kzalloc(sizeof(*i_sec), GFP_KERNEL);
if (i_sec == NULL)
return -ENOMEM;
inode->i_security = i_sec;
return 0;
}
static void pfk_ecryptfs_inode_free_security(struct inode *inode)
{
if (inode == NULL)
return;
kzfree(inode->i_security);
}
static struct security_hook_list pfk_ecryptfs_hooks[] = {
LSM_HOOK_INIT(inode_alloc_security, pfk_ecryptfs_inode_alloc_security),
LSM_HOOK_INIT(inode_free_security, pfk_ecryptfs_inode_free_security),
};
/*
* pfk_ecryptfs_lsm_init() - makes sure either se-linux or pfk_ecryptfs are
* registered as security module.
* pfk_ecryptfs_lsm_init() - makes sure either se-linux is
* registered as security module as it is required by pfk_ecryptfs.
*
* This is required because ecryptfs uses a field inside security struct in
* inode to store its info
*/
static int __init pfk_ecryptfs_lsm_init(void)
{
/* Check if PFK is the chosen lsm via security_module_enable() */
if (security_module_enable("pfk_ecryptfs")) {
security_add_hooks(pfk_ecryptfs_hooks,
ARRAY_SIZE(pfk_ecryptfs_hooks));
pr_debug("pfk_ecryptfs is the chosen lsm, registered successfully !\n");
} else {
pr_debug("pfk_ecryptfs is not the chosen lsm.\n");
if (!selinux_is_enabled()) {
pr_err("se linux is not enabled.\n");
return -ENODEV;
}
if (!selinux_is_enabled()) {
pr_err("PFE eCryptfs requires se linux to be enabled\n");
return -ENODEV;
}
return 0;

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, The Linux Foundation. All rights reserved.
* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -199,8 +199,6 @@ static struct security_hook_list pft_hooks[] = {
LSM_HOOK_INIT(file_open, pft_file_open),
LSM_HOOK_INIT(file_permission, pft_file_permission),
LSM_HOOK_INIT(file_close, pft_file_close),
LSM_HOOK_INIT(allow_merge_bio, pft_allow_merge_bio),
};
static int __init pft_lsm_init(struct pft_device *dev)
@ -211,7 +209,8 @@ static int __init pft_lsm_init(struct pft_device *dev)
dev->is_chosen_lsm = true;
pr_debug("pft is the chosen lsm, registered successfully !\n");
} else {
pr_debug("pft is not the chosen lsm.\n");
pr_err("pft is not the chosen lsm\n");
return -ENODEV;
}
return 0;

View file

@ -852,11 +852,6 @@ int security_file_open(struct file *file, const struct cred *cred)
return fsnotify_perm(file, MAY_OPEN);
}
int security_file_close(struct file *file)
{
return call_int_hook(file_close, 0, file);
}
int security_task_create(unsigned long clone_flags)
{
return call_int_hook(task_create, 0, clone_flags);

View file

@ -83,8 +83,6 @@
#include <linux/export.h>
#include <linux/msg.h>
#include <linux/shm.h>
#include <linux/pft.h>
#include <linux/pfk.h>
#include "avc.h"
#include "objsec.h"
@ -1773,15 +1771,9 @@ static int may_create(struct inode *dir,
if (rc)
return rc;
rc = avc_has_perm(newsid, sbsec->sid,
return avc_has_perm(newsid, sbsec->sid,
SECCLASS_FILESYSTEM,
FILESYSTEM__ASSOCIATE, &ad);
if (rc)
return rc;
rc = pft_inode_mknod(dir, dentry, 0, 0);
return rc;
}
/* Check whether a task can create a key. */
@ -1837,14 +1829,7 @@ static int may_link(struct inode *dir,
return 0;
}
rc = avc_has_perm(sid, isec->sid, isec->sclass, av, &ad);
if (rc)
return rc;
if (kind == MAY_UNLINK)
rc = pft_inode_unlink(dir, dentry);
return rc;
return avc_has_perm(sid, isec->sid, isec->sclass, av, &ad);
}
static inline int may_rename(struct inode *old_dir,
@ -2814,21 +2799,9 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
static int selinux_inode_create(struct inode *dir, struct dentry *dentry, umode_t mode)
{
int ret;
ret = pft_inode_create(dir, dentry, mode);
if (ret < 0)
return ret;
return may_create(dir, dentry, SECCLASS_FILE);
}
static int selinux_inode_post_create(struct inode *dir, struct dentry *dentry,
umode_t mode)
{
return pft_inode_post_create(dir, dentry, mode);
}
static int selinux_inode_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry)
{
return may_link(dir, old_dentry, MAY_LINK);
@ -2862,12 +2835,6 @@ static int selinux_inode_mknod(struct inode *dir, struct dentry *dentry, umode_t
static int selinux_inode_rename(struct inode *old_inode, struct dentry *old_dentry,
struct inode *new_inode, struct dentry *new_dentry)
{
int rc;
rc = pft_inode_rename(old_inode, old_dentry, new_inode, new_dentry);
if (rc)
return rc;
return may_rename(old_inode, old_dentry, new_inode, new_dentry);
}
@ -2992,9 +2959,6 @@ static int selinux_inode_setotherxattr(struct dentry *dentry, const char *name)
{
const struct cred *cred = current_cred();
if (pft_inode_set_xattr(dentry, name, NULL, 0, 0) < 0)
return -EACCES;
if (!strncmp(name, XATTR_SECURITY_PREFIX,
sizeof XATTR_SECURITY_PREFIX - 1)) {
if (!strcmp(name, XATTR_NAME_CAPS)) {
@ -3245,16 +3209,11 @@ static int selinux_file_permission(struct file *file, int mask)
struct file_security_struct *fsec = file->f_security;
struct inode_security_struct *isec = inode->i_security;
u32 sid = current_sid();
int ret;
if (!mask)
/* No permission to check. Existence test. */
return 0;
ret = pft_file_permission(file, mask);
if (ret < 0)
return ret;
if (sid == fsec->sid && fsec->isid == isec->sid &&
fsec->pseqno == avc_policy_seqno())
/* No change since file_open check. */
@ -3545,11 +3504,6 @@ static int selinux_file_open(struct file *file, const struct cred *cred)
{
struct file_security_struct *fsec;
struct inode_security_struct *isec;
int ret;
ret = pft_file_open(file, cred);
if (ret < 0)
return ret;
fsec = file->f_security;
isec = file_inode(file)->i_security;
@ -3573,11 +3527,6 @@ static int selinux_file_open(struct file *file, const struct cred *cred)
return file_path_has_perm(cred, file, open_file_to_av(file));
}
static int selinux_file_close(struct file *file)
{
return pft_file_close(file);
}
/* task security operations */
static int selinux_task_create(unsigned long clone_flags)
@ -5981,7 +5930,6 @@ static struct security_hook_list selinux_hooks[] = {
LSM_HOOK_INIT(inode_free_security, selinux_inode_free_security),
LSM_HOOK_INIT(inode_init_security, selinux_inode_init_security),
LSM_HOOK_INIT(inode_create, selinux_inode_create),
LSM_HOOK_INIT(inode_post_create, selinux_inode_post_create),
LSM_HOOK_INIT(inode_link, selinux_inode_link),
LSM_HOOK_INIT(inode_unlink, selinux_inode_unlink),
LSM_HOOK_INIT(inode_symlink, selinux_inode_symlink),
@ -6018,7 +5966,6 @@ static struct security_hook_list selinux_hooks[] = {
LSM_HOOK_INIT(file_receive, selinux_file_receive),
LSM_HOOK_INIT(file_open, selinux_file_open),
LSM_HOOK_INIT(file_close, selinux_file_close),
LSM_HOOK_INIT(task_create, selinux_task_create),
LSM_HOOK_INIT(cred_alloc_blank, selinux_cred_alloc_blank),