* FIXME: we should try harder by querying the mds for the ino.
  */
 static struct dentry *__fh_to_dentry(struct super_block *sb,
-                                    struct ceph_nfs_fh *fh)
+                                    struct ceph_nfs_fh *fh, int fh_len)
 {
        struct ceph_mds_client *mdsc = ceph_sb_to_client(sb)->mdsc;
        struct inode *inode;
        struct ceph_vino vino;
        int err;
 
+       if (fh_len < sizeof(*fh) / 4)
+               return ERR_PTR(-ESTALE);
+
        dout("__fh_to_dentry %llx\n", fh->ino);
        vino.ino = fh->ino;
        vino.snap = CEPH_NOSNAP;
  * convert connectable fh to dentry
  */
 static struct dentry *__cfh_to_dentry(struct super_block *sb,
-                                     struct ceph_nfs_confh *cfh)
+                                     struct ceph_nfs_confh *cfh, int fh_len)
 {
        struct ceph_mds_client *mdsc = ceph_sb_to_client(sb)->mdsc;
        struct inode *inode;
        struct ceph_vino vino;
        int err;
 
+       if (fh_len < sizeof(*cfh) / 4)
+               return ERR_PTR(-ESTALE);
+
        dout("__cfh_to_dentry %llx (%llx/%x)\n",
             cfh->ino, cfh->parent_ino, cfh->parent_name_hash);
 
                                        int fh_len, int fh_type)
 {
        if (fh_type == 1)
-               return __fh_to_dentry(sb, (struct ceph_nfs_fh *)fid->raw);
+               return __fh_to_dentry(sb, (struct ceph_nfs_fh *)fid->raw,
+                                                               fh_len);
        else
-               return __cfh_to_dentry(sb, (struct ceph_nfs_confh *)fid->raw);
+               return __cfh_to_dentry(sb, (struct ceph_nfs_confh *)fid->raw,
+                                                               fh_len);
 }
 
 /*
 
        if (fh_type == 1)
                return ERR_PTR(-ESTALE);
+       if (fh_len < sizeof(*cfh) / 4)
+               return ERR_PTR(-ESTALE);
 
        pr_debug("fh_to_parent %llx/%d\n", cfh->parent_ino,
                 cfh->parent_name_hash);
 
        case GFS2_SMALL_FH_SIZE:
        case GFS2_LARGE_FH_SIZE:
        case GFS2_OLD_FH_SIZE:
+               if (fh_len < GFS2_SMALL_FH_SIZE)
+                       return NULL;
                this.no_formal_ino = ((u64)be32_to_cpu(fh[0])) << 32;
                this.no_formal_ino |= be32_to_cpu(fh[1]);
                this.no_addr = ((u64)be32_to_cpu(fh[2])) << 32;
        switch (fh_type) {
        case GFS2_LARGE_FH_SIZE:
        case GFS2_OLD_FH_SIZE:
+               if (fh_len < GFS2_LARGE_FH_SIZE)
+                       return NULL;
                parent.no_formal_ino = ((u64)be32_to_cpu(fh[4])) << 32;
                parent.no_formal_ino |= be32_to_cpu(fh[5]);
                parent.no_addr = ((u64)be32_to_cpu(fh[6])) << 32;
 
                        reiserfs_warning(sb, "reiserfs-13077",
                                "nfsd/reiserfs, fhtype=%d, len=%d - odd",
                                fh_type, fh_len);
-               fh_type = 5;
+               fh_type = fh_len;
        }
+       if (fh_len < 2)
+               return NULL;
 
        return reiserfs_get_dentry(sb, fid->raw[0], fid->raw[1],
                (fh_type == 3 || fh_type >= 5) ? fid->raw[2] : 0);
 struct dentry *reiserfs_fh_to_parent(struct super_block *sb, struct fid *fid,
                int fh_len, int fh_type)
 {
+       if (fh_type > fh_len)
+               fh_type = fh_len;
        if (fh_type < 4)
                return NULL;
 
 
        struct xfs_fid64        *fid64 = (struct xfs_fid64 *)fid;
        struct inode            *inode = NULL;
 
+       if (fh_len < xfs_fileid_length(fileid_type))
+               return NULL;
+
        switch (fileid_type) {
        case FILEID_INO32_GEN_PARENT:
                inode = xfs_nfs_get_inode(sb, fid->i32.parent_ino,
 
 {
        struct inode *inode;
        struct dentry *dentry = NULL;
-       u64 inum = fid->raw[2];
-       inum = (inum << 32) | fid->raw[1];
+       u64 inum;
 
        if (fh_len < 3)
                return NULL;
 
+       inum = fid->raw[2];
+       inum = (inum << 32) | fid->raw[1];
+
        inode = ilookup5(sb, (unsigned long)(inum + fid->raw[0]),
                        shmem_match, fid->raw);
        if (inode) {