2017-01-12 02:18:13

by J. Bruce Fields

[permalink] [raw]
Subject: [PATCH 1/3] nfsd: fix supported attributes for acl & labels

From: "J. Bruce Fields" <[email protected]>

Oops--in 916d2d844afd I moved some constants into an array for
convenience, but here I'm accidentally writing to that array.

The effect is that if you ever encounter a filesystem lacking support
for ACLs or security labels, then all queries of supported attributes
will report that attribute as unsupported from then on.

Fixes: 916d2d844afd "nfsd: clean up supported attribute handling"
Signed-off-by: J. Bruce Fields <[email protected]>
---
fs/nfsd/nfs4xdr.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 64c262aef633..048b06861f94 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -2439,7 +2439,9 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp,
p++; /* to be backfilled later */

if (bmval0 & FATTR4_WORD0_SUPPORTED_ATTRS) {
- u32 *supp = nfsd_suppattrs[minorversion];
+ u32 supp[3];
+
+ memcpy(supp, nfsd_suppattrs[minorversion], sizeof(supp));

if (!IS_POSIXACL(dentry->d_inode))
supp[0] &= ~FATTR4_WORD0_ACL;
--
2.9.3



2017-01-12 02:18:08

by J. Bruce Fields

[permalink] [raw]
Subject: [PATCH 3/3] nfsd: opt in to labeled nfs per export

From: "J. Bruce Fields" <[email protected]>

Currently turning on NFSv4.2 results in 4.2 clients suddenly seeing the
individual file labels as they're set on the server. This is not what
they've previously seen, and not appropriate in may cases. (In
particular, if clients have heterogenous security policies then one
client's labels may not even make sense to another.) Labeled NFS should
be opted in only in those cases when the administrator knows it makes
sense.

It's helpful to be able to turn 4.2 on by default, and otherwise the
protocol upgrade seems free of regressions. So, default labeled NFS to
off and provide an export flag to reenable it.

Users wanting labeled NFS support on an export will henceforth need to:

- make sure 4.2 support is enabled on client and server (as
before), and
- upgrade the server nfs-utils to a version supporting the new
"security_label" export flag.
- set that "security_label" flag on the export.

This is commit may be seen as a regression to anyone currently depending
on security labels. We believe those cases are currently rare.

Reported-by: [email protected]
Signed-off-by: J. Bruce Fields <[email protected]>
---
fs/nfsd/export.c | 1 +
fs/nfsd/nfs4proc.c | 4 ++++
fs/nfsd/nfs4xdr.c | 5 ++++-
include/uapi/linux/nfsd/export.h | 5 +++--
4 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c
index 43e109cc0ccc..e71f11b1a180 100644
--- a/fs/nfsd/export.c
+++ b/fs/nfsd/export.c
@@ -1102,6 +1102,7 @@ static struct flags {
{ NFSEXP_NOAUTHNLM, {"insecure_locks", ""}},
{ NFSEXP_V4ROOT, {"v4root", ""}},
{ NFSEXP_PNFS, {"pnfs", ""}},
+ { NFSEXP_SECURITY_LABEL, {"security_label", ""}},
{ 0, {"", ""}}
};

diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 74a6e573e061..6f0b89d1c09b 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -95,11 +95,15 @@ check_attr_support(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
u32 *bmval, u32 *writable)
{
struct dentry *dentry = cstate->current_fh.fh_dentry;
+ struct svc_export *exp = cstate->current_fh.fh_export;

if (!nfsd_attrs_supported(cstate->minorversion, bmval))
return nfserr_attrnotsupp;
if ((bmval[0] & FATTR4_WORD0_ACL) && !IS_POSIXACL(d_inode(dentry)))
return nfserr_attrnotsupp;
+ if ((bmval[2] & FATTR4_WORD2_SECURITY_LABEL) &&
+ !(exp->ex_flags & NFSEXP_SECURITY_LABEL))
+ return nfserr_attrnotsupp;
if (writable && !bmval_is_subset(bmval, writable))
return nfserr_inval;
if (writable && (bmval[2] & FATTR4_WORD2_MODE_UMASK) &&
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 7a63d442042c..0d6b257ee1a0 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -2416,8 +2416,11 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp,
#ifdef CONFIG_NFSD_V4_SECURITY_LABEL
if ((bmval2 & FATTR4_WORD2_SECURITY_LABEL) ||
bmval0 & FATTR4_WORD0_SUPPORTED_ATTRS) {
- err = security_inode_getsecctx(d_inode(dentry),
+ if (exp->ex_flags & NFSEXP_SECURITY_LABEL)
+ err = security_inode_getsecctx(d_inode(dentry),
&context, &contextlen);
+ else
+ err = -EOPNOTSUPP;
contextsupport = (err == 0);
if (bmval2 & FATTR4_WORD2_SECURITY_LABEL) {
if (err == -EOPNOTSUPP)
diff --git a/include/uapi/linux/nfsd/export.h b/include/uapi/linux/nfsd/export.h
index 0df7bd5d2fb1..c3be256107c6 100644
--- a/include/uapi/linux/nfsd/export.h
+++ b/include/uapi/linux/nfsd/export.h
@@ -32,7 +32,8 @@
#define NFSEXP_ASYNC 0x0010
#define NFSEXP_GATHERED_WRITES 0x0020
#define NFSEXP_NOREADDIRPLUS 0x0040
-/* 80 100 currently unused */
+#define NFSEXP_SECURITY_LABEL 0x0080
+/* 0x100 currently unused */
#define NFSEXP_NOHIDE 0x0200
#define NFSEXP_NOSUBTREECHECK 0x0400
#define NFSEXP_NOAUTHNLM 0x0800 /* Don't authenticate NLM requests - just trust */
@@ -53,7 +54,7 @@
#define NFSEXP_PNFS 0x20000

/* All flags that we claim to support. (Note we don't support NOACL.) */
-#define NFSEXP_ALLFLAGS 0x3FE7F
+#define NFSEXP_ALLFLAGS 0x3FEFF

/* The flags that may vary depending on security flavor: */
#define NFSEXP_SECINFO_FLAGS (NFSEXP_READONLY | NFSEXP_ROOTSQUASH \
--
2.9.3


2017-01-12 02:18:08

by J. Bruce Fields

[permalink] [raw]
Subject: [PATCH 2/3] nfsd: constify nfsd_suppatttrs

From: "J. Bruce Fields" <[email protected]>

To keep me from making that mistake again.

Signed-off-by: J. Bruce Fields <[email protected]>
---
fs/nfsd/nfs4xdr.c | 2 +-
fs/nfsd/nfsd.h | 6 +++---
2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 048b06861f94..7a63d442042c 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -58,7 +58,7 @@

#define NFSDDBG_FACILITY NFSDDBG_XDR

-u32 nfsd_suppattrs[3][3] = {
+const u32 nfsd_suppattrs[3][3] = {
{NFSD4_SUPPORTED_ATTRS_WORD0,
NFSD4_SUPPORTED_ATTRS_WORD1,
NFSD4_SUPPORTED_ATTRS_WORD2},
diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h
index d74c8c44dc35..d96606801d47 100644
--- a/fs/nfsd/nfsd.h
+++ b/fs/nfsd/nfsd.h
@@ -362,16 +362,16 @@ void nfsd_lockd_shutdown(void);
FATTR4_WORD2_MODE_UMASK | \
NFSD4_2_SECURITY_ATTRS)

-extern u32 nfsd_suppattrs[3][3];
+extern const u32 nfsd_suppattrs[3][3];

-static inline bool bmval_is_subset(u32 *bm1, u32 *bm2)
+static inline bool bmval_is_subset(const u32 *bm1, const u32 *bm2)
{
return !((bm1[0] & ~bm2[0]) ||
(bm1[1] & ~bm2[1]) ||
(bm1[2] & ~bm2[2]));
}

-static inline bool nfsd_attrs_supported(u32 minorversion, u32 *bmval)
+static inline bool nfsd_attrs_supported(u32 minorversion, const u32 *bmval)
{
return bmval_is_subset(bmval, nfsd_suppattrs[minorversion]);
}
--
2.9.3


2017-01-12 02:22:07

by J. Bruce Fields

[permalink] [raw]
Subject: [PATCH] exportfs: support "security_label" export option

From: "J. Bruce Fields" <[email protected]>

On recent kernels only exports with NFSEXP_SECURITY_LABEL set will
export security labels.

Signed-off-by: J. Bruce Fields <[email protected]>
---
support/include/nfs/export.h | 3 ++-
support/nfs/exports.c | 4 ++++
utils/exportfs/exportfs.c | 2 ++
utils/exportfs/exports.man | 8 ++++++++
4 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/support/include/nfs/export.h b/support/include/nfs/export.h
index 1194255899bd..0eca828ee3ad 100644
--- a/support/include/nfs/export.h
+++ b/support/include/nfs/export.h
@@ -18,7 +18,8 @@
#define NFSEXP_ASYNC 0x0010
#define NFSEXP_GATHERED_WRITES 0x0020
#define NFSEXP_NOREADDIRPLUS 0x0040
-/* 80, 100 unused */
+#define NFSEXP_SECURITY_LABEL 0x0080
+/* 0x100 unused */
#define NFSEXP_NOHIDE 0x0200
#define NFSEXP_NOSUBTREECHECK 0x0400
#define NFSEXP_NOAUTHNLM 0x0800
diff --git a/support/nfs/exports.c b/support/nfs/exports.c
index d992747c13a1..92bd6e60ddf7 100644
--- a/support/nfs/exports.c
+++ b/support/nfs/exports.c
@@ -274,6 +274,8 @@ putexportent(struct exportent *ep)
"no_" : "");
if (ep->e_flags & NFSEXP_NOREADDIRPLUS)
fprintf(fp, "nordirplus,");
+ if (ep->e_flags & NFSEXP_SECURITY_LABEL)
+ fprintf(fp, "security_label,");
fprintf(fp, "%spnfs,", (ep->e_flags & NFSEXP_PNFS)? "" : "no_");
if (ep->e_flags & NFSEXP_FSID) {
fprintf(fp, "fsid=%d,", ep->e_fsid);
@@ -543,6 +545,8 @@ parseopts(char *cp, struct exportent *ep, int warn, int *had_subtree_opt_ptr)
setflags(NFSEXP_ASYNC, active, ep);
else if (!strcmp(opt, "nordirplus"))
setflags(NFSEXP_NOREADDIRPLUS, active, ep);
+ else if (!strcmp(opt, "security_label"))
+ setflags(NFSEXP_SECURITY_LABEL, active, ep);
else if (!strcmp(opt, "nohide"))
setflags(NFSEXP_NOHIDE, active, ep);
else if (!strcmp(opt, "hide"))
diff --git a/utils/exportfs/exportfs.c b/utils/exportfs/exportfs.c
index 15a15835a01f..38039978ef5f 100644
--- a/utils/exportfs/exportfs.c
+++ b/utils/exportfs/exportfs.c
@@ -705,6 +705,8 @@ dump(int verbose, int export_format)
c = dumpopt(c, "insecure_locks");
if (ep->e_flags & NFSEXP_NOREADDIRPLUS)
c = dumpopt(c, "nordirplus");
+ if (ep->e_flags & NFSEXP_SECURITY_LABEL)
+ c = dumpopt(c, "security_label");
if (ep->e_flags & NFSEXP_NOACL)
c = dumpopt(c, "no_acl");
if (ep->e_flags & NFSEXP_PNFS)
diff --git a/utils/exportfs/exports.man b/utils/exportfs/exports.man
index 93092463153b..d8de6bec2583 100644
--- a/utils/exportfs/exports.man
+++ b/utils/exportfs/exports.man
@@ -417,6 +417,14 @@ devices. The default can be explicitly requested with the
.I no_pnfs
option.

+.TP
+.IR security_label
+With this option set, clients using NFSv4.2 or higher will be able to
+set and retrieve security labels (such as those used by SELinux). This
+will only work if all clients use a consistent security policy. Note
+that early kernels did not support this export option, and instead
+enabled security labels by default.
+
.SS User ID Mapping
.PP
.B nfsd
--
2.9.3