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>
This commit is contained in:
parent
bcc0e65f47
commit
1bf85d8c98
@ -1165,6 +1165,18 @@ static bool nfs4_clear_cap_atomic_open_v1(struct nfs_server *server,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static fmode_t _nfs4_ctx_to_accessmode(const struct nfs_open_context *ctx)
|
||||||
|
{
|
||||||
|
return ctx->mode & (FMODE_READ|FMODE_WRITE|FMODE_EXEC);
|
||||||
|
}
|
||||||
|
|
||||||
|
static fmode_t _nfs4_ctx_to_openmode(const struct nfs_open_context *ctx)
|
||||||
|
{
|
||||||
|
fmode_t ret = ctx->mode & (FMODE_READ|FMODE_WRITE);
|
||||||
|
|
||||||
|
return (ctx->mode & FMODE_EXEC) ? FMODE_READ | ret : ret;
|
||||||
|
}
|
||||||
|
|
||||||
static u32
|
static u32
|
||||||
nfs4_map_atomic_open_share(struct nfs_server *server,
|
nfs4_map_atomic_open_share(struct nfs_server *server,
|
||||||
fmode_t fmode, int openflags)
|
fmode_t fmode, int openflags)
|
||||||
@ -2900,14 +2912,13 @@ static unsigned nfs4_exclusive_attrset(struct nfs4_opendata *opendata,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int _nfs4_open_and_get_state(struct nfs4_opendata *opendata,
|
static int _nfs4_open_and_get_state(struct nfs4_opendata *opendata,
|
||||||
fmode_t fmode,
|
int flags, struct nfs_open_context *ctx)
|
||||||
int flags,
|
|
||||||
struct nfs_open_context *ctx)
|
|
||||||
{
|
{
|
||||||
struct nfs4_state_owner *sp = opendata->owner;
|
struct nfs4_state_owner *sp = opendata->owner;
|
||||||
struct nfs_server *server = sp->so_server;
|
struct nfs_server *server = sp->so_server;
|
||||||
struct dentry *dentry;
|
struct dentry *dentry;
|
||||||
struct nfs4_state *state;
|
struct nfs4_state *state;
|
||||||
|
fmode_t acc_mode = _nfs4_ctx_to_accessmode(ctx);
|
||||||
unsigned int seq;
|
unsigned int seq;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -2946,7 +2957,8 @@ static int _nfs4_open_and_get_state(struct nfs4_opendata *opendata,
|
|||||||
/* Parse layoutget results before we check for access */
|
/* Parse layoutget results before we check for access */
|
||||||
pnfs_parse_lgopen(state->inode, opendata->lgp, ctx);
|
pnfs_parse_lgopen(state->inode, opendata->lgp, ctx);
|
||||||
|
|
||||||
ret = nfs4_opendata_access(sp->so_cred, opendata, state, fmode, flags);
|
ret = nfs4_opendata_access(sp->so_cred, opendata, state,
|
||||||
|
acc_mode, flags);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
@ -2978,7 +2990,7 @@ static int _nfs4_do_open(struct inode *dir,
|
|||||||
struct dentry *dentry = ctx->dentry;
|
struct dentry *dentry = ctx->dentry;
|
||||||
const struct cred *cred = ctx->cred;
|
const struct cred *cred = ctx->cred;
|
||||||
struct nfs4_threshold **ctx_th = &ctx->mdsthreshold;
|
struct nfs4_threshold **ctx_th = &ctx->mdsthreshold;
|
||||||
fmode_t fmode = ctx->mode & (FMODE_READ|FMODE_WRITE|FMODE_EXEC);
|
fmode_t fmode = _nfs4_ctx_to_openmode(ctx);
|
||||||
enum open_claim_type4 claim = NFS4_OPEN_CLAIM_NULL;
|
enum open_claim_type4 claim = NFS4_OPEN_CLAIM_NULL;
|
||||||
struct iattr *sattr = c->sattr;
|
struct iattr *sattr = c->sattr;
|
||||||
struct nfs4_label *label = c->label;
|
struct nfs4_label *label = c->label;
|
||||||
@ -3024,7 +3036,7 @@ static int _nfs4_do_open(struct inode *dir,
|
|||||||
if (d_really_is_positive(dentry))
|
if (d_really_is_positive(dentry))
|
||||||
opendata->state = nfs4_get_open_state(d_inode(dentry), sp);
|
opendata->state = nfs4_get_open_state(d_inode(dentry), sp);
|
||||||
|
|
||||||
status = _nfs4_open_and_get_state(opendata, fmode, flags, ctx);
|
status = _nfs4_open_and_get_state(opendata, flags, ctx);
|
||||||
if (status != 0)
|
if (status != 0)
|
||||||
goto err_free_label;
|
goto err_free_label;
|
||||||
state = ctx->state;
|
state = ctx->state;
|
||||||
@ -3594,9 +3606,9 @@ static void nfs4_close_context(struct nfs_open_context *ctx, int is_sync)
|
|||||||
if (ctx->state == NULL)
|
if (ctx->state == NULL)
|
||||||
return;
|
return;
|
||||||
if (is_sync)
|
if (is_sync)
|
||||||
nfs4_close_sync(ctx->state, ctx->mode);
|
nfs4_close_sync(ctx->state, _nfs4_ctx_to_openmode(ctx));
|
||||||
else
|
else
|
||||||
nfs4_close_state(ctx->state, ctx->mode);
|
nfs4_close_state(ctx->state, _nfs4_ctx_to_openmode(ctx));
|
||||||
}
|
}
|
||||||
|
|
||||||
#define FATTR4_WORD1_NFS40_MASK (2*FATTR4_WORD1_MOUNTED_ON_FILEID - 1UL)
|
#define FATTR4_WORD1_NFS40_MASK (2*FATTR4_WORD1_MOUNTED_ON_FILEID - 1UL)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user