diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/nfs/nfs4proc.c | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 1840ebc78fd..69aab8db494 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -769,6 +769,8 @@ static int _nfs4_do_access(struct inode *inode, struct rpc_cred *cred, int openf mask |= MAY_READ; if (openflags & FMODE_WRITE) mask |= MAY_WRITE; + if (openflags & FMODE_EXEC) + mask |= MAY_EXEC; status = nfs_access_get_cached(inode, cred, &cache); if (status == 0) goto out; @@ -1269,7 +1271,16 @@ out: static int nfs4_intent_set_file(struct nameidata *nd, struct path *path, struct nfs4_state *state) { struct file *filp; + int ret; + /* If the open_intent is for execute, we have an extra check to make */ + if (nd->intent.open.flags & FMODE_EXEC) { + ret = _nfs4_do_access(state->inode, + state->owner->so_cred, + nd->intent.open.flags); + if (ret < 0) + goto out_close; + } filp = lookup_instantiate_filp(nd, path->dentry, NULL); if (!IS_ERR(filp)) { struct nfs_open_context *ctx; @@ -1277,8 +1288,10 @@ static int nfs4_intent_set_file(struct nameidata *nd, struct path *path, struct ctx->state = state; return 0; } + ret = PTR_ERR(filp); +out_close: nfs4_close_state(path, state, nd->intent.open.flags); - return PTR_ERR(filp); + return ret; } struct dentry * |