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 ...
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, ...This part surely looks reasonable. --
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 --
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 --
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, ...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 */
...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 ...On Mon, Sep 29, 2008 at 01:06:23PM -0400, David P. Quigley wrote: 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 --
This does appear to be a miss-merge. --
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 ...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) + ...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> --
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
--
