All of lore.kernel.org
 help / color / mirror / Atom feed
From: "J. Bruce Fields" <bfields@fieldses.org>
To: Konstantin Khorenko <khorenko@parallels.com>
Cc: Neil Brown <neilb@suse.de>,
	linux-nfs@vger.kernel.org,
	Linux Kernel Mailing List <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH] NFSD: memory corruption due to writing beyond the stat array
Date: Wed, 2 Feb 2011 13:19:17 -0500	[thread overview]
Message-ID: <20110202181917.GD3015@fieldses.org> (raw)
In-Reply-To: <4D4815BD.5090404@parallels.com>

On Tue, Feb 01, 2011 at 05:16:29PM +0300, Konstantin Khorenko wrote:
> Hi All,
> 
> i've found a bug which makes NFSD to corrupt memory due to writing beyond the stat array.
> 
> Initially this issue was found on 2.6.18-x RHEL5 kernel, but the same seems to be true for the current mainstream kernel (checked on 2.6.38-rc3).
> 
> ./fs/nfsd/vfs.c:
> static inline struct raparms *
> nfsd_get_raparms(dev_t dev, ino_t ino)
> {
> ...
>        // here we searched our file in a readahead cache
>        // but not found it
> ...
>          depth = nfsdstats.ra_size*11/10;
> ...
>        // some stuff, but "depth" is not changed
> ...
>          nfsdstats.ra_depth[depth*10/nfsdstats.ra_size]++;
> ...
> }
> 
> And here we write to the 12th array element
> (nfsdstats.ra_size*11/10*10/nfsdstats.ra_size == 11),

Actually, I think that's true only if ra_size is divisible by 10; if
not, then depth will be something *less* than ra_size*11/10, so
depth*10/ra_size will be something less than 11 (namely 10).

> This means that each time we did not find a file in a readahead cache we
> corrupt memory.

... and ra_size is set to 16 * min(2, numthreads/8), so I think you'll
hit this only if min(2, numthreads/8) (rounded down) is a multiple of 5?
So for example someone using a number of threads that's a power of 2
shouldn't hit this case.

> Fortunately in a kernel with NFSDv4 compiled in it corrupts
> (inc) NFS4 ops counter, but in a kernel with NFSDv4 disabled it corrupts (inc)
> some other data, that lays in the memory beyond nfsdstats.
> 
> Proposed fix is attached.

So after the fix:

> -	depth = nfsdstats.ra_size*11/10;
> +	depth = nfsdstats.ra_size;

depth*10/nfsdstats will always be 10 in this case.  Looks good.

Thanks for finding this!

--b.

      reply	other threads:[~2011-02-02 18:19 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-02-01 14:16 [PATCH] NFSD: memory corruption due to writing beyond the stat array Konstantin Khorenko
2011-02-02 18:19 ` J. Bruce Fields [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=20110202181917.GD3015@fieldses.org \
    --to=bfields@fieldses.org \
    --cc=khorenko@parallels.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-nfs@vger.kernel.org \
    --cc=neilb@suse.de \
    /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.