All of lore.kernel.org
 help / color / mirror / Atom feed
From: Trond Myklebust <trond.myklebust@primarydata.com>
To: David Ramos <daramos@stanford.edu>
Cc: linux-nfs@vger.kernel.org
Subject: Re: Possible NFS 4.1 client vulnerability: uninitialized/garbage kfree() in decode_cb_sequence_args()
Date: Wed, 11 Feb 2015 17:42:42 -0500	[thread overview]
Message-ID: <1423694562.7169.12.camel@primarydata.com> (raw)
In-Reply-To: <572E44F4-FA95-4D53-949F-B553974F2F2B@stanford.edu>

Hi David,

On Wed, 2015-02-11 at 13:39 -0800, David Ramos wrote:
> Hello,
> 
> Our UC-KLEE tool found a kfree() of an uninitialized pointer in decode_cb_sequence_args (fs/nfs/callback_xdr.c) that may be remotely exploitable. The bug affects Linux kernel 3.16.3, but it appears to date back to commit 4aece6a19cf7f474f15eb861ba74db4479884ce3 (4/1/2009), which first implemented the CB_SEQUENCE operation from NFS 4.1.
> 
> Here is some of the relevant code:
>  458        if (args->csa_nrclists) {
>  459                args->csa_rclists = kmalloc_array(args->csa_nrclists,
>  460                                                  sizeof(*args->csa_rclists),
>  461                                                  GFP_KERNEL);
>  ...
>  465                for (i = 0; i < args->csa_nrclists; i++) {
>  466                        status = decode_rc_list(xdr, &args->csa_rclists[i]);
>  467                        if (status)
>  468                                goto out_free;
>  469                }
>  470        }
>  …
>  487out_free:
>  488        for (i = 0; i < args->csa_nrclists; i++)
>  489                kfree(args->csa_rclists[i].rcl_refcalls);
> 
> If a call to decode_rc_list() on line 466 returns non-zero during iteration ‘i', the kfree() call at line 489 will attempt to free uninitialized (heap garbage) pointers for all indices in [i, args->csa_nrclists).
> 
> I’m not familiar enough with the NFS internals to understand whether an attacker can cause decode_rc_list() to fail (i.e., by causing read_buf() to fail), but it seems plausible?
> 

Thanks for reporting this!

I can't see this issue as being exploitable without a fair amount of
trouble because the above RPC request would be incoming on a TCP
connection that was initiated by the NFSv4.1 client. If someone can do
that level of spoofing, then they can cause all sorts of mischief for
the client.

How about the following fix?

Cheers
  Trond

8<------------------------------------------------------------
>From 5d4f299811799ec4731e27983939ea83186be939 Mon Sep 17 00:00:00 2001
From: Trond Myklebust <trond.myklebust@primarydata.com>
Date: Wed, 11 Feb 2015 17:27:55 -0500
Subject: [PATCH] NFSv4.1: Fix a kfree() of uninitialised pointers in
 decode_cb_sequence_args

If the call to decode_rc_list() fails due to a memory allocation error,
then we need to truncate the array size to ensure that we only call
kfree() on those pointer that were allocated.

Reported-by: David Ramos <daramos@stanford.edu>
Fixes: 4aece6a19cf7f ("nfs41: cb_sequence xdr implementation")
Cc: stable@vger.kernel.org
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
---
 fs/nfs/callback_xdr.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/fs/nfs/callback_xdr.c b/fs/nfs/callback_xdr.c
index f4ccfe6521ec..02f8d09e119f 100644
--- a/fs/nfs/callback_xdr.c
+++ b/fs/nfs/callback_xdr.c
@@ -464,8 +464,10 @@ static __be32 decode_cb_sequence_args(struct svc_rqst *rqstp,
 
 		for (i = 0; i < args->csa_nrclists; i++) {
 			status = decode_rc_list(xdr, &args->csa_rclists[i]);
-			if (status)
+			if (status) {
+				args->csa_nrclists = i;
 				goto out_free;
+			}
 		}
 	}
 	status = 0;
-- 
2.1.0




  reply	other threads:[~2015-02-11 22:42 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-02-11 21:39 Possible NFS 4.1 client vulnerability: uninitialized/garbage kfree() in decode_cb_sequence_args() David Ramos
2015-02-11 22:42 ` Trond Myklebust [this message]
2015-02-11 22:58   ` David Ramos
     [not found]   ` <C957EAEA-BA10-4C95-A95B-09FD0F9B12B1@stanford.edu>
2015-02-11 23:08     ` Trond Myklebust

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=1423694562.7169.12.camel@primarydata.com \
    --to=trond.myklebust@primarydata.com \
    --cc=daramos@stanford.edu \
    --cc=linux-nfs@vger.kernel.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.