linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC v3] Security Label Support for NFSv4
@ 2008-09-29 17:06 David P. Quigley
  2008-09-29 17:06 ` [PATCH 01/14] VFS: Factor out part of vfs_setxattr so it can be called from the SELinux hook for inode_setsecctx David P. Quigley
                   ` (9 more replies)
  0 siblings, 10 replies; 24+ messages in thread
From: David P. Quigley @ 2008-09-29 17:06 UTC (permalink / raw)
  To: hch, viro, casey, sds, matthew.dodd, trond.myklebust, bfields
  Cc: linux-kernel, linux-fsdevel, linux-security-module, selinux, labeled-nfs


I sent this patchset out just before LPC so I think it might have been
overlooked by some people. I am resending the patchset with some corrections
based on comments by Casey and Steve in hopes that it gets more attention this
time.

It has been six months since the last time we submitted a patch set to the
mailing list for review. In this time we have fixed almost all of the issues
that people have had with the last patch set and have added a new feature to
allow for process labels to be transported with the RPC request. Below I
review each of the issues raised with the last patch set and what was done to
fix them. I also list the features present in this patch set and known issues.

When reviewing the code please be critical of it. We have reached the point
where we think we have the proper set of initial features implemented so we
would like to address all of the major and minor concerns with the code so it
can be cleaned up and submitted for inclusion. If you want a tree with the
patches already applied we have posted a public git tree that is ready for
cloning and use. This tree can be found at http://git.selinuxproject.org/git
and can be cloned with the command below. You can also find information on how
to setup a labeled nfs mount at http://www.selinuxproject.org/page/Labeled_NFS
however the putclientlabel mount option specified in the setup document is no
longer supported.

git-clone git://git.selinuxproject.org/~dpquigl/lnfs.git

Features:

* Client
	* Obtains labels from server for NFS files while still allowing for
	SELinux context mounts to override untrusted labeled servers.
	* Allows setting labels on files over NFS via xattr interface.
	* New security flavor (auth_seclabel) to transport process label to
	  server. This is a derivative of auth_unix so it does not support
	  kerberos which has its own issues that need to be dealt with.
* Server
	* Exports labels to clients. As of the moment there is no ability to
	restrict this based on label components such as MLS levels.
	* Persistent storage of labels assuming exported file system supports
	it.
	* If present uses process label for permission checks on server. Only
	effective if both client and server are running the same MAC model and
	policy. This will be addressed later by the label translation work.

Known Limitations/Bugs

If you want to utilize process label transport and file labels properly each
side must implement the same MAC model and be running the same policy. It is
possible for two SELinux systems to talk to each other if they have different
policies however from a policy perspective you can't be guaranteed that a type
on the client means the same thing on the server. Work is being done on
providing a DOI translation framework but is currently on the back burner so
work can be done to polish up this prototype and work on the IETF documents.

Concerns from last submission:

The patch to add maclabel_getname has been removed and replaced with the
{get,set,notify}secctx hooks that were discussed on the mailing list.

The use of the iattr structure to pass label data up and down the call stack
has been replace with a method that mimics the NFSv4 ACL implementation. A new
structure nfs4_label has been added and is added to the necessary functions to
pass the data around. 

Andrew's request to make the name and value pointers to the vfs helper for
setxattr const has been addressed.

The lifecycle management patch for the fattr structure has not been addressed
because it will probably be replaced with a method similar to what we did to
fix the iattr problem. Also the maximum label size has been set at 4096. I
know there are some concerns with hard limits on label size but Trond and
Bruce have brought up issues with doing memory reallocation inside of the XDR
handlers. Since it isn't appropriate to realloc memory there and there is no
effective retry capability if the buffer isn't large enough this doesn't seem
like an option.

The mount code has been changed to use Eric Paris's new security parameter
and now it uses the new text based mount system.

---

 fs/Kconfig                          |   17 ++
 fs/nfs/client.c                     |   18 ++-
 fs/nfs/dir.c                        |   24 ++
 fs/nfs/getroot.c                    |   34 +++
 fs/nfs/inode.c                      |   61 +++++-
 fs/nfs/namespace.c                  |    3 +
 fs/nfs/nfs3proc.c                   |   10 +
 fs/nfs/nfs4proc.c                   |  447 +++++++++++++++++++++++++++++++---
 fs/nfs/nfs4xdr.c                    |   56 ++++-
 fs/nfs/proc.c                       |   12 +-
 fs/nfs/super.c                      |   29 +++-
 fs/nfsd/auth.c                      |   21 ++
 fs/nfsd/export.c                    |    3 +
 fs/nfsd/nfs4proc.c                  |   25 ++-
 fs/nfsd/nfs4xdr.c                   |  101 ++++++++-
 fs/nfsd/vfs.c                       |   22 ++
 fs/xattr.c                          |   55 ++++-
 include/linux/nfs4.h                |    8 +
 include/linux/nfs4_mount.h          |    8 +-
 include/linux/nfs_fs.h              |   48 ++++
 include/linux/nfs_fs_sb.h           |    2 +-
 include/linux/nfs_xdr.h             |    7 +
 include/linux/nfsd/export.h         |    5 +-
 include/linux/nfsd/nfsd.h           |    9 +-
 include/linux/nfsd/xdr4.h           |    3 +
 include/linux/security.h            |   75 ++++++
 include/linux/sunrpc/auth.h         |    4 +
 include/linux/sunrpc/msg_prot.h     |    1 +
 include/linux/sunrpc/svcauth.h      |    4 +
 include/linux/xattr.h               |    1 +
 net/sunrpc/Makefile                 |    1 +
 net/sunrpc/auth.c                   |   16 ++
 net/sunrpc/auth_seclabel.c          |  291 +++++++++++++++++++++++
 net/sunrpc/svc.c                    |    1 +
 net/sunrpc/svcauth.c                |    6 +
 net/sunrpc/svcauth_unix.c           |   97 ++++++++-
 security/security.c                 |   34 +++
 security/selinux/hooks.c            |  148 ++++++++++--
 security/selinux/include/security.h |    4 +
 security/selinux/ss/policydb.c      |    5 +-
 security/smack/smack_lsm.c          |   11 +
 41 files changed, 1627 insertions(+), 100 deletions(-)


^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH 01/14] VFS: Factor out part of vfs_setxattr so it can be called from the SELinux hook for inode_setsecctx.
  2008-09-29 17:06 [RFC v3] Security Label Support for NFSv4 David P. Quigley
@ 2008-09-29 17:06 ` David P. Quigley
  2008-09-30 19:51   ` Serge E. Hallyn
  2008-09-29 17:06 ` [PATCH 05/14] SELinux: Add new labeling type native labels David P. Quigley
                   ` (8 subsequent siblings)
  9 siblings, 1 reply; 24+ messages in thread
From: David P. Quigley @ 2008-09-29 17:06 UTC (permalink / raw)
  To: hch, viro, casey, sds, matthew.dodd, trond.myklebust, bfields
  Cc: linux-kernel, linux-fsdevel, linux-security-module, selinux,
	labeled-nfs, David P. Quigley, Matthew N. Dodd

This factors out the part of the vfs_setxattr function that performs the
setting of the xattr and its notification. This is needed so the SELinux
implementation of inode_setsecctx can handle the setting of it's xattr while
maintaining the proper separation of layers.

Signed-off-by: Matthew N. Dodd <Matthew.Dodd@sparta.com>
Signed-off-by: David P. Quigley <dpquigl@tycho.nsa.gov>
---
 fs/xattr.c            |   55 +++++++++++++++++++++++++++++++++++++-----------
 include/linux/xattr.h |    1 +
 2 files changed, 43 insertions(+), 13 deletions(-)

diff --git a/fs/xattr.c b/fs/xattr.c
index 468377e..2f93006 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -66,22 +66,28 @@ xattr_permission(struct inode *inode, const char *name, int mask)
 	return inode_permission(inode, mask);
 }
 
