aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2009-06-17 21:02:13 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2009-06-17 21:02:13 -0400
commit8e02f6b9aae9b265064f929c6df15222b9baf256 (patch)
treeb5f018180a6b130731c085ee6ae7c060decfe538
parenta14017db2852f9393a401a0f64053c331003babf (diff)
NFS: Update MNT and MNT3 reply decoding functions
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> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r--fs/nfs/internal.h2
-rw-r--r--fs/nfs/mount_clnt.c63
-rw-r--r--fs/nfs/nfsroot.c2
-rw-r--r--fs/nfs/super.c2
4 files changed, 55 insertions, 14 deletions
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index 0207758de44a..10cf1110df48 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -83,6 +83,8 @@ struct nfs_mount_request {
83 unsigned short protocol; 83 unsigned short protocol;
84 struct nfs_fh *fh; 84 struct nfs_fh *fh;
85 int noresvport; 85 int noresvport;
86 unsigned int *auth_flav_len;
87 rpc_authflavor_t *auth_flavs;
86}; 88};
87 89
88extern int nfs_mount(struct nfs_mount_request *info); 90extern int nfs_mount(struct nfs_mount_request *info);
diff --git a/fs/nfs/mount_clnt.c b/fs/nfs/mount_clnt.c
index ed0a27ed538d..618d815c3093 100644
--- a/fs/nfs/mount_clnt.c
+++ b/fs/nfs/mount_clnt.c
@@ -39,6 +39,9 @@
39 * XDR argument and result sizes 39 * XDR argument and result sizes
40 */ 40 */
41#define MNT_enc_dirpath_sz encode_dirpath_sz 41#define MNT_enc_dirpath_sz encode_dirpath_sz
42#define MNT_dec_mountres_sz (MNT_status_sz + MNT_fhandle_sz)
43#define MNT_dec_mountres3_sz (MNT_status_sz + MNT_fhandle_sz + \
44 MNT_authflav3_sz)
42 45
43/* 46/*
44 * Defined by RFC 1094, section A.5 47 * Defined by RFC 1094, section A.5
@@ -140,8 +143,10 @@ struct mnt_fhstatus {
140 */ 143 */
141int nfs_mount(struct nfs_mount_request *info) 144int nfs_mount(struct nfs_mount_request *info)
142{ 145{
143 struct mnt_fhstatus result = { 146 struct mountres result = {
144 .fh = info->fh 147 .fh = info->fh,
148 .auth_count = info->auth_flav_len,
149 .auth_flavors = info->auth_flavs,
145 }; 150 };
146 struct rpc_message msg = { 151 struct rpc_message msg = {
147 .rpc_argp = info->dirpath, 152 .rpc_argp = info->dirpath,
@@ -180,7 +185,7 @@ int nfs_mount(struct nfs_mount_request *info)
180 185
181 if (status < 0) 186 if (status < 0)
182 goto out_call_err; 187 goto out_call_err;
183 if (result.status != 0) 188 if (result.errno != 0)
184 goto out_mnt_err; 189 goto out_mnt_err;
185 190
186 dprintk("NFS: MNT request succeeded\n"); 191 dprintk("NFS: MNT request succeeded\n");
@@ -191,16 +196,16 @@ out:
191 196
192out_clnt_err: 197out_clnt_err:
193 status = PTR_ERR(mnt_clnt); 198 status = PTR_ERR(mnt_clnt);
194 dprintk("NFS: failed to create RPC client, status=%d\n", status); 199 dprintk("NFS: failed to create MNT RPC client, status=%d\n", status);
195 goto out; 200 goto out;
196 201
197out_call_err: 202out_call_err:
198 dprintk("NFS: failed to start MNT request, status=%d\n", status); 203 dprintk("NFS: MNT request failed, status=%d\n", status);
199 goto out; 204 goto out;
200 205
201out_mnt_err: 206out_mnt_err:
202 dprintk("NFS: MNT server returned result %d\n", result.status); 207 dprintk("NFS: MNT server returned result %d\n", result.errno);
203 status = nfs_stat_to_errno(result.status); 208 status = result.errno;
204 goto out; 209 goto out;
205} 210}
206 211
@@ -291,6 +296,20 @@ static int decode_fhandle(struct xdr_stream *xdr, struct mountres *res)
291 return 0; 296 return 0;
292} 297}
293 298
299static int mnt_dec_mountres(struct rpc_rqst *req, __be32 *p,
300 struct mountres *res)
301{
302 struct xdr_stream xdr;
303 int status;
304
305 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
306
307 status = decode_status(&xdr, res);
308 if (unlikely(status != 0 || res->errno != 0))
309 return status;
310 return decode_fhandle(&xdr, res);
311}
312
294static int decode_fhs_status(struct xdr_stream *xdr, struct mountres *res) 313static int decode_fhs_status(struct xdr_stream *xdr, struct mountres *res)
295{ 314{
296 unsigned int i; 315 unsigned int i;
@@ -371,6 +390,25 @@ static int decode_auth_flavors(struct xdr_stream *xdr, struct mountres *res)
371 return 0; 390 return 0;
372} 391}
373 392
393static int mnt_dec_mountres3(struct rpc_rqst *req, __be32 *p,
394 struct mountres *res)
395{
396 struct xdr_stream xdr;
397 int status;
398
399 xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
400
401 status = decode_fhs_status(&xdr, res);
402 if (unlikely(status != 0 || res->errno != 0))
403 return status;
404 status = decode_fhandle3(&xdr, res);
405 if (unlikely(status != 0)) {
406 res->errno = -EBADHANDLE;
407 return 0;
408 }
409 return decode_auth_flavors(&xdr, res);
410}
411
374static int xdr_decode_fhstatus3(struct rpc_rqst *req, __be32 *p, 412static int xdr_decode_fhstatus3(struct rpc_rqst *req, __be32 *p,
375 struct mnt_fhstatus *res) 413 struct mnt_fhstatus *res)
376{ 414{
@@ -388,16 +426,13 @@ static int xdr_decode_fhstatus3(struct rpc_rqst *req, __be32 *p,
388 return 0; 426 return 0;
389} 427}
390 428
391#define MNT_fhstatus_sz (1 + 8)
392#define MNT_fhstatus3_sz (1 + 16)
393
394static struct rpc_procinfo mnt_procedures[] = { 429static struct rpc_procinfo mnt_procedures[] = {
395 [MOUNTPROC_MNT] = { 430 [MOUNTPROC_MNT] = {
396 .p_proc = MOUNTPROC_MNT, 431 .p_proc = MOUNTPROC_MNT,
397 .p_encode = (kxdrproc_t)mnt_enc_dirpath, 432 .p_encode = (kxdrproc_t)mnt_enc_dirpath,
398 .p_decode = (kxdrproc_t) xdr_decode_fhstatus, 433 .p_decode = (kxdrproc_t)mnt_dec_mountres,
399 .p_arglen = MNT_enc_dirpath_sz, 434 .p_arglen = MNT_enc_dirpath_sz,
400 .p_replen = MNT_fhstatus_sz, 435 .p_replen = MNT_dec_mountres_sz,
401 .p_statidx = MOUNTPROC_MNT, 436 .p_statidx = MOUNTPROC_MNT,
402 .p_name = "MOUNT", 437 .p_name = "MOUNT",
403 }, 438 },
@@ -407,9 +442,9 @@ static struct rpc_procinfo mnt3_procedures[] = {
407 [MOUNTPROC3_MNT] = { 442 [MOUNTPROC3_MNT] = {
408 .p_proc = MOUNTPROC3_MNT, 443 .p_proc = MOUNTPROC3_MNT,
409 .p_encode = (kxdrproc_t)mnt_enc_dirpath, 444 .p_encode = (kxdrproc_t)mnt_enc_dirpath,
410 .p_decode = (kxdrproc_t) xdr_decode_fhstatus3, 445 .p_decode = (kxdrproc_t)mnt_dec_mountres3,
411 .p_arglen = MNT_enc_dirpath_sz, 446 .p_arglen = MNT_enc_dirpath_sz,
412 .p_replen = MNT_fhstatus3_sz, 447 .p_replen = MNT_dec_mountres3_sz,
413 .p_statidx = MOUNTPROC3_MNT, 448 .p_statidx = MOUNTPROC3_MNT,
414 .p_name = "MOUNT", 449 .p_name = "MOUNT",
415 }, 450 },
diff --git a/fs/nfs/nfsroot.c b/fs/nfs/nfsroot.c
index 24c1b93874c4..8c55b27c0de4 100644
--- a/fs/nfs/nfsroot.c
+++ b/fs/nfs/nfsroot.c
@@ -490,6 +490,7 @@ static int __init root_nfs_get_handle(void)
490{ 490{
491 struct nfs_fh fh; 491 struct nfs_fh fh;
492 struct sockaddr_in sin; 492 struct sockaddr_in sin;
493 unsigned int auth_flav_len = 0;
493 struct nfs_mount_request request = { 494 struct nfs_mount_request request = {
494 .sap = (struct sockaddr *)&sin, 495 .sap = (struct sockaddr *)&sin,
495 .salen = sizeof(sin), 496 .salen = sizeof(sin),
@@ -499,6 +500,7 @@ static int __init root_nfs_get_handle(void)
499 .protocol = (nfs_data.flags & NFS_MOUNT_TCP) ? 500 .protocol = (nfs_data.flags & NFS_MOUNT_TCP) ?
500 XPRT_TRANSPORT_TCP : XPRT_TRANSPORT_UDP, 501 XPRT_TRANSPORT_TCP : XPRT_TRANSPORT_UDP,
501 .fh = &fh, 502 .fh = &fh,
503 .auth_flav_len = &auth_flav_len,
502 }; 504 };
503 int status; 505 int status;
504 506
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 539a61a0887b..0b72357cdc41 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -1380,6 +1380,7 @@ out_security_failure:
1380static int nfs_try_mount(struct nfs_parsed_mount_data *args, 1380static int nfs_try_mount(struct nfs_parsed_mount_data *args,
1381 struct nfs_fh *root_fh) 1381 struct nfs_fh *root_fh)
1382{ 1382{
1383 unsigned int auth_flavor_len = 0;
1383 struct nfs_mount_request request = { 1384 struct nfs_mount_request request = {
1384 .sap = (struct sockaddr *) 1385 .sap = (struct sockaddr *)
1385 &args->mount_server.address, 1386 &args->mount_server.address,
@@ -1387,6 +1388,7 @@ static int nfs_try_mount(struct nfs_parsed_mount_data *args,
1387 .protocol = args->mount_server.protocol, 1388 .protocol = args->mount_server.protocol,
1388 .fh = root_fh, 1389 .fh = root_fh,
1389 .noresvport = args->flags & NFS_MOUNT_NORESVPORT, 1390 .noresvport = args->flags & NFS_MOUNT_NORESVPORT,
1391 .auth_flav_len = &auth_flavor_len,
1390 }; 1392 };
1391 int status; 1393 int status;
1392 1394