[PATCH 09/16] CacheFiles: Permit a process's create SID to be overridden [try #3]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Make it possible for a process's file creation SID to be temporarily overridden
by CacheFiles so that files created in the cache have the right label attached.

Without this facility, files created in the cache will be given the current
file creation SID of whatever process happens to have invoked CacheFiles
indirectly by means of opening a netfs file at the time the cache file is
created.

Signed-Off-By: David Howells <dhowells@xxxxxxxxxx>
---

 include/linux/security.h |   39 +++++++++++++++++++++++++++++++++++++++
 security/dummy.c         |   14 ++++++++++++++
 security/selinux/hooks.c |   20 ++++++++++++++++++++
 3 files changed, 73 insertions(+), 0 deletions(-)

diff --git a/include/linux/security.h b/include/linux/security.h
index c11dc8a..edd1677 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -1147,6 +1147,15 @@ struct request_sock;
  *	@secdata contains the security context.
  *	@seclen contains the length of the security context.
  *
+ * @get_fscreate_secid:
+ *	Get the current FS security ID.
+ *	@secid points the location in which to return the security ID.
+ *
+ * @set_fscreate_secid:
+ *	Set the current FS security ID.
+ *	@secid contains the security ID to set.
+ *	@oldsecid points the location in which to return the old security ID.
+ *
  * This is the main security structure.
  */
 struct security_operations {
@@ -1330,6 +1339,8 @@ struct security_operations {
  	int (*setprocattr)(struct task_struct *p, char *name, void *value, size_t size);
 	int (*secid_to_secctx)(u32 secid, char **secdata, u32 *seclen);
 	void (*release_secctx)(char *secdata, u32 seclen);
+	int (*get_fscreate_secid)(u32 *secid);
+	int (*set_fscreate_secid)(u32 secid, u32 *oldsecid);
 
 #ifdef CONFIG_SECURITY_NETWORK
 	int (*unix_stream_connect) (struct socket * sock,
@@ -2127,6 +2138,16 @@ static inline void security_release_secctx(char *secdata, u32 seclen)
 	return security_ops->release_secctx(secdata, seclen);
 }
 
+static inline int security_get_fscreate_secid(u32 *secid)
+{
+	return security_ops->get_fscreate_secid(secid);
+}
+
+static inline int security_set_fscreate_secid(u32 secid, u32 *oldsecid)
+{
+	return security_ops->set_fscreate_secid(secid, oldsecid);
+}
+
 /* prototypes */
 extern int security_init	(void);
 extern int register_security	(struct security_operations *ops);
@@ -2795,6 +2816,11 @@ static inline void securityfs_remove(struct dentry *dentry)
 {
 }
 
+static inline int security_to_secctx_secid(char *secdata, u32 seclen, u32 *secid)
+{
+	return -EOPNOTSUPP;
+}
+
 static inline int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
 {
 	return -EOPNOTSUPP;
@@ -2803,6 +2829,19 @@ static inline int security_secid_to_secctx(u32 secid, char **secdata, u32 *secle
 static inline void security_release_secctx(char *secdata, u32 seclen)
 {
 }
+
+static inline int security_get_fscreate_secid(u32 *secid)
+{
+	*secid = 0;
+	return 0;
+}
+
+static inline int security_set_fscreate_secid(u32 secid, u32 *oldsecid)
+{
+	*oldsecid = 0;
+	return 0;
+}
+
 #endif	/* CONFIG_SECURITY */
 
 #ifdef CONFIG_SECURITY_NETWORK
diff --git a/security/dummy.c b/security/dummy.c
index 19d813d..9e81edb 100644
--- a/security/dummy.c
+++ b/security/dummy.c
@@ -930,6 +930,18 @@ static void dummy_release_secctx(char *secdata, u32 seclen)
 {
 }
 
+static int dummy_get_fscreate_secid(u32 *secid)
+{
+	*secid = 0;
+	return 0;
+}
+
+static int dummy_set_fscreate_secid(u32 secid, u32 *oldsecid)
+{
+	*oldsecid = 0;
+	return 0;
+}
+
 #ifdef CONFIG_KEYS
 static inline int dummy_key_alloc(struct key *key, struct task_struct *ctx,
 				  unsigned long flags)
@@ -1084,6 +1096,8 @@ void security_fixup_ops (struct security_operations *ops)
  	set_to_dummy_if_null(ops, setprocattr);
  	set_to_dummy_if_null(ops, secid_to_secctx);
  	set_to_dummy_if_null(ops, release_secctx);
+ 	set_to_dummy_if_null(ops, get_fscreate_secid);
+ 	set_to_dummy_if_null(ops, set_fscreate_secid);
 #ifdef CONFIG_SECURITY_NETWORK
 	set_to_dummy_if_null(ops, unix_stream_connect);
 	set_to_dummy_if_null(ops, unix_may_send);
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 6237933..f82a03d 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -4661,6 +4661,24 @@ static void selinux_release_secctx(char *secdata, u32 seclen)
 	kfree(secdata);
 }
 
+static int selinux_get_fscreate_secid(u32 *secid)
+{
+	struct task_security_struct *tsec = current->security;
+
+	*secid = tsec->create_sid;
+	return 0;
+}
+
+static int selinux_set_fscreate_secid(u32 secid, u32 *oldsecid)
+{
+	struct task_security_struct *tsec = current->security;
+	u32 oldsid = tsec->create_sid;
+
+	tsec->create_sid = secid;
+	*oldsecid = oldsid;
+	return 0;
+}
+
 #ifdef CONFIG_KEYS
 
 static int selinux_key_alloc(struct key *k, struct task_struct *tsk,
@@ -4843,6 +4861,8 @@ static struct security_operations selinux_ops = {
 
 	.secid_to_secctx =		selinux_secid_to_secctx,
 	.release_secctx =		selinux_release_secctx,
+	.get_fscreate_secid =		selinux_get_fscreate_secid,
+	.set_fscreate_secid =		selinux_set_fscreate_secid,
 
         .unix_stream_connect =		selinux_socket_unix_stream_connect,
 	.unix_may_send =		selinux_socket_unix_may_send,

-
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]
  Powered by Linux