Merge branch 'labeled-nfs' into linux-next
authorTrond Myklebust <Trond.Myklebust@netapp.com>
Fri, 28 Jun 2013 20:29:51 +0000 (16:29 -0400)
committerTrond Myklebust <Trond.Myklebust@netapp.com>
Fri, 28 Jun 2013 20:29:51 +0000 (16:29 -0400)
* labeled-nfs:
  NFS: Apply v4.1 capabilities to v4.2
  NFS: Add in v4.2 callback operation
  NFS: Make callbacks minor version generic
  Kconfig: Add Kconfig entry for Labeled NFS V4 client
  NFS: Extend NFS xattr handlers to accept the security namespace
  NFS: Client implementation of Labeled-NFS
  NFS: Add label lifecycle management
  NFS:Add labels to client function prototypes
  NFSv4: Extend fattr bitmaps to support all 3 words
  NFSv4: Introduce new label structure
  NFSv4: Add label recommended attribute and NFSv4 flags
  NFSv4.2: Added NFS v4.2 support to the NFS client
  SELinux: Add new labeling type native labels
  LSM: Add flags field to security_sb_set_mnt_opts for in kernel mount data.
  Security: Add Hook to test if the particular xattr is part of a MAC model.
  Security: Add hook to calculate context based on a negative dentry.
  NFS: Add NFSv4.2 protocol constants

Conflicts:
fs/nfs/nfs4proc.c

13 files changed:
1  2 
fs/nfs/callback_proc.c
fs/nfs/callback_xdr.c
fs/nfs/client.c
fs/nfs/dir.c
fs/nfs/inode.c
fs/nfs/internal.h
fs/nfs/nfs4_fs.h
fs/nfs/nfs4client.c
fs/nfs/nfs4proc.c
fs/nfs/nfs4xdr.c
fs/nfs/super.c
include/linux/nfs_fs.h
include/linux/nfs_xdr.h

Simple merge
Simple merge
diff --cc fs/nfs/client.c
Simple merge
diff --cc fs/nfs/dir.c
Simple merge
diff --cc fs/nfs/inode.c
Simple merge
Simple merge
Simple merge
Simple merge
index 6d46f966d169643b57531565abfe59396d952168,c0d3123b6eba2bffa2ff650de7e854fae1886ed2..d95616f140ad1be205d2980520a235b20b8ca9dd
@@@ -77,17 -77,66 +77,68 @@@ static int _nfs4_recover_proc_open(stru
  static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *);
  static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *, struct nfs4_state *);
  static void nfs_fixup_referral_attributes(struct nfs_fattr *fattr);
- static int nfs4_proc_getattr(struct nfs_server *, struct nfs_fh *, struct nfs_fattr *);
- static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr);
+ static int nfs4_proc_getattr(struct nfs_server *, struct nfs_fh *, struct nfs_fattr *, struct nfs4_label *label);
+ static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr, struct nfs4_label *label);
  static int nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred,
                            struct nfs_fattr *fattr, struct iattr *sattr,
-                           struct nfs4_state *state);
+                           struct nfs4_state *state, struct nfs4_label *ilabel,
+                           struct nfs4_label *olabel);
  #ifdef CONFIG_NFS_V4_1
 -static int nfs41_test_stateid(struct nfs_server *, nfs4_stateid *);
 -static int nfs41_free_stateid(struct nfs_server *, nfs4_stateid *);
 +static int nfs41_test_stateid(struct nfs_server *, nfs4_stateid *,
 +              struct rpc_cred *);
 +static int nfs41_free_stateid(struct nfs_server *, nfs4_stateid *,
 +              struct rpc_cred *);
  #endif
+ #ifdef CONFIG_NFS_V4_SECURITY_LABEL
+ static inline struct nfs4_label *
+ nfs4_label_init_security(struct inode *dir, struct dentry *dentry,
+       struct iattr *sattr, struct nfs4_label *label)
+ {
+       int err;
+       if (label == NULL)
+               return NULL;
+       if (nfs_server_capable(dir, NFS_CAP_SECURITY_LABEL) == 0)
+               return NULL;
+       if (NFS_SERVER(dir)->nfs_client->cl_minorversion < 2)
+               return NULL;
+       err = security_dentry_init_security(dentry, sattr->ia_mode,
+                               &dentry->d_name, (void **)&label->label, &label->len);
+       if (err == 0)
+               return label;
+       return NULL;
+ }
+ static inline void
+ nfs4_label_release_security(struct nfs4_label *label)
+ {
+       if (label)
+               security_release_secctx(label->label, label->len);
+ }
+ static inline u32 *nfs4_bitmask(struct nfs_server *server, struct nfs4_label *label)
+ {
+       if (label)
+               return server->attr_bitmask;
+       return server->attr_bitmask_nl;
+ }
+ #else
+ static inline struct nfs4_label *
+ nfs4_label_init_security(struct inode *dir, struct dentry *dentry,
+       struct iattr *sattr, struct nfs4_label *l)
+ { return NULL; }
+ static inline void
+ nfs4_label_release_security(struct nfs4_label *label)
+ { return; }
+ static inline u32 *
+ nfs4_bitmask(struct nfs_server *server, struct nfs4_label *label)
+ { return server->attr_bitmask; }
+ #endif
  /* Prevent leaks of NFSv4 errors into userland */
  static int nfs4_map_errors(int err)
  {
   * Returns a referenced nfs4_state
   */
  static int _nfs4_do_open(struct inode *dir,
 -                      struct dentry *dentry,
 -                      fmode_t fmode,
 +                      struct nfs_open_context *ctx,
                        int flags,
-                       struct iattr *sattr)
+                       struct iattr *sattr,
 -                      struct nfs4_label *label,
 -                      struct rpc_cred *cred,
 -                      struct nfs4_state **res,
 -                      struct nfs4_threshold **ctx_th)
