]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob
f7b05e209e8851ee303ae30ff5eae2b6e235ac34
[thirdparty/kernel/stable-queue.git] /
1 From 1574dff8996ab1ed92c09012f8038b5566fce313 Mon Sep 17 00:00:00 2001
2 From: Sachin Prabhu <sprabhu@redhat.com>
3 Date: Wed, 20 Apr 2011 13:09:35 +0100
4 Subject: Open with O_CREAT flag set fails to open existing files on non writable directories
5
6 From: Sachin Prabhu <sprabhu@redhat.com>
7
8 commit 1574dff8996ab1ed92c09012f8038b5566fce313 upstream.
9
10 An open on a NFS4 share using the O_CREAT flag on an existing file for
11 which we have permissions to open but contained in a directory with no
12 write permissions will fail with EACCES.
13
14 A tcpdump shows that the client had set the open mode to UNCHECKED which
15 indicates that the file should be created if it doesn't exist and
16 encountering an existing flag is not an error. Since in this case the
17 file exists and can be opened by the user, the NFS server is wrong in
18 attempting to check create permissions on the parent directory.
19
20 The patch adds a conditional statement to check for create permissions
21 only if the file doesn't exist.
22
23 Signed-off-by: Sachin S. Prabhu <sprabhu@redhat.com>
24 Signed-off-by: J. Bruce Fields <bfields@redhat.com>
25 Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
26
27 ---
28 fs/nfsd/vfs.c | 9 ++++++++-
29 1 file changed, 8 insertions(+), 1 deletion(-)
30
31 --- a/fs/nfsd/vfs.c
32 +++ b/fs/nfsd/vfs.c
33 @@ -1363,7 +1363,7 @@ nfsd_create_v3(struct svc_rqst *rqstp, s
34 goto out;
35 if (!(iap->ia_valid & ATTR_MODE))
36 iap->ia_mode = 0;
37 - err = fh_verify(rqstp, fhp, S_IFDIR, NFSD_MAY_CREATE);
38 + err = fh_verify(rqstp, fhp, S_IFDIR, NFSD_MAY_EXEC);
39 if (err)
40 goto out;
41
42 @@ -1385,6 +1385,13 @@ nfsd_create_v3(struct svc_rqst *rqstp, s
43 if (IS_ERR(dchild))
44 goto out_nfserr;
45
46 + /* If file doesn't exist, check for permissions to create one */
47 + if (!dchild->d_inode) {
48 + err = fh_verify(rqstp, fhp, S_IFDIR, NFSD_MAY_CREATE);
49 + if (err)
50 + goto out;
51 + }
52 +
53 err = fh_compose(resfhp, fhp->fh_export, dchild, fhp);
54 if (err)
55 goto out;