Re: [PATCH] NFS: Fix filehandle bounds checking in nfs_fh_to_dentry()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, 2025-07-22 at 22:17 +0800, zhangjian (CG) wrote:
> 
> 
> On 2025/7/22 21:58, Trond Myklebust wrote:
> > From: Trond Myklebust <trond.myklebust@xxxxxxxxxxxxxxx>
> > 
> > The function needs to check the minimal filehandle length before it
> > can
> > access the embedded filehandle.
> > 
> > Reported-by: zhangjian <zhangjian496@xxxxxxxxxx>
> > Fixes: 20fa19027286 ("nfs: add export operations")
> > Signed-off-by: Trond Myklebust <trond.myklebust@xxxxxxxxxxxxxxx>
> > ---
> >  fs/nfs/export.c | 11 +++++++++--
> >  1 file changed, 9 insertions(+), 2 deletions(-)
> > 
> > diff --git a/fs/nfs/export.c b/fs/nfs/export.c
> > index e9c233b6fd20..a10dd5f9d078 100644
> > --- a/fs/nfs/export.c
> > +++ b/fs/nfs/export.c
> > @@ -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;
> 
> May this return ERR_PTR(-EINVAL) instead of NULL?
> I'm not sure if it is expected to be translated as ESTALE.

Technically, knfsd should be returning NFSERR_BADHANDLE in both this
case and in the check below, however there doesn't appear to be a way
to get nfsd_set_fh_dentry() to return that error.

For open_by_handle_at(), the manpage documents the error to be returned
as being ESTALE, and that is enforced in 'do_handle_to_path()'.

> 
> > +	/* 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;
> 

-- 
Trond Myklebust
Linux NFS client maintainer, Hammerspace
trondmy@xxxxxxxxxx, trond.myklebust@xxxxxxxxxxxxxxx





[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux