diff options
author | J. Bruce Fields <bfields@citi.umich.edu> | 2007-11-12 16:05:03 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-11-12 17:28:08 -0500 |
commit | 6fa02839bf9412e18e773d04e96182b4cd0b5d57 (patch) | |
tree | 063ee35d4da2bd1289ae9e9a64b5f02c825ef5f2 | |
parent | ac8587dcb58e40dd336d99d60f852041e06cc3dd (diff) |
nfsd4: recheck for secure ports in fh_verify
As with commit 7fc90ec93a5eb71f4b08403baf5ba7176b3ec6b1 ("knfsd: nfsd:
call nfsd_setuser() on fh_compose(), fix nfsd4 permissions problem")
this is a case where we need to redo a security check in fh_verify()
even though the filehandle already has an associated dentry--if the
filehandle was created by fh_compose() in an earlier operation of the
nfsv4 compound, then we may not have done these checks yet.
Without this fix it is possible, for example, to traverse from an export
without the secure ports requirement to one with it in a single
compound, and bypass the secure port check on the new export.
While we're here, fix up some minor style problems and change a printk()
to a dprintk(), to make it harder for random unprivileged users to spam
the logs.
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
Reviewed-By: NeilBrown <neilb@suse.de>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | fs/nfsd/nfsfh.c | 43 |
1 files changed, 26 insertions, 17 deletions
diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c index 4f712e970584..468f17a78441 100644 --- a/fs/nfsd/nfsfh.c +++ b/fs/nfsd/nfsfh.c | |||
@@ -95,6 +95,22 @@ nfsd_mode_check(struct svc_rqst *rqstp, umode_t mode, int type) | |||
95 | return 0; | 95 | return 0; |
96 | } | 96 | } |
97 | 97 | ||
98 | static __be32 nfsd_setuser_and_check_port(struct svc_rqst *rqstp, | ||
99 | struct svc_export *exp) | ||
100 | { | ||
101 | /* Check if the request originated from a secure port. */ | ||
102 | if (!rqstp->rq_secure && EX_SECURE(exp)) { | ||
103 | char buf[RPC_MAX_ADDRBUFLEN]; | ||
104 | dprintk(KERN_WARNING | ||
105 | "nfsd: request from insecure port %s!\n", | ||
106 | svc_print_addr(rqstp, buf, sizeof(buf))); | ||
107 | return nfserr_perm; | ||
108 | } | ||
109 | |||
110 | /* Set user creds for this exportpoint */ | ||
111 | return nfserrno(nfsd_setuser(rqstp, exp)); | ||
112 | } | ||
113 | |||
98 | /* | 114 | /* |
99 | * Perform sanity checks on the dentry in a client's file handle. | 115 | * Perform sanity checks on the dentry in a client's file handle. |
100 | * | 116 | * |
@@ -167,18 +183,7 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access) | |||
167 | goto out; | 183 | goto out; |
168 | } | 184 | } |
169 | 185 | ||
170 | /* Check if the request originated from a secure port. */ | 186 | error = nfsd_setuser_and_check_port(rqstp, exp); |
171 | error = nfserr_perm; | ||
172 | if (!rqstp->rq_secure && EX_SECURE(exp)) { | ||
173 | char buf[RPC_MAX_ADDRBUFLEN]; | ||
174 | printk(KERN_WARNING | ||
175 | "nfsd: request from insecure port %s!\n", | ||
176 | svc_print_addr(rqstp, buf, sizeof(buf))); | ||
177 | goto out; | ||
178 | } | ||
179 | |||
180 | /* Set user creds for this exportpoint */ | ||
181 | error = nfserrno(nfsd_setuser(rqstp, exp)); | ||
182 | if (error) | 187 | if (error) |
183 | goto out; | 188 | goto out; |
184 | 189 | ||
@@ -227,18 +232,22 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access) | |||
227 | fhp->fh_export = exp; | 232 | fhp->fh_export = exp; |
228 | nfsd_nr_verified++; | 233 | nfsd_nr_verified++; |
229 | } else { | 234 | } else { |
230 | /* just rechecking permissions | 235 | /* |
231 | * (e.g. nfsproc_create calls fh_verify, then nfsd_create does as well) | 236 | * just rechecking permissions |
237 | * (e.g. nfsproc_create calls fh_verify, then nfsd_create | ||
238 | * does as well) | ||
232 | */ | 239 | */ |
233 | dprintk("nfsd: fh_verify - just checking\n"); | 240 | dprintk("nfsd: fh_verify - just checking\n"); |
234 | dentry = fhp->fh_dentry; | 241 | dentry = fhp->fh_dentry; |
235 | exp = fhp->fh_export; | 242 | exp = fhp->fh_export; |
236 | /* Set user creds for this exportpoint; necessary even | 243 | /* |
244 | * Set user creds for this exportpoint; necessary even | ||
237 | * in the "just checking" case because this may be a | 245 | * in the "just checking" case because this may be a |
238 | * filehandle that was created by fh_compose, and that | 246 | * filehandle that was created by fh_compose, and that |
239 | * is about to be used in another nfsv4 compound | 247 | * is about to be used in another nfsv4 compound |
240 | * operation */ | 248 | * operation. |
241 | error = nfserrno(nfsd_setuser(rqstp, exp)); | 249 | */ |
250 | error = nfsd_setuser_and_check_port(rqstp, exp); | ||
242 | if (error) | 251 | if (error) |
243 | goto out; | 252 | goto out; |
244 | } | 253 | } |