Commit 301f0268b63d1b07268e46f5901fc51d6cac20eb

Authored by Al Viro
1 parent ca4e05195d

nfsd: racy access to ->d_name in nsfd4_encode_path()

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Showing 1 changed file with 8 additions and 6 deletions Side-by-side Diff

... ... @@ -1816,10 +1816,7 @@
1816 1816 static __be32 nfsd4_encode_path(const struct path *root,
1817 1817 const struct path *path, __be32 **pp, int *buflen)
1818 1818 {
1819   - struct path cur = {
1820   - .mnt = path->mnt,
1821   - .dentry = path->dentry,
1822   - };
  1819 + struct path cur = *path;
1823 1820 __be32 *p = *pp;
1824 1821 struct dentry **components = NULL;
1825 1822 unsigned int ncomponents = 0;
1826 1823  
1827 1824  
1828 1825  
1829 1826  
... ... @@ -1859,14 +1856,19 @@
1859 1856  
1860 1857 while (ncomponents) {
1861 1858 struct dentry *dentry = components[ncomponents - 1];
1862   - unsigned int len = dentry->d_name.len;
  1859 + unsigned int len;
1863 1860  
  1861 + spin_lock(&dentry->d_lock);
  1862 + len = dentry->d_name.len;
1864 1863 *buflen -= 4 + (XDR_QUADLEN(len) << 2);
1865   - if (*buflen < 0)
  1864 + if (*buflen < 0) {
  1865 + spin_unlock(&dentry->d_lock);
1866 1866 goto out_free;
  1867 + }
1867 1868 WRITE32(len);
1868 1869 WRITEMEM(dentry->d_name.name, len);
1869 1870 dprintk("/%s", dentry->d_name.name);
  1871 + spin_unlock(&dentry->d_lock);
1870 1872 dput(dentry);
1871 1873 ncomponents--;
1872 1874 }