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 ...
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 ...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, ...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 ...This patch adds the ability to encode and decode file labels on the server for
the purpose of sending them to the client and also to process label change
requests from the client.
Signed-off-by: Matthew N. Dodd <Matthew.Dodd@sparta.com>
Signed-off-by: David P. Quigley <dpquigl@tycho.nsa.gov>
---
fs/nfsd/export.c | 3 +
fs/nfsd/nfs4proc.c | 25 +++++++++++-
fs/nfsd/nfs4xdr.c | 101 ++++++++++++++++++++++++++++++++++++++++++---
fs/nfsd/vfs.c | 22 ++++++++++
include/linux/nfsd/nfsd.h | 2 +
5 files changed, 146 insertions(+), 7 deletions(-)
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c
index 9dc036f..2523420 100644
--- a/fs/nfsd/export.c
+++ b/fs/nfsd/export.c
@@ -1436,6 +1436,9 @@ static struct flags {
{ NFSEXP_ALLSQUASH, {"all_squash", ""}},
{ NFSEXP_ASYNC, {"async", "sync"}},
{ NFSEXP_GATHERED_WRITES, {"wdelay", "no_wdelay"}},
+#ifdef CONFIG_NFSD_V4_SECURITY_LABEL
+ { NFSEXP_SECURITY_LABEL, {"security_label", ""}},
+#endif
{ NFSEXP_NOHIDE, {"nohide", ""}},
{ NFSEXP_CROSSMOUNT, {"crossmnt", ""}},
{ NFSEXP_NOSUBTREECHECK, {"no_subtree_check", ""}},
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index e5b51ff..b5576ed 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -49,6 +49,10 @@
#include <linux/nfs4_acl.h>
#include <linux/sunrpc/gss_api.h>
+#ifdef CONFIG_NFSD_V4_SECURITY_LABEL
+#include <linux/security.h>
+#endif
+
#define NFSDDBG_FACILITY NFSDDBG_PROC
static inline void
@@ -103,6 +107,13 @@ do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_o
(u32 *)open->op_verf.data,
&open->op_truncate, &created);
+#ifdef CONFIG_NFSD_V4_SECURITY_LABEL
+ if (!status && open->op_label != NULL)
+ /* Is it appropriate to just kick back an error? */
+ status = security_inode_setsecctx(resfh.fh_dentry,
+ open->op_label->label, open->op_label->len);
+#endif
+
/* If we ever decide to use different attrs to store the
* verifier in ...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 recommended attribute named label into the NFSv4 file
attribute structure. It also adds several new flags to allow the NFS client and
server to determine if this attribute is supported and if it is being sent over
the wire.
Signed-off-by: Matthew N. Dodd <Matthew.Dodd@sparta.com>
Signed-off-by: David P. Quigley <dpquigl@tycho.nsa.gov>
---
include/linux/nfs4.h | 2 ++
include/linux/nfs_fs_sb.h | 2 +-
include/linux/nfs_xdr.h | 4 ++++
include/linux/nfsd/export.h | 5 +++--
include/linux/nfsd/nfsd.h | 7 ++++---
5 files changed, 14 insertions(+), 6 deletions(-)
diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h
index ea03667..144eacf 100644
--- a/include/linux/nfs4.h
+++ b/include/linux/nfs4.h
@@ -21,6 +21,7 @@
#define NFS4_FHSIZE 128
#define NFS4_MAXPATHLEN PATH_MAX
#define NFS4_MAXNAMLEN NAME_MAX
+#define NFS4_MAXLABELLEN 4096
#define NFS4_ACCESS_READ 0x0001
#define NFS4_ACCESS_LOOKUP 0x0002
@@ -345,6 +346,7 @@ enum lock_type4 {
#define FATTR4_WORD1_TIME_MODIFY (1UL << 21)
#define FATTR4_WORD1_TIME_MODIFY_SET (1UL << 22)
#define FATTR4_WORD1_MOUNTED_ON_FILEID (1UL << 23)
+#define FATTR4_WORD1_SECURITY_LABEL (1UL << 31)
#define NFSPROC4_NULL 0
#define NFSPROC4_COMPOUND 1
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
index c9beacd..9475bb0 100644
--- a/include/linux/nfs_fs_sb.h
+++ b/include/linux/nfs_fs_sb.h
@@ -135,5 +135,5 @@ struct nfs_server {
#define NFS_CAP_SYMLINKS (1U << 2)
#define NFS_CAP_ACLS (1U << 3)
#define NFS_CAP_ATOMIC_OPEN (1U << 4)
-
+#define NFS_CAP_SECURITY_LABEL (1U << 5)
#endif
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index 8c77c11..0d77568 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -56,6 +56,10 @@ struct nfs_fattr {
__u64 change_attr; /* NFSv4 change attribute */
__u64 pre_change_attr;/* pre-op NFSv4 change attribute */
unsigned ...There are areas in the Labeled NFS code where where we need to test if the
attribute being requested exhibits the semantics of a MAC model. This allows us
to make sure that we get the desired semantics from the attribute instead of
something else such as capabilities or a time based LSM.
Signed-off-by: Matthew N. Dodd <Matthew.Dodd@sparta.com>
Signed-off-by: David P. Quigley <dpquigl@tycho.nsa.gov>
---
include/linux/security.h | 11 +++++++++++
security/security.c | 6 ++++++
security/selinux/hooks.c | 6 ++++++
security/smack/smack_lsm.c | 11 +++++++++++
4 files changed, 34 insertions(+), 0 deletions(-)
diff --git a/include/linux/security.h b/include/linux/security.h
index 42b9128..3031e6c 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -1244,6 +1244,10 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
* @pages contains the number of pages.
* Return 0 if permission is granted.
*
+ * @ismaclabel:
+ * Check if the extended attribute specified by @name represents a MAC label.
+ * @name full extended attribute name to check against LSM as a MAC label.
+ *
* @secid_to_secctx:
* Convert secid to security context.
* @secid contains the security ID.
@@ -1508,6 +1512,7 @@ struct security_operations {
int (*getprocattr) (struct task_struct *p, char *name, char **value);
int (*setprocattr) (struct task_struct *p, char *name, void *value, size_t size);
+ int (*ismaclabel) (const char * name);
int (*secid_to_secctx) (u32 secid, char **secdata, u32 *seclen);
int (*secctx_to_secid) (const char *secdata, u32 seclen, u32 *secid);
void (*release_secctx) (char *secdata, u32 seclen);
@@ -1762,6 +1767,7 @@ int security_getprocattr(struct task_struct *p, char *name, char **value);
int security_setprocattr(struct task_struct *p, char *name, void *value, size_t size);
int security_netlink_send(struct sock *sk, struct sk_buff *skb);
int security_netlink_recv(struct sk_buff *skb, int ...--
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 --
Two fields have been added to the nfs_fattr structure to carry the security label and its length. This has raised the need to provide lifecycle management for these values. This patch introduces two macros nfs_fattr_alloc and nfs_fattr_fini which are used to allocate and destroy these fields inside the nfs_fattr structure. These macros do not modify any other components of the structure so nfs_fattr_init still has to be used on these structures. In the event that CONFIG_SECURITY is not set these calls should compile away. Signed-off-by: Matthew N. Dodd <Matthew.Dodd@sparta.com> Signed-off-by: David P. Quigley <dpquigl@tycho.nsa.gov> --- fs/nfs/client.c | 18 +++++++++- fs/nfs/dir.c | 24 +++++++++++++ fs/nfs/getroot.c | 35 ++++++++++++++++++- fs/nfs/inode.c | 16 +++++++++ fs/nfs/namespace.c | 3 ++ fs/nfs/nfs3proc.c | 7 ++++ fs/nfs/nfs4proc.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++- fs/nfs/proc.c | 12 ++++++- fs/nfs/super.c | 4 ++ include/linux/nfs_fs.h | 46 +++++++++++++++++++++++++ 10 files changed, 248 insertions(+), 5 deletions(-) diff --git a/fs/nfs/client.c b/fs/nfs/client.c index 5ee23e7..756d554 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c @@ -902,6 +902,8 @@ struct nfs_server *nfs_create_server(const struct nfs_parsed_mount_data *data, struct nfs_fattr fattr; int error; + memset(&fattr, 0, sizeof(struct nfs_fattr)); + server = nfs_alloc_server(); if (!server) return ERR_PTR(-ENOMEM); @@ -952,10 +954,12 @@ struct nfs_server *nfs_create_server(const struct nfs_parsed_mount_data *data, spin_unlock(&nfs_client_lock); server->mount_time = jiffies; + nfs_fattr_fini(&fattr); return server; error: nfs_free_server(server); + nfs_fattr_fini(&fattr); return ERR_PTR(error); } @@ -1073,7 +1077,7 @@ static int nfs4_init_server(struct nfs_server *server, goto error; /* Initialise the client representation from the ...
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 @@ ...
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, ...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 ...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 patch implements the client transport and handling support for labeled
NFS. The patch adds two functions to encode and decode the security label
recommended attribute which makes use of the LSM hooks added earlier. It also
adds code to grab the label from the file attribute structures and encode the
label to be sent back to the server.
Signed-off-by: Matthew N. Dodd <Matthew.Dodd@sparta.com>
Signed-off-by: David P. Quigley <dpquigl@tycho.nsa.gov>
---
fs/nfs/inode.c | 45 ++++++-
fs/nfs/nfs4proc.c | 303 ++++++++++++++++++++++++++++++++++++++++++----
fs/nfs/nfs4xdr.c | 55 ++++++++-
fs/nfs/super.c | 16 +++-
include/linux/nfs_fs.h | 2 +
security/selinux/hooks.c | 5 +
6 files changed, 391 insertions(+), 35 deletions(-)
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 40d7142..dde0667 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -143,10 +143,13 @@ static void nfs_zap_caches_locked(struct inode *inode)
nfsi->attrtimeo_timestamp = jiffies;
memset(NFS_COOKIEVERF(inode), 0, sizeof(NFS_COOKIEVERF(inode)));
+ nfsi->cache_validity |= NFS_INO_INVALID_ATTR| \
+ NFS_INO_INVALID_LABEL| \
+ NFS_INO_INVALID_ACCESS| \
+ NFS_INO_INVALID_ACL| \
+ NFS_INO_REVAL_PAGECACHE;
if (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode))
- nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL|NFS_INO_REVAL_PAGECACHE;
- else
- nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL|NFS_INO_REVAL_PAGECACHE;
+ nfsi->cache_validity |= NFS_INO_INVALID_DATA;
}
void nfs_zap_caches(struct inode *inode)
@@ -235,6 +238,29 @@ nfs_init_locked(struct inode *inode, void *opaque)
/* Don't use READDIRPLUS on directories that we believe are too large */
#define NFS_LIMIT_READDIRPLUS (8*PAGE_SIZE)
+#ifdef CONFIG_NFS_V4_SECURITY_LABEL
+void nfs_setsecurity(struct inode *inode, struct nfs_fattr *fattr)
+{
+ int ...