diff options
author | Trond Myklebust <trond.myklebust@primarydata.com> | 2014-07-10 08:54:32 -0400 |
---|---|---|
committer | Trond Myklebust <trond.myklebust@primarydata.com> | 2014-07-12 18:20:55 -0400 |
commit | f3792d63d2a377b7cbe91a204e9582c4cf831eb3 (patch) | |
tree | e1104771d92dd40473ce9210e0d7f3233d327b9b /fs/nfs/nfs4proc.c | |
parent | 31434f496abb9f3410b10f541462fe58613dd3ad (diff) |
NFSv4: Fix OPEN w/create access mode checking
POSIX states that open("foo", O_CREAT|O_RDONLY, 000) should succeed if
the file "foo" does not already exist. With the current NFS client,
it will fail with an EACCES error because of the permissions checks in
nfs4_opendata_access().
Fix is to turn that test off if the server says that we created the file.
Reported-by: "Frank S. Filz" <ffilzlnx@mindspring.com>
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r-- | fs/nfs/nfs4proc.c | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index b0e5705599bf..1300013e9b4e 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -1952,6 +1952,14 @@ static int _nfs4_recover_proc_open(struct nfs4_opendata *data) | |||
1952 | return status; | 1952 | return status; |
1953 | } | 1953 | } |
1954 | 1954 | ||
1955 | /* | ||
1956 | * Additional permission checks in order to distinguish between an | ||
1957 | * open for read, and an open for execute. This works around the | ||
1958 | * fact that NFSv4 OPEN treats read and execute permissions as being | ||
1959 | * the same. | ||
1960 | * Note that in the non-execute case, we want to turn off permission | ||
1961 | * checking if we just created a new file (POSIX open() semantics). | ||
1962 | */ | ||
1955 | static int nfs4_opendata_access(struct rpc_cred *cred, | 1963 | static int nfs4_opendata_access(struct rpc_cred *cred, |
1956 | struct nfs4_opendata *opendata, | 1964 | struct nfs4_opendata *opendata, |
1957 | struct nfs4_state *state, fmode_t fmode, | 1965 | struct nfs4_state *state, fmode_t fmode, |
@@ -1966,14 +1974,14 @@ static int nfs4_opendata_access(struct rpc_cred *cred, | |||
1966 | return 0; | 1974 | return 0; |
1967 | 1975 | ||
1968 | mask = 0; | 1976 | mask = 0; |
1969 | /* don't check MAY_WRITE - a newly created file may not have | 1977 | /* |
1970 | * write mode bits, but POSIX allows the creating process to write. | 1978 | * Use openflags to check for exec, because fmode won't |
1971 | * use openflags to check for exec, because fmode won't | 1979 | * always have FMODE_EXEC set when file open for exec. |
1972 | * always have FMODE_EXEC set when file open for exec. */ | 1980 | */ |
1973 | if (openflags & __FMODE_EXEC) { | 1981 | if (openflags & __FMODE_EXEC) { |
1974 | /* ONLY check for exec rights */ | 1982 | /* ONLY check for exec rights */ |
1975 | mask = MAY_EXEC; | 1983 | mask = MAY_EXEC; |
1976 | } else if (fmode & FMODE_READ) | 1984 | } else if ((fmode & FMODE_READ) && !opendata->file_created) |
1977 | mask = MAY_READ; | 1985 | mask = MAY_READ; |
1978 | 1986 | ||
1979 | cache.cred = cred; | 1987 | cache.cred = cred; |