@@ -2095,13 +2095,11 @@ void __init loadpin_add_hooks(void);
static inline void loadpin_add_hooks(void) { };
#endif
-extern int lsm_cred_alloc(struct cred *cred, gfp_t gfp);
extern int lsm_inode_alloc(struct inode *inode);
#ifdef CONFIG_SECURITY
-void lsm_early_cred(struct cred *cred);
-void lsm_early_inode(struct inode *inode);
-void lsm_early_task(struct task_struct *task);
+void __init lsm_early_cred(struct cred *cred);
+void __init lsm_early_task(struct task_struct *task);
#endif
#endif /* ! __LINUX_LSM_HOOKS_H */
@@ -267,7 +267,7 @@ EXPORT_SYMBOL(unregister_lsm_notifier);
*
* Returns 0, or -ENOMEM if memory can't be allocated.
*/
-int lsm_cred_alloc(struct cred *cred, gfp_t gfp)
+static int lsm_cred_alloc(struct cred *cred, gfp_t gfp)
{
if (blob_sizes.lbs_cred == 0) {
cred->security = NULL;
@@ -286,7 +286,7 @@ int lsm_cred_alloc(struct cred *cred, gfp_t gfp)
*
* Allocate the cred blob for all the modules if it's not already there
*/
-void lsm_early_cred(struct cred *cred)
+void __init lsm_early_cred(struct cred *cred)
{
int rc;
@@ -344,7 +344,7 @@ void __init security_add_blobs(struct lsm_blob_sizes *needed)
*
* Returns 0, or -ENOMEM if memory can't be allocated.
*/
-int lsm_file_alloc(struct file *file)
+static int lsm_file_alloc(struct file *file)
{
if (!lsm_file_cache) {
file->f_security = NULL;
@@ -378,25 +378,6 @@ int lsm_inode_alloc(struct inode *inode)
return 0;
}
-/**
- * lsm_early_inode - during initialization allocate a composite inode blob
- * @inode: the inode that needs a blob
- *
- * Allocate the inode blob for all the modules if it's not already there
- */
-void lsm_early_inode(struct inode *inode)
-{
- int rc;
-
- if (inode == NULL)
- panic("%s: NULL inode.\n", __func__);
- if (inode->i_security != NULL)
- return;
- rc = lsm_inode_alloc(inode);
- if (rc)
- panic("%s: Early inode alloc failed.\n", __func__);
-}
-
/**
* lsm_task_alloc - allocate a composite task blob
* @task: the task that needs a blob
@@ -466,7 +447,7 @@ int lsm_msg_msg_alloc(struct msg_msg *mp)
*
* Allocate the task blob for all the modules if it's not already there
*/
-void lsm_early_task(struct task_struct *task)
+void __init lsm_early_task(struct task_struct *task)
{
int rc;
@@ -332,8 +332,11 @@ static struct inode_security_struct *backing_inode_security(struct dentry *dentr
static void inode_free_security(struct inode *inode)
{
struct inode_security_struct *isec = selinux_inode(inode);
- struct superblock_security_struct *sbsec = inode->i_sb->s_security;
+ struct superblock_security_struct *sbsec;
+ if (!isec)
+ return;
+ sbsec = inode->i_sb->s_security;
/*
* As not all inode security structures are in a list, we check for
* empty list outside of the lock to make sure that we won't waste
@@ -180,6 +180,8 @@ static inline struct inode_security_struct *selinux_inode(
const struct inode *inode)
{
#ifdef CONFIG_SECURITY_STACKING
+ if (unlikely(!inode->i_security))
+ return NULL;
return inode->i_security + selinux_blob_sizes.lbs_inode;
#else
return inode->i_security;
@@ -750,6 +750,13 @@ static int smack_set_mnt_opts(struct super_block *sb,
if (sp->smk_flags & SMK_SB_INITIALIZED)
return 0;
+ if (inode->i_security == NULL) {
+ int rc = lsm_inode_alloc(inode);
+
+ if (rc)
+ return rc;
+ }
+
if (!smack_privileged(CAP_MAC_ADMIN)) {
/*
* Unprivileged mounts don't get to specify Smack values.
@@ -818,7 +825,6 @@ static int smack_set_mnt_opts(struct super_block *sb,
/*
* Initialize the root inode.
*/
- lsm_early_inode(inode);
init_inode_smack(inode, sp->smk_root);
if (transmute) {
lsm_early_cred()/lsm_early_task() are called from only __init functions. lsm_cred_alloc()/lsm_file_alloc() are called from only security/security.c . lsm_early_inode() should be avoided because it is not appropriate to call panic() when lsm_early_inode() is called after __init phase. Since all free hooks are called when one of init hooks failed, each free hook needs to check whether init hook was called. The original changes are from Tetsuo Handa. I have made minor changes in some places, but this is mostly his code. Signed-off-by: Casey Schaufler <casey@schaufler-ca.com> --- include/linux/lsm_hooks.h | 6 ++---- security/security.c | 27 ++++----------------------- security/selinux/hooks.c | 5 ++++- security/selinux/include/objsec.h | 2 ++ security/smack/smack_lsm.c | 8 +++++++- 5 files changed, 19 insertions(+), 29 deletions(-)