summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTrond Myklebust <trond.myklebust@hammerspace.com>2019-06-27 06:30:48 -0400
committerTrond Myklebust <trond.myklebust@hammerspace.com>2019-07-06 14:54:25 -0400
commit1bf85d8c98756421e29b9990469ee63bb0bc87cc (patch)
treec27a2436eba998457011c275881a3286a4b7d7ac
parentbcc0e65f47def010d8d1c4cf09bdc698fe061b77 (diff)
NFSv4: Handle open for execute correctly
When mapping the NFSv4 context to an open mode and access mode, we need to treat the FMODE_EXEC flag differently. For the open mode, FMODE_EXEC means we need read share access. For the access mode checking, we need to verify that the user actually has execute access. Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
-rw-r--r--fs/nfs/nfs4proc.c28
1 files changed, 20 insertions, 8 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 6418cb6c079b..26626ea1f197 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -1165,6 +1165,18 @@ static bool nfs4_clear_cap_atomic_open_v1(struct nfs_server *server,
1165 return true; 1165 return true;
1166} 1166}
1167 1167
1168static fmode_t _nfs4_ctx_to_accessmode(const struct nfs_open_context *ctx)
1169{
1170 return ctx->mode & (FMODE_READ|FMODE_WRITE|FMODE_EXEC);
1171}
1172
1173static fmode_t _nfs4_ctx_to_openmode(const struct nfs_open_context *ctx)
1174{
1175 fmode_t ret = ctx->mode & (FMODE_READ|FMODE_WRITE);
1176
1177 return (ctx->mode & FMODE_EXEC) ? FMODE_READ | ret : ret;
1178}
1179
1168static u32 1180static u32
1169nfs4_map_atomic_open_share(struct nfs_server *server, 1181nfs4_map_atomic_open_share(struct nfs_server *server,
1170 fmode_t fmode, int openflags) 1182 fmode_t fmode, int openflags)
@@ -2900,14 +2912,13 @@ static unsigned nfs4_exclusive_attrset(struct nfs4_opendata *opendata,
2900} 2912}
2901 2913
2902static int _nfs4_open_and_get_state(struct nfs4_opendata *opendata, 2914static int _nfs4_open_and_get_state(struct nfs4_opendata *opendata,
2903 fmode_t fmode, 2915 int flags, struct nfs_open_context *ctx)
2904 int flags,
2905 struct nfs_open_context *ctx)
2906{ 2916{
2907 struct nfs4_state_owner *sp = opendata->owner; 2917 struct nfs4_state_owner *sp = opendata->owner;
2908 struct nfs_server *server = sp->so_server; 2918 struct nfs_server *server = sp->so_server;
2909 struct dentry *dentry; 2919 struct dentry *dentry;
2910 struct nfs4_state *state; 2920 struct nfs4_state *state;
2921 fmode_t acc_mode = _nfs4_ctx_to_accessmode(ctx);
2911 unsigned int seq; 2922 unsigned int seq;
2912 int ret; 2923 int ret;
2913 2924
@@ -2946,7 +2957,8 @@ static int _nfs4_open_and_get_state(struct nfs4_opendata *opendata,
2946 /* Parse layoutget results before we check for access */ 2957 /* Parse layoutget results before we check for access */
2947 pnfs_parse_lgopen(state->inode, opendata->lgp, ctx); 2958 pnfs_parse_lgopen(state->inode, opendata->lgp, ctx);
2948 2959
2949 ret = nfs4_opendata_access(sp->so_cred, opendata, state, fmode, flags); 2960 ret = nfs4_opendata_access(sp->so_cred, opendata, state,
2961 acc_mode, flags);
2950 if (ret != 0) 2962 if (ret != 0)
2951 goto out; 2963 goto out;
2952 2964
@@ -2978,7 +2990,7 @@ static int _nfs4_do_open(struct inode *dir,
2978 struct dentry *dentry = ctx->dentry; 2990 struct dentry *dentry = ctx->dentry;
2979 const struct cred *cred = ctx->cred; 2991 const struct cred *cred = ctx->cred;
2980 struct nfs4_threshold **ctx_th = &ctx->mdsthreshold; 2992 struct nfs4_threshold **ctx_th = &ctx->mdsthreshold;
2981 fmode_t fmode = ctx->mode & (FMODE_READ|FMODE_WRITE|FMODE_EXEC); 2993 fmode_t fmode = _nfs4_ctx_to_openmode(ctx);
2982 enum open_claim_type4 claim = NFS4_OPEN_CLAIM_NULL; 2994 enum open_claim_type4 claim = NFS4_OPEN_CLAIM_NULL;
2983 struct iattr *sattr = c->sattr; 2995 struct iattr *sattr = c->sattr;
2984 struct nfs4_label *label = c->label; 2996 struct nfs4_label *label = c->label;
@@ -3024,7 +3036,7 @@ static int _nfs4_do_open(struct inode *dir,
3024 if (d_really_is_positive(dentry)) 3036 if (d_really_is_positive(dentry))
3025 opendata->state = nfs4_get_open_state(d_inode(dentry), sp); 3037 opendata->state = nfs4_get_open_state(d_inode(dentry), sp);
3026 3038
3027 status = _nfs4_open_and_get_state(opendata, fmode, flags, ctx); 3039 status = _nfs4_open_and_get_state(opendata, flags, ctx);
3028 if (status != 0) 3040 if (status != 0)
3029 goto err_free_label; 3041 goto err_free_label;
3030 state = ctx->state; 3042 state = ctx->state;
@@ -3594,9 +3606,9 @@ static void nfs4_close_context(struct nfs_open_context *ctx, int is_sync)
3594 if (ctx->state == NULL) 3606 if (ctx->state == NULL)
3595 return; 3607 return;
3596 if (is_sync) 3608 if (is_sync)
3597 nfs4_close_sync(ctx->state, ctx->mode); 3609 nfs4_close_sync(ctx->state, _nfs4_ctx_to_openmode(ctx));
3598 else 3610 else
3599 nfs4_close_state(ctx->state, ctx->mode); 3611 nfs4_close_state(ctx->state, _nfs4_ctx_to_openmode(ctx));
3600} 3612}
3601 3613
3602#define FATTR4_WORD1_NFS40_MASK (2*FATTR4_WORD1_MOUNTED_ON_FILEID - 1UL) 3614#define FATTR4_WORD1_NFS40_MASK (2*FATTR4_WORD1_MOUNTED_ON_FILEID - 1UL)