From: Chuck Lever <chuck.lever@oracle.com>
To: trond.myklebust@fys.uio.no
Cc: linux-nfs@vger.kernel.org
Subject: [PATCH 6/8] NFS: Update MNT and MNT3 reply decoding functions
Date: Sat, 13 Jun 2009 19:26:23 -0400 [thread overview]
Message-ID: <20090613232623.3225.52634.stgit@isabey.1015granger.net> (raw)
In-Reply-To: <20090613232149.3225.92143.stgit-r85ClMMopbrwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
Solder xdr_stream-based XDR decoding functions into the in-kernel mountd
client that are more careful about checking data types and watching for
buffer overflows. The new MNT3 decoder includes support for auth-flavor
list decoding.
The "_sz" macro for MNT3 replies was missing the size of the file handle.
I've added this back, and included the size of the auth flavor array.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
fs/nfs/internal.h | 2 ++
fs/nfs/mount_clnt.c | 63 ++++++++++++++++++++++++++++++++++++++++-----------
fs/nfs/nfsroot.c | 2 ++
fs/nfs/super.c | 2 ++
4 files changed, 55 insertions(+), 14 deletions(-)
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index b13b456..82a78c8 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -83,6 +83,8 @@ struct nfs_mount_request {
unsigned short protocol;
struct nfs_fh *fh;
int noresvport;
+ unsigned int *auth_flav_len;
+ rpc_authflavor_t *auth_flavs;
};
extern int nfs_mount(struct nfs_mount_request *info);
diff --git a/fs/nfs/mount_clnt.c b/fs/nfs/mount_clnt.c
index ed0a27e..618d815 100644
--- a/fs/nfs/mount_clnt.c
+++ b/fs/nfs/mount_clnt.c
@@ -39,6 +39,9 @@
* XDR argument and result sizes
*/
#define MNT_enc_dirpath_sz encode_dirpath_sz
+#define MNT_dec_mountres_sz (MNT_status_sz + MNT_fhandle_sz)
+#define MNT_dec_mountres3_sz (MNT_status_sz + MNT_fhandle_sz + \
+ MNT_authflav3_sz)
/*
* Defined by RFC 1094, section A.5
@@ -140,8 +143,10 @@ struct mnt_fhstatus {
*/
int nfs_mount(struct nfs_mount_request *info)
{
- struct mnt_fhstatus result = {
- .fh = info->fh
+ struct mountres result = {
+ .fh = info->fh,
+ .auth_count = info->auth_flav_len,
+ .auth_flavors = info->auth_flavs,
};
struct rpc_message msg = {
.rpc_argp = info->dirpath,
@@ -180,7 +185,7 @@ int nfs_mount(struct nfs_mount_request *info)
if (status < 0)
goto out_call_err;
- if (result.status != 0)
+ if (result.errno != 0)
goto out_mnt_err;
dprintk("NFS: MNT request succeeded\n");
@@ -191,16 +196,16 @@ out:
out_clnt_err:
status = PTR_ERR(mnt_clnt);
- dprintk("NFS: failed to create RPC client, status=%d\n", status);
+ dprintk("NFS: failed to create MNT RPC client, status=%d\n", status);
goto out;
out_call_err:
- dprintk("NFS: failed to start MNT request, status=%d\n", status);
+ dprintk("NFS: MNT request failed, status=%d\n", status);
goto out;
out_mnt_err:
- dprintk("NFS: MNT server returned result %d\n", result.status);
- status = nfs_stat_to_errno(result.status);
+ dprintk("NFS: MNT server returned result %d\n", result.errno);
+ status = result.errno;
goto out;
}
@@ -291,6 +296,20 @@ static int decode_fhandle(struct xdr_stream *xdr, struct mountres *res)
return 0;
}
+static int mnt_dec_mountres(struct rpc_rqst *req, __be32 *p,
+ struct mountres *res)
+{
+ struct xdr_stream xdr;
+ int status;
+
+ xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
+
+ status = decode_status(&xdr, res);
+ if (unlikely(status != 0 || res->errno != 0))
+ return status;
+ return decode_fhandle(&xdr, res);
+}
+
static int decode_fhs_status(struct xdr_stream *xdr, struct mountres *res)
{
unsigned int i;
@@ -371,6 +390,25 @@ static int decode_auth_flavors(struct xdr_stream *xdr, struct mountres *res)
return 0;
}
+static int mnt_dec_mountres3(struct rpc_rqst *req, __be32 *p,
+ struct mountres *res)
+{
+ struct xdr_stream xdr;
+ int status;
+
+ xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
+
+ status = decode_fhs_status(&xdr, res);
+ if (unlikely(status != 0 || res->errno != 0))
+ return status;
+ status = decode_fhandle3(&xdr, res);
+ if (unlikely(status != 0)) {
+ res->errno = -EBADHANDLE;
+ return 0;
+ }
+ return decode_auth_flavors(&xdr, res);
+}
+
static int xdr_decode_fhstatus3(struct rpc_rqst *req, __be32 *p,
struct mnt_fhstatus *res)
{
@@ -388,16 +426,13 @@ static int xdr_decode_fhstatus3(struct rpc_rqst *req, __be32 *p,
return 0;
}
-#define MNT_fhstatus_sz (1 + 8)
-#define MNT_fhstatus3_sz (1 + 16)
-
static struct rpc_procinfo mnt_procedures[] = {
[MOUNTPROC_MNT] = {
.p_proc = MOUNTPROC_MNT,
.p_encode = (kxdrproc_t)mnt_enc_dirpath,
- .p_decode = (kxdrproc_t) xdr_decode_fhstatus,
+ .p_decode = (kxdrproc_t)mnt_dec_mountres,
.p_arglen = MNT_enc_dirpath_sz,
- .p_replen = MNT_fhstatus_sz,
+ .p_replen = MNT_dec_mountres_sz,
.p_statidx = MOUNTPROC_MNT,
.p_name = "MOUNT",
},
@@ -407,9 +442,9 @@ static struct rpc_procinfo mnt3_procedures[] = {
[MOUNTPROC3_MNT] = {
.p_proc = MOUNTPROC3_MNT,
.p_encode = (kxdrproc_t)mnt_enc_dirpath,
- .p_decode = (kxdrproc_t) xdr_decode_fhstatus3,
+ .p_decode = (kxdrproc_t)mnt_dec_mountres3,
.p_arglen = MNT_enc_dirpath_sz,
- .p_replen = MNT_fhstatus3_sz,
+ .p_replen = MNT_dec_mountres3_sz,
.p_statidx = MOUNTPROC3_MNT,
.p_name = "MOUNT",
},
diff --git a/fs/nfs/nfsroot.c b/fs/nfs/nfsroot.c
index 24c1b93..8c55b27 100644
--- a/fs/nfs/nfsroot.c
+++ b/fs/nfs/nfsroot.c
@@ -490,6 +490,7 @@ static int __init root_nfs_get_handle(void)
{
struct nfs_fh fh;
struct sockaddr_in sin;
+ unsigned int auth_flav_len = 0;
struct nfs_mount_request request = {
.sap = (struct sockaddr *)&sin,
.salen = sizeof(sin),
@@ -499,6 +500,7 @@ static int __init root_nfs_get_handle(void)
.protocol = (nfs_data.flags & NFS_MOUNT_TCP) ?
XPRT_TRANSPORT_TCP : XPRT_TRANSPORT_UDP,
.fh = &fh,
+ .auth_flav_len = &auth_flav_len,
};
int status;
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 3502e46..8b3b494 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -1380,6 +1380,7 @@ out_security_failure:
static int nfs_try_mount(struct nfs_parsed_mount_data *args,
struct nfs_fh *root_fh)
{
+ unsigned int auth_flavor_len = 0;
struct nfs_mount_request request = {
.sap = (struct sockaddr *)
&args->mount_server.address,
@@ -1387,6 +1388,7 @@ static int nfs_try_mount(struct nfs_parsed_mount_data *args,
.protocol = args->mount_server.protocol,
.fh = root_fh,
.noresvport = args->flags & NFS_MOUNT_NORESVPORT,
+ .auth_flav_len = &auth_flavor_len,
};
int status;
next prev parent reply other threads:[~2009-06-13 23:26 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-06-13 23:25 [PATCH 0/8] Mount XDR rewrite, and parser bugfix, take 2 Chuck Lever
[not found] ` <20090613232149.3225.92143.stgit-r85ClMMopbrwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
2009-06-13 23:25 ` [PATCH 1/8] NFS: Use xdr_stream-based XDR encoder for MNT's dirpath argument Chuck Lever
2009-06-13 23:25 ` [PATCH 2/8] NFS: remove unused function in fs/nfs/mount_clnt.c Chuck Lever
2009-06-13 23:26 ` [PATCH 3/8] NFS: Add separate mountd status code decoders for each mountd version Chuck Lever
2009-06-13 23:26 ` [PATCH 4/8] NFS: add new file handle decoders to in-kernel mountd client Chuck Lever
2009-06-13 23:26 ` [PATCH 5/8] NFS: add XDR decoder for mountd version 3 auth-flavor lists Chuck Lever
2009-06-13 23:26 ` Chuck Lever [this message]
2009-06-13 23:26 ` [PATCH 7/8] NFS: Remove unused XDR decoder functions Chuck Lever
2009-06-13 23:26 ` [PATCH 8/8] NFS: Invalid mount option values should always fail, even with "sloppy" Chuck Lever
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=20090613232623.3225.52634.stgit@isabey.1015granger.net \
--to=chuck.lever@oracle.com \
--cc=linux-nfs@vger.kernel.org \
--cc=trond.myklebust@fys.uio.no \
/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