-int
-vfs_setxattr(struct dentry *dentry, const char *name, const void *value,
-		size_t size, int flags)
+/**
+ *  __vfs_setxattr_noperm - perform setxattr operation without performing
+ *  permission checks.
+ *
+ *  @dentry - object to perform setxattr on
+ *  @name - xattr name to set
+ *  @value - value to set @name to
+ *  @size - size of @value
+ *  @flags - flags to pass into filesystem operations
+ *
+ *  returns the result of the internal setxattr or setsecurity operations.
+ *
+ *  This function requires the caller to lock the inode's i_mutex before it
+ *  is executed. It also assumes that the caller will make the appropriate
+ *  permission checks.
+ */
+int __vfs_setxattr_noperm(struct dentry *dentry, const char *name,
+		const void *value, size_t size, int flags)
 {
 	struct inode *inode = dentry->d_inode;
-	int error;
-
-	error = xattr_permission(inode, name, MAY_WRITE);
-	if (error)
-		return error;
+	int error = -EOPNOTSUPP;
 
-	mutex_lock(&inode->i_mutex);
-	error = security_inode_setxattr(dentry, name, value, size, flags);
-	if (error)
-		goto out;
-	error = -EOPNOTSUPP;
 	if (inode->i_op->setxattr) {
 		error = inode->i_op->setxattr(dentry, name, value, size, flags);
 		if (!error) {
@@ -97,6 +103,29 @@ vfs_setxattr(struct dentry *dentry, const char *name, const void *value,
 		if (!error)
 			fsnotify_xattr(dentry);
 	}
+
+	return error;
+}
+
+
+int
+vfs_setxattr(struct dentry *dentry, const char *name, const void *value,
+		size_t size, int flags)
+{
+	struct inode *inode = dentry->d_inode;
+	int error;
+
+	error = xattr_permission(inode, name, MAY_WRITE);
+	if (error)
+		return error;
+
+	mutex_lock(&inode->i_mutex);
+	error = security_inode_setxattr(dentry, name, value, size, flags);
+	if (error)
+		goto out;
+
+	error = __vfs_setxattr_noperm(dentry, name, value, size, flags);
+
 out:
 	mutex_unlock(&inode->i_mutex);
 	return error;
diff --git a/include/linux/xattr.h b/include/linux/xattr.h
index d131e35..5c84af8 100644
--- a/include/linux/xattr.h
+++ b/include/linux/xattr.h
@@ -49,6 +49,7 @@ struct xattr_handler {
 ssize_t xattr_getsecurity(struct inode *, const char *, void *, size_t);
 ssize_t vfs_getxattr(struct dentry *, const char *, void *, size_t);
 ssize_t vfs_listxattr(struct dentry *d, char *list, size_t size);
+int __vfs_setxattr_noperm(struct dentry *, const char *, const void *, size_t, int);
 int vfs_setxattr(struct dentry *, const char *, const void *, size_t, int);
 int vfs_removexattr(struct dentry *, const char *);
 
-- 
1.5.5.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 05/14] SELinux: Add new labeling type native labels
  2008-09-29 17:06 [RFC v3] Security Label Support for NFSv4 David P. Quigley
  2008-09-29 17:06 ` [PATCH 01/14] VFS: Factor out part of vfs_setxattr so it can be called from the SELinux hook for inode_setsecctx David P. Quigley
@ 2008-09-29 17:06 ` David P. Quigley
  2008-09-29 17:06 ` [PATCH 06/14] KConfig: Add KConfig entries for Labeled NFS David P. Quigley
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 24+ messages in thread
From: David P. Quigley @ 2008-09-29 17:06 UTC (permalink / raw)
  To: hch, viro, casey, sds, matthew.dodd, trond.myklebust, bfields
  Cc: linux-kernel, linux-fsdevel, linux-security-module, selinux,
	labeled-nfs, David P. Quigley, Matthew N. Dodd

There currently doesn't exist a labeling type that is adequate for use with
labeled NFS. Since NFS doesn't really support xattrs we can't use the use xattr
labeling behavior. For this we developed a new labeling type. The native
labeling type is used solely by NFS to ensure NFS inodes are labeled at runtime
by the NFS code instead of relying on the SELinux security server on the client
end.

Signed-off-by: Matthew N. Dodd <Matthew.Dodd@sparta.com>
Signed-off-by: David P. Quigley <dpquigl@tycho.nsa.gov>
---
 security/selinux/hooks.c            |   74 +++++++++++++++++++++++++++-------
 security/selinux/include/security.h |    4 ++
 security/selinux/ss/policydb.c      |    5 ++-
 3 files changed, 66 insertions(+), 17 deletions(-)

diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 248fa5c..78e79d3 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -88,7 +88,7 @@
 #define XATTR_SELINUX_SUFFIX "selinux"
 #define XATTR_NAME_SELINUX XATTR_SECURITY_PREFIX XATTR_SELINUX_SUFFIX
 
-#define NUM_SEL_MNT_OPTS 4
+#define NUM_SEL_MNT_OPTS 5
 
 extern unsigned int policydb_loaded_version;
 extern int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm);
@@ -300,13 +300,14 @@ extern int ss_initialized;
 
 /* The file system's label must be initialized prior to use. */
 
-static char *labeling_behaviors[6] = {
+static char *labeling_behaviors[7] = {
 	"uses xattr",
 	"uses transition SIDs",
 	"uses task SIDs",
 	"uses genfs_contexts",
 	"not configured for labeling",
 	"uses mountpoint labeling",
+	"uses native labels",
 };
 
 static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dentry);
@@ -322,6 +323,7 @@ enum {
 	Opt_fscontext = 2,
 	Opt_defcontext = 3,
 	Opt_rootcontext = 4,
+	Opt_native_labels = 5,
 };
 
 static match_table_t tokens = {
@@ -329,6 +331,7 @@ static match_table_t tokens = {
 	{Opt_fscontext, FSCONTEXT_STR "%s"},
 	{Opt_defcontext, DEFCONTEXT_STR "%s"},
 	{Opt_rootcontext, ROOTCONTEXT_STR "%s"},
+	{Opt_native_labels, NATIVELABELS_STR},
 	{Opt_error, NULL},
 };
 
@@ -516,6 +519,10 @@ static int selinux_get_mnt_opts(const struct super_block *sb,
 		opts->mnt_opts[i] = context;
 		opts->mnt_opts_flags[i++] = ROOTCONTEXT_MNT;
 	}
+	if (sbsec->flags == NATIVE_LABELS_MNT) {
+		opts->mnt_opts[i] = NULL;
+		opts->mnt_opts_flags[i++] = NATIVE_LABELS_MNT;
+	}
 
 	BUG_ON(i != opts->num_mnt_opts);
 
@@ -604,12 +611,16 @@ static int selinux_set_mnt_opts(struct super_block *sb,
 	 */
 	for (i = 0; i < num_opts; i++) {
 		u32 sid;
+		if (flags[i] == NATIVE_LABELS_MNT) {
+			sbsec->flags | = NATIVE_LABELS_MNT;
+			continue;
+		}
 		rc = security_context_to_sid(mount_options[i],
-					     strlen(mount_options[i]), &sid);
+				strlen(mount_options[i]), &sid);
 		if (rc) {
 			printk(KERN_WARNING "SELinux: security_context_to_sid"
-			       "(%s) failed for (dev %s, type %s) errno=%d\n",
-			       mount_options[i], sb->s_id, name, rc);
+					"(%s) failed for (dev %s, type %s) errno=%d\n",
+					mount_options[i], sb->s_id, name, rc);
 			goto out;
 		}
 		switch (flags[i]) {
@@ -668,14 +679,15 @@ static int selinux_set_mnt_opts(struct super_block *sb,
 	if (strcmp(sb->s_type->name, "proc") == 0)
 		sbsec->proc = 1;
 
-	/* Determine the labeling behavior to use for this filesystem type. */
-	rc = security_fs_use(sb->s_type->name, &sbsec->behavior, &sbsec->sid);
-	if (rc) {
-		printk(KERN_WARNING "%s: security_fs_use(%s) returned %d\n",
-		       __func__, sb->s_type->name, rc);
-		goto out;
+	if (!sbsec->behavior) {
+		/* Determine the labeling behavior to use for this filesystem type. */
+		rc = security_fs_use(sb->s_type->name, &sbsec->behavior, &sbsec->sid);
+		if (rc) {
+			printk(KERN_WARNING "%s: security_fs_use(%s) returned %d\n",
+					__func__, sb->s_type->name, rc);
+			goto out;
+		}
 	}
-
 	/* sets the context of the superblock for the fs being mounted. */
 	if (fscontext_sid) {
 
@@ -691,6 +703,11 @@ static int selinux_set_mnt_opts(struct super_block *sb,
 	 * sets the label used on all file below the mountpoint, and will set
 	 * the superblock context if not already set.
 	 */
+	/* NATIVE_LABELS can be overridden by 'context=' mounts, below. */
+	if (sbsec->flags & NATIVE_LABELS_MNT) {
+		sbsec->behavior = SECURITY_FS_USE_NATIVE;
+	}
+
 	if (context_sid) {
 		if (!fscontext_sid) {
 			rc = may_context_mount_sb_relabel(context_sid, sbsec, tsec);
@@ -707,6 +724,7 @@ static int selinux_set_mnt_opts(struct super_block *sb,
 
 		sbsec->mntpoint_sid = context_sid;
 		sbsec->behavior = SECURITY_FS_USE_MNTPOINT;
+		sbsec->flags &= ~NATIVE_LABELS_MNT; /* Exclusive */
 	}
 
 	if (rootcontext_sid) {
@@ -719,7 +737,8 @@ static int selinux_set_mnt_opts(struct super_block *sb,
 	}
 
 	if (defcontext_sid) {
-		if (sbsec->behavior != SECURITY_FS_USE_XATTR) {
+		if (sbsec->behavior != SECURITY_FS_USE_XATTR &&
+			sbsec->behavior != SECURITY_FS_USE_NATIVE) {
 			rc = -EINVAL;
 			printk(KERN_WARNING "SELinux: defcontext option is "
 			       "invalid for this filesystem type\n");
@@ -816,6 +835,7 @@ static int selinux_parse_opts_str(char *options,
 	char *p;
 	char *context = NULL, *defcontext = NULL;
 	char *fscontext = NULL, *rootcontext = NULL;
+	int native_labels = 0;
 	int rc, num_mnt_opts = 0;
 
 	opts->num_mnt_opts = 0;
@@ -883,9 +903,15 @@ static int selinux_parse_opts_str(char *options,
 			}
 			break;
 
+		case Opt_native_labels:
+			printk("%s() got Opt_native_labels\n", __func__);
+			native_labels = 1;
+			break;
+
+
 		default:
 			rc = -EINVAL;
-			printk(KERN_WARNING "SELinux:  unknown mount option\n");
+			printk(KERN_WARNING "SELinux: unknown mount option \"%s\"\n", p);
 			goto out_err;
 
 		}
@@ -918,6 +944,10 @@ static int selinux_parse_opts_str(char *options,
 		opts->mnt_opts[num_mnt_opts] = defcontext;
 		opts->mnt_opts_flags[num_mnt_opts++] = DEFCONTEXT_MNT;
 	}
+	if (native_labels) {
+		opts->mnt_opts[num_mnt_opts] = NULL;
+		opts->mnt_opts_flags[num_mnt_opts++] = NATIVE_LABELS_MNT;
+	}
 
 	opts->num_mnt_opts = num_mnt_opts;
 	return 0;
@@ -963,7 +993,12 @@ void selinux_write_opts(struct seq_file *m, struct security_mnt_opts *opts)
 	char *prefix;
 
 	for (i = 0; i < opts->num_mnt_opts; i++) {
-		char *has_comma = strchr(opts->mnt_opts[i], ',');
+		char *has_comma;
+
+		if (opts->mnt_opts[i])
+			has_comma = strchr(opts->mnt_opts[i], ',');
+		else
+			has_comma = NULL;
 
 		switch (opts->mnt_opts_flags[i]) {
 		case CONTEXT_MNT:
@@ -978,6 +1013,10 @@ void selinux_write_opts(struct seq_file *m, struct security_mnt_opts *opts)
 		case DEFCONTEXT_MNT:
 			prefix = DEFCONTEXT_STR;
 			break;
+		case NATIVE_LABELS_MNT:
+			seq_putc(m, ',');
+			seq_puts(m, NATIVELABELS_STR);
+			continue;
 		default:
 			BUG();
 		};
@@ -1185,6 +1224,8 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
 	}
 
 	switch (sbsec->behavior) {
+	case SECURITY_FS_USE_NATIVE:
+		break;
 	case SECURITY_FS_USE_XATTR:
 		if (!inode->i_op->getxattr) {
 			isec->sid = sbsec->def_sid;
@@ -2360,7 +2401,8 @@ static inline int selinux_option(char *option, int len)
 	return (match_prefix(CONTEXT_STR, sizeof(CONTEXT_STR)-1, option, len) ||
 		match_prefix(FSCONTEXT_STR, sizeof(FSCONTEXT_STR)-1, option, len) ||
 		match_prefix(DEFCONTEXT_STR, sizeof(DEFCONTEXT_STR)-1, option, len) ||
-		match_prefix(ROOTCONTEXT_STR, sizeof(ROOTCONTEXT_STR)-1, option, len));
+		match_prefix(ROOTCONTEXT_STR, sizeof(ROOTCONTEXT_STR)-1, option, len) ||
+		match_prefix(NATIVELABELS_STR, sizeof(NATIVELABELS_STR)-1, option, len));
 }
 
 static inline void take_option(char **to, char *from, int *first, int len)
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index 7c54300..effe060 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -40,11 +40,13 @@
 #define FSCONTEXT_MNT	0x02
 #define ROOTCONTEXT_MNT	0x04
 #define DEFCONTEXT_MNT	0x08
+#define	NATIVE_LABELS_MNT	0x10
 
 #define CONTEXT_STR	"context="
 #define FSCONTEXT_STR	"fscontext="
 #define ROOTCONTEXT_STR	"rootcontext="
 #define DEFCONTEXT_STR	"defcontext="
+#define NATIVELABELS_STR "native_labels"
 
 struct netlbl_lsm_secattr;
 
@@ -134,6 +136,8 @@ int security_get_allow_unknown(void);
 #define SECURITY_FS_USE_GENFS		4 /* use the genfs support */
 #define SECURITY_FS_USE_NONE		5 /* no labeling support */
 #define SECURITY_FS_USE_MNTPOINT	6 /* use mountpoint labeling */
+#define SECURITY_FS_USE_NATIVE		7 /* use native label support */
+#define SECURITY_FS_USE_MAX		7 /* Highest SECURITY_FS_USE_XXX */
 
 int security_fs_use(const char *fstype, unsigned int *behavior,
 	u32 *sid);
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index 2391761..4740a5a 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -1764,7 +1764,10 @@ int policydb_read(struct policydb *p, void *fp)
 				if (rc < 0)
 					goto bad;
 				c->v.behavior = le32_to_cpu(buf[0]);
-				if (c->v.behavior > SECURITY_FS_USE_NONE)
+				/* Determined at runtime, not in policy DB. */
+				if (c->v.behavior == SECURITY_FS_USE_MNTPOINT)
+					goto bad;
+				if (c->v.behavior > SECURITY_FS_USE_MAX)
 					goto bad;
 				len = le32_to_cpu(buf[1]);
 				c->u.name = kmalloc(len + 1, GFP_KERNEL);
-- 
1.5.5.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 06/14] KConfig: Add KConfig entries for Labeled NFS
  2008-09-29 17:06 [RFC v3] Security Label Support for NFSv4 David P. Quigley
  2008-09-29 17:06 ` [PATCH 01/14] VFS: Factor out part of vfs_setxattr so it can be called from the SELinux hook for inode_setsecctx David P. Quigley
  2008-09-29 17:06 ` [PATCH 05/14] SELinux: Add new labeling type native labels David P. Quigley
@ 2008-09-29 17:06 ` David P. Quigley
  2008-09-30 20:40   ` Serge E. Hallyn
  2008-09-29 17:06 ` [PATCH 08/14] NFS: Add security_label text mount option and handling code to NFS David P. Quigley
                   ` (6 subsequent siblings)
  9 siblings, 1 reply; 24+ messages in thread
From: David P. Quigley @ 2008-09-29 17:06 UTC (permalink / raw)
  To: hch, viro, casey, sds, matthew.dodd, trond.myklebust, bfields
  Cc: linux-kernel, linux-fsdevel, linux-security-module, selinux,
	labeled-nfs, David P. Quigley, Matthew N. Dodd

This patch adds two entries into the fs/KConfig file. The first entry
NFS_V4_SECURITY_LABEL enables security label support for the NFSv4 client while
the second entry NFSD_V4_SECURITY_LABEL enables security labeling support on
the server side.

Signed-off-by: Matthew N. Dodd <Matthew.Dodd@sparta.com>
Signed-off-by: David P. Quigley <dpquigl@tycho.nsa.gov>
---
 fs/Kconfig |   17 +++++++++++++++++
 1 files changed, 17 insertions(+), 0 deletions(-)

diff --git a/fs/Kconfig b/fs/Kconfig
index abccb5d..47ffb42 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -1633,6 +1633,7 @@ config NFS_V4
 
 	  If unsure, say N.
 
+
 config ROOT_NFS
 	bool "Root file system on NFS"
 	depends on NFS_FS=y && IP_PNP
@@ -1644,6 +1645,15 @@ config ROOT_NFS
 
 	  Most people say N here.
 
+config NFS_V4_SECURITY_LABEL
+	bool "Provide Security Label support for NFSv4 client"
+	depends on NFS_V4 && SECURITY
+	help
+	  Say Y here if you want label attribute support for NFS version 4.
+
+
+	  If unsure, say N.
+
 config NFSD
 	tristate "NFS server support"
 	depends on INET
@@ -1725,6 +1735,13 @@ config NFSD_V4
 
 	  If unsure, say N.
 
+config NFSD_V4_SECURITY_LABEL
+	bool "Provide Security Label support for NFSv4 server"
+	depends on NFSD_V4 && SECURITY
+	help
+	  If you would like to include support for label file attributes
+	  over NFSv4, say Y here.
+
 config LOCKD
 	tristate
 
-- 
1.5.5.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 08/14] NFS: Add security_label text mount option and handling code to NFS
  2008-09-29 17:06 [RFC v3] Security Label Support for NFSv4 David P. Quigley
                   ` (2 preceding siblings ...)
  2008-09-29 17:06 ` [PATCH 06/14] KConfig: Add KConfig entries for Labeled NFS David P. Quigley
@ 2008-09-29 17:06 ` David P. Quigley
  2008-09-29 17:06 ` [PATCH 10/14] NFSv4: Introduce new label structure David P. Quigley
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 24+ messages in thread
From: David P. Quigley @ 2008-09-29 17:06 UTC (permalink / raw)
  To: hch, viro, casey, sds, matthew.dodd, trond.myklebust, bfields
  Cc: linux-kernel, linux-fsdevel, linux-security-module, selinux,
	labeled-nfs, David P. Quigley, Matthew N. Dodd

This patch adds two new text options to to the NFS mount options to specify
security labeling. It also sends certain LSM related mount options into the
module for handling.

Signed-off-by: Matthew N. Dodd <Matthew.Dodd@sparta.com>
Signed-off-by: David P. Quigley <dpquigl@tycho.nsa.gov>
---
 fs/nfs/super.c             |    9 +++++++++
 include/linux/nfs4_mount.h |    6 +++++-
 security/selinux/hooks.c   |    2 +-
 3 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 9abcd2b..256ce27 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -75,6 +75,7 @@ enum {
 	Opt_acl, Opt_noacl,
 	Opt_rdirplus, Opt_nordirplus,
 	Opt_sharecache, Opt_nosharecache,
+	Opt_security_label, Opt_nosecurity_label,
 
 	/* Mount options that take integer arguments */
 	Opt_port,
@@ -128,6 +129,8 @@ static match_table_t nfs_mount_option_tokens = {
 	{ Opt_nordirplus, "nordirplus" },
 	{ Opt_sharecache, "sharecache" },
 	{ Opt_nosharecache, "nosharecache" },
+	{ Opt_security_label, "security_label" },
+	{ Opt_nosecurity_label, "nosecurity_label" },
 
 	{ Opt_port, "port=%u" },
 	{ Opt_rsize, "rsize=%u" },
@@ -1033,6 +1036,12 @@ static int nfs_parse_mount_options(char *raw,
 		case Opt_nosharecache:
 			mnt->flags |= NFS_MOUNT_UNSHARED;
 			break;
+		case Opt_nosecurity_label:
+			mnt->flags &= ~NFS4_MOUNT_SECURITY_LABEL;
+			break;
+		case Opt_security_label:
+			mnt->flags |= NFS4_MOUNT_SECURITY_LABEL;
+			break;
 
 		/*
 		 * options that take numeric values
diff --git a/include/linux/nfs4_mount.h b/include/linux/nfs4_mount.h
index a0dcf66..e65067b 100644
--- a/include/linux/nfs4_mount.h
+++ b/include/linux/nfs4_mount.h
@@ -17,6 +17,7 @@
  * but here they are anyway.
  */
 #define NFS4_MOUNT_VERSION	1
+#define NFS4_MAX_CONTEXT_LEN	4096
 
 struct nfs_string {
 	unsigned int len;
@@ -53,6 +54,8 @@ struct nfs4_mount_data {
 	/* Pseudo-flavours to use for authentication. See RFC2623 */
 	int auth_flavourlen;			/* 1 */
 	int __user *auth_flavours;		/* 1 */
+
+	char context[NFS4_MAX_CONTEXT_LEN + 1];  /* 2 */
 };
 
 /* bits in the flags field */
@@ -66,6 +69,7 @@ struct nfs4_mount_data {
 #define NFS4_MOUNT_NOAC		0x0020	/* 1 */
 #define NFS4_MOUNT_STRICTLOCK	0x1000	/* 1 */
 #define NFS4_MOUNT_UNSHARED	0x8000	/* 1 */
-#define NFS4_MOUNT_FLAGMASK	0x9033
+#define NFS4_MOUNT_SECURITY_LABEL 0x10000 /* 2 */
+#define NFS4_MOUNT_FLAGMASK	0x19033
 
 #endif
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 78e79d3..6919766 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -612,7 +612,7 @@ static int selinux_set_mnt_opts(struct super_block *sb,
 	for (i = 0; i < num_opts; i++) {
 		u32 sid;
 		if (flags[i] == NATIVE_LABELS_MNT) {
-			sbsec->flags | = NATIVE_LABELS_MNT;
+			sbsec->flags |= NATIVE_LABELS_MNT;
 			continue;
 		}
 		rc = security_context_to_sid(mount_options[i],
-- 
1.5.5.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 10/14] NFSv4: Introduce new label structure
  2008-09-29 17:06 [RFC v3] Security Label Support for NFSv4 David P. Quigley
                   ` (3 preceding siblings ...)
  2008-09-29 17:06 ` [PATCH 08/14] NFS: Add security_label text mount option and handling code to NFS David P. Quigley
@ 2008-09-29 17:06 ` David P. Quigley
  2008-09-29 17:06 ` [PATCH 11/14] NFS/RPC: Add the auth_seclabel security flavor to allow the process label to be sent to the server David P. Quigley
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 24+ messages in thread
From: David P. Quigley @ 2008-09-29 17:06 UTC (permalink / raw)
  To: hch, viro, casey, sds, matthew.dodd, trond.myklebust, bfields
  Cc: linux-kernel, linux-fsdevel, linux-security-module, selinux,
	labeled-nfs, David P. Quigley, Matthew N. Dodd

In order to mimic the way that NFSv4 ACLs are implemented we have created a
structure to be used to pass label data up and down the call chain. This patch
adds the new structure and new members to the required NFSv4 call structures.

Signed-off-by: Matthew N. Dodd <Matthew.Dodd@sparta.com>
Signed-off-by: David P. Quigley <dpquigl@tycho.nsa.gov>
---
 include/linux/nfs4.h      |    6 ++++++
 include/linux/nfs_xdr.h   |    3 +++
 include/linux/nfsd/xdr4.h |    3 +++
 3 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h
index 144eacf..dd99b27 100644
--- a/include/linux/nfs4.h
+++ b/include/linux/nfs4.h
@@ -112,6 +112,12 @@ struct nfs4_acl {
 	struct nfs4_ace	aces[0];
 };
 
+struct nfs4_label {
+	void		*label;
+	u32		len;
+};
+
+
 typedef struct { char data[NFS4_VERIFIER_SIZE]; } nfs4_verifier;
 typedef struct { char data[NFS4_STATEID_SIZE]; } nfs4_stateid;
 
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index 0d77568..c4fa2df 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -135,6 +135,7 @@ struct nfs_openargs {
 	const struct nfs_server *server;	 /* Needed for ID mapping */
 	const u32 *		bitmask;
 	__u32			claim;
+	const struct nfs4_label *label;
 };
 
 struct nfs_openres {
@@ -353,6 +354,7 @@ struct nfs_setattrargs {
 	struct iattr *                  iap;
 	const struct nfs_server *	server; /* Needed for name mapping */
 	const u32 *			bitmask;
+	const struct nfs4_label *	label;
 };
 
 struct nfs_setaclargs {
@@ -577,6 +579,7 @@ struct nfs4_create_arg {
 	const struct iattr *		attrs;
 	const struct nfs_fh *		dir_fh;
 	const u32 *			bitmask;
+	const struct nfs4_label *	label;
 };
 
 struct nfs4_create_res {
diff --git a/include/linux/nfsd/xdr4.h b/include/linux/nfsd/xdr4.h
index 27bd3e3..a0f3d79 100644
--- a/include/linux/nfsd/xdr4.h
+++ b/include/linux/nfsd/xdr4.h
@@ -94,6 +94,7 @@ struct nfsd4_create {
 	struct iattr	cr_iattr;           /* request */
 	struct nfsd4_change_info  cr_cinfo; /* response */
 	struct nfs4_acl *cr_acl;
+	struct nfs4_label *cr_label;
 };
 #define cr_linklen	u.link.namelen
 #define cr_linkname	u.link.name
@@ -223,6 +224,7 @@ struct nfsd4_open {
 	int		op_truncate;        /* used during processing */
 	struct nfs4_stateowner *op_stateowner; /* used during processing */
 	struct nfs4_acl *op_acl;
+	struct nfs4_label *op_label;
 };
 #define op_iattr	u.iattr
 #define op_verf		u.verf
@@ -304,6 +306,7 @@ struct nfsd4_setattr {
 	u32		sa_bmval[2];        /* request */
 	struct iattr	sa_iattr;           /* request */
 	struct nfs4_acl *sa_acl;
+	struct nfs4_label *sa_label;
 };
 
 struct nfsd4_setclientid {
-- 
1.5.5.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 11/14] NFS/RPC: Add the auth_seclabel security flavor to allow the process label to be sent to the server.
  2008-09-29 17:06 [RFC v3] Security Label Support for NFSv4 David P. Quigley
                   ` (4 preceding siblings ...)
  2008-09-29 17:06 ` [PATCH 10/14] NFSv4: Introduce new label structure David P. Quigley
@ 2008-09-29 17:06 ` David P. Quigley
  2008-10-03 14:23   ` Andy Whitcroft
  2008-09-29 17:06 ` [PATCH 13/14] NFS: Extend NFS xattr handlers to accept the security namespace David P. Quigley
                   ` (3 subsequent siblings)
  9 siblings, 1 reply; 24+ messages in thread
From: David P. Quigley @ 2008-09-29 17:06 UTC (permalink / raw)
  To: hch, viro, casey, sds, matthew.dodd, trond.myklebust, bfields
  Cc: linux-kernel, linux-fsdevel, linux-security-module, selinux,
	labeled-nfs, David P. Quigley, Matthew N. Dodd

This patch adds a new RPC flavor that allows the NFSv4 client to pass the
process label of the calling process on the client to the server to make an
access control decision. This is accomplished by taking the credential from the
wire and replacing the acting credential on the server for the NFSD process
with that new context.

Signed-off-by: Matthew N. Dodd <Matthew.Dodd@sparta.com>
Signed-off-by: David P. Quigley <dpquigl@tycho.nsa.gov>
---
 fs/nfs/nfs4proc.c               |    6 +-
 fs/nfsd/auth.c                  |   21 +++
 include/linux/sunrpc/auth.h     |    4 +
 include/linux/sunrpc/msg_prot.h |    1 +
 include/linux/sunrpc/svcauth.h  |    4 +
 net/sunrpc/Makefile             |    1 +
 net/sunrpc/auth.c               |   16 ++
 net/sunrpc/auth_seclabel.c      |  291 +++++++++++++++++++++++++++++++++++++++
 net/sunrpc/svc.c                |    1 +
 net/sunrpc/svcauth.c            |    6 +
 net/sunrpc/svcauth_unix.c       |   97 +++++++++++++-
 security/security.c             |    2 +
 security/selinux/hooks.c        |    2 +-
 13 files changed, 446 insertions(+), 6 deletions(-)
 create mode 100644 net/sunrpc/auth_seclabel.c

diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index c4a4271..92522cc 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -1410,6 +1410,9 @@ nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
 	struct nfs4_state *state;
 	struct dentry *res;
 
+	cred = rpc_lookup_cred();
+	if (IS_ERR(cred))
+		return (struct dentry *)cred;
 	if (nd->flags & LOOKUP_CREATE) {
 		attr.ia_mode = nd->intent.open.create_mode;
 		attr.ia_valid = ATTR_MODE;
@@ -1420,9 +1423,6 @@ nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
 		BUG_ON(nd->intent.open.flags & O_CREAT);
 	}
 
-	cred = rpc_lookup_cred();
-	if (IS_ERR(cred))
-		return (struct dentry *)cred;
 	parent = dentry->d_parent;
 	/* Protect against concurrent sillydeletes */
 	nfs_block_sillyrename(parent);
diff --git a/fs/nfsd/auth.c b/fs/nfsd/auth.c
index 294992e..400edf5 100644
--- a/fs/nfsd/auth.c
+++ b/fs/nfsd/auth.c
@@ -10,6 +10,9 @@
 #include <linux/sunrpc/svcauth.h>
 #include <linux/nfsd/nfsd.h>
 #include <linux/nfsd/export.h>
+#ifdef CONFIG_SECURITY
+#include <linux/security.h>
+#endif
 #include "auth.h"
 
 int nfsexp_flags(struct svc_rqst *rqstp, struct svc_export *exp)
@@ -32,6 +35,24 @@ int nfsd_setuser(struct svc_rqst *rqstp, struct svc_export *exp)
 	int flags = nfsexp_flags(rqstp, exp);
 	int ret;
 
+#ifdef CONFIG_SECURITY
+	if (cred.cr_label_len != 0) {
+		ret = security_setprocattr(current, "current",
+				(void *)cred.cr_label, cred.cr_label_len);
+		if (ret < 0) {
+			printk(KERN_ERR "%s(): "
+					"flavor %d "
+					"security_setprocattr(\"%*s\", %d) = %d\n",
+					__func__,
+					rqstp->rq_flavor,
+					cred.cr_label_len,
+					(char *)cred.cr_label,
+					cred.cr_label_len, ret);
+			return ret;
+		}
+	}
+#endif
+	
 	if (flags & NFSEXP_ALLSQUASH) {
 		cred.cr_uid = exp->ex_anon_uid;
 		cred.cr_gid = exp->ex_anon_gid;
diff --git a/include/linux/sunrpc/auth.h b/include/linux/sunrpc/auth.h
index 3f63218..11c054d 100644
--- a/include/linux/sunrpc/auth.h
+++ b/include/linux/sunrpc/auth.h
@@ -27,6 +27,10 @@ struct auth_cred {
 	gid_t	gid;
 	struct group_info *group_info;
 	unsigned char machine_cred : 1;
+#ifdef CONFIG_SECURITY
+	char   *label;
+	size_t  label_len;
+#endif
 };
 
 /*
diff --git a/include/linux/sunrpc/msg_prot.h b/include/linux/sunrpc/msg_prot.h
index 70df4f1..e2667f6 100644
--- a/include/linux/sunrpc/msg_prot.h
+++ b/include/linux/sunrpc/msg_prot.h
@@ -24,6 +24,7 @@ enum rpc_auth_flavors {
 	RPC_AUTH_DES   = 3,
 	RPC_AUTH_KRB   = 4,
 	RPC_AUTH_GSS   = 6,
+	RPC_AUTH_SECLABEL = 7,
 	RPC_AUTH_MAXFLAVOR = 8,
 	/* pseudoflavors: */
 	RPC_AUTH_GSS_KRB5  = 390003,
diff --git a/include/linux/sunrpc/svcauth.h b/include/linux/sunrpc/svcauth.h
index d39dbdc..5557361 100644
--- a/include/linux/sunrpc/svcauth.h
+++ b/include/linux/sunrpc/svcauth.h
@@ -21,6 +21,10 @@ struct svc_cred {
 	uid_t			cr_uid;
 	gid_t			cr_gid;
 	struct group_info	*cr_group_info;
+#ifdef CONFIG_SECURITY
+	void			*cr_label;
+	u32			cr_label_len;
+#endif
 };
 
 struct svc_rqst;		/* forward decl */
diff --git a/net/sunrpc/Makefile b/net/sunrpc/Makefile
index 5369aa3..5e03065 100644
--- a/net/sunrpc/Makefile
+++ b/net/sunrpc/Makefile
@@ -6,6 +6,7 @@
 obj-$(CONFIG_SUNRPC) += sunrpc.o
 obj-$(CONFIG_SUNRPC_GSS) += auth_gss/
 obj-$(CONFIG_SUNRPC_XPRT_RDMA) += xprtrdma/
+obj-$(CONFIG_SECURITY) += auth_seclabel.o
 
 sunrpc-y := clnt.o xprt.o socklib.o xprtsock.o sched.o \
 	    auth.o auth_null.o auth_unix.o auth_generic.o \
diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c
index 6bfea9e..b1d9e4e 100644
--- a/net/sunrpc/auth.c
+++ b/net/sunrpc/auth.c
@@ -14,6 +14,7 @@
 #include <linux/hash.h>
 #include <linux/sunrpc/clnt.h>
 #include <linux/spinlock.h>
+#include <linux/security.h>
 
 #ifdef RPC_DEBUG
 # define RPCDBG_FACILITY	RPCDBG_AUTH
@@ -359,11 +360,19 @@ rpcauth_lookupcred(struct rpc_auth *auth, int flags)
 
 	dprintk("RPC:       looking up %s cred\n",
 		auth->au_ops->au_name);
+#ifdef CONFIG_SECURITY
+	acred.label_len = security_getprocattr(current, "current",&acred.label);
+#endif
 	get_group_info(acred.group_info);
 	ret = auth->au_ops->lookup_cred(auth, &acred, flags);
 	put_group_info(acred.group_info);
+#ifdef CONFIG_SECURITY
+	if (acred.label != NULL)
+		security_release_secctx(acred.label, acred.label_len);
+#endif
 	return ret;
 }
+EXPORT_SYMBOL_GPL(rpcauth_lookupcred);
 
 void
 rpcauth_init_cred(struct rpc_cred *cred, const struct auth_cred *acred,
@@ -403,11 +412,18 @@ rpcauth_bind_root_cred(struct rpc_task *task)
 
 	dprintk("RPC: %5u looking up %s cred\n",
 		task->tk_pid, task->tk_client->cl_auth->au_ops->au_name);
+#ifdef CONFIG_SECURITY
+	acred.label_len = security_getprocattr(current, "current",&acred.label);
+#endif
 	ret = auth->au_ops->lookup_cred(auth, &acred, 0);
 	if (!IS_ERR(ret))
 		task->tk_msg.rpc_cred = ret;
 	else
 		task->tk_status = PTR_ERR(ret);
+#ifdef CONFIG_SECURITY
+	if (acred.label != NULL)
+		security_release_secctx(acred.label, acred.label_len);
+#endif
 }
 
 static void
diff --git a/net/sunrpc/auth_seclabel.c b/net/sunrpc/auth_seclabel.c
new file mode 100644
index 0000000..3e3b8ef
--- /dev/null
+++ b/net/sunrpc/auth_seclabel.c
@@ -0,0 +1,291 @@
+/*
+ * linux/net/sunrpc/auth_seclabel.c
+ *
+ * UNIX-style authentication; no AUTH_SHORT support
+ * SECLABEL-style authentication with security label support
+ *
+ * Copyright (C) 2007, 2008, SPARTA, Inc.
+ * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de>
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+
+#include <linux/sunrpc/clnt.h>
+#include <linux/sunrpc/auth.h>
+#include <linux/security.h>
+
+#define NFS_NGROUPS	16
+
+struct seclabel_cred {
+	struct rpc_cred		slc_base;
+	gid_t			slc_gid;
+	gid_t			slc_gids[NFS_NGROUPS];
+	char		       *slc_label;
+	size_t			slc_label_len;
+};
+#define slc_uid			slc_base.cr_uid
+
+#define UNX_WRITESLACK		(21 + (UNX_MAXNODENAME >> 2))
+
+#ifdef RPC_DEBUG
+# define RPCDBG_FACILITY	RPCDBG_AUTH
+#endif
+
+static struct rpc_auth		seclabel_auth;
+static struct rpc_cred_cache	seclabel_cred_cache;
+static const struct rpc_credops	seclabel_credops;
+
+static struct rpc_auth *
+seclabel_create(struct rpc_clnt *clnt, rpc_authflavor_t flavor)
+{
+	dprintk("RPC:       creating SECLABEL authenticator for client %p\n",
+			clnt);
+	atomic_inc(&seclabel_auth.au_count);
+	return &seclabel_auth;
+}
+
+static void
+seclabel_destroy(struct rpc_auth *auth)
+{
+	dprintk("RPC:       destroying SECLABEL authenticator %p\n", auth);
+	rpcauth_clear_credcache(auth->au_credcache);
+}
+
+/*
+ * Lookup AUTH_SECLABEL creds for current process
+ */
+static struct rpc_cred *
+seclabel_lookup_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
+{
+	return rpcauth_lookup_credcache(auth, acred, flags);
+}
+
+static struct rpc_cred *
+seclabel_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
+{
+	struct seclabel_cred	*cred;
+	unsigned int groups = 0;
+	unsigned int i;
+
+	dprintk("RPC:       allocating SECLABEL cred for uid %d gid %d\n",
+			acred->uid, acred->gid);
+
+	if (!(cred = kmalloc(sizeof(*cred), GFP_KERNEL)))
+		return ERR_PTR(-ENOMEM);
+
+	cred->slc_label = kmalloc(acred->label_len, GFP_KERNEL);
+	if (cred->slc_label == NULL) {
+		kfree(cred);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	rpcauth_init_cred(&cred->slc_base, acred, auth, &seclabel_credops);
+	cred->slc_base.cr_flags = 1UL << RPCAUTH_CRED_UPTODATE;
+
+	if (acred->group_info != NULL)
+		groups = acred->group_info->ngroups;
+	if (groups > NFS_NGROUPS)
+		groups = NFS_NGROUPS;
+
+	cred->slc_gid = acred->gid;
+	for (i = 0; i < groups; i++)
+		cred->slc_gids[i] = GROUP_AT(acred->group_info, i);
+	if (i < NFS_NGROUPS)
+		cred->slc_gids[i] = NOGROUP;
+
+	cred->slc_label_len = acred->label_len;
+	memcpy(cred->slc_label, acred->label, acred->label_len);
+
+	return &cred->slc_base;
+}
+
+static void
+seclabel_free_cred(struct seclabel_cred *seclabel_cred)
+{
+	dprintk("RPC:       seclabel_free_cred %p\n", seclabel_cred);
+	security_release_secctx(seclabel_cred->slc_label,
+				seclabel_cred->slc_label_len);
+	kfree(seclabel_cred);
+}
+
+static void
+seclabel_free_cred_callback(struct rcu_head *head)
+{
+	struct seclabel_cred *seclabel_cred = container_of(head, struct seclabel_cred, slc_base.cr_rcu);
+	seclabel_free_cred(seclabel_cred);
+}
+
+static void
+seclabel_destroy_cred(struct rpc_cred *cred)
+{
+	call_rcu(&cred->cr_rcu, seclabel_free_cred_callback);
+}
+
+/*
+ * Match credentials against current process creds.
+ * The root_override argument takes care of cases where the caller may
+ * request root creds (e.g. for NFS swapping).
+ */
+static int
+seclabel_match(struct auth_cred *acred, struct rpc_cred *rcred, int flags)
+{
+	struct seclabel_cred	*cred = container_of(rcred, struct seclabel_cred, slc_base);
+	unsigned int groups = 0;
+	unsigned int i;
+
+
+	if (acred->label_len != cred->slc_label_len)
+		return 0;
+	if (strcmp(acred->label, cred->slc_label) != 0)
+		return 0;
+	if (cred->slc_uid != acred->uid || cred->slc_gid != acred->gid)
+		return 0;
+
+	if (acred->group_info != NULL)
+		groups = acred->group_info->ngroups;
+	if (groups > NFS_NGROUPS)
+		groups = NFS_NGROUPS;
+	for (i = 0; i < groups ; i++)
+		if (cred->slc_gids[i] != GROUP_AT(acred->group_info, i))
+			return 0;
+	return 1;
+}
+
+/*
+ * Marshal credentials.
+ * Maybe we should keep a cached credential for performance reasons.
+ */
+static __be32 *
+seclabel_marshal(struct rpc_task *task, __be32 *p)
+{
+	struct rpc_clnt	*clnt = task->tk_client;
+	struct seclabel_cred	*cred = container_of(task->tk_msg.rpc_cred, struct seclabel_cred, slc_base);
+	__be32		*base, *hold;
+	int		i;
+
+	*p++ = htonl(RPC_AUTH_SECLABEL);
+	base = p++;
+	*p++ = htonl(jiffies/HZ);
+
+	/*
+	 * Copy the UTS nodename captured when the client was created.
+	 */
+	p = xdr_encode_array(p, clnt->cl_nodename, clnt->cl_nodelen);
+
+	/*
+	 * Label
+	 */
+	p = xdr_encode_array(p, cred->slc_label, cred->slc_label_len);
+
+	*p++ = htonl((u32) cred->slc_uid);
+	*p++ = htonl((u32) cred->slc_gid);
+	hold = p++;
+	for (i = 0; i < 16 && cred->slc_gids[i] != (gid_t) NOGROUP; i++)
+		*p++ = htonl((u32) cred->slc_gids[i]);
+	*hold = htonl(p - hold - 1);		/* gid array length */
+	*base = htonl((p - base - 1) << 2);	/* cred length */
+
+	*p++ = htonl(RPC_AUTH_NULL);
+	*p++ = htonl(0);
+
+	return p;
+}
+
+/*
+ * Refresh credentials. This is a no-op for AUTH_SECLABEL
+ */
+static int
+seclabel_refresh(struct rpc_task *task)
+{
+	set_bit(RPCAUTH_CRED_UPTODATE, &task->tk_msg.rpc_cred->cr_flags);
+	return 0;
+}
+
+static __be32 *
+seclabel_validate(struct rpc_task *task, __be32 *p)
+{
+	rpc_authflavor_t	flavor;
+	u32			size;
+
+	flavor = ntohl(*p++);
+	if (flavor != RPC_AUTH_NULL &&
+	    flavor != RPC_AUTH_SECLABEL &&
+	    flavor != RPC_AUTH_SHORT) {
+		printk("RPC: bad verf flavor: %u\n", flavor);
+		return NULL;
+	}
+
+	size = ntohl(*p++);
+	if (size > RPC_MAX_AUTH_SIZE) {
+		printk("RPC: giant verf size: %u\n", size);
+		return NULL;
+	}
+	task->tk_msg.rpc_cred->cr_auth->au_rslack = (size >> 2) + 2;
+	p += (size >> 2);
+
+	return p;
+}
+
+static const struct rpc_authops authseclabel_ops = {
+	.owner		= THIS_MODULE,
+	.au_flavor	= RPC_AUTH_SECLABEL,
+	.au_name	= "SECLABEL",
+	.create		= seclabel_create,
+	.destroy	= seclabel_destroy,
+	.lookup_cred	= seclabel_lookup_cred,
+	.crcreate	= seclabel_create_cred,
+};
+
+static struct rpc_cred_cache	seclabel_cred_cache = {
+};
+
+static struct rpc_auth		seclabel_auth = {
+	.au_cslack	= UNX_WRITESLACK,
+	.au_rslack	= 2,			/* assume AUTH_NULL verf */
+	.au_ops		= &authseclabel_ops,
+	.au_flavor	= RPC_AUTH_SECLABEL,
+	.au_count	= ATOMIC_INIT(0),
+	.au_credcache	= &seclabel_cred_cache,
+};
+
+static const struct rpc_credops seclabel_credops = {
+	.cr_name	= "AUTH_SECLABEL",
+	.crdestroy	= seclabel_destroy_cred,
+	.crbind		= rpcauth_generic_bind_cred,
+	.crmatch	= seclabel_match,
+	.crmarshal	= seclabel_marshal,
+	.crrefresh	= seclabel_refresh,
+	.crvalidate	= seclabel_validate,
+};
+
+/*
+ * Initialize RPCSEC_GSS module
+ */
+static int __init init_auth_seclabel(void)
+{
+	int err = 0;
+
+	err = rpcauth_register(&authseclabel_ops);
+	if (err)
+		goto out;
+
+	spin_lock_init(&seclabel_cred_cache.lock);
+
+	return 0;
+out:
+	rpcauth_unregister(&authseclabel_ops);
+	return err;
+}
+
+static void __exit exit_auth_seclabel(void)
+{
+        rpcauth_unregister(&authseclabel_ops);
+}
+
+MODULE_LICENSE("GPL");
+module_init(init_auth_seclabel)
+module_exit(exit_auth_seclabel)
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index 5a32cb7..126eeb1 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -830,6 +830,7 @@ svc_process(struct svc_rqst *rqstp)
 	rqstp->rq_res.buflen = PAGE_SIZE;
 	rqstp->rq_res.tail[0].iov_base = NULL;
 	rqstp->rq_res.tail[0].iov_len = 0;
+	memset(&rqstp->rq_cred, 0, sizeof(struct svc_cred));
 	/* Will be turned off only in gss privacy case: */
 	rqstp->rq_splice_ok = 1;
 
diff --git a/net/sunrpc/svcauth.c b/net/sunrpc/svcauth.c
index 8a73cbb..ca8c99f 100644
--- a/net/sunrpc/svcauth.c
+++ b/net/sunrpc/svcauth.c
@@ -26,11 +26,17 @@
  */
 extern struct auth_ops svcauth_null;
 extern struct auth_ops svcauth_unix;
+#ifdef CONFIG_SECURITY
+extern struct auth_ops svcauth_seclabel;
+#endif
 
 static DEFINE_SPINLOCK(authtab_lock);
 static struct auth_ops	*authtab[RPC_AUTH_MAXFLAVOR] = {
 	[0] = &svcauth_null,
 	[1] = &svcauth_unix,
+#ifdef CONFIG_SECURITY
+	[RPC_AUTH_SECLABEL] = &svcauth_seclabel,
+#endif
 };
 
 int
diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c
index f24800f..4dfecf0 100644
--- a/net/sunrpc/svcauth_unix.c
+++ b/net/sunrpc/svcauth_unix.c
@@ -31,6 +31,9 @@ struct unix_domain {
 };
 
 extern struct auth_ops svcauth_unix;
+#ifdef CONFIG_SECURITY
+extern struct auth_ops svcauth_seclabel;
+#endif
 
 struct auth_domain *unix_domain_find(char *name)
 {
@@ -43,7 +46,11 @@ struct auth_domain *unix_domain_find(char *name)
 			if (new && rv != &new->h)
 				auth_domain_put(&new->h);
 
-			if (rv->flavour != &svcauth_unix) {
+			if (rv->flavour != &svcauth_unix
+#ifdef CONFIG_SECURITY
+			    && rv->flavour != &svcauth_seclabel
+#endif
+			   ) {
 				auth_domain_put(rv);
 				return NULL;
 			}
@@ -358,7 +365,11 @@ int auth_unix_add_addr(struct in6_addr *addr, struct auth_domain *dom)
 	struct unix_domain *udom;
 	struct ip_map *ipmp;
 
-	if (dom->flavour != &svcauth_unix)
+	if (dom->flavour != &svcauth_unix
+#ifdef CONFIG_SECURITY
+	    && dom->flavour != &svcauth_seclabel
+#endif
+	   )
 		return -EINVAL;
 	udom = container_of(dom, struct unix_domain, h);
 	ipmp = ip_map_lookup("nfsd", addr);
@@ -374,6 +385,11 @@ int auth_unix_forget_old(struct auth_domain *dom)
 {
 	struct unix_domain *udom;
 
+	if (dom->flavour != &svcauth_unix
+#ifdef CONFIG_SECURITY
+	    && dom->flavour != &svcauth_seclabel
+#endif
+	   )
 	if (dom->flavour != &svcauth_unix)
 		return -EINVAL;
 	udom = container_of(dom, struct unix_domain, h);
@@ -873,3 +889,80 @@ struct auth_ops svcauth_unix = {
 	.set_client	= svcauth_unix_set_client,
 };
 
+#ifdef CONFIG_SECURITY
+static int
+svcauth_seclabel_accept(struct svc_rqst *rqstp, __be32 *authp)
+{
+	struct kvec	*argv = &rqstp->rq_arg.head[0];
+	struct kvec	*resv = &rqstp->rq_res.head[0];
+	struct svc_cred	*cred = &rqstp->rq_cred;
+	u32		slen, i;
+	int		len   = argv->iov_len;
+
+	cred->cr_group_info = NULL;
+	rqstp->rq_client = NULL;
+
+	if ((len -= 3*4) < 0)
+		return SVC_GARBAGE;
+
+	svc_getu32(argv);			/* length */
+	svc_getu32(argv);			/* time stamp */
+	slen = XDR_QUADLEN(svc_getnl(argv));	/* machname length */
+	if (slen > 64 || (len -= (slen + 3)*4) < 0)
+		goto badcred;
+	argv->iov_base = (void*)((__be32*)argv->iov_base + slen);	/* skip machname */
+	argv->iov_len -= slen*4;
+
+	slen = svc_getnl(argv);			/* security label length */
+	/* XXX: sanity check label... */
+	cred->cr_label = argv->iov_base;
+	cred->cr_label_len = slen;
+	argv->iov_base = (void*)((__be32*)argv->iov_base + XDR_QUADLEN(slen));
+	argv->iov_len -= slen;
+
+	cred->cr_uid = svc_getnl(argv);		/* uid */
+	cred->cr_gid = svc_getnl(argv);		/* gid */
+	slen = svc_getnl(argv);			/* gids length */
+	if (slen > 16 || (len -= (slen + 2)*4) < 0)
+		goto badcred;
+	if (unix_gid_find(cred->cr_uid, &cred->cr_group_info, rqstp)
+	    == -EAGAIN)
+		return SVC_DROP;
+	if (cred->cr_group_info == NULL) {
+		cred->cr_group_info = groups_alloc(slen);
+		if (cred->cr_group_info == NULL)
+			return SVC_DROP;
+		for (i = 0; i < slen; i++)
+			GROUP_AT(cred->cr_group_info, i) = svc_getnl(argv);
+	} else {
+		for (i = 0; i < slen ; i++)
+			svc_getnl(argv);
+	}
+	if (svc_getu32(argv) != htonl(RPC_AUTH_NULL) || svc_getu32(argv) != 0) {
+		*authp = rpc_autherr_badverf;
+		return SVC_DENIED;
+	}
+
+	/* Put NULL verifier */
+	svc_putnl(resv, RPC_AUTH_NULL);
+	svc_putnl(resv, 0);
+
+	rqstp->rq_flavor = RPC_AUTH_SECLABEL;
+	return SVC_OK;
+
+badcred:
+	*authp = rpc_autherr_badcred;
+	return SVC_DENIED;
+}
+
+struct auth_ops svcauth_seclabel = {
+	.name		= "seclabel",
+	.owner		= THIS_MODULE,
+	.flavour	= RPC_AUTH_SECLABEL,
+	.accept 	= svcauth_seclabel_accept,
+	.release	= svcauth_unix_release,
+	.domain_release	= svcauth_unix_domain_release,
+	.set_client	= svcauth_unix_set_client,
+};
+#endif
+
diff --git a/security/security.c b/security/security.c
index 1955094..2337d7f 100644
--- a/security/security.c
+++ b/security/security.c
@@ -841,11 +841,13 @@ int security_getprocattr(struct task_struct *p, char *name, char **value)
 {
 	return security_ops->getprocattr(p, name, value);
 }
+EXPORT_SYMBOL(security_getprocattr);
 
 int security_setprocattr(struct task_struct *p, char *name, void *value, size_t size)
 {
 	return security_ops->setprocattr(p, name, value, size);
 }
+EXPORT_SYMBOL(security_setprocattr);
 
 int security_netlink_send(struct sock *sk, struct sk_buff *skb)
 {
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 6919766..05a10be 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -5298,7 +5298,7 @@ static int selinux_setprocattr(struct task_struct *p,
 			return -EINVAL;
 
 		/* Only allow single threaded processes to change context */
-		if (atomic_read(&p->mm->mm_users) != 1) {
+		if (p->mm && atomic_read(&p->mm->mm_users) != 1) {
 			struct task_struct *g, *t;
 			struct mm_struct *mm = p->mm;
 			read_lock(&tasklist_lock);
-- 
1.5.5.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 13/14] NFS: Extend NFS xattr handlers to accept the security namespace
  2008-09-29 17:06 [RFC v3] Security Label Support for NFSv4 David P. Quigley
                   ` (5 preceding siblings ...)
  2008-09-29 17:06 ` [PATCH 11/14] NFS/RPC: Add the auth_seclabel security flavor to allow the process label to be sent to the server David P. Quigley
@ 2008-09-29 17:06 ` David P. Quigley
       [not found] ` <1222707986-26606-4-git-send-email-dpquigl@tycho.nsa.gov>
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 24+ messages in thread
From: David P. Quigley @ 2008-09-29 17:06 UTC (permalink / raw)
  To: hch, viro, casey, sds, matthew.dodd, trond.myklebust, bfields
  Cc: linux-kernel, linux-fsdevel, linux-security-module, selinux,
	labeled-nfs, David P. Quigley, Matthew N. Dodd

The existing NFSv4 xattr handlers do not accept xattr calls to the security
namespace. This patch extends these handlers to accept xattrs from the security
namespace in addition to the default NFSv4 ACL namespace.

Signed-off-by: Matthew N. Dodd <Matthew.Dodd@sparta.com>
Signed-off-by: David P. Quigley <dpquigl@tycho.nsa.gov>
---
 fs/nfs/nfs4proc.c   |   52 ++++++++++++++++++++++++++++++++++++++++----------
 security/security.c |    1 +
 2 files changed, 42 insertions(+), 11 deletions(-)

diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 622bf71..845e1da 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -3934,10 +3934,17 @@ int nfs4_setxattr(struct dentry *dentry, const char *key, const void *buf,
 {
 	struct inode *inode = dentry->d_inode;
 
-	if (strcmp(key, XATTR_NAME_NFSV4_ACL) != 0)
-		return -EOPNOTSUPP;
-
-	return nfs4_proc_set_acl(inode, buf, buflen);
+	if (strcmp(key, XATTR_NAME_NFSV4_ACL) == 0) {
+		if (!S_ISREG(inode->i_mode) &&
+		   (!S_ISDIR(inode->i_mode) || inode->i_mode & S_ISVTX))
+			return -EPERM;
+		return nfs4_proc_set_acl(inode, buf, buflen);
+	}
+#ifdef CONFIG_NFS_V4_SECURITY_LABEL
+	if (security_ismaclabel(key))
+		return nfs4_set_security_label(dentry, buf, buflen);
+#endif
+	return -EOPNOTSUPP;
 }
 
 /* The getxattr man page suggests returning -ENODATA for unknown attributes,
@@ -3949,22 +3956,45 @@ ssize_t nfs4_getxattr(struct dentry *dentry, const char *key, void *buf,
 {
 	struct inode *inode = dentry->d_inode;
 
-	if (strcmp(key, XATTR_NAME_NFSV4_ACL) != 0)
-		return -EOPNOTSUPP;
+	if (strcmp(key, XATTR_NAME_NFSV4_ACL) == 0)
+		return nfs4_proc_get_acl(inode, buf, buflen);
 
-	return nfs4_proc_get_acl(inode, buf, buflen);
+#ifdef CONFIG_NFS_V4_SECURITY_LABEL
+	if (security_ismaclabel(key))
+		return nfs4_get_security_label(inode, buf, buflen);
+#endif
+	return -EOPNOTSUPP;
 }
 
 ssize_t nfs4_listxattr(struct dentry *dentry, char *buf, size_t buflen)
 {
-	size_t len = strlen(XATTR_NAME_NFSV4_ACL) + 1;
+	size_t len = 0, l;
+	char *p;
 
-	if (!nfs4_server_supports_acls(NFS_SERVER(dentry->d_inode)))
+	if (nfs4_server_supports_acls(NFS_SERVER(dentry->d_inode)))
+		len += strlen(XATTR_NAME_NFSV4_ACL) + 1;
+#ifdef CONFIG_NFS_V4_SECURITY_LABEL
+	if (nfs_server_capable(dentry->d_inode, NFS_CAP_SECURITY_LABEL))
+		len += security_inode_listsecurity(dentry->d_inode, NULL, 0);
+#endif
+	if (!len)
 		return 0;
 	if (buf && buflen < len)
 		return -ERANGE;
-	if (buf)
-		memcpy(buf, XATTR_NAME_NFSV4_ACL, len);
+	if (!buf)
+		return len;
+
+	p = buf;
+	if (nfs4_server_supports_acls(NFS_SERVER(dentry->d_inode))) {
+		l = strlen(XATTR_NAME_NFSV4_ACL) + 1;
+		memcpy(p, XATTR_NAME_NFSV4_ACL, l);
+		p += l;
+	}
+#ifdef CONFIG_NFS_V4_SECURITY_LABEL
+	if (nfs_server_capable(dentry->d_inode, NFS_CAP_SECURITY_LABEL))
+		p += security_inode_listsecurity(dentry->d_inode, p,
+			buflen - (p - buf));
+#endif
 	return len;
 }
 
diff --git a/security/security.c b/security/security.c
index 2337d7f..44d6e37 100644
--- a/security/security.c
+++ b/security/security.c
@@ -536,6 +536,7 @@ int security_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer
 		return 0;
 	return security_ops->inode_listsecurity(inode, buffer, buffer_size);
 }
+EXPORT_SYMBOL(security_inode_listsecurity);
 
 void security_inode_getsecid(const struct inode *inode, u32 *secid)
 {
-- 
1.5.5.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* Re: [PATCH 01/14] VFS: Factor out part of vfs_setxattr so it can be called from the SELinux hook for inode_setsecctx.
  2008-09-29 17:06 ` [PATCH 01/14] VFS: Factor out part of vfs_setxattr so it can be called from the SELinux hook for inode_setsecctx David P. Quigley
@ 2008-09-30 19:51   ` Serge E. Hallyn
  0 siblings, 0 replies; 24+ messages in thread
From: Serge E. Hallyn @ 2008-09-30 19:51 UTC (permalink / raw)
  To: David P. Quigley
  Cc: hch, viro, casey, sds, matthew.dodd, trond.myklebust, bfields,
	linux-kernel, linux-fsdevel, linux-security-module, selinux,
	labeled-nfs

Quoting David P. Quigley (dpquigl@tycho.nsa.gov):
> This factors out the part of the vfs_setxattr function that performs the
> setting of the xattr and its notification. This is needed so the SELinux
> implementation of inode_setsecctx can handle the setting of it's xattr while
> maintaining the proper separation of layers.
> 
> Signed-off-by: Matthew N. Dodd <Matthew.Dodd@sparta.com>
> Signed-off-by: David P. Quigley <dpquigl@tycho.nsa.gov>

This part surely looks reasonable.

Acked-by: Serge Hallyn <serue@us.ibm.com>
> ---
>  fs/xattr.c            |   55 +++++++++++++++++++++++++++++++++++++-----------
>  include/linux/xattr.h |    1 +
>  2 files changed, 43 insertions(+), 13 deletions(-)
> 
> diff --git a/fs/xattr.c b/fs/xattr.c
> index 468377e..2f93006 100644
> --- a/fs/xattr.c
> +++ b/fs/xattr.c
> @@ -66,22 +66,28 @@ xattr_permission(struct inode *inode, const char *name, int mask)
>  	return inode_permission(inode, mask);
>  }
> 
> -int
> -vfs_setxattr(struct dentry *dentry, const char *name, const void *value,
> -		size_t size, int flags)
> +/**
> + *  __vfs_setxattr_noperm - perform setxattr operation without performing
> + *  permission checks.
> + *
> + *  @dentry - object to perform setxattr on
> + *  @name - xattr name to set
> + *  @value - value to set @name to
> + *  @size - size of @value
> + *  @flags - flags to pass into filesystem operations
> + *
> + *  returns the result of the internal setxattr or setsecurity operations.
> + *
> + *  This function requires the caller to lock the inode's i_mutex before it
> + *  is executed. It also assumes that the caller will make the appropriate
> + *  permission checks.
> + */
> +int __vfs_setxattr_noperm(struct dentry *dentry, const char *name,
> +		const void *value, size_t size, int flags)
>  {
>  	struct inode *inode = dentry->d_inode;
> -	int error;
> -
> -	error = xattr_permission(inode, name, MAY_WRITE);
> -	if (error)
> -		return error;
> +	int error = -EOPNOTSUPP;
> 
> -	mutex_lock(&inode->i_mutex);
> -	error = security_inode_setxattr(dentry, name, value, size, flags);
> -	if (error)
> -		goto out;
> -	error = -EOPNOTSUPP;
>  	if (inode->i_op->setxattr) {
>  		error = inode->i_op->setxattr(dentry, name, value, size, flags);
>  		if (!error) {
> @@ -97,6 +103,29 @@ vfs_setxattr(struct dentry *dentry, const char *name, const void *value,
>  		if (!error)
>  			fsnotify_xattr(dentry);
>  	}
> +
> +	return error;
> +}
> +
> +
> +int
> +vfs_setxattr(struct dentry *dentry, const char *name, const void *value,
> +		size_t size, int flags)
> +{
> +	struct inode *inode = dentry->d_inode;
> +	int error;
> +
> +	error = xattr_permission(inode, name, MAY_WRITE);
> +	if (error)
> +		return error;
> +
> +	mutex_lock(&inode->i_mutex);
> +	error = security_inode_setxattr(dentry, name, value, size, flags);
> +	if (error)
> +		goto out;
> +
> +	error = __vfs_setxattr_noperm(dentry, name, value, size, flags);
> +
>  out:
>  	mutex_unlock(&inode->i_mutex);
>  	return error;
> diff --git a/include/linux/xattr.h b/include/linux/xattr.h
> index d131e35..5c84af8 100644
> --- a/include/linux/xattr.h
> +++ b/include/linux/xattr.h
> @@ -49,6 +49,7 @@ struct xattr_handler {
>  ssize_t xattr_getsecurity(struct inode *, const char *, void *, size_t);
>  ssize_t vfs_getxattr(struct dentry *, const char *, void *, size_t);
>  ssize_t vfs_listxattr(struct dentry *d, char *list, size_t size);
> +int __vfs_setxattr_noperm(struct dentry *, const char *, const void *, size_t, int);
>  int vfs_setxattr(struct dentry *, const char *, const void *, size_t, int);
>  int vfs_removexattr(struct dentry *, const char *);
> 
> -- 
> 1.5.5.1
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 02/14] LSM/SELinux: inode_{get,set,notify}secctx hooks to access LSM security context information.
       [not found] ` <1222707986-26606-3-git-send-email-dpquigl@tycho.nsa.gov>
@ 2008-09-30 20:01   ` Serge E. Hallyn
  2008-10-06 20:52     ` David P. Quigley
  2008-09-30 20:22   ` Serge E. Hallyn
  1 sibling, 1 reply; 24+ messages in thread
From: Serge E. Hallyn @ 2008-09-30 20:01 UTC (permalink / raw)
  To: David P. Quigley
  Cc: hch, viro, casey, sds, matthew.dodd, trond.myklebust, bfields,
	linux-kernel, linux-fsdevel, linux-security-module, selinux,
	labeled-nfs

Quoting David P. Quigley (dpquigl@tycho.nsa.gov):
> This patch introduces three new hooks. The inode_getsecctx hook is used to get
> all relevant information from an LSM about an inode. The inode_setsecctx is
> used to set both the in-core and on-disk state for the inode based on a context
> derived from inode_getsecctx.The final hook inode_notifysecctx will notify the
> LSM of a change for the in-core state of the inode in question. These hooks are
> for use in the labeled NFS code and addresses concerns of how to set security
> on an inode in a multi-xattr LSM. For historical reasons Stephen Smalley's
> explanation of the reason for these hooks is pasted below.
> 
> Quote Stephen Smalley
> 
> inode_setsecctx:  Change the security context of an inode.  Updates the
> in core security context managed by the security module and invokes the
> fs code as needed (via __vfs_setxattr_noperm) to update any backing
> xattrs that represent the context.  Example usage:  NFS server invokes
> this hook to change the security context in its incore inode and on the
> backing file system to a value provided by the client on a SETATTR
> operation.
> 
> inode_notifysecctx:  Notify the security module of what the security
> context of an inode should be.  Initializes the incore security context
> managed by the security module for this inode.  Example usage:  NFS
> client invokes this hook to initialize the security context in its
> incore inode to the value provided by the server for the file when the
> server returned the file's attributes to the client.
> 
> Signed-off-by: Matthew N. Dodd <Matthew.Dodd@sparta.com>
> Signed-off-by: David P. Quigley <dpquigl@tycho.nsa.gov>
> ---
>  include/linux/security.h |   50 ++++++++++++++++++++++++++++++++++++++++++++++
>  security/security.c      |   18 ++++++++++++++++
>  security/selinux/hooks.c |   25 +++++++++++++++++++++++
>  3 files changed, 93 insertions(+), 0 deletions(-)
> 
> diff --git a/include/linux/security.h b/include/linux/security.h
> index 80c4d00..8b5b041 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -1289,6 +1289,36 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
>   *	audit_rule_init.
>   *	@rule contains the allocated rule
>   *
> + * @inode_notifysecctx:
> + *	Notify the security module of what the security context of an inode
> + *	should be.  Initializes the incore security context managed by the
> + *	security module for this inode.  Example usage:  NFS client invokes
> + *	this hook to initialize the security context in its incore inode to the
> + *	value provided by the server for the file when the server returned the
> + *	file's attributes to the client.
> + *
> + * 	@inode we wish to set the security context of.
> + * 	@ctx contains the string which we wish to set in the inode.
> + * 	@ctxlen contains the length of @ctx.
> + *
> + * @inode_setsecctx:
> + * 	Change the security context of an inode.  Updates the
> + * 	incore security context managed by the security module and invokes the
> + * 	fs code as needed (via __vfs_setxattr_noperm) to update any backing
> + * 	xattrs that represent the context.  Example usage:  NFS server invokes
> + * 	this hook to change the security context in its incore inode and on the
> + * 	backing filesystem to a value provided by the client on a SETATTR
> + * 	operation.
> + *
> + * 	@dentry contains the inode we wish to set the security context of.
> + * 	@ctx contains the string which we wish to set in the inode.
> + * 	@ctxlen contains the length of @ctx.
> + *
> + * @inode_getsecctx:
> + * 	Returns a string containing all relavent security context information
> + * 	@inode we wish to set the security context of.
> + *	@ctx is a pointer to place the allocated security context should be placed.

sentence above is odd.  How about

	@ctx is a pointer in which to place the allocated security context

> + *	@ctxlen points to the place to put the length of @ctx.
>   * This is the main security structure.
>   */
>  struct security_operations {
> @@ -1479,6 +1509,10 @@ struct security_operations {
>  	int (*secctx_to_secid) (const char *secdata, u32 seclen, u32 *secid);
>  	void (*release_secctx) (char *secdata, u32 seclen);
> 
> +	int (*inode_notifysecctx)(struct inode *inode, void *ctx, u32 ctxlen);
> +	int (*inode_setsecctx)(struct dentry *dentry, void *ctx, u32 ctxlen);
> +	int (*inode_getsecctx)(struct inode *inode, void **ctx, u32 *ctxlen);
> +
>  #ifdef CONFIG_SECURITY_NETWORK
>  	int (*unix_stream_connect) (struct socket *sock,
>  				    struct socket *other, struct sock *newsk);
> @@ -1727,6 +1761,9 @@ int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen);
>  int security_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid);
>  void security_release_secctx(char *secdata, u32 seclen);
> 
> +int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen);
> +int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen);
> +int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen);
>  #else /* CONFIG_SECURITY */
>  struct security_mnt_opts {
>  };
> @@ -2458,6 +2495,19 @@ static inline int security_secctx_to_secid(const char *secdata,
>  static inline void security_release_secctx(char *secdata, u32 seclen)
>  {
>  }
> +
> +static inline int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen)
> +{
> +	return -EOPNOTSUPP;
> +}
> +static inline int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen)
> +{
> +	return -EOPNOTSUPP;
> +}
> +static inline int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen)
> +{
> +	return -EOPNOTSUPP;
> +}
>  #endif	/* CONFIG_SECURITY */
> 
>  #ifdef CONFIG_SECURITY_NETWORK
> diff --git a/security/security.c b/security/security.c
> index 3a4b4f5..d0fd42a 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -869,6 +869,24 @@ void security_release_secctx(char *secdata, u32 seclen)
>  }
>  EXPORT_SYMBOL(security_release_secctx);
> 
> +int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen)
> +{
> +	return security_ops->inode_notifysecctx(inode, ctx, ctxlen);
> +}
> +EXPORT_SYMBOL(security_inode_notifysecctx);
> +
> +int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen)
> +{
> +	return security_ops->inode_setsecctx(dentry, ctx, ctxlen);
> +}
> +EXPORT_SYMBOL(security_inode_setsecctx);
> +
> +int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen)
> +{
> +	return security_ops->inode_getsecctx(inode, ctx, ctxlen);
> +}
> +EXPORT_SYMBOL(security_inode_getsecctx);
> +
>  #ifdef CONFIG_SECURITY_NETWORK
> 
>  int security_unix_stream_connect(struct socket *sock, struct socket *other,
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index 03fc6a8..b07871b 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -5285,6 +5285,28 @@ static void selinux_release_secctx(char *secdata, u32 seclen)
>  	kfree(secdata);
>  }
> 
> +/*
> + *	This hook requires that the inode i_mutex be locked

'called with inode->i_mutex locked' would make more sense here.
Requirements on the callers would make more sense in the comments
in include/linux/security.h, right?

No code objections, though.

Acked-by: Serge Hallyn <serue@us.ibm.com>

> + */
> +static int selinux_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen)
> +{
> +	return selinux_inode_setsecurity(inode, XATTR_SELINUX_SUFFIX, ctx, ctxlen, 0);
> +}
> +
> +/*
> + *	This hook requires that the inode i_mutex be locked
> + */
> +static int selinux_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen)
> +{
> +	return __vfs_setxattr_noperm(dentry, XATTR_NAME_SELINUX, ctx, ctxlen, 0);
> +}
> +
> +static int selinux_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen)
> +{
> +	*ctxlen = selinux_inode_getsecurity(inode, XATTR_SELINUX_SUFFIX,
> +						ctx, true);
> +	return *ctxlen;
> +}
>  #ifdef CONFIG_KEYS
> 
>  static int selinux_key_alloc(struct key *k, struct task_struct *tsk,
> @@ -5491,6 +5513,9 @@ static struct security_operations selinux_ops = {
>  	.secid_to_secctx =		selinux_secid_to_secctx,
>  	.secctx_to_secid =		selinux_secctx_to_secid,
>  	.release_secctx =		selinux_release_secctx,
> +	.inode_notifysecctx =		selinux_inode_notifysecctx,
> +	.inode_setsecctx =		selinux_inode_setsecctx,
> +	.inode_getsecctx =		selinux_inode_getsecctx,
> 
>  	.unix_stream_connect =		selinux_socket_unix_stream_connect,
>  	.unix_may_send =		selinux_socket_unix_may_send,
> -- 
> 1.5.5.1
> 
> 
> --
> This message was distributed to subscribers of the selinux mailing list.
> If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
> the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 03/14] Security: Add hook to calculate context based on a negative dentry.
       [not found] ` <1222707986-26606-4-git-send-email-dpquigl@tycho.nsa.gov>
@ 2008-09-30 20:15   ` Serge E. Hallyn
  2008-10-10 17:54     ` David P. Quigley
  0 siblings, 1 reply; 24+ messages in thread
From: Serge E. Hallyn @ 2008-09-30 20:15 UTC (permalink / raw)
  To: David P. Quigley
  Cc: hch, viro, casey, sds, matthew.dodd, trond.myklebust, bfields,
	linux-kernel, linux-fsdevel, linux-security-module, selinux,
	labeled-nfs

Quoting David P. Quigley (dpquigl@tycho.nsa.gov):
> There is a time where we need to calculate a context without the
> inode having been created yet. To do this we take the negative dentry and
> calculate a context based on the process and the parent directory contexts.
> 
> Signed-off-by: Matthew N. Dodd <Matthew.Dodd@sparta.com>
> Signed-off-by: David P. Quigley <dpquigl@tycho.nsa.gov>
> ---
>  include/linux/security.h |   14 ++++++++++++++
>  security/security.c      |    7 +++++++
>  security/selinux/hooks.c |   36 ++++++++++++++++++++++++++++++++++++
>  3 files changed, 57 insertions(+), 0 deletions(-)
> 
> diff --git a/include/linux/security.h b/include/linux/security.h
> index 8b5b041..42b9128 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -1379,6 +1379,9 @@ struct security_operations {
>  	void (*sb_clone_mnt_opts) (const struct super_block *oldsb,
>  				   struct super_block *newsb);
>  	int (*sb_parse_opts_str) (char *options, struct security_mnt_opts *opts);
> +	int (*dentry_init_security) (struct dentry *dentry, int mode,
> +				     void **ctx, u32 *ctxlen);

This of course needs a description at top of include/linux/security.h.

> +
> 
>  	int (*inode_alloc_security) (struct inode *inode);
>  	void (*inode_free_security) (struct inode *inode);
> @@ -1651,6 +1654,8 @@ int security_sb_set_mnt_opts(struct super_block *sb, struct security_mnt_opts *o
>  void security_sb_clone_mnt_opts(const struct super_block *oldsb,
>  				struct super_block *newsb);
>  int security_sb_parse_opts_str(char *options, struct security_mnt_opts *opts);
> +int security_dentry_init_security (struct dentry *dentry, int mode,
> +				   void **ctx, u32 *ctxlen);
> 
>  int security_inode_alloc(struct inode *inode);
>  void security_inode_free(struct inode *inode);
> @@ -1994,6 +1999,15 @@ static inline int security_inode_alloc(struct inode *inode)
>  static inline void security_inode_free(struct inode *inode)
>  { }
> 
> +static inline int security_dentry_init_security (struct dentry *dentry,
> +						 int mode,
> +						 void **ctx,
> +						 u32 *ctxlen)
> +{
> +	return -EOPNOTSUPP;
> +}
> +
> +
>  static inline int security_inode_init_security(struct inode *inode,
>  						struct inode *dir,
>  						char **name,
> diff --git a/security/security.c b/security/security.c
> index d0fd42a..b22a110 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -349,6 +349,13 @@ void security_inode_free(struct inode *inode)
>  	security_ops->inode_free_security(inode);
>  }
> 
> +int security_dentry_init_security (struct dentry *dentry, int mode,
> +				   void **ctx, u32 *ctxlen)
> +{
> +	return security_ops->dentry_init_security (dentry, mode, ctx, ctxlen);
> +}
> +EXPORT_SYMBOL(security_dentry_init_security);
> +
>  int security_inode_init_security(struct inode *inode, struct inode *dir,
>  				  char **name, void **value, size_t *len)
>  {
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index b07871b..680db1d 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -2504,6 +2504,41 @@ static void selinux_inode_free_security(struct inode *inode)
>  	inode_free_security(inode);
>  }
> 
> +/*
> + * For now, we need a way to compute a SID for

Just 'Compute a SID for...' ?

> + * a dentry as the inode is not yet available
> + * (and under NFSv4 has no label backed by an EA anyway.
> + */
> +static int selinux_dentry_init_security(struct dentry *dentry, int mode, void **ctx, u32 *ctxlen)
> +{
> +	struct task_security_struct *tsec;
> +	struct inode_security_struct *dsec;
> +	struct superblock_security_struct *sbsec;
> +	struct inode *dir = dentry->d_parent->d_inode;
> +	u32 newsid;
> +	int rc;
> +
> +	tsec = current->security;
> +	dsec = dir->i_security;
> +	sbsec = dir->i_sb->s_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(mode),
> +					     &newsid);
> +		if (rc) {
> +			printk(KERN_WARNING "%s:  "
> +			       "security_transition_sid failed, rc=%d\n",
> +			       __FUNCTION__, -rc);
> +			return rc;
> +		}
> +	}
> +
> +	return security_sid_to_context(newsid, (char **)ctx, ctxlen);
> +}
> +
>  static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
>  				       char **name, void **value,
>  				       size_t *len)
> @@ -5413,6 +5448,7 @@ static struct security_operations selinux_ops = {
>  	.sb_clone_mnt_opts =		selinux_sb_clone_mnt_opts,
>  	.sb_parse_opts_str = 		selinux_parse_opts_str,
> 
> +	.dentry_init_security =		selinux_dentry_init_security,
> 
>  	.inode_alloc_security =		selinux_inode_alloc_security,
>  	.inode_free_security =		selinux_inode_free_security,
> -- 
> 1.5.5.1
> 
> 
> --
> This message was distributed to subscribers of the selinux mailing list.
> If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
> the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 02/14] LSM/SELinux: inode_{get,set,notify}secctx hooks to access LSM security context information.
       [not found] ` <1222707986-26606-3-git-send-email-dpquigl@tycho.nsa.gov>
  2008-09-30 20:01   ` [PATCH 02/14] LSM/SELinux: inode_{get,set,notify}secctx hooks to access LSM security context information Serge E. Hallyn
@ 2008-09-30 20:22   ` Serge E. Hallyn
  2008-10-06 20:52     ` David P. Quigley
  1 sibling, 1 reply; 24+ messages in thread
From: Serge E. Hallyn @ 2008-09-30 20:22 UTC (permalink / raw)
  To: David P. Quigley
  Cc: hch, viro, casey, sds, matthew.dodd, trond.myklebust, bfields,
	linux-kernel, linux-fsdevel, linux-security-module, selinux,
	labeled-nfs

Quoting David P. Quigley (dpquigl@tycho.nsa.gov):
> This patch introduces three new hooks. The inode_getsecctx hook is used to get
> all relevant information from an LSM about an inode. The inode_setsecctx is
> used to set both the in-core and on-disk state for the inode based on a context
> derived from inode_getsecctx.The final hook inode_notifysecctx will notify the
> LSM of a change for the in-core state of the inode in question. These hooks are
> for use in the labeled NFS code and addresses concerns of how to set security
> on an inode in a multi-xattr LSM. For historical reasons Stephen Smalley's
> explanation of the reason for these hooks is pasted below.
> 
> Quote Stephen Smalley
> 
> inode_setsecctx:  Change the security context of an inode.  Updates the
> in core security context managed by the security module and invokes the
> fs code as needed (via __vfs_setxattr_noperm) to update any backing
> xattrs that represent the context.  Example usage:  NFS server invokes
> this hook to change the security context in its incore inode and on the
> backing file system to a value provided by the client on a SETATTR
> operation.
> 
> inode_notifysecctx:  Notify the security module of what the security
> context of an inode should be.  Initializes the incore security context
> managed by the security module for this inode.  Example usage:  NFS
> client invokes this hook to initialize the security context in its
> incore inode to the value provided by the server for the file when the
> server returned the file's attributes to the client.
> 
> Signed-off-by: Matthew N. Dodd <Matthew.Dodd@sparta.com>
> Signed-off-by: David P. Quigley <dpquigl@tycho.nsa.gov>

Hmm, sorry, for all of these new hooks which you introduce, you do not
define empty cap_* versions and assign them when need in
security_fixup_ops().  But you unconditionally call them if
CONFIG_SECURITY=y.  So if you compile a kernel with CONFIG_SECURITY=y
but CONFIG_SECURITY_SELINUX=n, don't you hose your box?

> ---
>  include/linux/security.h |   50 ++++++++++++++++++++++++++++++++++++++++++++++
>  security/security.c      |   18 ++++++++++++++++
>  security/selinux/hooks.c |   25 +++++++++++++++++++++++
>  3 files changed, 93 insertions(+), 0 deletions(-)
> 
> diff --git a/include/linux/security.h b/include/linux/security.h
> index 80c4d00..8b5b041 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -1289,6 +1289,36 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
>   *	audit_rule_init.
>   *	@rule contains the allocated rule
>   *
> + * @inode_notifysecctx:
> + *	Notify the security module of what the security context of an inode
> + *	should be.  Initializes the incore security context managed by the
> + *	security module for this inode.  Example usage:  NFS client invokes
> + *	this hook to initialize the security context in its incore inode to the
> + *	value provided by the server for the file when the server returned the
> + *	file's attributes to the client.
> + *
> + * 	@inode we wish to set the security context of.
> + * 	@ctx contains the string which we wish to set in the inode.
> + * 	@ctxlen contains the length of @ctx.
> + *
> + * @inode_setsecctx:
> + * 	Change the security context of an inode.  Updates the
> + * 	incore security context managed by the security module and invokes the
> + * 	fs code as needed (via __vfs_setxattr_noperm) to update any backing
> + * 	xattrs that represent the context.  Example usage:  NFS server invokes
> + * 	this hook to change the security context in its incore inode and on the
> + * 	backing filesystem to a value provided by the client on a SETATTR
> + * 	operation.
> + *
> + * 	@dentry contains the inode we wish to set the security context of.
> + * 	@ctx contains the string which we wish to set in the inode.
> + * 	@ctxlen contains the length of @ctx.
> + *
> + * @inode_getsecctx:
> + * 	Returns a string containing all relavent security context information
> + * 	@inode we wish to set the security context of.
> + *	@ctx is a pointer to place the allocated security context should be placed.
> + *	@ctxlen points to the place to put the length of @ctx.
>   * This is the main security structure.
>   */
>  struct security_operations {
> @@ -1479,6 +1509,10 @@ struct security_operations {
>  	int (*secctx_to_secid) (const char *secdata, u32 seclen, u32 *secid);
>  	void (*release_secctx) (char *secdata, u32 seclen);
> 
> +	int (*inode_notifysecctx)(struct inode *inode, void *ctx, u32 ctxlen);
> +	int (*inode_setsecctx)(struct dentry *dentry, void *ctx, u32 ctxlen);
> +	int (*inode_getsecctx)(struct inode *inode, void **ctx, u32 *ctxlen);
> +
>  #ifdef CONFIG_SECURITY_NETWORK
>  	int (*unix_stream_connect) (struct socket *sock,
>  				    struct socket *other, struct sock *newsk);
> @@ -1727,6 +1761,9 @@ int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen);
>  int security_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid);
>  void security_release_secctx(char *secdata, u32 seclen);
> 
> +int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen);
> +int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen);
> +int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen);
>  #else /* CONFIG_SECURITY */
>  struct security_mnt_opts {
>  };
> @@ -2458,6 +2495,19 @@ static inline int security_secctx_to_secid(const char *secdata,
>  static inline void security_release_secctx(char *secdata, u32 seclen)
>  {
>  }
> +
> +static inline int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen)
> +{
> +	return -EOPNOTSUPP;
> +}
> +static inline int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen)
> +{
> +	return -EOPNOTSUPP;
> +}
> +static inline int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen)
> +{
> +	return -EOPNOTSUPP;
> +}
>  #endif	/* CONFIG_SECURITY */
> 
>  #ifdef CONFIG_SECURITY_NETWORK
> diff --git a/security/security.c b/security/security.c
> index 3a4b4f5..d0fd42a 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -869,6 +869,24 @@ void security_release_secctx(char *secdata, u32 seclen)
>  }
>  EXPORT_SYMBOL(security_release_secctx);
> 
> +int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen)
> +{
> +	return security_ops->inode_notifysecctx(inode, ctx, ctxlen);
> +}
> +EXPORT_SYMBOL(security_inode_notifysecctx);
> +
> +int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen)
> +{
> +	return security_ops->inode_setsecctx(dentry, ctx, ctxlen);
> +}
> +EXPORT_SYMBOL(security_inode_setsecctx);
> +
> +int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen)
> +{
> +	return security_ops->inode_getsecctx(inode, ctx, ctxlen);
> +}
> +EXPORT_SYMBOL(security_inode_getsecctx);
> +
>  #ifdef CONFIG_SECURITY_NETWORK
> 
>  int security_unix_stream_connect(struct socket *sock, struct socket *other,
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index 03fc6a8..b07871b 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -5285,6 +5285,28 @@ static void selinux_release_secctx(char *secdata, u32 seclen)
>  	kfree(secdata);
>  }
> 
> +/*
> + *	This hook requires that the inode i_mutex be locked
> + */
> +static int selinux_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen)
> +{
> +	return selinux_inode_setsecurity(inode, XATTR_SELINUX_SUFFIX, ctx, ctxlen, 0);
> +}
> +
> +/*
> + *	This hook requires that the inode i_mutex be locked
> + */
> +static int selinux_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen)
> +{
> +	return __vfs_setxattr_noperm(dentry, XATTR_NAME_SELINUX, ctx, ctxlen, 0);
> +}
> +
> +static int selinux_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen)
> +{
> +	*ctxlen = selinux_inode_getsecurity(inode, XATTR_SELINUX_SUFFIX,
> +						ctx, true);
> +	return *ctxlen;
> +}
>  #ifdef CONFIG_KEYS
> 
>  static int selinux_key_alloc(struct key *k, struct task_struct *tsk,
> @@ -5491,6 +5513,9 @@ static struct security_operations selinux_ops = {
>  	.secid_to_secctx =		selinux_secid_to_secctx,
>  	.secctx_to_secid =		selinux_secctx_to_secid,
>  	.release_secctx =		selinux_release_secctx,
> +	.inode_notifysecctx =		selinux_inode_notifysecctx,
> +	.inode_setsecctx =		selinux_inode_setsecctx,
> +	.inode_getsecctx =		selinux_inode_getsecctx,
> 
>  	.unix_stream_connect =		selinux_socket_unix_stream_connect,
>  	.unix_may_send =		selinux_socket_unix_may_send,
> -- 
> 1.5.5.1
> 
> 
> --
> This message was distributed to subscribers of the selinux mailing list.
> If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
> the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 06/14] KConfig: Add KConfig entries for Labeled NFS
  2008-09-29 17:06 ` [PATCH 06/14] KConfig: Add KConfig entries for Labeled NFS David P. Quigley
@ 2008-09-30 20:40   ` Serge E. Hallyn
  0 siblings, 0 replies; 24+ messages in thread
From: Serge E. Hallyn @ 2008-09-30 20:40 UTC (permalink / raw)
  To: David P. Quigley
  Cc: hch, viro, casey, sds, matthew.dodd, trond.myklebust, bfields,
	linux-kernel, linux-fsdevel, linux-security-module, selinux,
	labeled-nfs

Quoting David P. Quigley (dpquigl@tycho.nsa.gov):
> This patch adds two entries into the fs/KConfig file. The first entry
> NFS_V4_SECURITY_LABEL enables security label support for the NFSv4 client while
> the second entry NFSD_V4_SECURITY_LABEL enables security labeling support on
> the server side.
> 
> Signed-off-by: Matthew N. Dodd <Matthew.Dodd@sparta.com>
> Signed-off-by: David P. Quigley <dpquigl@tycho.nsa.gov>
> ---
>  fs/Kconfig |   17 +++++++++++++++++
>  1 files changed, 17 insertions(+), 0 deletions(-)
> 
> diff --git a/fs/Kconfig b/fs/Kconfig
> index abccb5d..47ffb42 100644
> --- a/fs/Kconfig
> +++ b/fs/Kconfig
> @@ -1633,6 +1633,7 @@ config NFS_V4
> 
>  	  If unsure, say N.
> 
> +
>  config ROOT_NFS
>  	bool "Root file system on NFS"
>  	depends on NFS_FS=y && IP_PNP
> @@ -1644,6 +1645,15 @@ config ROOT_NFS
> 
>  	  Most people say N here.
> 
> +config NFS_V4_SECURITY_LABEL
> +	bool "Provide Security Label support for NFSv4 client"
> +	depends on NFS_V4 && SECURITY
> +	help
> +	  Say Y here if you want label attribute support for NFS version 4.

A little more here :)

