The Linux Kernel Mailing List
 help / color / mirror / Atom feed
From: David Laight <david.laight.linux@gmail.com>
To: "Chuck Lever" <cel@kernel.org>
Cc: "Chuck Lever" <chuck.lever@oracle.com>,
	"Jeff Layton" <jlayton@kernel.org>, NeilBrown <neil@brown.name>,
	linux-nfs@vger.kernel.org, linux-kernel@vger.kernel.org,
	"Olga Kornievskaia" <okorniev@redhat.com>,
	"Dai Ngo" <Dai.Ngo@oracle.com>, "Tom Talpey" <tom@talpey.com>,
	"Andrew Morton" <akpm@osdl.org>,
	"Linus Torvalds" <torvalds@linux-foundation.org>
Subject: Re: [PATCH net-next] fs: nfsd: Fix buffer overflow in write_pool_threads()
Date: Mon, 17 Aug 2026 09:06:41 +0100	[thread overview]
Message-ID: <20260817090641.082489a5@pumpkin> (raw)
In-Reply-To: <9e99253f-99d9-4ecd-8911-2844621a6ae6@app.fastmail.com>

On Sun, 16 Aug 2026 13:43:58 -0400
"Chuck Lever" <cel@kernel.org> wrote:

> On Wed, Aug 12, 2026, at 5:04 PM, David Laight wrote:
> > On Wed, 12 Aug 2026 16:19:22 -0400
> > "Chuck Lever" <cel@kernel.org> wrote:
> >  
> >> On Wed, Aug 12, 2026, at 3:33 PM, David Laight wrote:  
> >> > write_pool_threads() writes the number of threads in each pool into a
> >> > caller-supplied 'almost PAGE_SIZE' buffer.
> >> > If there are enough pools to overflow the buffer the code continues
> >> > writing beynd its end.
> >> >
> >> > Fix the overflow check so that it actually works.
> >> >
> >> > Fixes: eed2965af1bae "knfsd: allow admin to set nthreads per node"
> >> > Signed-off-by: David Laight <david.laight.linux@gmail.com>
> >> > ---
> >> >
> >> > I'm pretty sure this is 'root only' code.
> >> > So you'd have to try very hard to actually get the overflow.
> >> >
> >> >  fs/nfsd/nfsctl.c | 10 +++++-----
> >> >  1 file changed, 5 insertions(+), 5 deletions(-)
> >> >
> >> > diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
> >> > index 39e7012a60d8..b74048aa2402 100644
> >> > --- a/fs/nfsd/nfsctl.c
> >> > +++ b/fs/nfsd/nfsctl.c
> >> > @@ -483,8 +483,7 @@ static ssize_t write_pool_threads(struct file 
> >> > *file, char *buf, size_t size)
> >> >  		 * file, sorry.  Report zero threads.
> >> >  		 */
> >> >  		mutex_unlock(&nfsd_mutex);
> >> > -		strcpy(buf, "0\n");
> >> > -		return strlen(buf);
> >> > +		return strscpy(buf, "0\n", SIMPLE_TRANSACTION_LIMIT);
> >> >  	}
> >> > 
> >> >  	nthreads = kzalloc_objs(int, npools);
> >> > @@ -523,13 +522,14 @@ static ssize_t write_pool_threads(struct file 
> >> > *file, char *buf, size_t size)
> >> > 
> >> >  	mesg = buf;
> >> >  	size = SIMPLE_TRANSACTION_LIMIT;
> >> > -	for (i = 0; i < npools && size > 0; i++) {
> >> > -		snprintf(mesg, size, "%d%c", nthreads[i], (i == npools-1 ? '\n' : ' '));
> >> > -		len = strlen(mesg);
> >> > +	for (i = 0; i < npools; i++) {
> >> > +		len = scnprintf(mesg, size, "%d ", nthreads[i]);
> >> >  		size -= len;
> >> >  		mesg += len;
> >> >  	}
> >> >  	rv = mesg - buf;
> >> > +	if (rv != SIMPLE_TRANSACTION_LIMIT - 1)
> >> > +		msg[-1] = '\n';    
> >> 
> >> Did you mean "mesg[-1] = '\n';" here?  
> >
> > Yes - and I thought I'd compiled it ...
> > I did decide not to worry about the missing '\n' when the output 'just fits'.
> > After all you need over 1300 pools with 10 threads to get to 4k.
> > I'd bet something else dies first.
> >
> > 	David
> >
> > (Oh I've replaced Linus's 20 year old email I copied from the commit with
> > his current one (he acked it) and deleted the broken one from the author.)  
> 
> I've convinced myself that the actual problem is the truncation. The
> buffer overflow cannot occur.

My analysis was:
size is size_t so unsigned.
So after snprintf() truncates the 'size -= len' is going to generate a
big number, so the 'size > 0' check doesn't terminate the loop.
Which would mean that the next iteration would write beyond the buffer.
But I think there is a check in snprintf() for 'silly' lengths that may
stop the overwrite.
That doesn't stop the length returned to the caller being longer that
the buffer.
I didn't look what happens as the call site, the buffer will be copied
back to user, if the user provided a long enough buffer that might read
beyond the end of the page.

Of course this is all likely impossible for other reasons.
(and root only).

	David

> I've posted a patch to address that.
> 
> 


      reply	other threads:[~2026-08-17  8:06 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-12 19:33 [PATCH net-next] fs: nfsd: Fix buffer overflow in write_pool_threads() David Laight
2026-08-12 20:19 ` Chuck Lever
2026-08-12 21:04   ` David Laight
2026-08-16 17:43     ` Chuck Lever
2026-08-17  8:06       ` David Laight [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260817090641.082489a5@pumpkin \
    --to=david.laight.linux@gmail.com \
    --cc=Dai.Ngo@oracle.com \
    --cc=akpm@osdl.org \
    --cc=cel@kernel.org \
    --cc=chuck.lever@oracle.com \
    --cc=jlayton@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-nfs@vger.kernel.org \
    --cc=neil@brown.name \
    --cc=okorniev@redhat.com \
    --cc=tom@talpey.com \
    --cc=torvalds@linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox