diff options
Diffstat (limited to 'fs/nfsd/nfsxdr.c')
-rw-r--r-- | fs/nfsd/nfsxdr.c | 53 |
1 files changed, 37 insertions, 16 deletions
diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c index 0c24b9e24fe8..cb3e7fadb772 100644 --- a/fs/nfsd/nfsxdr.c +++ b/fs/nfsd/nfsxdr.c | |||
@@ -231,9 +231,10 @@ int | |||
231 | nfssvc_decode_sattrargs(struct svc_rqst *rqstp, __be32 *p, | 231 | nfssvc_decode_sattrargs(struct svc_rqst *rqstp, __be32 *p, |
232 | struct nfsd_sattrargs *args) | 232 | struct nfsd_sattrargs *args) |
233 | { | 233 | { |
234 | if (!(p = decode_fh(p, &args->fh)) | 234 | p = decode_fh(p, &args->fh); |
235 | || !(p = decode_sattr(p, &args->attrs))) | 235 | if (!p) |
236 | return 0; | 236 | return 0; |
237 | p = decode_sattr(p, &args->attrs); | ||
237 | 238 | ||
238 | return xdr_argsize_check(rqstp, p); | 239 | return xdr_argsize_check(rqstp, p); |
239 | } | 240 | } |
@@ -284,8 +285,9 @@ int | |||
284 | nfssvc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p, | 285 | nfssvc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p, |
285 | struct nfsd_writeargs *args) | 286 | struct nfsd_writeargs *args) |
286 | { | 287 | { |
287 | unsigned int len; | 288 | unsigned int len, hdr, dlen; |
288 | int v; | 289 | int v; |
290 | |||
289 | if (!(p = decode_fh(p, &args->fh))) | 291 | if (!(p = decode_fh(p, &args->fh))) |
290 | return 0; | 292 | return 0; |
291 | 293 | ||
@@ -293,11 +295,30 @@ nfssvc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p, | |||
293 | args->offset = ntohl(*p++); /* offset */ | 295 | args->offset = ntohl(*p++); /* offset */ |
294 | p++; /* totalcount */ | 296 | p++; /* totalcount */ |
295 | len = args->len = ntohl(*p++); | 297 | len = args->len = ntohl(*p++); |
296 | rqstp->rq_vec[0].iov_base = (void*)p; | 298 | /* |
297 | rqstp->rq_vec[0].iov_len = rqstp->rq_arg.head[0].iov_len - | 299 | * The protocol specifies a maximum of 8192 bytes. |
298 | (((void*)p) - rqstp->rq_arg.head[0].iov_base); | 300 | */ |
299 | if (len > NFSSVC_MAXBLKSIZE_V2) | 301 | if (len > NFSSVC_MAXBLKSIZE_V2) |
300 | len = NFSSVC_MAXBLKSIZE_V2; | 302 | return 0; |
303 | |||
304 | /* | ||
305 | * Check to make sure that we got the right number of | ||
306 | * bytes. | ||
307 | */ | ||
308 | hdr = (void*)p - rqstp->rq_arg.head[0].iov_base; | ||
309 | dlen = rqstp->rq_arg.head[0].iov_len + rqstp->rq_arg.page_len | ||
310 | - hdr; | ||
311 | |||
312 | /* | ||
313 | * Round the length of the data which was specified up to | ||
314 | * the next multiple of XDR units and then compare that | ||
315 | * against the length which was actually received. | ||
316 | */ | ||
317 | if (dlen != XDR_QUADLEN(len)*4) | ||
318 | return 0; | ||
319 | |||
320 | rqstp->rq_vec[0].iov_base = (void*)p; | ||
321 | rqstp->rq_vec[0].iov_len = rqstp->rq_arg.head[0].iov_len - hdr; | ||
301 | v = 0; | 322 | v = 0; |
302 | while (len > rqstp->rq_vec[v].iov_len) { | 323 | while (len > rqstp->rq_vec[v].iov_len) { |
303 | len -= rqstp->rq_vec[v].iov_len; | 324 | len -= rqstp->rq_vec[v].iov_len; |
@@ -306,18 +327,18 @@ nfssvc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p, | |||
306 | rqstp->rq_vec[v].iov_len = PAGE_SIZE; | 327 | rqstp->rq_vec[v].iov_len = PAGE_SIZE; |
307 | } | 328 | } |
308 | rqstp->rq_vec[v].iov_len = len; | 329 | rqstp->rq_vec[v].iov_len = len; |
309 | args->vlen = v+1; | 330 | args->vlen = v + 1; |
310 | return rqstp->rq_vec[0].iov_len > 0; | 331 | return 1; |
311 | } | 332 | } |
312 | 333 | ||
313 | int | 334 | int |
314 | nfssvc_decode_createargs(struct svc_rqst *rqstp, __be32 *p, | 335 | nfssvc_decode_createargs(struct svc_rqst *rqstp, __be32 *p, |
315 | struct nfsd_createargs *args) | 336 | struct nfsd_createargs *args) |
316 | { | 337 | { |
317 | if (!(p = decode_fh(p, &args->fh)) | 338 | if ( !(p = decode_fh(p, &args->fh)) |
318 | || !(p = decode_filename(p, &args->name, &args->len)) | 339 | || !(p = decode_filename(p, &args->name, &args->len))) |
319 | || !(p = decode_sattr(p, &args->attrs))) | ||
320 | return 0; | 340 | return 0; |
341 | p = decode_sattr(p, &args->attrs); | ||
321 | 342 | ||
322 | return xdr_argsize_check(rqstp, p); | 343 | return xdr_argsize_check(rqstp, p); |
323 | } | 344 | } |
@@ -361,11 +382,11 @@ int | |||
361 | nfssvc_decode_symlinkargs(struct svc_rqst *rqstp, __be32 *p, | 382 | nfssvc_decode_symlinkargs(struct svc_rqst *rqstp, __be32 *p, |
362 | struct nfsd_symlinkargs *args) | 383 | struct nfsd_symlinkargs *args) |
363 | { | 384 | { |
364 | if (!(p = decode_fh(p, &args->ffh)) | 385 | if ( !(p = decode_fh(p, &args->ffh)) |
365 | || !(p = decode_filename(p, &args->fname, &args->flen)) | 386 | || !(p = decode_filename(p, &args->fname, &args->flen)) |
366 | || !(p = decode_pathname(p, &args->tname, &args->tlen)) | 387 | || !(p = decode_pathname(p, &args->tname, &args->tlen))) |
367 | || !(p = decode_sattr(p, &args->attrs))) | ||
368 | return 0; | 388 | return 0; |
389 | p = decode_sattr(p, &args->attrs); | ||
369 | 390 | ||
370 | return xdr_argsize_check(rqstp, p); | 391 | return xdr_argsize_check(rqstp, p); |
371 | } | 392 | } |