"Say Y here if you want security label attribute support for NFS version
4.  Security labels allow security modules like SELinux and Smack to
label files to facilitate enforcement of their policies.

If you do not wish to enforce SELinux or Smack policies on NFSv4 files,
say N."

Or something...  the idea being to make it clear to anyone configuring
a new kernel whether they should say n or y.

> +
> +
> +	  If unsure, say N.
> +
>  config NFSD
>  	tristate "NFS server support"
>  	depends on INET
> @@ -1725,6 +1735,13 @@ config NFSD_V4
> 
>  	  If unsure, say N.
> 
> +config NFSD_V4_SECURITY_LABEL
> +	bool "Provide Security Label support for NFSv4 server"
> +	depends on NFSD_V4 && SECURITY
> +	help
> +	  If you would like to include support for label file attributes
> +	  over NFSv4, say Y here.
> +
>  config LOCKD
>  	tristate
> 
> -- 
> 1.5.5.1
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 11/14] NFS/RPC: Add the auth_seclabel security flavor to allow the process label to be sent to the server.
  2008-09-29 17:06 ` [PATCH 11/14] NFS/RPC: Add the auth_seclabel security flavor to allow the process label to be sent to the server David P. Quigley
@ 2008-10-03 14:23   ` Andy Whitcroft
  2008-10-03 15:44     ` Matthew N. Dodd
  0 siblings, 1 reply; 24+ messages in thread
From: Andy Whitcroft @ 2008-10-03 14:23 UTC (permalink / raw)
  To: David P. Quigley
  Cc: hch, viro, casey, sds, matthew.dodd, trond.myklebust, bfields,
	linux-kernel, linux-fsdevel, linux-security-module, selinux,
	labeled-nfs

On Mon, Sep 29, 2008 at 01:06:23PM -0400, David P. Quigley wrote:
[...]
>  
> +	if (dom->flavour != &svcauth_unix
> +#ifdef CONFIG_SECURITY
> +	    && dom->flavour != &svcauth_seclabel
> +#endif
> +	   )
>  	if (dom->flavour != &svcauth_unix)
>  		return -EINVAL;
>  	udom = container_of(dom, struct unix_domain, h);
> @@ -873,3 +889,80 @@ struct auth_ops svcauth_unix = {
>  	.set_client	= svcauth_unix_set_client,
>  };

checkpatch picked up on a suspect code indent for this hunk.  It is
unhappy about the second if expecting it to be indented.  By the looks
of this I am suspecting a miss-merge of the change in this function and
the second if should have been removed.  To my reading it actually still
does the right thing but ...

-apw

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 11/14] NFS/RPC: Add the auth_seclabel security flavor to allow the process label to be sent to the server.
  2008-10-03 14:23   ` Andy Whitcroft
