]> rtime.felk.cvut.cz Git - linux-imx.git/blobdiff - fs/nfs/nfs4proc.c
NFS: Fix access to suid/sgid executables
[linux-imx.git] / fs / nfs / nfs4proc.c
index 5d864fb3657885ff9eb8a043d880f2c1490f8d0e..cf747ef8665078a2a684b256402ab63484a77665 100644 (file)
@@ -1626,7 +1626,8 @@ static int _nfs4_recover_proc_open(struct nfs4_opendata *data)
 
 static int nfs4_opendata_access(struct rpc_cred *cred,
                                struct nfs4_opendata *opendata,
-                               struct nfs4_state *state, fmode_t fmode)
+                               struct nfs4_state *state, fmode_t fmode,
+                               int openflags)
 {
        struct nfs_access_entry cache;
        u32 mask;
@@ -1638,11 +1639,14 @@ static int nfs4_opendata_access(struct rpc_cred *cred,
 
        mask = 0;
        /* don't check MAY_WRITE - a newly created file may not have
-        * write mode bits, but POSIX allows the creating process to write */
-       if (fmode & FMODE_READ)
-               mask |= MAY_READ;
-       if (fmode & FMODE_EXEC)
-               mask |= MAY_EXEC;
+        * write mode bits, but POSIX allows the creating process to write.
+        * use openflags to check for exec, because fmode won't
+        * always have FMODE_EXEC set when file open for exec. */
+       if (openflags & __FMODE_EXEC) {
+               /* ONLY check for exec rights */
+               mask = MAY_EXEC;
+       } else if (fmode & FMODE_READ)
+               mask = MAY_READ;
 
        cache.cred = cred;
        cache.jiffies = jiffies;
@@ -1896,7 +1900,7 @@ static int _nfs4_do_open(struct inode *dir,
        if (server->caps & NFS_CAP_POSIX_LOCK)
                set_bit(NFS_STATE_POSIX_LOCKS, &state->flags);
 
-       status = nfs4_opendata_access(cred, opendata, state, fmode);
+       status = nfs4_opendata_access(cred, opendata, state, fmode, flags);
        if (status != 0)
                goto err_opendata_put;