++                      struct nfs4_label *label)
  {
        struct nfs4_state_owner  *sp;
        struct nfs4_state     *state = NULL;
        struct nfs_server       *server = NFS_SERVER(dir);
        struct nfs4_opendata *opendata;
 +      struct dentry *dentry = ctx->dentry;
 +      struct rpc_cred *cred = ctx->cred;
 +      struct nfs4_threshold **ctx_th = &ctx->mdsthreshold;
 +      fmode_t fmode = ctx->mode & (FMODE_READ|FMODE_WRITE|FMODE_EXEC);
        enum open_claim_type4 claim = NFS4_OPEN_CLAIM_NULL;
+       struct nfs4_label *olabel = NULL;
        int status;
  
        /* Protect against reboot recovery conflicts */
        if (dentry->d_inode != NULL)
                opendata->state = nfs4_get_open_state(dentry->d_inode, sp);
  
 -      status = _nfs4_open_and_get_state(opendata, fmode, flags, &state);
 +      status = _nfs4_open_and_get_state(opendata, fmode, flags, ctx);
        if (status != 0)
-               goto err_opendata_put;
+               goto err_free_label;
 +      state = ctx->state;
  
        if ((opendata->o_arg.open_flags & O_EXCL) &&
            (opendata->o_arg.createmode != NFS4_CREATE_GUARDED)) {
                kfree(opendata->f_attr.mdsthreshold);
        opendata->f_attr.mdsthreshold = NULL;
  
+       nfs4_label_free(olabel);
        nfs4_opendata_put(opendata);
        nfs4_put_state_owner(sp);
 -      *res = state;
        return 0;
+ err_free_label:
+       nfs4_label_free(olabel);
  err_opendata_put:
        kfree(opendata->f_attr.mdsthreshold);
        nfs4_opendata_put(opendata);
@@@ -2097,18 -2148,23 +2184,19 @@@ out_err
  
  
  static struct nfs4_state *nfs4_do_open(struct inode *dir,
 -                                      struct dentry *dentry,
 -                                      fmode_t fmode,
 +                                      struct nfs_open_context *ctx,
                                        int flags,
-                                       struct iattr *sattr)
+                                       struct iattr *sattr,
 -                                      struct nfs4_label *label,
 -                                      struct rpc_cred *cred,
 -                                      struct nfs4_threshold **ctx_th)
++                                      struct nfs4_label *label)
  {
        struct nfs_server *server = NFS_SERVER(dir);
        struct nfs4_exception exception = { };
        struct nfs4_state *res;
        int status;
  
 -      fmode &= FMODE_READ|FMODE_WRITE|FMODE_EXEC;
        do {
-               status = _nfs4_do_open(dir, ctx, flags, sattr);
 -              status = _nfs4_do_open(dir, dentry, fmode, flags, sattr, label, cred,
 -                                     &res, ctx_th);
++              status = _nfs4_do_open(dir, ctx, flags, sattr, label);
 +              res = ctx->state;
                if (status == 0)
                        break;
                /* NOTE: BAD_SEQID means the server and client disagree about the
@@@ -2458,12 -2522,20 +2554,18 @@@ static struct inode 
  nfs4_atomic_open(struct inode *dir, struct nfs_open_context *ctx, int open_flags, struct iattr *attr)
  {
        struct nfs4_state *state;
+       struct nfs4_label l = {0, 0, 0, NULL}, *label = NULL;
+       label = nfs4_label_init_security(dir, ctx->dentry, attr, &l);
  
        /* Protect against concurrent sillydeletes */
-       state = nfs4_do_open(dir, ctx, open_flags, attr);
 -      state = nfs4_do_open(dir, ctx->dentry, ctx->mode, open_flags, attr, label,
 -                           ctx->cred, &ctx->mdsthreshold);
++      state = nfs4_do_open(dir, ctx, open_flags, attr, label);
+       nfs4_label_release_security(label);
        if (IS_ERR(state))
                return ERR_CAST(state);
 -      ctx->state = state;
 -      return igrab(state->inode);
 +      return state->inode;
  }
  
  static void nfs4_close_context(struct nfs_open_context *ctx, int is_sync)
@@@ -3067,13 -3183,22 +3213,16 @@@ nfs4_proc_create(struct inode *dir, str
        if (IS_ERR(ctx))
                return PTR_ERR(ctx);
  
+       ilabel = nfs4_label_init_security(dir, dentry, sattr, &l);
        sattr->ia_mode &= ~current_umask();
-       state = nfs4_do_open(dir, ctx, flags, sattr);
 -      state = nfs4_do_open(dir, dentry, ctx->mode,
 -                      flags, sattr, ilabel, ctx->cred,
 -                      &ctx->mdsthreshold);
 -      d_drop(dentry);
++      state = nfs4_do_open(dir, ctx, flags, sattr, ilabel);
        if (IS_ERR(state)) {
                status = PTR_ERR(state);
                goto out;
        }
 -      d_add(dentry, igrab(state->inode));
 -      nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
 -      ctx->state = state;
  out:
+       nfs4_label_release_security(ilabel);
        put_nfs_open_context(ctx);
        return status;
  }
Simple merge
diff --cc fs/nfs/super.c
Simple merge
Simple merge
Simple merge