summaryrefslogtreecommitdiff
path: root/security
diff options
context:
space:
mode:
Diffstat (limited to 'security')
-rw-r--r--security/dummy.c7
-rw-r--r--security/selinux/hooks.c59
-rw-r--r--security/selinux/include/objsec.h1
3 files changed, 67 insertions, 0 deletions
diff --git a/security/dummy.c b/security/dummy.c
index 6ff887586479..e8a00fa80469 100644
--- a/security/dummy.c
+++ b/security/dummy.c
@@ -258,6 +258,12 @@ static void dummy_inode_free_security (struct inode *inode)
return;
}
+static int dummy_inode_init_security (struct inode *inode, struct inode *dir,
+ char **name, void **value, size_t *len)
+{
+ return -EOPNOTSUPP;
+}
+
static int dummy_inode_create (struct inode *inode, struct dentry *dentry,
int mask)
{
@@ -886,6 +892,7 @@ void security_fixup_ops (struct security_operations *ops)
set_to_dummy_if_null(ops, sb_post_pivotroot);
set_to_dummy_if_null(ops, inode_alloc_security);
set_to_dummy_if_null(ops, inode_free_security);
+ set_to_dummy_if_null(ops, inode_init_security);
set_to_dummy_if_null(ops, inode_create);
set_to_dummy_if_null(ops, inode_post_create);
set_to_dummy_if_null(ops, inode_link);
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 8641f8894b4c..63701fe0e1ad 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -1274,6 +1274,7 @@ static int post_create(struct inode *dir,
struct inode *inode;
struct inode_security_struct *dsec;
struct superblock_security_struct *sbsec;
+ struct inode_security_struct *isec;
u32 newsid;
char *context;
unsigned int len;
@@ -1293,6 +1294,11 @@ static int post_create(struct inode *dir,
return 0;
}
+ isec = inode->i_security;
+
+ if (isec->security_attr_init)
+ return 0;
+
if (tsec->create_sid && sbsec->behavior != SECURITY_FS_USE_MNTPOINT) {
newsid = tsec->create_sid;
} else {
@@ -2018,6 +2024,58 @@ static void selinux_inode_free_security(struct inode *inode)
inode_free_security(inode);
}
+static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
+ char **name, void **value,
+ size_t *len)
+{
+ struct task_security_struct *tsec;
+ struct inode_security_struct *dsec;
+ struct superblock_security_struct *sbsec;
+ struct inode_security_struct *isec;
+ u32 newsid;
+ int rc;
+ char *namep, *context;
+
+ tsec = current->security;
+ dsec = dir->i_security;
+ sbsec = dir->i_sb->s_security;
+ isec = inode->i_security;
+
+ if (tsec->create_sid && sbsec->behavior != SECURITY_FS_USE_MNTPOINT) {
+ newsid = tsec->create_sid;
+ } else {
+ rc = security_transition_sid(tsec->sid, dsec->sid,
+ inode_mode_to_security_class(inode->i_mode),
+ &newsid);
+ if (rc) {
+ printk(KERN_WARNING "%s: "
+ "security_transition_sid failed, rc=%d (dev=%s "
+ "ino=%ld)\n",
+ __FUNCTION__,
+ -rc, inode->i_sb->s_id, inode->i_ino);
+ return rc;
+ }
+ }
+
+ inode_security_set_sid(inode, newsid);
+
+ namep = kstrdup(XATTR_SELINUX_SUFFIX, GFP_KERNEL);
+ if (!namep)
+ return -ENOMEM;
+ *name = namep;
+
+ rc = security_sid_to_context(newsid, &context, len);
+ if (rc) {
+ kfree(namep);
+ return rc;
+ }
+ *value = context;
+
+ isec->security_attr_init = 1;
+
+ return 0;
+}
+
static int selinux_inode_create(struct inode *dir, struct dentry *dentry, int mask)
{
return may_create(dir, dentry, SECCLASS_FILE);
@@ -4298,6 +4356,7 @@ static struct security_operations selinux_ops = {
.inode_alloc_security = selinux_inode_alloc_security,
.inode_free_security = selinux_inode_free_security,
+ .inode_init_security = selinux_inode_init_security,
.inode_create = selinux_inode_create,
.inode_post_create = selinux_inode_post_create,
.inode_link = selinux_inode_link,
diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h
index 887937c8134a..c515bc0b58a1 100644
--- a/security/selinux/include/objsec.h
+++ b/security/selinux/include/objsec.h
@@ -46,6 +46,7 @@ struct inode_security_struct {
unsigned char initialized; /* initialization flag */
struct semaphore sem;
unsigned char inherit; /* inherit SID from parent entry */
+ unsigned char security_attr_init; /* security attributes init flag */
};
struct file_security_struct {