diff options
author | J. Bruce Fields <bfields@redhat.com> | 2014-06-20 19:52:21 +0400 |
---|---|---|
committer | J. Bruce Fields <bfields@redhat.com> | 2014-07-09 01:14:23 +0400 |
commit | 52ee04330f585d1b5bc40442f07df07248fa3aee (patch) | |
tree | 6a176680872e4bc505cdf410645afe9252ad2619 /fs/nfsd/vfs.c | |
parent | 0aeae33f5d5fbd4af775e7c84795db9254d4a165 (diff) | |
download | linux-52ee04330f585d1b5bc40442f07df07248fa3aee.tar.xz |
nfsd: let nfsd_symlink assume null-terminated data
Currently nfsd_symlink has a weird hack to serve callers who don't
null-terminate symlink data: it looks ahead at the next byte to see if
it's zero, and copies it to a new buffer to null-terminate if not.
That means callers don't have to null-terminate, but they *do* have to
ensure that the byte following the end of the data is theirs to read.
That's a bit subtle, and the NFSv4 code actually got this wrong.
So let's just throw out that code and let callers pass null-terminated
strings; we've already fixed them to do that.
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs/nfsd/vfs.c')
-rw-r--r-- | fs/nfsd/vfs.c | 17 |
1 files changed, 3 insertions, 14 deletions
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 6ffaa70300ed..7518c65f9a5a 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -1504,7 +1504,7 @@ out_nfserr: __be32 nfsd_symlink(struct svc_rqst *rqstp, struct svc_fh *fhp, char *fname, int flen, - char *path, int plen, + char *path, struct svc_fh *resfhp, struct iattr *iap) { @@ -1513,7 +1513,7 @@ nfsd_symlink(struct svc_rqst *rqstp, struct svc_fh *fhp, int host_err; err = nfserr_noent; - if (!flen || !plen) + if (!flen || path[0] == '\0') goto out; err = nfserr_exist; if (isdotent(fname, flen)) @@ -1534,18 +1534,7 @@ nfsd_symlink(struct svc_rqst *rqstp, struct svc_fh *fhp, if (IS_ERR(dnew)) goto out_nfserr; - if (unlikely(path[plen] != 0)) { - char *path_alloced = kmalloc(plen+1, GFP_KERNEL); - if (path_alloced == NULL) - host_err = -ENOMEM; - else { - strncpy(path_alloced, path, plen); - path_alloced[plen] = 0; - host_err = vfs_symlink(dentry->d_inode, dnew, path_alloced); - kfree(path_alloced); - } - } else - host_err = vfs_symlink(dentry->d_inode, dnew, path); + host_err = vfs_symlink(dentry->d_inode, dnew, path); err = nfserrno(host_err); if (!err) err = nfserrno(commit_metadata(fhp)); |