Skip to content

Commit 1bf85d8

Browse files
author
Trond Myklebust
committed
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 <[email protected]>
1 parent bcc0e65 commit 1bf85d8

File tree

1 file changed

+20
-8
lines changed

1 file changed

+20
-8
lines changed

fs/nfs/nfs4proc.c

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1165,6 +1165,18 @@ static bool nfs4_clear_cap_atomic_open_v1(struct nfs_server *server,
11651165
return true;
11661166
}
11671167

1168+
static 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+
1173+
static 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+
11681180
static u32
11691181
nfs4_map_atomic_open_share(struct nfs_server *server,
11701182
fmode_t fmode, int openflags)
@@ -2900,14 +2912,13 @@ static unsigned nfs4_exclusive_attrset(struct nfs4_opendata *opendata,
29002912
}
29012913

29022914
static int _nfs4_open_and_get_state(struct nfs4_opendata *opendata,
2903-
fmode_t fmode,
2904-
int flags,
2905-
struct nfs_open_context *ctx)
2915+
int flags, struct nfs_open_context *ctx)
29062916
{
29072917
struct nfs4_state_owner *sp = opendata->owner;
29082918
struct nfs_server *server = sp->so_server;
29092919
struct dentry *dentry;
29102920
struct nfs4_state *state;
2921+
fmode_t acc_mode = _nfs4_ctx_to_accessmode(ctx);
29112922
unsigned int seq;
29122923
int ret;
29132924

@@ -2946,7 +2957,8 @@ static int _nfs4_open_and_get_state(struct nfs4_opendata *opendata,
29462957
/* Parse layoutget results before we check for access */
29472958
pnfs_parse_lgopen(state->inode, opendata->lgp, ctx);
29482959

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);
29502962
if (ret != 0)
29512963
goto out;
29522964

@@ -2978,7 +2990,7 @@ static int _nfs4_do_open(struct inode *dir,
29782990
struct dentry *dentry = ctx->dentry;
29792991
const struct cred *cred = ctx->cred;
29802992
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);
29822994
enum open_claim_type4 claim = NFS4_OPEN_CLAIM_NULL;
29832995
struct iattr *sattr = c->sattr;
29842996
struct nfs4_label *label = c->label;
@@ -3024,7 +3036,7 @@ static int _nfs4_do_open(struct inode *dir,
30243036
if (d_really_is_positive(dentry))
30253037
opendata->state = nfs4_get_open_state(d_inode(dentry), sp);
30263038

3027-
status = _nfs4_open_and_get_state(opendata, fmode, flags, ctx);
3039+
status = _nfs4_open_and_get_state(opendata, flags, ctx);
30283040
if (status != 0)
30293041
goto err_free_label;
30303042
state = ctx->state;
@@ -3594,9 +3606,9 @@ static void nfs4_close_context(struct nfs_open_context *ctx, int is_sync)
35943606
if (ctx->state == NULL)
35953607
return;
35963608
if (is_sync)
3597-
nfs4_close_sync(ctx->state, ctx->mode);
3609+
nfs4_close_sync(ctx->state, _nfs4_ctx_to_openmode(ctx));
35983610
else
3599-
nfs4_close_state(ctx->state, ctx->mode);
3611+
nfs4_close_state(ctx->state, _nfs4_ctx_to_openmode(ctx));
36003612
}
36013613

36023614
#define FATTR4_WORD1_NFS40_MASK (2*FATTR4_WORD1_MOUNTED_ON_FILEID - 1UL)

0 commit comments

Comments
 (0)