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.
>
>
prev parent 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.