Commit 7fc90ec93a5eb71f4b08403baf5ba7176b3ec6b1
Committed by
Linus Torvalds
1 parent
a8cddc5dfc
Exists in
master
and in
4 other branches
[PATCH] knfsd: nfsd: call nfsd_setuser() on fh_compose(), fix nfsd4 permissions problem
In the typical v2/v3 case the only new filehandles used as arguments to operations are filehandles taken directly off the wire, which don't get dentries until fh_verify() is called. But in v4 the filehandles that are arguments to operations were often created by previous operations (putrootfh, lookup, etc.) using fh_compose, which sets the dentry in the filehandle without calling nfsd_setuser(). This also means that, for example, if filesystem B is mounted on filesystem A, and filesystem A is exported without root-squashing, then a client can bypass the rootsquashing on B using a compound that starts at a filehandle in A, crosses into B using lookups, and then does stuff in B. Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu> Signed-off-by: Neil Brown <neilb@suse.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Showing 1 changed file with 8 additions and 7 deletions Side-by-side Diff
fs/nfsd/nfsfh.c
| ... | ... | @@ -187,13 +187,6 @@ |
| 187 | 187 | goto out; |
| 188 | 188 | } |
| 189 | 189 | |
| 190 | - /* Set user creds for this exportpoint */ | |
| 191 | - error = nfsd_setuser(rqstp, exp); | |
| 192 | - if (error) { | |
| 193 | - error = nfserrno(error); | |
| 194 | - goto out; | |
| 195 | - } | |
| 196 | - | |
| 197 | 190 | /* |
| 198 | 191 | * Look up the dentry using the NFS file handle. |
| 199 | 192 | */ |
| ... | ... | @@ -250,6 +243,14 @@ |
| 250 | 243 | exp = fhp->fh_export; |
| 251 | 244 | } |
| 252 | 245 | cache_get(&exp->h); |
| 246 | + | |
| 247 | + /* Set user creds for this exportpoint; necessary even in the "just | |
| 248 | + * checking" case because this may be a filehandle that was created by | |
| 249 | + * fh_compose, and that is about to be used in another nfsv4 compound | |
| 250 | + * operation */ | |
| 251 | + error = nfserrno(nfsd_setuser(rqstp, exp)); | |
| 252 | + if (error) | |
| 253 | + goto out; | |
| 253 | 254 | |
| 254 | 255 | error = nfsd_mode_check(rqstp, dentry->d_inode->i_mode, type); |
| 255 | 256 | if (error) |