@ 2008-10-03 15:44     ` Matthew N. Dodd
  0 siblings, 0 replies; 24+ messages in thread
From: Matthew N. Dodd @ 2008-10-03 15:44 UTC (permalink / raw)
  To: Andy Whitcroft
  Cc: David P. Quigley, hch, viro, casey, sds, trond.myklebust,
	bfields, linux-kernel, linux-fsdevel, linux-security-module,
	selinux, labeled-nfs

Andy Whitcroft wrote:
> On Mon, Sep 29, 2008 at 01:06:23PM -0400, David P. Quigley wrote:
> [...]
>>  
>> +	if (dom->flavour != &svcauth_unix
>> +#ifdef CONFIG_SECURITY
>> +	    && dom->flavour != &svcauth_seclabel
>> +#endif
>> +	   )
>>  	if (dom->flavour != &svcauth_unix)
>>  		return -EINVAL;
>>  	udom = container_of(dom, struct unix_domain, h);
>> @@ -873,3 +889,80 @@ struct auth_ops svcauth_unix = {
>>  	.set_client	= svcauth_unix_set_client,
>>  };
> 
> checkpatch picked up on a suspect code indent for this hunk.  It is
> unhappy about the second if expecting it to be indented.  By the looks
> of this I am suspecting a miss-merge of the change in this function and
> the second if should have been removed.  To my reading it actually still
> does the right thing but ...

This does appear to be a miss-merge.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 02/14] LSM/SELinux: inode_{get,set,notify}secctx hooks to access LSM security context information.
  2008-09-30 20:01   ` [PATCH 02/14] LSM/SELinux: inode_{get,set,notify}secctx hooks to access LSM security context information Serge E. Hallyn
