]> git.ipfire.org Git - thirdparty/kernel/stable.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)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 28 Aug 2025 14:22:36 +0000 (16:22 +0200)
[ Upstream commit ef93a685e01a281b5e2a25ce4e3428cf9371a205 ]

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>
Signed-off-by: Sasha Levin <sashal@kernel.org>
fs/nfs/export.c

index 993be63ab3015f2da621b1c93ca47696604794e1..784d0f1cfb931ba2656edc3b5f2f57024b239d06 100644 (file)
@@ -67,14 +67,21 @@ nfs_fh_to_dentry(struct super_block *sb, struct fid *fid,
        struct nfs4_label *label = NULL;
        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;