ceph: avoid panic with mismatched symlink sizes in fill_inode()
[linux-2.6-block.git] / fs / ceph / inode.c
index 2c489378b4cd6b470d06ecc9f3c60fc67ea6e1cf..9fff9f3b17e4a5206a9073cec2be714fba44bda0 100644 (file)
@@ -677,18 +677,19 @@ static int fill_inode(struct inode *inode,
        case S_IFLNK:
                inode->i_op = &ceph_symlink_iops;
                if (!ci->i_symlink) {
-                       int symlen = iinfo->symlink_len;
+                       u32 symlen = iinfo->symlink_len;
                        char *sym;
 
-                       BUG_ON(symlen != inode->i_size);
                        spin_unlock(&ci->i_ceph_lock);
 
+                       err = -EINVAL;
+                       if (WARN_ON(symlen != inode->i_size))
+                               goto out;
+
                        err = -ENOMEM;
-                       sym = kmalloc(symlen+1, GFP_NOFS);
+                       sym = kstrndup(iinfo->symlink, symlen, GFP_NOFS);
                        if (!sym)
                                goto out;
-                       memcpy(sym, iinfo->symlink, symlen);
-                       sym[symlen] = 0;
 
                        spin_lock(&ci->i_ceph_lock);
                        if (!ci->i_symlink)