Re: [PATCH 09/10] nfsd: cap decoded POSIX ACL count to bound sort cost

Jeff Layton <[email protected]>
Newsgroups gmane.linux.nfs,gmane.linux.kernel
Message-ID <[email protected]>
On Fri, 2026-05-29 at 09:34 +0200, Cedric Blancher wrote:
> What about (finally) getting rid of the bubble sort?
> 
> Ced
> 

It's certainly not clear to me that it's necessary (is it?). I'm not
opposed to removing it, but I'd rather not make a behavioral change
like this in the context of this patchset.

Maybe you could propose a patch to remove it?


> On Fri, 29 May 2026 at 00:02, Jeff Layton <[email protected]> wrote:
> > 
> > From: Chris Mason <[email protected]>
> > 
> > nfsd4_decode_posixacl() reads a u32 entry count off the wire and passes
> > it straight to posix_acl_alloc() and sort_pacl_range(). The latter is
> > an O(n^2) bubble sort, so a client-chosen count drives unbounded CPU in
> > the server's compound processing path.
> > 
> >     nfsd4_decode_posixacl()
> >       xdr_stream_decode_u32(&count)       /* uncapped u32 */
> >       posix_acl_alloc(count, GFP_KERNEL)
> >       sort_pacl_range(*acl, 0, count - 1) /* O(n^2) bubble sort */
> > 
> > The encoder side in the same file already rejects ACLs whose a_count
> > exceeds NFS_ACL_MAX_ENTRIES, but the decoder introduced in commit
> > 5fc51dfc2eb1 ("NFSD: Add support for XDR decoding POSIX draft ACLs")
> > omitted the symmetric check.
> > 
> > Fix by rejecting a wire count greater than NFS_ACL_MAX_ENTRIES with
> > nfserr_resource, before any allocation, so the sort is bounded by
> > NFS_ACL_MAX_ENTRIES^2 comparisons.
> > 
> > Fixes: 5fc51dfc2eb1 ("NFSD: Add support for XDR decoding POSIX draft ACLs")
> > Assisted-by: kres:claude-opus-4-7
> > Signed-off-by: Chris Mason <[email protected]>
> > ---
> >  fs/nfsd/nfs4xdr.c | 2 ++
> >  1 file changed, 2 insertions(+)
> > 
> > diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
> > index c6c50c376b23..5469c6c207ba 100644
> > --- a/fs/nfsd/nfs4xdr.c
> > +++ b/fs/nfsd/nfs4xdr.c
> > @@ -448,6 +448,8 @@ nfsd4_decode_posixacl(struct nfsd4_compoundargs *argp, struct posix_acl **acl)
> > 
> >         if (xdr_stream_decode_u32(argp->xdr, &count) < 0)
> >                 return nfserr_bad_xdr;
> > +       if (count > NFS_ACL_MAX_ENTRIES)
> > +               return nfserr_resource;
> > 
> >         *acl = posix_acl_alloc(count, GFP_KERNEL);
> >         if (*acl == NULL)
> > 
> > --
> > 2.54.0
> > 
> > 
> 

-- 
Jeff Layton <[email protected]>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.