From: Vitaliy Gusev <gusev.vitaliy@nexenta.com>
To: Al Viro <viro@zeniv.linux.org.uk>
Cc: Trond Myklebust <Trond.Myklebust@netapp.com>,
David Howells <dhowells@redhat.com>,
linux-fsdevel@vger.kernel.org
Subject: [PATCH 1/3] nfs: Fix memory corruption up to 90KB due to not expected FS_LOCATION
Date: Mon, 07 Feb 2011 19:35:10 +0300 [thread overview]
Message-ID: <1297096510.20025.158.camel@vT510> (raw)
There are a remote vulnerability for nfs4-client. That allows
a remote NFSv4 server or attacker in middle rewrite memory on
NFSv4 client.
Of course if encryption is used then only server can do corruption.
Idea is:
1. Client send GETATTR request to server, but there are not
checks for bitmask in reply from server. Therefore server may return
more attributes than were asked.
2. Pointer to struct nfs_fattr is passed to
decode_getfattr_generic() and decode_getfattr(), but
that parameter is considered as pointer to struct nfs4_fs_locations
in case set FATTR4_WORD0_FS_LOCATIONS in reply.
But there is no check for types for pointer that was passed!
3. Remote side can set FATTR4_WORD0_FS_LOCATIONS and write
datas fsattr4_fs_locations in reply to client.
4. sizeof(nfs4_fs_locations) is about 92080 bytes in kernel 2.6.38
So ~ 90 Kbytes can be overwritten in memory of NFSv4 client.
Affected kernels: all from v2.6.18
Simple testcase for NFSv4 server: add next code at begin of
nfsd4_encode_fattr()
if (!strcmp("filexxx", dentry->d_name.name)) {
bmval[0] |= FATTR4_WORD0_FS_LOCATIONS;
bmval0 |= FATTR4_WORD0_FS_LOCATIONS;
}
After that NFSv4 client that tries to touch 'filexxx' will
catch kernel panic.
Signed-off-by: Gusev Vitaliy <gusev.vitaliy@nexenta.com>
---
fs/nfs/nfs4xdr.c | 16 ++++++++++++----
1 files changed, 12 insertions(+), 4 deletions(-)
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 242b392..8dbfd9a 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -4301,7 +4301,8 @@ xdr_error:
}
static int decode_getfattr_generic(struct xdr_stream *xdr, struct
nfs_fattr *fattr,
- struct nfs_fh *fh, const struct nfs_server *server, int may_sleep)
+ struct nfs_fh *fh, const struct nfs_server *server, int may_sleep,
+ int expect_fsloc)
{
__be32 *savep;
uint32_t attrlen,
@@ -4316,6 +4317,9 @@ static int decode_getfattr_generic(struct
xdr_stream *xdr, struct nfs_fattr *fat
if (status < 0)
goto xdr_error;
+ if (!expect_fsloc)
+ bitmap[0] &= ~FATTR4_WORD0_FS_LOCATIONS;
+
status = decode_attr_length(xdr, &attrlen, &savep);
if (status < 0)
goto xdr_error;
@@ -4333,7 +4337,7 @@ xdr_error:
static int decode_getfattr(struct xdr_stream *xdr, struct nfs_fattr
*fattr,
const struct nfs_server *server, int may_sleep)
{
- return decode_getfattr_generic(xdr, fattr, NULL, server, may_sleep);
+ return decode_getfattr_generic(xdr, fattr, NULL, server, may_sleep,
0);
}
/*
@@ -6338,9 +6342,11 @@ static int nfs4_xdr_dec_fs_locations(struct
rpc_rqst *req,
if (status)
goto out;
xdr_enter_page(xdr, PAGE_SIZE);
- status = decode_getfattr(xdr, &res->fs_locations->fattr,
+ status = decode_getfattr_generic(xdr, &res->fs_locations->fattr,
+ NULL,
res->fs_locations->server,
- !RPC_IS_ASYNC(req->rq_task));
+ !RPC_IS_ASYNC(req->rq_task),
+ 1);
out:
return status;
}
@@ -6677,6 +6683,8 @@ int nfs4_decode_dirent(struct xdr_stream *xdr,
struct nfs_entry *entry,
if (decode_attr_bitmap(xdr, bitmap) < 0)
goto out_overflow;
+ bitmap[0] &= ~FATTR4_WORD0_FS_LOCATIONS;
+
if (decode_attr_length(xdr, &len, &p) < 0)
goto out_overflow;
reply other threads:[~2011-02-07 16:52 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
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=1297096510.20025.158.camel@vT510 \
--to=gusev.vitaliy@nexenta.com \
--cc=Trond.Myklebust@netapp.com \
--cc=dhowells@redhat.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=viro@zeniv.linux.org.uk \
/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