]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
NFS: Fix filehandle bounds checking in nfs_fh_to_dentry()
authorTrond Myklebust <trond.myklebust@hammerspace.com>
Tue, 22 Jul 2025 13:24:58 +0000 (09:24 -0400)
committerTrond Myklebust <trond.myklebust@hammerspace.com>
Tue, 22 Jul 2025 13:50:56 +0000 (09:50 -0400)
The function needs to check the minimal filehandle length before it can
access the embedded filehandle.

Reported-by: zhangjian <zhangjian496@huawei.com>
Fixes: 20fa19027286 ("nfs: add export operations")
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
fs/nfs/export.c

index e9c233b6fd2095a68aebdd0275a9d56551a2501a..a10dd5f9d0786eb111113bf524a1af8b7da0fb6e 100644 (file)
@@ -66,14 +66,21 @@ nfs_fh_to_dentry(struct super_block *sb, struct fid *fid,
 {
        struct nfs_fattr *fattr = NULL;
        struct nfs_fh *server_fh = nfs_exp_embedfh(fid->raw);
-       size_t fh_size = offsetof(struct nfs_fh, data) + server_fh->size;
+       size_t fh_size = offsetof(struct nfs_fh, data);
        const struct nfs_rpc_ops *rpc_ops;
        struct dentry *dentry;
        struct inode *inode;
-       int len = EMBED_FH_OFF + XDR_QUADLEN(fh_size);
+       int len = EMBED_FH_OFF;
        u32 *p = fid->raw;
        int ret;
 
+       /* Initial check of bounds */
+       if (fh_len < len + XDR_QUADLEN(fh_size) ||
+           fh_len > XDR_QUADLEN(NFS_MAXFHSIZE))
+               return NULL;
+       /* Calculate embedded filehandle size */
+       fh_size += server_fh->size;
+       len += XDR_QUADLEN(fh_size);
        /* NULL translates to ESTALE */
        if (fh_len < len || fh_type != len)
                return NULL;