@ 2008-10-06 20:52     ` David P. Quigley
  0 siblings, 0 replies; 24+ messages in thread
From: David P. Quigley @ 2008-10-06 20:52 UTC (permalink / raw)
  To: Serge E. Hallyn
  Cc: hch, viro, casey, sds, matthew.dodd, trond.myklebust, bfields,
	linux-kernel, linux-fsdevel, linux-security-module, selinux,
	labeled-nfs

Fixed.

On Tue, 2008-09-30 at 15:01 -0500, Serge E. Hallyn wrote:
> Quoting David P. Quigley (dpquigl@tycho.nsa.gov):
> > This patch introduces three new hooks. The inode_getsecctx hook is used to get
> > all relevant information from an LSM about an inode. The inode_setsecctx is
> > used to set both the in-core and on-disk state for the inode based on a context
> > derived from inode_getsecctx.The final hook inode_notifysecctx will notify the
> > LSM of a change for the in-core state of the inode in question. These hooks are
> > for use in the labeled NFS code and addresses concerns of how to set security
> > on an inode in a multi-xattr LSM. For historical reasons Stephen Smalley's
> > explanation of the reason for these hooks is pasted below.
> > 
> > Quote Stephen Smalley
> > 
> > inode_setsecctx:  Change the security context of an inode.  Updates the
> > in core security context managed by the security module and invokes the
> > fs code as needed (via __vfs_setxattr_noperm) to update any backing
> > xattrs that represent the context.  Example usage:  NFS server invokes
> > this hook to change the security context in its incore inode and on the
> > backing file system to a value provided by the client on a SETATTR
> > operation.
> > 
> > inode_notifysecctx:  Notify the security module of what the security
> > context of an inode should be.  Initializes the incore security context
> > managed by the security module for this inode.  Example usage:  NFS
> > client invokes this hook to initialize the security context in its
> > incore inode to the value provided by the server for the file when the
> > server returned the file's attributes to the client.
> > 
> > Signed-off-by: Matthew N. Dodd <Matthew.Dodd@sparta.com>
> > Signed-off-by: David P. Quigley <dpquigl@tycho.nsa.gov>
> > ---
> >  include/linux/security.h |   50 ++++++++++++++++++++++++++++++++++++++++++++++
> >  security/security.c      |   18 ++++++++++++++++
> >  security/selinux/hooks.c |   25 +++++++++++++++++++++++
> >  3 files changed, 93 insertions(+), 0 deletions(-)
> > 
> > diff --git a/include/linux/security.h b/include/linux/security.h
> > index 80c4d00..8b5b041 100644
> > --- a/include/linux/security.h
> > +++ b/include/linux/security.h
> > @@ -1289,6 +1289,36 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
> >   *	audit_rule_init.
> >   *	@rule contains the allocated rule
> >   *
> > + * @inode_notifysecctx:
> > + *	Notify the security module of what the security context of an inode
> > + *	should be.  Initializes the incore security context managed by the
> > + *	security module for this inode.  Example usage:  NFS client invokes
> > + *	this hook to initialize the security context in its incore inode to the
> > + *	value provided by the server for the file when the server returned the
> > + *	file's attributes to the client.
> > + *
> > + * 	@inode we wish to set the security context of.
> > + * 	@ctx contains the string which we wish to set in the inode.
> > + * 	@ctxlen contains the length of @ctx.
> > + *
> > + * @inode_setsecctx:
> > + * 	Change the security context of an inode.  Updates the
> > + * 	incore security context managed by the security module and invokes the
> > + * 	fs code as needed (via __vfs_setxattr_noperm) to update any backing
> > + * 	xattrs that represent the context.  Example usage:  NFS server invokes
> > + * 	this hook to change the security context in its incore inode and on the
> > + * 	backing filesystem to a value provided by the client on a SETATTR
> > + * 	operation.
> > + *
> > + * 	@dentry contains the inode we wish to set the security context of.
> > + * 	@ctx contains the string which we wish to set in the inode.
> > + * 	@ctxlen contains the length of @ctx.
> > + *
> > + * @inode_getsecctx:
> > + * 	Returns a string containing all relavent security context information
> > + * 	@inode we wish to set the security context of.
> > + *	@ctx is a pointer to place the allocated security context should be placed.
> 
> sentence above is odd.  How about
> 
> 	@ctx is a pointer in which to place the allocated security context
> 
> > + *	@ctxlen points to the place to put the length of @ctx.
> >   * This is the main security structure.
> >   */
> >  struct security_operations {
> > @@ -1479,6 +1509,10 @@ struct security_operations {
> >  	int (*secctx_to_secid) (const char *secdata, u32 seclen, u32 *secid);
> >  	void (*release_secctx) (char *secdata, u32 seclen);
> > 
> > +	int (*inode_notifysecctx)(struct inode *inode, void *ctx, u32 ctxlen);
> > +	int (*inode_setsecctx)(struct dentry *dentry, void *ctx, u32 ctxlen);
> > +	int (*inode_getsecctx)(struct inode *inode, void **ctx, u32 *ctxlen);
> > +
> >  #ifdef CONFIG_SECURITY_NETWORK
> >  	int (*unix_stream_connect) (struct socket *sock,
> >  				    struct socket *other, struct sock *newsk);
> > @@ -1727,6 +1761,9 @@ int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen);
> >  int security_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid);
> >  void security_release_secctx(char *secdata, u32 seclen);
> > 
> > +int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen);
> > +int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen);
> > +int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen);
> >  #else /* CONFIG_SECURITY */
> >  struct security_mnt_opts {
> >  };
> > @@ -2458,6 +2495,19 @@ static inline int security_secctx_to_secid(const char *secdata,
> >  static inline void security_release_secctx(char *secdata, u32 seclen)
> >  {
> >  }
> > +
> > +static inline int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen)
> > +{
> > +	return -EOPNOTSUPP;
> > +}
> > +static inline int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen)
> > +{
> > +	return -EOPNOTSUPP;
> > +}
> > +static inline int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen)
> > +{
> > +	return -EOPNOTSUPP;
> > +}
> >  #endif	/* CONFIG_SECURITY */
> > 
> >  #ifdef CONFIG_SECURITY_NETWORK
> > diff --git a/security/security.c b/security/security.c
> > index 3a4b4f5..d0fd42a 100644
> > --- a/security/security.c
> > +++ b/security/security.c
> > @@ -869,6 +869,24 @@ void security_release_secctx(char *secdata, u32 seclen)
> >  }
> >  EXPORT_SYMBOL(security_release_secctx);
> > 
> > +int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen)
> > +{
> > +	return security_ops->inode_notifysecctx(inode, ctx, ctxlen);
> > +}
> > +EXPORT_SYMBOL(security_inode_notifysecctx);
> > +
> > +int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen)
> > +{
> > +	return security_ops->inode_setsecctx(dentry, ctx, ctxlen);
> > +}
> > +EXPORT_SYMBOL(security_inode_setsecctx);
> > +
> > +int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen)
> > +{
> > +	return security_ops->inode_getsecctx(inode, ctx, ctxlen);
> > +}
> > +EXPORT_SYMBOL(security_inode_getsecctx);
> > +
> >  #ifdef CONFIG_SECURITY_NETWORK
> > 
> >  int security_unix_stream_connect(struct socket *sock, struct socket *other,
> > diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> > index 03fc6a8..b07871b 100644
> > --- a/security/selinux/hooks.c
> > +++ b/security/selinux/hooks.c
> > @@ -5285,6 +5285,28 @@ static void selinux_release_secctx(char *secdata, u32 seclen)
> >  	kfree(secdata);
> >  }
> > 
> > +/*
> > + *	This hook requires that the inode i_mutex be locked
> 
> 'called with inode->i_mutex locked' would make more sense here.
> Requirements on the callers would make more sense in the comments
> in include/linux/security.h, right?
> 
> No code objections, though.
> 
> Acked-by: Serge Hallyn <serue@us.ibm.com>
> 
> > + */
> > +static int selinux_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen)
> > +{
> > +	return selinux_inode_setsecurity(inode, XATTR_SELINUX_SUFFIX, ctx, ctxlen, 0);
> > +}
> > +
> > +/*
> > + *	This hook requires that the inode i_mutex be locked
> > + */
> > +static int selinux_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen)
> > +{
> > +	return __vfs_setxattr_noperm(dentry, XATTR_NAME_SELINUX, ctx, ctxlen, 0);
> > +}
> > +
> > +static int selinux_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen)
> > +{
> > +	*ctxlen = selinux_inode_getsecurity(inode, XATTR_SELINUX_SUFFIX,
> > +						ctx, true);
> > +	return *ctxlen;
> > +}
> >  #ifdef CONFIG_KEYS
> > 
> >  static int selinux_key_alloc(struct key *k, struct task_struct *tsk,
> > @@ -5491,6 +5513,9 @@ static struct security_operations selinux_ops = {
> >  	.secid_to_secctx =		selinux_secid_to_secctx,
> >  	.secctx_to_secid =		selinux_secctx_to_secid,
> >  	.release_secctx =		selinux_release_secctx,
> > +	.inode_notifysecctx =		selinux_inode_notifysecctx,
> > +	.inode_setsecctx =		selinux_inode_setsecctx,
> > +	.inode_getsecctx =		selinux_inode_getsecctx,
> > 
> >  	.unix_stream_connect =		selinux_socket_unix_stream_connect,
> >  	.unix_may_send =		selinux_socket_unix_may_send,
> > -- 
> > 1.5.5.1
> > 
> > 
> > --
> > This message was distributed to subscribers of the selinux mailing list.
> > If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
> > the words "unsubscribe selinux" without quotes as the message.


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 02/14] LSM/SELinux: inode_{get,set,notify}secctx hooks to access LSM security context information.
  2008-09-30 20:22   ` Serge E. Hallyn
