Commit 81ac95c5 authored by J. Bruce Fields's avatar J. Bruce Fields Committed by Linus Torvalds

[PATCH] nfsd4: fix open-create permissions

In the case where an open creates the file, we shouldn't be rechecking
permissions to open the file; the open succeeds regardless of what the new
file's mode bits say.

This patch fixes the problem, but only by introducing yet another parameter
to nfsd_create_v3.  This is ugly.  This will be fixed by later patches.
Signed-off-by: default avatarJ. Bruce Fields <bfields@citi.umich.edu>
Acked-by: default avatarNeil Brown <neilb@suse.de>
Cc: Jeff Garzik <jeff@garzik.org>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent af85852d
...@@ -258,7 +258,7 @@ nfsd3_proc_create(struct svc_rqst *rqstp, struct nfsd3_createargs *argp, ...@@ -258,7 +258,7 @@ nfsd3_proc_create(struct svc_rqst *rqstp, struct nfsd3_createargs *argp,
/* Now create the file and set attributes */ /* Now create the file and set attributes */
nfserr = nfsd_create_v3(rqstp, dirfhp, argp->name, argp->len, nfserr = nfsd_create_v3(rqstp, dirfhp, argp->name, argp->len,
attr, newfhp, attr, newfhp,
argp->createmode, argp->verf, NULL); argp->createmode, argp->verf, NULL, NULL);
RETURN_STATUS(nfserr); RETURN_STATUS(nfserr);
} }
......
...@@ -93,6 +93,7 @@ do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_o ...@@ -93,6 +93,7 @@ do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_o
{ {
struct svc_fh resfh; struct svc_fh resfh;
__be32 status; __be32 status;
int created = 0;
fh_init(&resfh, NFS4_FHSIZE); fh_init(&resfh, NFS4_FHSIZE);
open->op_truncate = 0; open->op_truncate = 0;
...@@ -105,7 +106,7 @@ do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_o ...@@ -105,7 +106,7 @@ do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_o
status = nfsd_create_v3(rqstp, current_fh, open->op_fname.data, status = nfsd_create_v3(rqstp, current_fh, open->op_fname.data,
open->op_fname.len, &open->op_iattr, open->op_fname.len, &open->op_iattr,
&resfh, open->op_createmode, &resfh, open->op_createmode,
(u32 *)open->op_verf.data, &open->op_truncate); (u32 *)open->op_verf.data, &open->op_truncate, &created);
} else { } else {
status = nfsd_lookup(rqstp, current_fh, status = nfsd_lookup(rqstp, current_fh,
open->op_fname.data, open->op_fname.len, &resfh); open->op_fname.data, open->op_fname.len, &resfh);
...@@ -122,6 +123,7 @@ do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_o ...@@ -122,6 +123,7 @@ do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_o
memcpy(open->op_stateowner->so_replay.rp_openfh, memcpy(open->op_stateowner->so_replay.rp_openfh,
&resfh.fh_handle.fh_base, resfh.fh_handle.fh_size); &resfh.fh_handle.fh_base, resfh.fh_handle.fh_size);
if (!created)
status = do_open_permission(rqstp, current_fh, open, MAY_NOP); status = do_open_permission(rqstp, current_fh, open, MAY_NOP);
out: out:
......
...@@ -1237,7 +1237,7 @@ __be32 ...@@ -1237,7 +1237,7 @@ __be32
nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp, nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
char *fname, int flen, struct iattr *iap, char *fname, int flen, struct iattr *iap,
struct svc_fh *resfhp, int createmode, u32 *verifier, struct svc_fh *resfhp, int createmode, u32 *verifier,
int *truncp) int *truncp, int *created)
{ {
struct dentry *dentry, *dchild = NULL; struct dentry *dentry, *dchild = NULL;
struct inode *dirp; struct inode *dirp;
...@@ -1331,6 +1331,8 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp, ...@@ -1331,6 +1331,8 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
host_err = vfs_create(dirp, dchild, iap->ia_mode, NULL); host_err = vfs_create(dirp, dchild, iap->ia_mode, NULL);
if (host_err < 0) if (host_err < 0)
goto out_nfserr; goto out_nfserr;
if (created)
*created = 1;
if (EX_ISSYNC(fhp->fh_export)) { if (EX_ISSYNC(fhp->fh_export)) {
err = nfserrno(nfsd_sync_dir(dentry)); err = nfserrno(nfsd_sync_dir(dentry));
......
...@@ -89,7 +89,7 @@ __be32 nfsd_access(struct svc_rqst *, struct svc_fh *, u32 *, u32 *); ...@@ -89,7 +89,7 @@ __be32 nfsd_access(struct svc_rqst *, struct svc_fh *, u32 *, u32 *);
__be32 nfsd_create_v3(struct svc_rqst *, struct svc_fh *, __be32 nfsd_create_v3(struct svc_rqst *, struct svc_fh *,
char *name, int len, struct iattr *attrs, char *name, int len, struct iattr *attrs,
struct svc_fh *res, int createmode, struct svc_fh *res, int createmode,
u32 *verifier, int *truncp); u32 *verifier, int *truncp, int *created);
__be32 nfsd_commit(struct svc_rqst *, struct svc_fh *, __be32 nfsd_commit(struct svc_rqst *, struct svc_fh *,
loff_t, unsigned long); loff_t, unsigned long);
#endif /* CONFIG_NFSD_V3 */ #endif /* CONFIG_NFSD_V3 */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment