Syzkaller found an slab-out-of-bounds in nfs_fh_to_dentry when the memory of server_fh is not passed from user space. So I add a check for input size. --- fs/nfs/export.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/fs/nfs/export.c b/fs/nfs/export.c index e9c233b6f..e0e77f8ca 100644 --- a/fs/nfs/export.c +++ b/fs/nfs/export.c @@ -65,8 +65,8 @@ nfs_fh_to_dentry(struct super_block *sb, struct fid *fid, int fh_len, int fh_type) { 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; + struct nfs_fh *server_fh; + size_t fh_size; const struct nfs_rpc_ops *rpc_ops; struct dentry *dentry; struct inode *inode; @@ -74,6 +74,14 @@ nfs_fh_to_dentry(struct super_block *sb, struct fid *fid, u32 *p = fid->raw; int ret; + /* check for user input size */ + if ((char*)server_fh <= (char*)p + || (int)((u32*)server_fh - (u32*)p + 1) < fh_len) + return ERR_PTR(-EINVAL); + + fh_size = offsetof(struct nfs_fh, data) + server_fh->size; + len = EMBED_FH_OFF + XDR_QUADLEN(fh_size); + /* NULL translates to ESTALE */ if (fh_len < len || fh_type != len) return NULL; -- 2.33.0