@ 2008-10-06 20:52     ` David P. Quigley
  0 siblings, 0 replies; 24+ messages in thread
From: David P. Quigley @ 2008-10-06 20:52 UTC (permalink / raw)
  To: Serge E. Hallyn
  Cc: hch, viro, casey, sds, matthew.dodd, trond.myklebust, bfields,
	linux-kernel, linux-fsdevel, linux-security-module, selinux,
	labeled-nfs

Fixed

On Tue, 2008-09-30 at 15:22 -0500, Serge E. Hallyn wrote:
> Quoting David P. Quigley (dpquigl@tycho.nsa.gov):
> > This patch introduces three new hooks. The inode_getsecctx hook is used to get
> > all relevant information from an LSM about an inode. The inode_setsecctx is
> > used to set both the in-core and on-disk state for the inode based on a context
> > derived from inode_getsecctx.The final hook inode_notifysecctx will notify the
> > LSM of a change for the in-core state of the inode in question. These hooks are
> > for use in the labeled NFS code and addresses concerns of how to set security
> > on an inode in a multi-xattr LSM. For historical reasons Stephen Smalley's
> > explanation of the reason for these hooks is pasted below.
> > 
> > Quote Stephen Smalley
> > 
> > inode_setsecctx:  Change the security context of an inode.  Updates the
> > in core security context managed by the security module and invokes the
> > fs code as needed (via __vfs_setxattr_noperm) to update any backing
> > xattrs that represent the context.  Example usage:  NFS server invokes
> > this hook to change the security context in its incore inode and on the
> > backing file system to a value provided by the client on a SETATTR
> > operation.
> > 
> > inode_notifysecctx:  Notify the security module of what the security
> > context of an inode should be.  Initializes the incore security context
> > managed by the security module for this inode.  Example usage:  NFS
> > client invokes this hook to initialize the security context in its
> > incore inode to the value provided by the server for the file when the
> > server returned the file's attributes to the client.
> > 
> > Signed-off-by: Matthew N. Dodd <Matthew.Dodd@sparta.com>
> > Signed-off-by: David P. Quigley <dpquigl@tycho.nsa.gov>
> 
> Hmm, sorry, for all of these new hooks which you introduce, you do not
> define empty cap_* versions and assign them when need in
> security_fixup_ops().  But you unconditionally call them if
> CONFIG_SECURITY=y.  So if you compile a kernel with CONFIG_SECURITY=y
> but CONFIG_SECURITY_SELINUX=n, don't you hose your box?
> 
> > ---
> >  include/linux/security.h |   50 ++++++++++++++++++++++++++++++++++++++++++++++
> >  security/security.c      |   18 ++++++++++++++++
> >  security/selinux/hooks.c |   25 +++++++++++++++++++++++
> >  3 files changed, 93 insertions(+), 0 deletions(-)
> > 
> > diff --git a/include/linux/security.h b/include/linux/security.h
> > index 80c4d00..8b5b041 100644
> > --- a/include/linux/security.h
> > +++ b/include/linux/security.h
> > @@ -1289,6 +1289,36 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
> >   *	audit_rule_init.
> >   *	@rule contains the allocated rule
> >   *
> > + * @inode_notifysecctx:
> > + *	Notify the security module of what the security context of an inode
> > + *	should be.  Initializes the incore security context managed by the
> > + *	security module for this inode.  Example usage:  NFS client invokes
> > + *	this hook to initialize the security context in its incore inode to the
> > + *	value provided by the server for the file when the server returned the
> > + *	file's attributes to the client.
> > + *
> > + * 	@inode we wish to set the security context of.
> > + * 	@ctx contains the string which we wish to set in the inode.
> > + * 	@ctxlen contains the length of @ctx.
> > + *
> > + * @inode_setsecctx:
> > + * 	Change the security context of an inode.  Updates the
> > + * 	incore security context managed by the security module and invokes the
> > + * 	fs code as needed (via __vfs_setxattr_noperm) to update any backing
> > + * 	xattrs that represent the context.  Example usage:  NFS server invokes
> > + * 	this hook to change the security context in its incore inode and on the
> > + * 	backing filesystem to a value provided by the client on a SETATTR
> > + * 	operation.
> > + *
> > + * 	@dentry contains the inode we wish to set the security context of.
> > + * 	@ctx contains the string which we wish to set in the inode.
> > + * 	@ctxlen contains the length of @ctx.
> > + *
> > + * @inode_getsecctx:
> > + * 	Returns a string containing all relavent security context information
> > + * 	@inode we wish to set the security context of.
> > + *	@ctx is a pointer to place the allocated security context should be placed.
> > + *	@ctxlen points to the place to put the length of @ctx.
> >   * This is the main security structure.
> >   */
> >  struct security_operations {
> > @@ -1479,6 +1509,10 @@ struct security_operations {
> >  	int (*secctx_to_secid) (const char *secdata, u32 seclen, u32 *secid);
> >  	void (*release_secctx) (char *secdata, u32 seclen);
> > 
> > +	int (*inode_notifysecctx)(struct inode *inode, void *ctx, u32 ctxlen);
> > +	int (*inode_setsecctx)(struct dentry *dentry, void *ctx, u32 ctxlen);
> > +	int (*inode_getsecctx)(struct inode *inode, void **ctx, u32 *ctxlen);
> > +
> >  #ifdef CONFIG_SECURITY_NETWORK
> >  	int (*unix_stream_connect) (struct socket *sock,
> >  				    struct socket *other, struct sock *newsk);
> > @@ -1727,6 +1761,9 @@ int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen);
> >  int security_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid);
> >  void security_release_secctx(char *secdata, u32 seclen);
> > 
> > +int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen);
> > +int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen);
> > +int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen);
> >  #else /* CONFIG_SECURITY */
> >  struct security_mnt_opts {
> >  };
> > @@ -2458,6 +2495,19 @@ static inline int security_secctx_to_secid(const char *secdata,
> >  static inline void security_release_secctx(char *secdata, u32 seclen)
> >  {
> >  }
> > +
> > +static inline int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen)
> > +{
> > +	return -EOPNOTSUPP;
> > +}
> > +static inline int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen)
> > +{
> > +	return -EOPNOTSUPP;
> > +}
> > +static inline int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen)
> > +{
> > +	return -EOPNOTSUPP;
> > +}
> >  #endif	/* CONFIG_SECURITY */
> > 
> >  #ifdef CONFIG_SECURITY_NETWORK
> > diff --git a/security/security.c b/security/security.c
> > index 3a4b4f5..d0fd42a 100644
> > --- a/security/security.c
> > +++ b/security/security.c
> > @@ -869,6 +869,24 @@ void security_release_secctx(char *secdata, u32 seclen)
> >  }
> >  EXPORT_SYMBOL(security_release_secctx);
> > 
> > +int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen)
> > +{
> > +	return security_ops->inode_notifysecctx(inode, ctx, ctxlen);
> > +}
> > +EXPORT_SYMBOL(security_inode_notifysecctx);
> > +
> > +int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen)
> > +{
> > +	return security_ops->inode_setsecctx(dentry, ctx, ctxlen);
> > +}
> > +EXPORT_SYMBOL(security_inode_setsecctx);
> > +
> > +int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen)
> > +{
> > +	return security_ops->inode_getsecctx(inode, ctx, ctxlen);
> > +}
> > +EXPORT_SYMBOL(security_inode_getsecctx);
> > +
> >  #ifdef CONFIG_SECURITY_NETWORK
> > 
> >  int security_unix_stream_connect(struct socket *sock, struct socket *other,
> > diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> > index 03fc6a8..b07871b 100644
> > --- a/security/selinux/hooks.c
> > +++ b/security/selinux/hooks.c
> > @@ -5285,6 +5285,28 @@ static void selinux_release_secctx(char *secdata, u32 seclen)
> >  	kfree(secdata);
> >  }
> > 
> > +/*
> > + *	This hook requires that the inode i_mutex be locked
> > + */
> > +static int selinux_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen)
> > +{
> > +	return selinux_inode_setsecurity(inode, XATTR_SELINUX_SUFFIX, ctx, ctxlen, 0);
> > +}
> > +
> > +/*
> > + *	This hook requires that the inode i_mutex be locked
> > + */
> > +static int selinux_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen)
> > +{
> > +	return __vfs_setxattr_noperm(dentry, XATTR_NAME_SELINUX, ctx, ctxlen, 0);
> > +}
> > +
> > +static int selinux_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen)
> > +{
> > +	*ctxlen = selinux_inode_getsecurity(inode, XATTR_SELINUX_SUFFIX,
> > +						ctx, true);
> > +	return *ctxlen;
> > +}
> >  #ifdef CONFIG_KEYS
> > 
> >  static int selinux_key_alloc(struct key *k, struct task_struct *tsk,
> > @@ -5491,6 +5513,9 @@ static struct security_operations selinux_ops = {
> >  	.secid_to_secctx =		selinux_secid_to_secctx,
> >  	.secctx_to_secid =		selinux_secctx_to_secid,
> >  	.release_secctx =		selinux_release_secctx,
> > +	.inode_notifysecctx =		selinux_inode_notifysecctx,
> > +	.inode_setsecctx =		selinux_inode_setsecctx,
> > +	.inode_getsecctx =		selinux_inode_getsecctx,
> > 
> >  	.unix_stream_connect =		selinux_socket_unix_stream_connect,
> >  	.unix_may_send =		selinux_socket_unix_may_send,
> > -- 
> > 1.5.5.1
> > 
> > 
> > --
> > This message was distributed to subscribers of the selinux mailing list.
> > If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
> > the words "unsubscribe selinux" without quotes as the message.


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 03/14] Security: Add hook to calculate context based on a negative dentry.
  2008-09-30 20:15   ` [PATCH 03/14] Security: Add hook to calculate context based on a negative dentry Serge E. Hallyn
