[Labeled-nfs] [PATCH 7/7] NFSv4: Server implementation of MAC Labeling
Casey Schaufler
casey at schaufler-ca.com
Wed Aug 1 17:33:58 EDT 2007
--- "David P. Quigley" <dpquigl at tycho.nsa.gov> wrote:
> From: David P. Quigley <dpquigl at tycho.nsa.gov>
>
> This patch implements the encoding of a MAC label on the server side to be
> sent
> across the wire to the NFSv4 client. At this time there is no method of
> receiving a label from the client to be set on the server.
Perhaps you should look into how the ACL code deals with attributes
with non-uniform sizes.
> Signed-off-by: David P. Quigley <dpquigl at tycho.nsa.gov>
> ---
> fs/nfsd/nfs4xdr.c | 77
> ++++++++++++++++++++++++++++++++++++++++++++++++++++-
> 1 files changed, 76 insertions(+), 1 deletions(-)
>
> diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
> index 8ef0964..593a0b9 100644
> --- a/fs/nfsd/nfs4xdr.c
> +++ b/fs/nfsd/nfs4xdr.c
> @@ -58,6 +58,7 @@
> #include <linux/nfs4_acl.h>
> #include <linux/sunrpc/gss_api.h>
> #include <linux/sunrpc/svcauth_gss.h>
> +#include <linux/security.h>
>
> #define NFSDDBG_FACILITY NFSDDBG_XDR
>
> @@ -408,6 +409,20 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32
> *bmval, struct iattr *ia
> goto xdr_error;
> }
> }
> +#ifdef CONFIG_NFSD_V4_MAC
> + if (bmval[1] & FATTR4_WORD1_MAC_LABEL) {
> + READ_BUF(4);
> + len += 4;
> + READ32(dummy32);
> + READ_BUF(dummy32);
> + len += (XDR_QUADLEN(dummy32) << 2);
> + READMEM(buf, dummy32);
> + if (security_secctx_to_secid(&iattr->ia_sid,
> + (char *)buf, dummy32) != 0)
> + goto out_nfserr;
> + iattr->ia_valid |= ATTR_MAC_LABEL;
> + }
> +#endif /* CONFIG_NFSD_V4_MAC */
> if (len != expected_len)
> goto xdr_error;
>
> @@ -1414,6 +1429,34 @@ nfsd4_encode_aclname(struct svc_rqst *rqstp, int
> whotype, uid_t id, int group,
> return nfsd4_encode_name(rqstp, whotype, id, group, p, buflen);
> }
>
> +#ifdef CONFIG_NFSD_V4_MAC
> +static inline __be32
> +nfsd4_encode_mac_label(struct svc_rqst *rqstp,
> + struct dentry *dentry,
> + __be32 **p, int *buflen)
> +{
> + char *context;
> + unsigned len = 0;
> + u32 secid;
> +
> + security_inode_getsecid(dentry->d_inode, &secid);
> + security_secid_to_secctx(secid, &context, &len);
> + if (len < 0)
> + return nfserrno(len);
> + if (*buflen < ((XDR_QUADLEN(len) << 2) + 4)) {
> + kfree(context);
> + return nfserr_resource;
> + }
> +
> + *p = xdr_encode_opaque(*p, context, len);
> + *buflen -= (XDR_QUADLEN(len) << 2) + 4;
> + BUG_ON(*buflen < 0);
> +
> + kfree(context);
> + return 0;
> +}
> +#endif /* CONFIG_NFSD_V4_MAC */
> +
> #define WORD0_ABSENT_FS_ATTRS (FATTR4_WORD0_FS_LOCATIONS | FATTR4_WORD0_FSID
> | \
> FATTR4_WORD0_RDATTR_ERROR)
> #define WORD1_ABSENT_FS_ATTRS FATTR4_WORD1_MOUNTED_ON_FILEID
> @@ -1508,6 +1551,17 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct
> svc_export *exp,
> bmval0 &= ~FATTR4_WORD0_FS_LOCATIONS;
> }
> }
> +#ifdef CONFIG_NFSD_V4_MAC
> + /**
> + * This really isn't a good way to do this. We need the framework to detect
> a
> + * mac implementation and handle this if it doesn't find one.
> + *
> + if (bmval1 & FATTR4_WORD1_MAC_LABEL) {
> + if(!selinux_enabled)
Eh Hm.
> + bmval1 &= ~FATTR_WORD1_MAC_LABEL;
> + }
> + */
> +#endif /* CONFIG_NFSD_V4_MAC */
> if ((buflen -= 16) < 0)
> goto out_resource;
>
> @@ -1518,15 +1572,25 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct
> svc_export *exp,
>
> if (bmval0 & FATTR4_WORD0_SUPPORTED_ATTRS) {
> u32 word0 = NFSD_SUPPORTED_ATTRS_WORD0;
> + u32 word1 = NFSD_SUPPORTED_ATTRS_WORD1;
> if ((buflen -= 12) < 0)
> goto out_resource;
> if (!aclsupport)
> word0 &= ~FATTR4_WORD0_ACL;
> if (!exp->ex_fslocs.locations)
> word0 &= ~FATTR4_WORD0_FS_LOCATIONS;
> + #ifdef CONFIG_NFSD_V4_MAC
> + /* XXX: should also be turned into a check to the framework */
> + /* XXX: turn this on unconditionally for now ...*/
> + if (1 || exp->ex_flags & NFSEXP_MAC_LABEL)
> + word1 |= FATTR4_WORD1_MAC_LABEL;
> + else
> + word1 &= ~FATTR4_WORD1_MAC_LABEL;
> + #endif /* CONFIG_NFSD_V4_MAC */
> +
> WRITE32(2);
> WRITE32(word0);
> - WRITE32(NFSD_SUPPORTED_ATTRS_WORD1);
> + WRITE32(word1);
> }
> if (bmval0 & FATTR4_WORD0_TYPE) {
> if ((buflen -= 4) < 0)
> @@ -1832,6 +1896,17 @@ out_acl:
> } else
> WRITE64((u64) stat.ino);
> }
> +#ifdef CONFIG_NFSD_V4_MAC
> + if (bmval1 & FATTR4_WORD1_MAC_LABEL) {
> + status = nfsd4_encode_mac_label(rqstp, dentry,
> + &p, &buflen);
> + if (status == nfserr_resource)
> + goto out_resource;
> + if (status)
> + goto out;
> + }
> +#endif /* CONFIG_NFSD_V4_MAC */
> +
> *attrlenp = htonl((char *)p - (char *)attrlenp - 4);
> *countp = p - buffer;
> status = nfs_ok;
> --
> 1.5.2.2
>
>
> --
> This message was distributed to subscribers of the selinux mailing list.
> If you no longer wish to subscribe, send mail to majordomo at tycho.nsa.gov with
> the words "unsubscribe selinux" without quotes as the message.
>
>
>
Casey Schaufler
casey at schaufler-ca.com
More information about the Labeled-nfs
mailing list