diff options
author | Chuck Lever <chuck.lever@oracle.com> | 2009-06-17 21:02:12 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2009-06-17 21:02:12 -0400 |
commit | 4fdcd9966d8469be26a6f12122ac21ffce19fc20 (patch) | |
tree | 569bdb9900053661ba59931cb49315c5de89a88b /fs/nfs/mount_clnt.c | |
parent | fb12529577541aa02f9c3d9e325329f9568dfb58 (diff) |
NFS: add new file handle decoders to in-kernel mountd client
Introduce xdr_stream-based XDR file handle decoders to the in-kernel
mountd client. These are more careful than the existing decoder
functions about buffer overflows and data type and range checking.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/mount_clnt.c')
-rw-r--r-- | fs/nfs/mount_clnt.c | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/fs/nfs/mount_clnt.c b/fs/nfs/mount_clnt.c index 8429885bc729..dd8c6f448eaa 100644 --- a/fs/nfs/mount_clnt.c +++ b/fs/nfs/mount_clnt.c | |||
@@ -31,6 +31,8 @@ | |||
31 | #define encode_dirpath_sz (1 + XDR_QUADLEN(MNTPATHLEN)) | 31 | #define encode_dirpath_sz (1 + XDR_QUADLEN(MNTPATHLEN)) |
32 | #define MNT_status_sz (1) | 32 | #define MNT_status_sz (1) |
33 | #define MNT_fhs_status_sz (1) | 33 | #define MNT_fhs_status_sz (1) |
34 | #define MNT_fhandle_sz XDR_QUADLEN(NFS2_FHSIZE) | ||
35 | #define MNT_fhandle3_sz (1 + XDR_QUADLEN(NFS3_FHSIZE)) | ||
34 | 36 | ||
35 | /* | 37 | /* |
36 | * XDR argument and result sizes | 38 | * XDR argument and result sizes |
@@ -272,6 +274,20 @@ static int decode_status(struct xdr_stream *xdr, struct mountres *res) | |||
272 | return 0; | 274 | return 0; |
273 | } | 275 | } |
274 | 276 | ||
277 | static int decode_fhandle(struct xdr_stream *xdr, struct mountres *res) | ||
278 | { | ||
279 | struct nfs_fh *fh = res->fh; | ||
280 | __be32 *p; | ||
281 | |||
282 | p = xdr_inline_decode(xdr, NFS2_FHSIZE); | ||
283 | if (unlikely(p == NULL)) | ||
284 | return -EIO; | ||
285 | |||
286 | fh->size = NFS2_FHSIZE; | ||
287 | memcpy(fh->data, p, NFS2_FHSIZE); | ||
288 | return 0; | ||
289 | } | ||
290 | |||
275 | static int decode_fhs_status(struct xdr_stream *xdr, struct mountres *res) | 291 | static int decode_fhs_status(struct xdr_stream *xdr, struct mountres *res) |
276 | { | 292 | { |
277 | unsigned int i; | 293 | unsigned int i; |
@@ -295,6 +311,29 @@ static int decode_fhs_status(struct xdr_stream *xdr, struct mountres *res) | |||
295 | return 0; | 311 | return 0; |
296 | } | 312 | } |
297 | 313 | ||
314 | static int decode_fhandle3(struct xdr_stream *xdr, struct mountres *res) | ||
315 | { | ||
316 | struct nfs_fh *fh = res->fh; | ||
317 | u32 size; | ||
318 | __be32 *p; | ||
319 | |||
320 | p = xdr_inline_decode(xdr, sizeof(size)); | ||
321 | if (unlikely(p == NULL)) | ||
322 | return -EIO; | ||
323 | |||
324 | size = ntohl(*p++); | ||
325 | if (size > NFS3_FHSIZE || size == 0) | ||
326 | return -EIO; | ||
327 | |||
328 | p = xdr_inline_decode(xdr, size); | ||
329 | if (unlikely(p == NULL)) | ||
330 | return -EIO; | ||
331 | |||
332 | fh->size = size; | ||
333 | memcpy(fh->data, p, size); | ||
334 | return 0; | ||
335 | } | ||
336 | |||
298 | static int xdr_decode_fhstatus3(struct rpc_rqst *req, __be32 *p, | 337 | static int xdr_decode_fhstatus3(struct rpc_rqst *req, __be32 *p, |
299 | struct mnt_fhstatus *res) | 338 | struct mnt_fhstatus *res) |
300 | { | 339 | { |