@ 2008-10-10 17:54     ` David P. Quigley
  2008-10-10 18:26       ` Serge E. Hallyn
  0 siblings, 1 reply; 24+ messages in thread
From: David P. Quigley @ 2008-10-10 17:54 UTC (permalink / raw)
  To: Serge E. Hallyn
  Cc: hch, viro, casey, sds, matthew.dodd, trond.myklebust, bfields,
	linux-kernel, linux-fsdevel, linux-security-module, selinux,
	labeled-nfs

Should I implement this hook in the capabilities module as well?

Dave


On Tue, 2008-09-30 at 15:15 -0500, Serge E. Hallyn wrote:
> Quoting David P. Quigley (dpquigl@tycho.nsa.gov):
> > There is a time where we need to calculate a context without the
> > inode having been created yet. To do this we take the negative dentry and
> > calculate a context based on the process and the parent directory contexts.
> > 
> > Signed-off-by: Matthew N. Dodd <Matthew.Dodd@sparta.com>
> > Signed-off-by: David P. Quigley <dpquigl@tycho.nsa.gov>
> > ---
> >  include/linux/security.h |   14 ++++++++++++++
> >  security/security.c      |    7 +++++++
> >  security/selinux/hooks.c |   36 ++++++++++++++++++++++++++++++++++++
> >  3 files changed, 57 insertions(+), 0 deletions(-)
> > 
> > diff --git a/include/linux/security.h b/include/linux/security.h
> > index 8b5b041..42b9128 100644
> > --- a/include/linux/security.h
> > +++ b/include/linux/security.h
> > @@ -1379,6 +1379,9 @@ struct security_operations {
> >  	void (*sb_clone_mnt_opts) (const struct super_block *oldsb,
> >  				   struct super_block *newsb);
> >  	int (*sb_parse_opts_str) (char *options, struct security_mnt_opts *opts);
> > +	int (*dentry_init_security) (struct dentry *dentry, int mode,
> > +				     void **ctx, u32 *ctxlen);
> 
> This of course needs a description at top of include/linux/security.h.
> 
> > +
> > 
> >  	int (*inode_alloc_security) (struct inode *inode);
> >  	void (*inode_free_security) (struct inode *inode);
> > @@ -1651,6 +1654,8 @@ int security_sb_set_mnt_opts(struct super_block *sb, struct security_mnt_opts *o
> >  void security_sb_clone_mnt_opts(const struct super_block *oldsb,
> >  				struct super_block *newsb);
> >  int security_sb_parse_opts_str(char *options, struct security_mnt_opts *opts);
> > +int security_dentry_init_security (struct dentry *dentry, int mode,
> > +				   void **ctx, u32 *ctxlen);
> > 
> >  int security_inode_alloc(struct inode *inode);
> >  void security_inode_free(struct inode *inode);
> > @@ -1994,6 +1999,15 @@ static inline int security_inode_alloc(struct inode *inode)
> >  static inline void security_inode_free(struct inode *inode)
> >  { }
> > 
> > +static inline int security_dentry_init_security (struct dentry *dentry,
> > +						 int mode,
> > +						 void **ctx,
> > +						 u32 *ctxlen)
> > +{
> > +	return -EOPNOTSUPP;
> > +}
> > +
> > +
> >  static inline int security_inode_init_security(struct inode *inode,
> >  						struct inode *dir,
> >  						char **name,
> > diff --git a/security/security.c b/security/security.c
> > index d0fd42a..b22a110 100644
> > --- a/security/security.c
> > +++ b/security/security.c
> > @@ -349,6 +349,13 @@ void security_inode_free(struct inode *inode)
> >  	security_ops->inode_free_security(inode);
> >  }
> > 
> > +int security_dentry_init_security (struct dentry *dentry, int mode,
> > +				   void **ctx, u32 *ctxlen)
> > +{
> > +	return security_ops->dentry_init_security (dentry, mode, ctx, ctxlen);
> > +}
> > +EXPORT_SYMBOL(security_dentry_init_security);
> > +
> >  int security_inode_init_security(struct inode *inode, struct inode *dir,
> >  				  char **name, void **value, size_t *len)
> >  {
> > diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> > index b07871b..680db1d 100644
> > --- a/security/selinux/hooks.c
> > +++ b/security/selinux/hooks.c
> > @@ -2504,6 +2504,41 @@ static void selinux_inode_free_security(struct inode *inode)
> >  	inode_free_security(inode);
> >  }
> > 
> > +/*
> > + * For now, we need a way to compute a SID for
> 
> Just 'Compute a SID for...' ?
> 
> > + * a dentry as the inode is not yet available
> > + * (and under NFSv4 has no label backed by an EA anyway.
> > + */
> > +static int selinux_dentry_init_security(struct dentry *dentry, int mode, void **ctx, u32 *ctxlen)
> > +{
> > +	struct task_security_struct *tsec;
> > +	struct inode_security_struct *dsec;
> > +	struct superblock_security_struct *sbsec;
> > +	struct inode *dir = dentry->d_parent->d_inode;
> > +	u32 newsid;
> > +	int rc;
> > +
> > +	tsec = current->security;
> > +	dsec = dir->i_security;
> > +	sbsec = dir->i_sb->s_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(mode),
> > +					     &newsid);
> > +		if (rc) {
> > +			printk(KERN_WARNING "%s:  "
> > +			       "security_transition_sid failed, rc=%d\n",
> > +			       __FUNCTION__, -rc);
> > +			return rc;
> > +		}
> > +	}
> > +
> > +	return security_sid_to_context(newsid, (char **)ctx, ctxlen);
> > +}
> > +
> >  static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
> >  				       char **name, void **value,
> >  				       size_t *len)
> > @@ -5413,6 +5448,7 @@ static struct security_operations selinux_ops = {
> >  	.sb_clone_mnt_opts =		selinux_sb_clone_mnt_opts,
> >  	.sb_parse_opts_str = 		selinux_parse_opts_str,
> > 
> > +	.dentry_init_security =		selinux_dentry_init_security,
> > 
> >  	.inode_alloc_security =		selinux_inode_alloc_security,
> >  	.inode_free_security =		selinux_inode_free_security,
> > -- 
> > 1.5.5.1
> > 
> > 
> > --
> > This message was distributed to subscribers of the selinux mailing list.
> > If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
> > the words "unsubscribe selinux" without quotes as the message.


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 03/14] Security: Add hook to calculate context based on a negative dentry.
  2008-10-10 17:54     ` David P. Quigley
@ 2008-10-10 18:26       ` Serge E. Hallyn
  0 siblings, 0 replies; 24+ messages in thread
From: Serge E. Hallyn @ 2008-10-10 18:26 UTC (permalink / raw)
  To: David P. Quigley
  Cc: hch, viro, casey, sds, matthew.dodd, trond.myklebust, bfields,
	linux-kernel, linux-fsdevel, linux-security-module, selinux,
	labeled-nfs

Quoting David P. Quigley (dpquigl@tycho.nsa.gov):
> Should I implement this hook in the capabilities module as well?

Yup.

-serge

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [RFC v3] Security Label Support for NFSv4
  2008-09-29 17:06 [RFC v3] Security Label Support for NFSv4 David P. Quigley
                   ` (8 preceding siblings ...)
       [not found] ` <1222707986-26606-3-git-send-email-dpquigl@tycho.nsa.gov>
@ 2008-10-13 23:31 ` James Morris
  2008-10-14  2:15   ` [Labeled-nfs] " Matthew N. Dodd
  9 siblings, 1 reply; 24+ messages in thread
From: James Morris @ 2008-10-13 23:31 UTC (permalink / raw)
  To: David P. Quigley
  Cc: hch, viro, casey, sds, matthew.dodd, trond.myklebust, bfields,
	linux-kernel, linux-fsdevel, linux-security-module, selinux,
	labeled-nfs

On Mon, 29 Sep 2008, David P. Quigley wrote:

> 	* New security flavor (auth_seclabel) to transport process label to
> 	  server. This is a derivative of auth_unix so it does not support
> 	  kerberos which has its own issues that need to be dealt with.

This is a problem, as discussed last year:

http://linux-nfs.org/pipermail/labeled-nfs/2007-November/000110.html

We can't require the use of a new auth flavor which is incompatible with 
auth_gss.


- James
-- 
James Morris
<jmorris@namei.org>

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [Labeled-nfs] [RFC v3] Security Label Support for NFSv4
  2008-10-13 23:31 ` [RFC v3] Security Label Support for NFSv4 James Morris
@ 2008-10-14  2:15   ` Matthew N. Dodd
  2008-10-14 13:20     ` Trond Myklebust
  0 siblings, 1 reply; 24+ messages in thread
From: Matthew N. Dodd @ 2008-10-14  2:15 UTC (permalink / raw)
  To: James Morris
  Cc: David P. Quigley, labeled-nfs, linux-kernel, linux-fsdevel,
	linux-security-module, viro, selinux

James Morris wrote:
> On Mon, 29 Sep 2008, David P. Quigley wrote:
> 
>> 	* New security flavor (auth_seclabel) to transport process label to
>> 	  server. This is a derivative of auth_unix so it does not support
>> 	  kerberos which has its own issues that need to be dealt with.
> 
> This is a problem, as discussed last year:
> 
> http://linux-nfs.org/pipermail/labeled-nfs/2007-November/000110.html
> 
> We can't require the use of a new auth flavor which is incompatible with 
> auth_gss.

auth_seclabel demonstrates the flavor independent changes required for 
any RPC layer process label transport.  A GSS solution is currently 
under discussion.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [Labeled-nfs] [RFC v3] Security Label Support for NFSv4
  2008-10-14  2:15   ` [Labeled-nfs] " Matthew N. Dodd
@ 2008-10-14 13:20     ` Trond Myklebust
  2008-10-14 14:28       ` David P. Quigley
  0 siblings, 1 reply; 24+ messages in thread
From: Trond Myklebust @ 2008-10-14 13:20 UTC (permalink / raw)
  To: Matthew N. Dodd
  Cc: James Morris, David P. Quigley, labeled-nfs, linux-kernel,
	linux-fsdevel, linux-security-module, viro, selinux

On Mon, 2008-10-13 at 22:15 -0400, Matthew N. Dodd wrote:
> James Morris wrote:
> > On Mon, 29 Sep 2008, David P. Quigley wrote:
> > 
> >> 	* New security flavor (auth_seclabel) to transport process label to
> >> 	  server. This is a derivative of auth_unix so it does not support
> >> 	  kerberos which has its own issues that need to be dealt with.
> > 
> > This is a problem, as discussed last year:
> > 
> > http://linux-nfs.org/pipermail/labeled-nfs/2007-November/000110.html
> > 
> > We can't require the use of a new auth flavor which is incompatible with 
> > auth_gss.
> 
> auth_seclabel demonstrates the flavor independent changes required for 
> any RPC layer process label transport.  A GSS solution is currently 
> under discussion.

Right, but I'm not particularly interested in merging "demonstration"
code that might end up requiring permanent support. I'd very much like
to see all of this get further through the IETF process before we talk
about merging into mainline.

Cheers
  Trond


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [Labeled-nfs] [RFC v3] Security Label Support for NFSv4
  2008-10-14 13:20     ` Trond Myklebust
@ 2008-10-14 14:28       ` David P. Quigley
  0 siblings, 0 replies; 24+ messages in thread
From: David P. Quigley @ 2008-10-14 14:28 UTC (permalink / raw)
  To: Trond Myklebust
  Cc: Matthew N. Dodd, James Morris, labeled-nfs, linux-kernel,
	linux-fsdevel, linux-security-module, viro, selinux

On Tue, 2008-10-14 at 09:20 -0400, Trond Myklebust wrote:
> On Mon, 2008-10-13 at 22:15 -0400, Matthew N. Dodd wrote:
> > James Morris wrote:
> > > On Mon, 29 Sep 2008, David P. Quigley wrote:
> > > 
> > >> 	* New security flavor (auth_seclabel) to transport process label to
> > >> 	  server. This is a derivative of auth_unix so it does not support
> > >> 	  kerberos which has its own issues that need to be dealt with.
> > > 
> > > This is a problem, as discussed last year:
> > > 
> > > http://linux-nfs.org/pipermail/labeled-nfs/2007-November/000110.html
> > > 
> > > We can't require the use of a new auth flavor which is incompatible with 
> > > auth_gss.
> > 
> > auth_seclabel demonstrates the flavor independent changes required for 
> > any RPC layer process label transport.  A GSS solution is currently 
> > under discussion.
> 
> Right, but I'm not particularly interested in merging "demonstration"
> code that might end up requiring permanent support. I'd very much like
> to see all of this get further through the IETF process before we talk
> about merging into mainline.
> 
> Cheers
>   Trond

Hello,
    Nico seems to have come up with a reasonable solution for this
problem we just need to sit down and draw up a document for it.
Apparently he already created a mechanism in rpcsec_gss for allowing you
to bind the rpc session to more than just the normal credentials. Once
we finalize this and get it into a draft we will work on implementing it
in the rpcsec_gss auth flavor.

Dave


^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH 03/14] Security: Add hook to calculate context based on a negative dentry.
  2008-09-15 20:41 [RFC] Labeled NFS Take 2 David P. Quigley
@ 2008-09-15 20:41 ` David P. Quigley
  0 siblings, 0 replies; 24+ messages in thread
From: David P. Quigley @ 2008-09-15 20:41 UTC (permalink / raw)
  To: hch, viro, casey, sds, matthew.dodd, trond.myklebust, bfields
  Cc: linux-kernel, linux-fsdevel, linux-security-module,
	David P. Quigley, Matthew N. Dodd

There is a time where we need to calculate a context without the
inode having been created yet. To do this we take the negative dentry and
calculate a context based on the process and the parent directory contexts.

Signed-off-by: Matthew N. Dodd <Matthew.Dodd@sparta.com>
Signed-off-by: David P. Quigley <dpquigl@tycho.nsa.gov>
---
 include/linux/security.h |   14 ++++++++++++++
 security/security.c      |    7 +++++++
 security/selinux/hooks.c |   36 ++++++++++++++++++++++++++++++++++++
 3 files changed, 57 insertions(+), 0 deletions(-)

diff --git a/include/linux/security.h b/include/linux/security.h
index 8b5b041..42b9128 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -1379,6 +1379,9 @@ struct security_operations {
 	void (*sb_clone_mnt_opts) (const struct super_block *oldsb,
 				   struct super_block *newsb);
 	int (*sb_parse_opts_str) (char *options, struct security_mnt_opts *opts);
+	int (*dentry_init_security) (struct dentry *dentry, int mode,
+				     void **ctx, u32 *ctxlen);
+
 
 	int (*inode_alloc_security) (struct inode *inode);
 	void (*inode_free_security) (struct inode *inode);
@@ -1651,6 +1654,8 @@ int security_sb_set_mnt_opts(struct super_block *sb, struct security_mnt_opts *o
 void security_sb_clone_mnt_opts(const struct super_block *oldsb,
 				struct super_block *newsb);
 int security_sb_parse_opts_str(char *options, struct security_mnt_opts *opts);
+int security_dentry_init_security (struct dentry *dentry, int mode,
+				   void **ctx, u32 *ctxlen);
 
 int security_inode_alloc(struct inode *inode);
 void security_inode_free(struct inode *inode);
@@ -1994,6 +1999,15 @@ static inline int security_inode_alloc(struct inode *inode)
 static inline void security_inode_free(struct inode *inode)
 { }
 
+static inline int security_dentry_init_security (struct dentry *dentry,
+						 int mode,
+						 void **ctx,
+						 u32 *ctxlen)
+{
+	return -EOPNOTSUPP;
+}
+
+
 static inline int security_inode_init_security(struct inode *inode,
 						struct inode *dir,
 						char **name,
diff --git a/security/security.c b/security/security.c
index d0fd42a..b22a110 100644
--- a/security/security.c
+++ b/security/security.c
@@ -349,6 +349,13 @@ void security_inode_free(struct inode *inode)
 	security_ops->inode_free_security(inode);
 }
 
+int security_dentry_init_security (struct dentry *dentry, int mode,
+				   void **ctx, u32 *ctxlen)
+{
+	return security_ops->dentry_init_security (dentry, mode, ctx, ctxlen);
+}
+EXPORT_SYMBOL(security_dentry_init_security);
+
 int security_inode_init_security(struct inode *inode, struct inode *dir,
 				  char **name, void **value, size_t *len)
 {
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index b07871b..680db1d 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -2504,6 +2504,41 @@ static void selinux_inode_free_security(struct inode *inode)
 	inode_free_security(inode);
 }
 
+/*
+ * For now, we need a way to compute a SID for
+ * a dentry as the inode is not yet available
+ * (and under NFSv4 has no label backed by an EA anyway.
+ */
+static int selinux_dentry_init_security(struct dentry *dentry, int mode, void **ctx, u32 *ctxlen)
+{
+	struct task_security_struct *tsec;
+	struct inode_security_struct *dsec;
+	struct superblock_security_struct *sbsec;
+	struct inode *dir = dentry->d_parent->d_inode;
+	u32 newsid;
+	int rc;
+
+	tsec = current->security;
+	dsec = dir->i_security;
+	sbsec = dir->i_sb->s_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(mode),
+					     &newsid);
+		if (rc) {
+			printk(KERN_WARNING "%s:  "
+			       "security_transition_sid failed, rc=%d\n",
+			       __FUNCTION__, -rc);
+			return rc;
+		}
+	}
+
+	return security_sid_to_context(newsid, (char **)ctx, ctxlen);
+}
+
 static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
 				       char **name, void **value,
 				       size_t *len)
@@ -5413,6 +5448,7 @@ static struct security_operations selinux_ops = {
 	.sb_clone_mnt_opts =		selinux_sb_clone_mnt_opts,
 	.sb_parse_opts_str = 		selinux_parse_opts_str,
 
+	.dentry_init_security =		selinux_dentry_init_security,
 
 	.inode_alloc_security =		selinux_inode_alloc_security,
 	.inode_free_security =		selinux_inode_free_security,
-- 
1.5.5.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

end of thread, other threads:[~2008-10-14 14:48 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-09-29 17:06 [RFC v3] Security Label Support for NFSv4 David P. Quigley
2008-09-29 17:06 ` [PATCH 01/14] VFS: Factor out part of vfs_setxattr so it can be called from the SELinux hook for inode_setsecctx David P. Quigley
2008-09-30 19:51   ` Serge E. Hallyn
2008-09-29 17:06 ` [PATCH 05/14] SELinux: Add new labeling type native labels David P. Quigley
2008-09-29 17:06 ` [PATCH 06/14] KConfig: Add KConfig entries for Labeled NFS David P. Quigley
2008-09-30 20:40   ` Serge E. Hallyn
2008-09-29 17:06 ` [PATCH 08/14] NFS: Add security_label text mount option and handling code to NFS David P. Quigley
2008-09-29 17:06 ` [PATCH 10/14] NFSv4: Introduce new label structure David P. Quigley
2008-09-29 17:06 ` [PATCH 11/14] NFS/RPC: Add the auth_seclabel security flavor to allow the process label to be sent to the server David P. Quigley
2008-10-03 14:23   ` Andy Whitcroft
2008-10-03 15:44     ` Matthew N. Dodd
2008-09-29 17:06 ` [PATCH 13/14] NFS: Extend NFS xattr handlers to accept the security namespace David P. Quigley
     [not found] ` <1222707986-26606-4-git-send-email-dpquigl@tycho.nsa.gov>
2008-09-30 20:15   ` [PATCH 03/14] Security: Add hook to calculate context based on a negative dentry Serge E. Hallyn
2008-10-10 17:54     ` David P. Quigley
2008-10-10 18:26       ` Serge E. Hallyn
     [not found] ` <1222707986-26606-3-git-send-email-dpquigl@tycho.nsa.gov>
2008-09-30 20:01   ` [PATCH 02/14] LSM/SELinux: inode_{get,set,notify}secctx hooks to access LSM security context information Serge E. Hallyn
2008-10-06 20:52     ` David P. Quigley
2008-09-30 20:22   ` Serge E. Hallyn
2008-10-06 20:52     ` David P. Quigley
2008-10-13 23:31 ` [RFC v3] Security Label Support for NFSv4 James Morris
2008-10-14  2:15   ` [Labeled-nfs] " Matthew N. Dodd
2008-10-14 13:20     ` Trond Myklebust
2008-10-14 14:28       ` David P. Quigley
  -- strict thread matches above, loose matches on Subject: below --
2008-09-15 20:41 [RFC] Labeled NFS Take 2 David P. Quigley
2008-09-15 20:41 ` [PATCH 03/14] Security: Add hook to calculate context based on a negative dentry David P. Quigley

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).