diff options
author | Benny Halevy <bhalevy@panasas.com> | 2009-08-14 10:20:14 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2009-08-14 14:02:23 -0400 |
commit | c0eae66ece40bdb8cd88c5106834b71a1c9f421c (patch) | |
tree | 6a82749181b4898ea1d4e51d01a2a6c8e0803e73 | |
parent | 2460ba57c49c36dfef0b62c929461de09240fe17 (diff) |
nfs: nfs4xdr: get rid of READ_BUF
Use xdr_inline_decode instead.
Open code debug printout and error return.
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r-- | fs/nfs/nfs4xdr.c | 475 |
1 files changed, 379 insertions, 96 deletions
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 3f49da0960e3..b0d690c3a24c 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c | |||
@@ -2423,24 +2423,6 @@ static int nfs4_xdr_enc_get_lease_time(struct rpc_rqst *req, uint32_t *p, | |||
2423 | } | 2423 | } |
2424 | #endif /* CONFIG_NFS_V4_1 */ | 2424 | #endif /* CONFIG_NFS_V4_1 */ |
2425 | 2425 | ||
2426 | /* | ||
2427 | * START OF "GENERIC" DECODE ROUTINES. | ||
2428 | * These may look a little ugly since they are imported from a "generic" | ||
2429 | * set of XDR encode/decode routines which are intended to be shared by | ||
2430 | * all of our NFSv4 implementations (OpenBSD, MacOS X...). | ||
2431 | * | ||
2432 | * If the pain of reading these is too great, it should be a straightforward | ||
2433 | * task to translate them into Linux-specific versions which are more | ||
2434 | * consistent with the style used in NFSv2/v3... | ||
2435 | */ | ||
2436 | #define READ_BUF(nbytes) do { \ | ||
2437 | p = xdr_inline_decode(xdr, nbytes); \ | ||
2438 | if (unlikely(!p)) { \ | ||
2439 | print_overflow_msg(__func__, xdr); \ | ||
2440 | return -EIO; \ | ||
2441 | } \ | ||
2442 | } while (0) | ||
2443 | |||
2444 | static void print_overflow_msg(const char *func, const struct xdr_stream *xdr) | 2426 | static void print_overflow_msg(const char *func, const struct xdr_stream *xdr) |
2445 | { | 2427 | { |
2446 | dprintk("nfs: %s: prematurely hit end of receive buffer. " | 2428 | dprintk("nfs: %s: prematurely hit end of receive buffer. " |
@@ -2452,28 +2434,42 @@ static int decode_opaque_inline(struct xdr_stream *xdr, unsigned int *len, char | |||
2452 | { | 2434 | { |
2453 | __be32 *p; | 2435 | __be32 *p; |
2454 | 2436 | ||
2455 | READ_BUF(4); | 2437 | p = xdr_inline_decode(xdr, 4); |
2438 | if (unlikely(!p)) | ||
2439 | goto out_overflow; | ||
2456 | *len = be32_to_cpup(p++); | 2440 | *len = be32_to_cpup(p++); |
2457 | READ_BUF(*len); | 2441 | p = xdr_inline_decode(xdr, *len); |
2442 | if (unlikely(!p)) | ||
2443 | goto out_overflow; | ||
2458 | *string = (char *)p; | 2444 | *string = (char *)p; |
2459 | return 0; | 2445 | return 0; |
2446 | out_overflow: | ||
2447 | print_overflow_msg(__func__, xdr); | ||
2448 | return -EIO; | ||
2460 | } | 2449 | } |
2461 | 2450 | ||
2462 | static int decode_compound_hdr(struct xdr_stream *xdr, struct compound_hdr *hdr) | 2451 | static int decode_compound_hdr(struct xdr_stream *xdr, struct compound_hdr *hdr) |
2463 | { | 2452 | { |
2464 | __be32 *p; | 2453 | __be32 *p; |
2465 | 2454 | ||
2466 | READ_BUF(8); | 2455 | p = xdr_inline_decode(xdr, 8); |
2456 | if (unlikely(!p)) | ||
2457 | goto out_overflow; | ||
2467 | hdr->status = be32_to_cpup(p++); | 2458 | hdr->status = be32_to_cpup(p++); |
2468 | hdr->taglen = be32_to_cpup(p++); | 2459 | hdr->taglen = be32_to_cpup(p++); |
2469 | 2460 | ||
2470 | READ_BUF(hdr->taglen + 4); | 2461 | p = xdr_inline_decode(xdr, hdr->taglen + 4); |
2462 | if (unlikely(!p)) | ||
2463 | goto out_overflow; | ||
2471 | hdr->tag = (char *)p; | 2464 | hdr->tag = (char *)p; |
2472 | p += XDR_QUADLEN(hdr->taglen); | 2465 | p += XDR_QUADLEN(hdr->taglen); |
2473 | hdr->nops = be32_to_cpup(p++); | 2466 | hdr->nops = be32_to_cpup(p++); |
2474 | if (unlikely(hdr->nops < 1)) | 2467 | if (unlikely(hdr->nops < 1)) |
2475 | return nfs4_stat_to_errno(hdr->status); | 2468 | return nfs4_stat_to_errno(hdr->status); |
2476 | return 0; | 2469 | return 0; |
2470 | out_overflow: | ||
2471 | print_overflow_msg(__func__, xdr); | ||
2472 | return -EIO; | ||
2477 | } | 2473 | } |
2478 | 2474 | ||
2479 | static int decode_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 expected) | 2475 | static int decode_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 expected) |
@@ -2482,7 +2478,9 @@ static int decode_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 expected) | |||
2482 | uint32_t opnum; | 2478 | uint32_t opnum; |
2483 | int32_t nfserr; | 2479 | int32_t nfserr; |
2484 | 2480 | ||
2485 | READ_BUF(8); | 2481 | p = xdr_inline_decode(xdr, 8); |
2482 | if (unlikely(!p)) | ||
2483 | goto out_overflow; | ||
2486 | opnum = be32_to_cpup(p++); | 2484 | opnum = be32_to_cpup(p++); |
2487 | if (opnum != expected) { | 2485 | if (opnum != expected) { |
2488 | dprintk("nfs: Server returned operation" | 2486 | dprintk("nfs: Server returned operation" |
@@ -2494,6 +2492,9 @@ static int decode_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 expected) | |||
2494 | if (nfserr != NFS_OK) | 2492 | if (nfserr != NFS_OK) |
2495 | return nfs4_stat_to_errno(nfserr); | 2493 | return nfs4_stat_to_errno(nfserr); |
2496 | return 0; | 2494 | return 0; |
2495 | out_overflow: | ||
2496 | print_overflow_msg(__func__, xdr); | ||
2497 | return -EIO; | ||
2497 | } | 2498 | } |
2498 | 2499 | ||
2499 | /* Dummy routine */ | 2500 | /* Dummy routine */ |
@@ -2503,8 +2504,11 @@ static int decode_ace(struct xdr_stream *xdr, void *ace, struct nfs_client *clp) | |||
2503 | unsigned int strlen; | 2504 | unsigned int strlen; |
2504 | char *str; | 2505 | char *str; |
2505 | 2506 | ||
2506 | READ_BUF(12); | 2507 | p = xdr_inline_decode(xdr, 12); |
2507 | return decode_opaque_inline(xdr, &strlen, &str); | 2508 | if (likely(p)) |
2509 | return decode_opaque_inline(xdr, &strlen, &str); | ||
2510 | print_overflow_msg(__func__, xdr); | ||
2511 | return -EIO; | ||
2508 | } | 2512 | } |
2509 | 2513 | ||
2510 | static int decode_attr_bitmap(struct xdr_stream *xdr, uint32_t *bitmap) | 2514 | static int decode_attr_bitmap(struct xdr_stream *xdr, uint32_t *bitmap) |
@@ -2512,27 +2516,39 @@ static int decode_attr_bitmap(struct xdr_stream *xdr, uint32_t *bitmap) | |||
2512 | uint32_t bmlen; | 2516 | uint32_t bmlen; |
2513 | __be32 *p; | 2517 | __be32 *p; |
2514 | 2518 | ||
2515 | READ_BUF(4); | 2519 | p = xdr_inline_decode(xdr, 4); |
2520 | if (unlikely(!p)) | ||
2521 | goto out_overflow; | ||
2516 | bmlen = be32_to_cpup(p++); | 2522 | bmlen = be32_to_cpup(p++); |
2517 | 2523 | ||
2518 | bitmap[0] = bitmap[1] = 0; | 2524 | bitmap[0] = bitmap[1] = 0; |
2519 | READ_BUF((bmlen << 2)); | 2525 | p = xdr_inline_decode(xdr, (bmlen << 2)); |
2526 | if (unlikely(!p)) | ||
2527 | goto out_overflow; | ||
2520 | if (bmlen > 0) { | 2528 | if (bmlen > 0) { |
2521 | bitmap[0] = be32_to_cpup(p++); | 2529 | bitmap[0] = be32_to_cpup(p++); |
2522 | if (bmlen > 1) | 2530 | if (bmlen > 1) |
2523 | bitmap[1] = be32_to_cpup(p++); | 2531 | bitmap[1] = be32_to_cpup(p++); |
2524 | } | 2532 | } |
2525 | return 0; | 2533 | return 0; |
2534 | out_overflow: | ||
2535 | print_overflow_msg(__func__, xdr); | ||
2536 | return -EIO; | ||
2526 | } | 2537 | } |
2527 | 2538 | ||
2528 | static inline int decode_attr_length(struct xdr_stream *xdr, uint32_t *attrlen, __be32 **savep) | 2539 | static inline int decode_attr_length(struct xdr_stream *xdr, uint32_t *attrlen, __be32 **savep) |
2529 | { | 2540 | { |
2530 | __be32 *p; | 2541 | __be32 *p; |
2531 | 2542 | ||
2532 | READ_BUF(4); | 2543 | p = xdr_inline_decode(xdr, 4); |
2544 | if (unlikely(!p)) | ||
2545 | goto out_overflow; | ||
2533 | *attrlen = be32_to_cpup(p++); | 2546 | *attrlen = be32_to_cpup(p++); |
2534 | *savep = xdr->p; | 2547 | *savep = xdr->p; |
2535 | return 0; | 2548 | return 0; |
2549 | out_overflow: | ||
2550 | print_overflow_msg(__func__, xdr); | ||
2551 | return -EIO; | ||
2536 | } | 2552 | } |
2537 | 2553 | ||
2538 | static int decode_attr_supported(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *bitmask) | 2554 | static int decode_attr_supported(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *bitmask) |
@@ -2555,7 +2571,9 @@ static int decode_attr_type(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t * | |||
2555 | if (unlikely(bitmap[0] & (FATTR4_WORD0_TYPE - 1U))) | 2571 | if (unlikely(bitmap[0] & (FATTR4_WORD0_TYPE - 1U))) |
2556 | return -EIO; | 2572 | return -EIO; |
2557 | if (likely(bitmap[0] & FATTR4_WORD0_TYPE)) { | 2573 | if (likely(bitmap[0] & FATTR4_WORD0_TYPE)) { |
2558 | READ_BUF(4); | 2574 | p = xdr_inline_decode(xdr, 4); |
2575 | if (unlikely(!p)) | ||
2576 | goto out_overflow; | ||
2559 | *type = be32_to_cpup(p++); | 2577 | *type = be32_to_cpup(p++); |
2560 | if (*type < NF4REG || *type > NF4NAMEDATTR) { | 2578 | if (*type < NF4REG || *type > NF4NAMEDATTR) { |
2561 | dprintk("%s: bad type %d\n", __func__, *type); | 2579 | dprintk("%s: bad type %d\n", __func__, *type); |
@@ -2566,6 +2584,9 @@ static int decode_attr_type(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t * | |||
2566 | } | 2584 | } |
2567 | dprintk("%s: type=0%o\n", __func__, nfs_type2fmt[*type]); | 2585 | dprintk("%s: type=0%o\n", __func__, nfs_type2fmt[*type]); |
2568 | return ret; | 2586 | return ret; |
2587 | out_overflow: | ||
2588 | print_overflow_msg(__func__, xdr); | ||
2589 | return -EIO; | ||
2569 | } | 2590 | } |
2570 | 2591 | ||
2571 | static int decode_attr_change(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *change) | 2592 | static int decode_attr_change(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *change) |
@@ -2577,7 +2598,9 @@ static int decode_attr_change(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t | |||
2577 | if (unlikely(bitmap[0] & (FATTR4_WORD0_CHANGE - 1U))) | 2598 | if (unlikely(bitmap[0] & (FATTR4_WORD0_CHANGE - 1U))) |
2578 | return -EIO; | 2599 | return -EIO; |
2579 | if (likely(bitmap[0] & FATTR4_WORD0_CHANGE)) { | 2600 | if (likely(bitmap[0] & FATTR4_WORD0_CHANGE)) { |
2580 | READ_BUF(8); | 2601 | p = xdr_inline_decode(xdr, 8); |
2602 | if (unlikely(!p)) | ||
2603 | goto out_overflow; | ||
2581 | p = xdr_decode_hyper(p, change); | 2604 | p = xdr_decode_hyper(p, change); |
2582 | bitmap[0] &= ~FATTR4_WORD0_CHANGE; | 2605 | bitmap[0] &= ~FATTR4_WORD0_CHANGE; |
2583 | ret = NFS_ATTR_FATTR_CHANGE; | 2606 | ret = NFS_ATTR_FATTR_CHANGE; |
@@ -2585,6 +2608,9 @@ static int decode_attr_change(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t | |||
2585 | dprintk("%s: change attribute=%Lu\n", __func__, | 2608 | dprintk("%s: change attribute=%Lu\n", __func__, |
2586 | (unsigned long long)*change); | 2609 | (unsigned long long)*change); |
2587 | return ret; | 2610 | return ret; |
2611 | out_overflow: | ||
2612 | print_overflow_msg(__func__, xdr); | ||
2613 | return -EIO; | ||
2588 | } | 2614 | } |
2589 | 2615 | ||
2590 | static int decode_attr_size(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *size) | 2616 | static int decode_attr_size(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *size) |
@@ -2596,13 +2622,18 @@ static int decode_attr_size(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t * | |||
2596 | if (unlikely(bitmap[0] & (FATTR4_WORD0_SIZE - 1U))) | 2622 | if (unlikely(bitmap[0] & (FATTR4_WORD0_SIZE - 1U))) |
2597 | return -EIO; | 2623 | return -EIO; |
2598 | if (likely(bitmap[0] & FATTR4_WORD0_SIZE)) { | 2624 | if (likely(bitmap[0] & FATTR4_WORD0_SIZE)) { |
2599 | READ_BUF(8); | 2625 | p = xdr_inline_decode(xdr, 8); |
2626 | if (unlikely(!p)) | ||
2627 | goto out_overflow; | ||
2600 | p = xdr_decode_hyper(p, size); | 2628 | p = xdr_decode_hyper(p, size); |
2601 | bitmap[0] &= ~FATTR4_WORD0_SIZE; | 2629 | bitmap[0] &= ~FATTR4_WORD0_SIZE; |
2602 | ret = NFS_ATTR_FATTR_SIZE; | 2630 | ret = NFS_ATTR_FATTR_SIZE; |
2603 | } | 2631 | } |
2604 | dprintk("%s: file size=%Lu\n", __func__, (unsigned long long)*size); | 2632 | dprintk("%s: file size=%Lu\n", __func__, (unsigned long long)*size); |
2605 | return ret; | 2633 | return ret; |
2634 | out_overflow: | ||
2635 | print_overflow_msg(__func__, xdr); | ||
2636 | return -EIO; | ||
2606 | } | 2637 | } |
2607 | 2638 | ||
2608 | static int decode_attr_link_support(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) | 2639 | static int decode_attr_link_support(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) |
@@ -2613,12 +2644,17 @@ static int decode_attr_link_support(struct xdr_stream *xdr, uint32_t *bitmap, ui | |||
2613 | if (unlikely(bitmap[0] & (FATTR4_WORD0_LINK_SUPPORT - 1U))) | 2644 | if (unlikely(bitmap[0] & (FATTR4_WORD0_LINK_SUPPORT - 1U))) |
2614 | return -EIO; | 2645 | return -EIO; |
2615 | if (likely(bitmap[0] & FATTR4_WORD0_LINK_SUPPORT)) { | 2646 | if (likely(bitmap[0] & FATTR4_WORD0_LINK_SUPPORT)) { |
2616 | READ_BUF(4); | 2647 | p = xdr_inline_decode(xdr, 4); |
2648 | if (unlikely(!p)) | ||
2649 | goto out_overflow; | ||
2617 | *res = be32_to_cpup(p++); | 2650 | *res = be32_to_cpup(p++); |
2618 | bitmap[0] &= ~FATTR4_WORD0_LINK_SUPPORT; | 2651 | bitmap[0] &= ~FATTR4_WORD0_LINK_SUPPORT; |
2619 | } | 2652 | } |
2620 | dprintk("%s: link support=%s\n", __func__, *res == 0 ? "false" : "true"); | 2653 | dprintk("%s: link support=%s\n", __func__, *res == 0 ? "false" : "true"); |
2621 | return 0; | 2654 | return 0; |
2655 | out_overflow: | ||
2656 | print_overflow_msg(__func__, xdr); | ||
2657 | return -EIO; | ||
2622 | } | 2658 | } |
2623 | 2659 | ||
2624 | static int decode_attr_symlink_support(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) | 2660 | static int decode_attr_symlink_support(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) |
@@ -2629,12 +2665,17 @@ static int decode_attr_symlink_support(struct xdr_stream *xdr, uint32_t *bitmap, | |||
2629 | if (unlikely(bitmap[0] & (FATTR4_WORD0_SYMLINK_SUPPORT - 1U))) | 2665 | if (unlikely(bitmap[0] & (FATTR4_WORD0_SYMLINK_SUPPORT - 1U))) |
2630 | return -EIO; | 2666 | return -EIO; |
2631 | if (likely(bitmap[0] & FATTR4_WORD0_SYMLINK_SUPPORT)) { | 2667 | if (likely(bitmap[0] & FATTR4_WORD0_SYMLINK_SUPPORT)) { |
2632 | READ_BUF(4); | 2668 | p = xdr_inline_decode(xdr, 4); |
2669 | if (unlikely(!p)) | ||
2670 | goto out_overflow; | ||
2633 | *res = be32_to_cpup(p++); | 2671 | *res = be32_to_cpup(p++); |
2634 | bitmap[0] &= ~FATTR4_WORD0_SYMLINK_SUPPORT; | 2672 | bitmap[0] &= ~FATTR4_WORD0_SYMLINK_SUPPORT; |
2635 | } | 2673 | } |
2636 | dprintk("%s: symlink support=%s\n", __func__, *res == 0 ? "false" : "true"); | 2674 | dprintk("%s: symlink support=%s\n", __func__, *res == 0 ? "false" : "true"); |
2637 | return 0; | 2675 | return 0; |
2676 | out_overflow: | ||
2677 | print_overflow_msg(__func__, xdr); | ||
2678 | return -EIO; | ||
2638 | } | 2679 | } |
2639 | 2680 | ||
2640 | static int decode_attr_fsid(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs_fsid *fsid) | 2681 | static int decode_attr_fsid(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs_fsid *fsid) |
@@ -2647,7 +2688,9 @@ static int decode_attr_fsid(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs | |||
2647 | if (unlikely(bitmap[0] & (FATTR4_WORD0_FSID - 1U))) | 2688 | if (unlikely(bitmap[0] & (FATTR4_WORD0_FSID - 1U))) |
2648 | return -EIO; | 2689 | return -EIO; |
2649 | if (likely(bitmap[0] & FATTR4_WORD0_FSID)) { | 2690 | if (likely(bitmap[0] & FATTR4_WORD0_FSID)) { |
2650 | READ_BUF(16); | 2691 | p = xdr_inline_decode(xdr, 16); |
2692 | if (unlikely(!p)) | ||
2693 | goto out_overflow; | ||
2651 | p = xdr_decode_hyper(p, &fsid->major); | 2694 | p = xdr_decode_hyper(p, &fsid->major); |
2652 | p = xdr_decode_hyper(p, &fsid->minor); | 2695 | p = xdr_decode_hyper(p, &fsid->minor); |
2653 | bitmap[0] &= ~FATTR4_WORD0_FSID; | 2696 | bitmap[0] &= ~FATTR4_WORD0_FSID; |
@@ -2657,6 +2700,9 @@ static int decode_attr_fsid(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs | |||
2657 | (unsigned long long)fsid->major, | 2700 | (unsigned long long)fsid->major, |
2658 | (unsigned long long)fsid->minor); | 2701 | (unsigned long long)fsid->minor); |
2659 | return ret; | 2702 | return ret; |
2703 | out_overflow: | ||
2704 | print_overflow_msg(__func__, xdr); | ||
2705 | return -EIO; | ||
2660 | } | 2706 | } |
2661 | 2707 | ||
2662 | static int decode_attr_lease_time(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) | 2708 | static int decode_attr_lease_time(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) |
@@ -2667,12 +2713,17 @@ static int decode_attr_lease_time(struct xdr_stream *xdr, uint32_t *bitmap, uint | |||
2667 | if (unlikely(bitmap[0] & (FATTR4_WORD0_LEASE_TIME - 1U))) | 2713 | if (unlikely(bitmap[0] & (FATTR4_WORD0_LEASE_TIME - 1U))) |
2668 | return -EIO; | 2714 | return -EIO; |
2669 | if (likely(bitmap[0] & FATTR4_WORD0_LEASE_TIME)) { | 2715 | if (likely(bitmap[0] & FATTR4_WORD0_LEASE_TIME)) { |
2670 | READ_BUF(4); | 2716 | p = xdr_inline_decode(xdr, 4); |
2717 | if (unlikely(!p)) | ||
2718 | goto out_overflow; | ||
2671 | *res = be32_to_cpup(p++); | 2719 | *res = be32_to_cpup(p++); |
2672 | bitmap[0] &= ~FATTR4_WORD0_LEASE_TIME; | 2720 | bitmap[0] &= ~FATTR4_WORD0_LEASE_TIME; |
2673 | } | 2721 | } |
2674 | dprintk("%s: file size=%u\n", __func__, (unsigned int)*res); | 2722 | dprintk("%s: file size=%u\n", __func__, (unsigned int)*res); |
2675 | return 0; | 2723 | return 0; |
2724 | out_overflow: | ||
2725 | print_overflow_msg(__func__, xdr); | ||
2726 | return -EIO; | ||
2676 | } | 2727 | } |
2677 | 2728 | ||
2678 | static int decode_attr_aclsupport(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) | 2729 | static int decode_attr_aclsupport(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) |
@@ -2683,12 +2734,17 @@ static int decode_attr_aclsupport(struct xdr_stream *xdr, uint32_t *bitmap, uint | |||
2683 | if (unlikely(bitmap[0] & (FATTR4_WORD0_ACLSUPPORT - 1U))) | 2734 | if (unlikely(bitmap[0] & (FATTR4_WORD0_ACLSUPPORT - 1U))) |
2684 | return -EIO; | 2735 | return -EIO; |
2685 | if (likely(bitmap[0] & FATTR4_WORD0_ACLSUPPORT)) { | 2736 | if (likely(bitmap[0] & FATTR4_WORD0_ACLSUPPORT)) { |
2686 | READ_BUF(4); | 2737 | p = xdr_inline_decode(xdr, 4); |
2738 | if (unlikely(!p)) | ||
2739 | goto out_overflow; | ||
2687 | *res = be32_to_cpup(p++); | 2740 | *res = be32_to_cpup(p++); |
2688 | bitmap[0] &= ~FATTR4_WORD0_ACLSUPPORT; | 2741 | bitmap[0] &= ~FATTR4_WORD0_ACLSUPPORT; |
2689 | } | 2742 | } |
2690 | dprintk("%s: ACLs supported=%u\n", __func__, (unsigned int)*res); | 2743 | dprintk("%s: ACLs supported=%u\n", __func__, (unsigned int)*res); |
2691 | return 0; | 2744 | return 0; |
2745 | out_overflow: | ||
2746 | print_overflow_msg(__func__, xdr); | ||
2747 | return -EIO; | ||
2692 | } | 2748 | } |
2693 | 2749 | ||
2694 | static int decode_attr_fileid(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *fileid) | 2750 | static int decode_attr_fileid(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *fileid) |
@@ -2700,13 +2756,18 @@ static int decode_attr_fileid(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t | |||
2700 | if (unlikely(bitmap[0] & (FATTR4_WORD0_FILEID - 1U))) | 2756 | if (unlikely(bitmap[0] & (FATTR4_WORD0_FILEID - 1U))) |
2701 | return -EIO; | 2757 | return -EIO; |
2702 | if (likely(bitmap[0] & FATTR4_WORD0_FILEID)) { | 2758 | if (likely(bitmap[0] & FATTR4_WORD0_FILEID)) { |
2703 | READ_BUF(8); | 2759 | p = xdr_inline_decode(xdr, 8); |
2760 | if (unlikely(!p)) | ||
2761 | goto out_overflow; | ||
2704 | p = xdr_decode_hyper(p, fileid); | 2762 | p = xdr_decode_hyper(p, fileid); |
2705 | bitmap[0] &= ~FATTR4_WORD0_FILEID; | 2763 | bitmap[0] &= ~FATTR4_WORD0_FILEID; |
2706 | ret = NFS_ATTR_FATTR_FILEID; | 2764 | ret = NFS_ATTR_FATTR_FILEID; |
2707 | } | 2765 | } |
2708 | dprintk("%s: fileid=%Lu\n", __func__, (unsigned long long)*fileid); | 2766 | dprintk("%s: fileid=%Lu\n", __func__, (unsigned long long)*fileid); |
2709 | return ret; | 2767 | return ret; |
2768 | out_overflow: | ||
2769 | print_overflow_msg(__func__, xdr); | ||
2770 | return -EIO; | ||
2710 | } | 2771 | } |
2711 | 2772 | ||
2712 | static int decode_attr_mounted_on_fileid(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *fileid) | 2773 | static int decode_attr_mounted_on_fileid(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *fileid) |
@@ -2718,13 +2779,18 @@ static int decode_attr_mounted_on_fileid(struct xdr_stream *xdr, uint32_t *bitma | |||
2718 | if (unlikely(bitmap[1] & (FATTR4_WORD1_MOUNTED_ON_FILEID - 1U))) | 2779 | if (unlikely(bitmap[1] & (FATTR4_WORD1_MOUNTED_ON_FILEID - 1U))) |
2719 | return -EIO; | 2780 | return -EIO; |
2720 | if (likely(bitmap[1] & FATTR4_WORD1_MOUNTED_ON_FILEID)) { | 2781 | if (likely(bitmap[1] & FATTR4_WORD1_MOUNTED_ON_FILEID)) { |
2721 | READ_BUF(8); | 2782 | p = xdr_inline_decode(xdr, 8); |
2783 | if (unlikely(!p)) | ||
2784 | goto out_overflow; | ||
2722 | p = xdr_decode_hyper(p, fileid); | 2785 | p = xdr_decode_hyper(p, fileid); |
2723 | bitmap[1] &= ~FATTR4_WORD1_MOUNTED_ON_FILEID; | 2786 | bitmap[1] &= ~FATTR4_WORD1_MOUNTED_ON_FILEID; |
2724 | ret = NFS_ATTR_FATTR_FILEID; | 2787 | ret = NFS_ATTR_FATTR_FILEID; |
2725 | } | 2788 | } |
2726 | dprintk("%s: fileid=%Lu\n", __func__, (unsigned long long)*fileid); | 2789 | dprintk("%s: fileid=%Lu\n", __func__, (unsigned long long)*fileid); |
2727 | return ret; | 2790 | return ret; |
2791 | out_overflow: | ||
2792 | print_overflow_msg(__func__, xdr); | ||
2793 | return -EIO; | ||
2728 | } | 2794 | } |
2729 | 2795 | ||
2730 | static int decode_attr_files_avail(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) | 2796 | static int decode_attr_files_avail(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) |
@@ -2736,12 +2802,17 @@ static int decode_attr_files_avail(struct xdr_stream *xdr, uint32_t *bitmap, uin | |||
2736 | if (unlikely(bitmap[0] & (FATTR4_WORD0_FILES_AVAIL - 1U))) | 2802 | if (unlikely(bitmap[0] & (FATTR4_WORD0_FILES_AVAIL - 1U))) |
2737 | return -EIO; | 2803 | return -EIO; |
2738 | if (likely(bitmap[0] & FATTR4_WORD0_FILES_AVAIL)) { | 2804 | if (likely(bitmap[0] & FATTR4_WORD0_FILES_AVAIL)) { |
2739 | READ_BUF(8); | 2805 | p = xdr_inline_decode(xdr, 8); |
2806 | if (unlikely(!p)) | ||
2807 | goto out_overflow; | ||
2740 | p = xdr_decode_hyper(p, res); | 2808 | p = xdr_decode_hyper(p, res); |
2741 | bitmap[0] &= ~FATTR4_WORD0_FILES_AVAIL; | 2809 | bitmap[0] &= ~FATTR4_WORD0_FILES_AVAIL; |
2742 | } | 2810 | } |
2743 | dprintk("%s: files avail=%Lu\n", __func__, (unsigned long long)*res); | 2811 | dprintk("%s: files avail=%Lu\n", __func__, (unsigned long long)*res); |
2744 | return status; | 2812 | return status; |
2813 | out_overflow: | ||
2814 | print_overflow_msg(__func__, xdr); | ||
2815 | return -EIO; | ||
2745 | } | 2816 | } |
2746 | 2817 | ||
2747 | static int decode_attr_files_free(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) | 2818 | static int decode_attr_files_free(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) |
@@ -2753,12 +2824,17 @@ static int decode_attr_files_free(struct xdr_stream *xdr, uint32_t *bitmap, uint | |||
2753 | if (unlikely(bitmap[0] & (FATTR4_WORD0_FILES_FREE - 1U))) | 2824 | if (unlikely(bitmap[0] & (FATTR4_WORD0_FILES_FREE - 1U))) |
2754 | return -EIO; | 2825 | return -EIO; |
2755 | if (likely(bitmap[0] & FATTR4_WORD0_FILES_FREE)) { | 2826 | if (likely(bitmap[0] & FATTR4_WORD0_FILES_FREE)) { |
2756 | READ_BUF(8); | 2827 | p = xdr_inline_decode(xdr, 8); |
2828 | if (unlikely(!p)) | ||
2829 | goto out_overflow; | ||
2757 | p = xdr_decode_hyper(p, res); | 2830 | p = xdr_decode_hyper(p, res); |
2758 | bitmap[0] &= ~FATTR4_WORD0_FILES_FREE; | 2831 | bitmap[0] &= ~FATTR4_WORD0_FILES_FREE; |
2759 | } | 2832 | } |
2760 | dprintk("%s: files free=%Lu\n", __func__, (unsigned long long)*res); | 2833 | dprintk("%s: files free=%Lu\n", __func__, (unsigned long long)*res); |
2761 | return status; | 2834 | return status; |
2835 | out_overflow: | ||
2836 | print_overflow_msg(__func__, xdr); | ||
2837 | return -EIO; | ||
2762 | } | 2838 | } |
2763 | 2839 | ||
2764 | static int decode_attr_files_total(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) | 2840 | static int decode_attr_files_total(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) |
@@ -2770,12 +2846,17 @@ static int decode_attr_files_total(struct xdr_stream *xdr, uint32_t *bitmap, uin | |||
2770 | if (unlikely(bitmap[0] & (FATTR4_WORD0_FILES_TOTAL - 1U))) | 2846 | if (unlikely(bitmap[0] & (FATTR4_WORD0_FILES_TOTAL - 1U))) |
2771 | return -EIO; | 2847 | return -EIO; |
2772 | if (likely(bitmap[0] & FATTR4_WORD0_FILES_TOTAL)) { | 2848 | if (likely(bitmap[0] & FATTR4_WORD0_FILES_TOTAL)) { |
2773 | READ_BUF(8); | 2849 | p = xdr_inline_decode(xdr, 8); |
2850 | if (unlikely(!p)) | ||
2851 | goto out_overflow; | ||
2774 | p = xdr_decode_hyper(p, res); | 2852 | p = xdr_decode_hyper(p, res); |
2775 | bitmap[0] &= ~FATTR4_WORD0_FILES_TOTAL; | 2853 | bitmap[0] &= ~FATTR4_WORD0_FILES_TOTAL; |
2776 | } | 2854 | } |
2777 | dprintk("%s: files total=%Lu\n", __func__, (unsigned long long)*res); | 2855 | dprintk("%s: files total=%Lu\n", __func__, (unsigned long long)*res); |
2778 | return status; | 2856 | return status; |
2857 | out_overflow: | ||
2858 | print_overflow_msg(__func__, xdr); | ||
2859 | return -EIO; | ||
2779 | } | 2860 | } |
2780 | 2861 | ||
2781 | static int decode_pathname(struct xdr_stream *xdr, struct nfs4_pathname *path) | 2862 | static int decode_pathname(struct xdr_stream *xdr, struct nfs4_pathname *path) |
@@ -2784,7 +2865,9 @@ static int decode_pathname(struct xdr_stream *xdr, struct nfs4_pathname *path) | |||
2784 | __be32 *p; | 2865 | __be32 *p; |
2785 | int status = 0; | 2866 | int status = 0; |
2786 | 2867 | ||
2787 | READ_BUF(4); | 2868 | p = xdr_inline_decode(xdr, 4); |
2869 | if (unlikely(!p)) | ||
2870 | goto out_overflow; | ||
2788 | n = be32_to_cpup(p++); | 2871 | n = be32_to_cpup(p++); |
2789 | if (n == 0) | 2872 | if (n == 0) |
2790 | goto root_path; | 2873 | goto root_path; |
@@ -2819,6 +2902,9 @@ out_eio: | |||
2819 | dprintk(" status %d", status); | 2902 | dprintk(" status %d", status); |
2820 | status = -EIO; | 2903 | status = -EIO; |
2821 | goto out; | 2904 | goto out; |
2905 | out_overflow: | ||
2906 | print_overflow_msg(__func__, xdr); | ||
2907 | return -EIO; | ||
2822 | } | 2908 | } |
2823 | 2909 | ||
2824 | static int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs4_fs_locations *res) | 2910 | static int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs4_fs_locations *res) |
@@ -2836,7 +2922,9 @@ static int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, st | |||
2836 | status = decode_pathname(xdr, &res->fs_path); | 2922 | status = decode_pathname(xdr, &res->fs_path); |
2837 | if (unlikely(status != 0)) | 2923 | if (unlikely(status != 0)) |
2838 | goto out; | 2924 | goto out; |
2839 | READ_BUF(4); | 2925 | p = xdr_inline_decode(xdr, 4); |
2926 | if (unlikely(!p)) | ||
2927 | goto out_overflow; | ||
2840 | n = be32_to_cpup(p++); | 2928 | n = be32_to_cpup(p++); |
2841 | if (n <= 0) | 2929 | if (n <= 0) |
2842 | goto out_eio; | 2930 | goto out_eio; |
@@ -2845,7 +2933,9 @@ static int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, st | |||
2845 | u32 m; | 2933 | u32 m; |
2846 | struct nfs4_fs_location *loc = &res->locations[res->nlocations]; | 2934 | struct nfs4_fs_location *loc = &res->locations[res->nlocations]; |
2847 | 2935 | ||
2848 | READ_BUF(4); | 2936 | p = xdr_inline_decode(xdr, 4); |
2937 | if (unlikely(!p)) | ||
2938 | goto out_overflow; | ||
2849 | m = be32_to_cpup(p++); | 2939 | m = be32_to_cpup(p++); |
2850 | 2940 | ||
2851 | loc->nservers = 0; | 2941 | loc->nservers = 0; |
@@ -2885,6 +2975,8 @@ static int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, st | |||
2885 | out: | 2975 | out: |
2886 | dprintk("%s: fs_locations done, error = %d\n", __func__, status); | 2976 | dprintk("%s: fs_locations done, error = %d\n", __func__, status); |
2887 | return status; | 2977 | return status; |
2978 | out_overflow: | ||
2979 | print_overflow_msg(__func__, xdr); | ||
2888 | out_eio: | 2980 | out_eio: |
2889 | status = -EIO; | 2981 | status = -EIO; |
2890 | goto out; | 2982 | goto out; |
@@ -2899,12 +2991,17 @@ static int decode_attr_maxfilesize(struct xdr_stream *xdr, uint32_t *bitmap, uin | |||
2899 | if (unlikely(bitmap[0] & (FATTR4_WORD0_MAXFILESIZE - 1U))) | 2991 | if (unlikely(bitmap[0] & (FATTR4_WORD0_MAXFILESIZE - 1U))) |
2900 | return -EIO; | 2992 | return -EIO; |
2901 | if (likely(bitmap[0] & FATTR4_WORD0_MAXFILESIZE)) { | 2993 | if (likely(bitmap[0] & FATTR4_WORD0_MAXFILESIZE)) { |
2902 | READ_BUF(8); | 2994 | p = xdr_inline_decode(xdr, 8); |
2995 | if (unlikely(!p)) | ||
2996 | goto out_overflow; | ||
2903 | p = xdr_decode_hyper(p, res); | 2997 | p = xdr_decode_hyper(p, res); |
2904 | bitmap[0] &= ~FATTR4_WORD0_MAXFILESIZE; | 2998 | bitmap[0] &= ~FATTR4_WORD0_MAXFILESIZE; |
2905 | } | 2999 | } |
2906 | dprintk("%s: maxfilesize=%Lu\n", __func__, (unsigned long long)*res); | 3000 | dprintk("%s: maxfilesize=%Lu\n", __func__, (unsigned long long)*res); |
2907 | return status; | 3001 | return status; |
3002 | out_overflow: | ||
3003 | print_overflow_msg(__func__, xdr); | ||
3004 | return -EIO; | ||
2908 | } | 3005 | } |
2909 | 3006 | ||
2910 | static int decode_attr_maxlink(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *maxlink) | 3007 | static int decode_attr_maxlink(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *maxlink) |
@@ -2916,12 +3013,17 @@ static int decode_attr_maxlink(struct xdr_stream *xdr, uint32_t *bitmap, uint32_ | |||
2916 | if (unlikely(bitmap[0] & (FATTR4_WORD0_MAXLINK - 1U))) | 3013 | if (unlikely(bitmap[0] & (FATTR4_WORD0_MAXLINK - 1U))) |
2917 | return -EIO; | 3014 | return -EIO; |
2918 | if (likely(bitmap[0] & FATTR4_WORD0_MAXLINK)) { | 3015 | if (likely(bitmap[0] & FATTR4_WORD0_MAXLINK)) { |
2919 | READ_BUF(4); | 3016 | p = xdr_inline_decode(xdr, 4); |
3017 | if (unlikely(!p)) | ||
3018 | goto out_overflow; | ||
2920 | *maxlink = be32_to_cpup(p++); | 3019 | *maxlink = be32_to_cpup(p++); |
2921 | bitmap[0] &= ~FATTR4_WORD0_MAXLINK; | 3020 | bitmap[0] &= ~FATTR4_WORD0_MAXLINK; |
2922 | } | 3021 | } |
2923 | dprintk("%s: maxlink=%u\n", __func__, *maxlink); | 3022 | dprintk("%s: maxlink=%u\n", __func__, *maxlink); |
2924 | return status; | 3023 | return status; |
3024 | out_overflow: | ||
3025 | print_overflow_msg(__func__, xdr); | ||
3026 | return -EIO; | ||
2925 | } | 3027 | } |
2926 | 3028 | ||
2927 | static int decode_attr_maxname(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *maxname) | 3029 | static int decode_attr_maxname(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *maxname) |
@@ -2933,12 +3035,17 @@ static int decode_attr_maxname(struct xdr_stream *xdr, uint32_t *bitmap, uint32_ | |||
2933 | if (unlikely(bitmap[0] & (FATTR4_WORD0_MAXNAME - 1U))) | 3035 | if (unlikely(bitmap[0] & (FATTR4_WORD0_MAXNAME - 1U))) |
2934 | return -EIO; | 3036 | return -EIO; |
2935 | if (likely(bitmap[0] & FATTR4_WORD0_MAXNAME)) { | 3037 | if (likely(bitmap[0] & FATTR4_WORD0_MAXNAME)) { |
2936 | READ_BUF(4); | 3038 | p = xdr_inline_decode(xdr, 4); |
3039 | if (unlikely(!p)) | ||
3040 | goto out_overflow; | ||
2937 | *maxname = be32_to_cpup(p++); | 3041 | *maxname = be32_to_cpup(p++); |
2938 | bitmap[0] &= ~FATTR4_WORD0_MAXNAME; | 3042 | bitmap[0] &= ~FATTR4_WORD0_MAXNAME; |
2939 | } | 3043 | } |
2940 | dprintk("%s: maxname=%u\n", __func__, *maxname); | 3044 | dprintk("%s: maxname=%u\n", __func__, *maxname); |
2941 | return status; | 3045 | return status; |
3046 | out_overflow: | ||
3047 | print_overflow_msg(__func__, xdr); | ||
3048 | return -EIO; | ||
2942 | } | 3049 | } |
2943 | 3050 | ||
2944 | static int decode_attr_maxread(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) | 3051 | static int decode_attr_maxread(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) |
@@ -2951,7 +3058,9 @@ static int decode_attr_maxread(struct xdr_stream *xdr, uint32_t *bitmap, uint32_ | |||
2951 | return -EIO; | 3058 | return -EIO; |
2952 | if (likely(bitmap[0] & FATTR4_WORD0_MAXREAD)) { | 3059 | if (likely(bitmap[0] & FATTR4_WORD0_MAXREAD)) { |
2953 | uint64_t maxread; | 3060 | uint64_t maxread; |
2954 | READ_BUF(8); | 3061 | p = xdr_inline_decode(xdr, 8); |
3062 | if (unlikely(!p)) | ||
3063 | goto out_overflow; | ||
2955 | p = xdr_decode_hyper(p, &maxread); | 3064 | p = xdr_decode_hyper(p, &maxread); |
2956 | if (maxread > 0x7FFFFFFF) | 3065 | if (maxread > 0x7FFFFFFF) |
2957 | maxread = 0x7FFFFFFF; | 3066 | maxread = 0x7FFFFFFF; |
@@ -2960,6 +3069,9 @@ static int decode_attr_maxread(struct xdr_stream *xdr, uint32_t *bitmap, uint32_ | |||
2960 | } | 3069 | } |
2961 | dprintk("%s: maxread=%lu\n", __func__, (unsigned long)*res); | 3070 | dprintk("%s: maxread=%lu\n", __func__, (unsigned long)*res); |
2962 | return status; | 3071 | return status; |
3072 | out_overflow: | ||
3073 | print_overflow_msg(__func__, xdr); | ||
3074 | return -EIO; | ||
2963 | } | 3075 | } |
2964 | 3076 | ||
2965 | static int decode_attr_maxwrite(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) | 3077 | static int decode_attr_maxwrite(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) |
@@ -2972,7 +3084,9 @@ static int decode_attr_maxwrite(struct xdr_stream *xdr, uint32_t *bitmap, uint32 | |||
2972 | return -EIO; | 3084 | return -EIO; |
2973 | if (likely(bitmap[0] & FATTR4_WORD0_MAXWRITE)) { | 3085 | if (likely(bitmap[0] & FATTR4_WORD0_MAXWRITE)) { |
2974 | uint64_t maxwrite; | 3086 | uint64_t maxwrite; |
2975 | READ_BUF(8); | 3087 | p = xdr_inline_decode(xdr, 8); |
3088 | if (unlikely(!p)) | ||
3089 | goto out_overflow; | ||
2976 | p = xdr_decode_hyper(p, &maxwrite); | 3090 | p = xdr_decode_hyper(p, &maxwrite); |
2977 | if (maxwrite > 0x7FFFFFFF) | 3091 | if (maxwrite > 0x7FFFFFFF) |
2978 | maxwrite = 0x7FFFFFFF; | 3092 | maxwrite = 0x7FFFFFFF; |
@@ -2981,6 +3095,9 @@ static int decode_attr_maxwrite(struct xdr_stream *xdr, uint32_t *bitmap, uint32 | |||
2981 | } | 3095 | } |
2982 | dprintk("%s: maxwrite=%lu\n", __func__, (unsigned long)*res); | 3096 | dprintk("%s: maxwrite=%lu\n", __func__, (unsigned long)*res); |
2983 | return status; | 3097 | return status; |
3098 | out_overflow: | ||
3099 | print_overflow_msg(__func__, xdr); | ||
3100 | return -EIO; | ||
2984 | } | 3101 | } |
2985 | 3102 | ||
2986 | static int decode_attr_mode(struct xdr_stream *xdr, uint32_t *bitmap, umode_t *mode) | 3103 | static int decode_attr_mode(struct xdr_stream *xdr, uint32_t *bitmap, umode_t *mode) |
@@ -2993,7 +3110,9 @@ static int decode_attr_mode(struct xdr_stream *xdr, uint32_t *bitmap, umode_t *m | |||
2993 | if (unlikely(bitmap[1] & (FATTR4_WORD1_MODE - 1U))) | 3110 | if (unlikely(bitmap[1] & (FATTR4_WORD1_MODE - 1U))) |
2994 | return -EIO; | 3111 | return -EIO; |
2995 | if (likely(bitmap[1] & FATTR4_WORD1_MODE)) { | 3112 | if (likely(bitmap[1] & FATTR4_WORD1_MODE)) { |
2996 | READ_BUF(4); | 3113 | p = xdr_inline_decode(xdr, 4); |
3114 | if (unlikely(!p)) | ||
3115 | goto out_overflow; | ||
2997 | tmp = be32_to_cpup(p++); | 3116 | tmp = be32_to_cpup(p++); |
2998 | *mode = tmp & ~S_IFMT; | 3117 | *mode = tmp & ~S_IFMT; |
2999 | bitmap[1] &= ~FATTR4_WORD1_MODE; | 3118 | bitmap[1] &= ~FATTR4_WORD1_MODE; |
@@ -3001,6 +3120,9 @@ static int decode_attr_mode(struct xdr_stream *xdr, uint32_t *bitmap, umode_t *m | |||
3001 | } | 3120 | } |
3002 | dprintk("%s: file mode=0%o\n", __func__, (unsigned int)*mode); | 3121 | dprintk("%s: file mode=0%o\n", __func__, (unsigned int)*mode); |
3003 | return ret; | 3122 | return ret; |
3123 | out_overflow: | ||
3124 | print_overflow_msg(__func__, xdr); | ||
3125 | return -EIO; | ||
3004 | } | 3126 | } |
3005 | 3127 | ||
3006 | static int decode_attr_nlink(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *nlink) | 3128 | static int decode_attr_nlink(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *nlink) |
@@ -3012,13 +3134,18 @@ static int decode_attr_nlink(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t | |||
3012 | if (unlikely(bitmap[1] & (FATTR4_WORD1_NUMLINKS - 1U))) | 3134 | if (unlikely(bitmap[1] & (FATTR4_WORD1_NUMLINKS - 1U))) |
3013 | return -EIO; | 3135 | return -EIO; |
3014 | if (likely(bitmap[1] & FATTR4_WORD1_NUMLINKS)) { | 3136 | if (likely(bitmap[1] & FATTR4_WORD1_NUMLINKS)) { |
3015 | READ_BUF(4); | 3137 | p = xdr_inline_decode(xdr, 4); |
3138 | if (unlikely(!p)) | ||
3139 | goto out_overflow; | ||
3016 | *nlink = be32_to_cpup(p++); | 3140 | *nlink = be32_to_cpup(p++); |
3017 | bitmap[1] &= ~FATTR4_WORD1_NUMLINKS; | 3141 | bitmap[1] &= ~FATTR4_WORD1_NUMLINKS; |
3018 | ret = NFS_ATTR_FATTR_NLINK; | 3142 | ret = NFS_ATTR_FATTR_NLINK; |
3019 | } | 3143 | } |
3020 | dprintk("%s: nlink=%u\n", __func__, (unsigned int)*nlink); | 3144 | dprintk("%s: nlink=%u\n", __func__, (unsigned int)*nlink); |
3021 | return ret; | 3145 | return ret; |
3146 | out_overflow: | ||
3147 | print_overflow_msg(__func__, xdr); | ||
3148 | return -EIO; | ||
3022 | } | 3149 | } |
3023 | 3150 | ||
3024 | static int decode_attr_owner(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs_client *clp, uint32_t *uid) | 3151 | static int decode_attr_owner(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs_client *clp, uint32_t *uid) |
@@ -3031,9 +3158,13 @@ static int decode_attr_owner(struct xdr_stream *xdr, uint32_t *bitmap, struct nf | |||
3031 | if (unlikely(bitmap[1] & (FATTR4_WORD1_OWNER - 1U))) | 3158 | if (unlikely(bitmap[1] & (FATTR4_WORD1_OWNER - 1U))) |
3032 | return -EIO; | 3159 | return -EIO; |
3033 | if (likely(bitmap[1] & FATTR4_WORD1_OWNER)) { | 3160 | if (likely(bitmap[1] & FATTR4_WORD1_OWNER)) { |
3034 | READ_BUF(4); | 3161 | p = xdr_inline_decode(xdr, 4); |
3162 | if (unlikely(!p)) | ||
3163 | goto out_overflow; | ||
3035 | len = be32_to_cpup(p++); | 3164 | len = be32_to_cpup(p++); |
3036 | READ_BUF(len); | 3165 | p = xdr_inline_decode(xdr, len); |
3166 | if (unlikely(!p)) | ||
3167 | goto out_overflow; | ||
3037 | if (len < XDR_MAX_NETOBJ) { | 3168 | if (len < XDR_MAX_NETOBJ) { |
3038 | if (nfs_map_name_to_uid(clp, (char *)p, len, uid) == 0) | 3169 | if (nfs_map_name_to_uid(clp, (char *)p, len, uid) == 0) |
3039 | ret = NFS_ATTR_FATTR_OWNER; | 3170 | ret = NFS_ATTR_FATTR_OWNER; |
@@ -3047,6 +3178,9 @@ static int decode_attr_owner(struct xdr_stream *xdr, uint32_t *bitmap, struct nf | |||
3047 | } | 3178 | } |
3048 | dprintk("%s: uid=%d\n", __func__, (int)*uid); | 3179 | dprintk("%s: uid=%d\n", __func__, (int)*uid); |
3049 | return ret; | 3180 | return ret; |
3181 | out_overflow: | ||
3182 | print_overflow_msg(__func__, xdr); | ||
3183 | return -EIO; | ||
3050 | } | 3184 | } |
3051 | 3185 | ||
3052 | static int decode_attr_group(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs_client *clp, uint32_t *gid) | 3186 | static int decode_attr_group(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs_client *clp, uint32_t *gid) |
@@ -3059,9 +3193,13 @@ static int decode_attr_group(struct xdr_stream *xdr, uint32_t *bitmap, struct nf | |||
3059 | if (unlikely(bitmap[1] & (FATTR4_WORD1_OWNER_GROUP - 1U))) | 3193 | if (unlikely(bitmap[1] & (FATTR4_WORD1_OWNER_GROUP - 1U))) |
3060 | return -EIO; | 3194 | return -EIO; |
3061 | if (likely(bitmap[1] & FATTR4_WORD1_OWNER_GROUP)) { | 3195 | if (likely(bitmap[1] & FATTR4_WORD1_OWNER_GROUP)) { |
3062 | READ_BUF(4); | 3196 | p = xdr_inline_decode(xdr, 4); |
3197 | if (unlikely(!p)) | ||
3198 | goto out_overflow; | ||
3063 | len = be32_to_cpup(p++); | 3199 | len = be32_to_cpup(p++); |
3064 | READ_BUF(len); | 3200 | p = xdr_inline_decode(xdr, len); |
3201 | if (unlikely(!p)) | ||
3202 | goto out_overflow; | ||
3065 | if (len < XDR_MAX_NETOBJ) { | 3203 | if (len < XDR_MAX_NETOBJ) { |
3066 | if (nfs_map_group_to_gid(clp, (char *)p, len, gid) == 0) | 3204 | if (nfs_map_group_to_gid(clp, (char *)p, len, gid) == 0) |
3067 | ret = NFS_ATTR_FATTR_GROUP; | 3205 | ret = NFS_ATTR_FATTR_GROUP; |
@@ -3075,6 +3213,9 @@ static int decode_attr_group(struct xdr_stream *xdr, uint32_t *bitmap, struct nf | |||
3075 | } | 3213 | } |
3076 | dprintk("%s: gid=%d\n", __func__, (int)*gid); | 3214 | dprintk("%s: gid=%d\n", __func__, (int)*gid); |
3077 | return ret; | 3215 | return ret; |
3216 | out_overflow: | ||
3217 | print_overflow_msg(__func__, xdr); | ||
3218 | return -EIO; | ||
3078 | } | 3219 | } |
3079 | 3220 | ||
3080 | static int decode_attr_rdev(struct xdr_stream *xdr, uint32_t *bitmap, dev_t *rdev) | 3221 | static int decode_attr_rdev(struct xdr_stream *xdr, uint32_t *bitmap, dev_t *rdev) |
@@ -3089,7 +3230,9 @@ static int decode_attr_rdev(struct xdr_stream *xdr, uint32_t *bitmap, dev_t *rde | |||
3089 | if (likely(bitmap[1] & FATTR4_WORD1_RAWDEV)) { | 3230 | if (likely(bitmap[1] & FATTR4_WORD1_RAWDEV)) { |
3090 | dev_t tmp; | 3231 | dev_t tmp; |
3091 | 3232 | ||
3092 | READ_BUF(8); | 3233 | p = xdr_inline_decode(xdr, 8); |
3234 | if (unlikely(!p)) | ||
3235 | goto out_overflow; | ||
3093 | major = be32_to_cpup(p++); | 3236 | major = be32_to_cpup(p++); |
3094 | minor = be32_to_cpup(p++); | 3237 | minor = be32_to_cpup(p++); |
3095 | tmp = MKDEV(major, minor); | 3238 | tmp = MKDEV(major, minor); |
@@ -3100,6 +3243,9 @@ static int decode_attr_rdev(struct xdr_stream *xdr, uint32_t *bitmap, dev_t *rde | |||
3100 | } | 3243 | } |
3101 | dprintk("%s: rdev=(0x%x:0x%x)\n", __func__, major, minor); | 3244 | dprintk("%s: rdev=(0x%x:0x%x)\n", __func__, major, minor); |
3102 | return ret; | 3245 | return ret; |
3246 | out_overflow: | ||
3247 | print_overflow_msg(__func__, xdr); | ||
3248 | return -EIO; | ||
3103 | } | 3249 | } |
3104 | 3250 | ||
3105 | static int decode_attr_space_avail(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) | 3251 | static int decode_attr_space_avail(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) |
@@ -3111,12 +3257,17 @@ static int decode_attr_space_avail(struct xdr_stream *xdr, uint32_t *bitmap, uin | |||
3111 | if (unlikely(bitmap[1] & (FATTR4_WORD1_SPACE_AVAIL - 1U))) | 3257 | if (unlikely(bitmap[1] & (FATTR4_WORD1_SPACE_AVAIL - 1U))) |
3112 | return -EIO; | 3258 | return -EIO; |
3113 | if (likely(bitmap[1] & FATTR4_WORD1_SPACE_AVAIL)) { | 3259 | if (likely(bitmap[1] & FATTR4_WORD1_SPACE_AVAIL)) { |
3114 | READ_BUF(8); | 3260 | p = xdr_inline_decode(xdr, 8); |
3261 | if (unlikely(!p)) | ||
3262 | goto out_overflow; | ||
3115 | p = xdr_decode_hyper(p, res); | 3263 | p = xdr_decode_hyper(p, res); |
3116 | bitmap[1] &= ~FATTR4_WORD1_SPACE_AVAIL; | 3264 | bitmap[1] &= ~FATTR4_WORD1_SPACE_AVAIL; |
3117 | } | 3265 | } |
3118 | dprintk("%s: space avail=%Lu\n", __func__, (unsigned long long)*res); | 3266 | dprintk("%s: space avail=%Lu\n", __func__, (unsigned long long)*res); |
3119 | return status; | 3267 | return status; |
3268 | out_overflow: | ||
3269 | print_overflow_msg(__func__, xdr); | ||
3270 | return -EIO; | ||
3120 | } | 3271 | } |
3121 | 3272 | ||
3122 | static int decode_attr_space_free(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) | 3273 | static int decode_attr_space_free(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) |
@@ -3128,12 +3279,17 @@ static int decode_attr_space_free(struct xdr_stream *xdr, uint32_t *bitmap, uint | |||
3128 | if (unlikely(bitmap[1] & (FATTR4_WORD1_SPACE_FREE - 1U))) | 3279 | if (unlikely(bitmap[1] & (FATTR4_WORD1_SPACE_FREE - 1U))) |
3129 | return -EIO; | 3280 | return -EIO; |
3130 | if (likely(bitmap[1] & FATTR4_WORD1_SPACE_FREE)) { | 3281 | if (likely(bitmap[1] & FATTR4_WORD1_SPACE_FREE)) { |
3131 | READ_BUF(8); | 3282 | p = xdr_inline_decode(xdr, 8); |
3283 | if (unlikely(!p)) | ||
3284 | goto out_overflow; | ||
3132 | p = xdr_decode_hyper(p, res); | 3285 | p = xdr_decode_hyper(p, res); |
3133 | bitmap[1] &= ~FATTR4_WORD1_SPACE_FREE; | 3286 | bitmap[1] &= ~FATTR4_WORD1_SPACE_FREE; |
3134 | } | 3287 | } |
3135 | dprintk("%s: space free=%Lu\n", __func__, (unsigned long long)*res); | 3288 | dprintk("%s: space free=%Lu\n", __func__, (unsigned long long)*res); |
3136 | return status; | 3289 | return status; |
3290 | out_overflow: | ||
3291 | print_overflow_msg(__func__, xdr); | ||
3292 | return -EIO; | ||
3137 | } | 3293 | } |
3138 | 3294 | ||
3139 | static int decode_attr_space_total(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) | 3295 | static int decode_attr_space_total(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) |
@@ -3145,12 +3301,17 @@ static int decode_attr_space_total(struct xdr_stream *xdr, uint32_t *bitmap, uin | |||
3145 | if (unlikely(bitmap[1] & (FATTR4_WORD1_SPACE_TOTAL - 1U))) | 3301 | if (unlikely(bitmap[1] & (FATTR4_WORD1_SPACE_TOTAL - 1U))) |
3146 | return -EIO; | 3302 | return -EIO; |
3147 | if (likely(bitmap[1] & FATTR4_WORD1_SPACE_TOTAL)) { | 3303 | if (likely(bitmap[1] & FATTR4_WORD1_SPACE_TOTAL)) { |
3148 | READ_BUF(8); | 3304 | p = xdr_inline_decode(xdr, 8); |
3305 | if (unlikely(!p)) | ||
3306 | goto out_overflow; | ||
3149 | p = xdr_decode_hyper(p, res); | 3307 | p = xdr_decode_hyper(p, res); |
3150 | bitmap[1] &= ~FATTR4_WORD1_SPACE_TOTAL; | 3308 | bitmap[1] &= ~FATTR4_WORD1_SPACE_TOTAL; |
3151 | } | 3309 | } |
3152 | dprintk("%s: space total=%Lu\n", __func__, (unsigned long long)*res); | 3310 | dprintk("%s: space total=%Lu\n", __func__, (unsigned long long)*res); |
3153 | return status; | 3311 | return status; |
3312 | out_overflow: | ||
3313 | print_overflow_msg(__func__, xdr); | ||
3314 | return -EIO; | ||
3154 | } | 3315 | } |
3155 | 3316 | ||
3156 | static int decode_attr_space_used(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *used) | 3317 | static int decode_attr_space_used(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *used) |
@@ -3162,7 +3323,9 @@ static int decode_attr_space_used(struct xdr_stream *xdr, uint32_t *bitmap, uint | |||
3162 | if (unlikely(bitmap[1] & (FATTR4_WORD1_SPACE_USED - 1U))) | 3323 | if (unlikely(bitmap[1] & (FATTR4_WORD1_SPACE_USED - 1U))) |
3163 | return -EIO; | 3324 | return -EIO; |
3164 | if (likely(bitmap[1] & FATTR4_WORD1_SPACE_USED)) { | 3325 | if (likely(bitmap[1] & FATTR4_WORD1_SPACE_USED)) { |
3165 | READ_BUF(8); | 3326 | p = xdr_inline_decode(xdr, 8); |
3327 | if (unlikely(!p)) | ||
3328 | goto out_overflow; | ||
3166 | p = xdr_decode_hyper(p, used); | 3329 | p = xdr_decode_hyper(p, used); |
3167 | bitmap[1] &= ~FATTR4_WORD1_SPACE_USED; | 3330 | bitmap[1] &= ~FATTR4_WORD1_SPACE_USED; |
3168 | ret = NFS_ATTR_FATTR_SPACE_USED; | 3331 | ret = NFS_ATTR_FATTR_SPACE_USED; |
@@ -3170,6 +3333,9 @@ static int decode_attr_space_used(struct xdr_stream *xdr, uint32_t *bitmap, uint | |||
3170 | dprintk("%s: space used=%Lu\n", __func__, | 3333 | dprintk("%s: space used=%Lu\n", __func__, |
3171 | (unsigned long long)*used); | 3334 | (unsigned long long)*used); |
3172 | return ret; | 3335 | return ret; |
3336 | out_overflow: | ||
3337 | print_overflow_msg(__func__, xdr); | ||
3338 | return -EIO; | ||
3173 | } | 3339 | } |
3174 | 3340 | ||
3175 | static int decode_attr_time(struct xdr_stream *xdr, struct timespec *time) | 3341 | static int decode_attr_time(struct xdr_stream *xdr, struct timespec *time) |
@@ -3178,12 +3344,17 @@ static int decode_attr_time(struct xdr_stream *xdr, struct timespec *time) | |||
3178 | uint64_t sec; | 3344 | uint64_t sec; |
3179 | uint32_t nsec; | 3345 | uint32_t nsec; |
3180 | 3346 | ||
3181 | READ_BUF(12); | 3347 | p = xdr_inline_decode(xdr, 12); |
3348 | if (unlikely(!p)) | ||
3349 | goto out_overflow; | ||
3182 | p = xdr_decode_hyper(p, &sec); | 3350 | p = xdr_decode_hyper(p, &sec); |
3183 | nsec = be32_to_cpup(p++); | 3351 | nsec = be32_to_cpup(p++); |
3184 | time->tv_sec = (time_t)sec; | 3352 | time->tv_sec = (time_t)sec; |
3185 | time->tv_nsec = (long)nsec; | 3353 | time->tv_nsec = (long)nsec; |
3186 | return 0; | 3354 | return 0; |
3355 | out_overflow: | ||
3356 | print_overflow_msg(__func__, xdr); | ||
3357 | return -EIO; | ||
3187 | } | 3358 | } |
3188 | 3359 | ||
3189 | static int decode_attr_time_access(struct xdr_stream *xdr, uint32_t *bitmap, struct timespec *time) | 3360 | static int decode_attr_time_access(struct xdr_stream *xdr, uint32_t *bitmap, struct timespec *time) |
@@ -3261,11 +3432,16 @@ static int decode_change_info(struct xdr_stream *xdr, struct nfs4_change_info *c | |||
3261 | { | 3432 | { |
3262 | __be32 *p; | 3433 | __be32 *p; |
3263 | 3434 | ||
3264 | READ_BUF(20); | 3435 | p = xdr_inline_decode(xdr, 20); |
3436 | if (unlikely(!p)) | ||
3437 | goto out_overflow; | ||
3265 | cinfo->atomic = be32_to_cpup(p++); | 3438 | cinfo->atomic = be32_to_cpup(p++); |
3266 | p = xdr_decode_hyper(p, &cinfo->before); | 3439 | p = xdr_decode_hyper(p, &cinfo->before); |
3267 | p = xdr_decode_hyper(p, &cinfo->after); | 3440 | p = xdr_decode_hyper(p, &cinfo->after); |
3268 | return 0; | 3441 | return 0; |
3442 | out_overflow: | ||
3443 | print_overflow_msg(__func__, xdr); | ||
3444 | return -EIO; | ||
3269 | } | 3445 | } |
3270 | 3446 | ||
3271 | static int decode_access(struct xdr_stream *xdr, struct nfs4_accessres *access) | 3447 | static int decode_access(struct xdr_stream *xdr, struct nfs4_accessres *access) |
@@ -3277,12 +3453,17 @@ static int decode_access(struct xdr_stream *xdr, struct nfs4_accessres *access) | |||
3277 | status = decode_op_hdr(xdr, OP_ACCESS); | 3453 | status = decode_op_hdr(xdr, OP_ACCESS); |
3278 | if (status) | 3454 | if (status) |
3279 | return status; | 3455 | return status; |
3280 | READ_BUF(8); | 3456 | p = xdr_inline_decode(xdr, 8); |
3457 | if (unlikely(!p)) | ||
3458 | goto out_overflow; | ||
3281 | supp = be32_to_cpup(p++); | 3459 | supp = be32_to_cpup(p++); |
3282 | acc = be32_to_cpup(p++); | 3460 | acc = be32_to_cpup(p++); |
3283 | access->supported = supp; | 3461 | access->supported = supp; |
3284 | access->access = acc; | 3462 | access->access = acc; |
3285 | return 0; | 3463 | return 0; |
3464 | out_overflow: | ||
3465 | print_overflow_msg(__func__, xdr); | ||
3466 | return -EIO; | ||
3286 | } | 3467 | } |
3287 | 3468 | ||
3288 | static int decode_opaque_fixed(struct xdr_stream *xdr, void *buf, size_t len) | 3469 | static int decode_opaque_fixed(struct xdr_stream *xdr, void *buf, size_t len) |
@@ -3341,10 +3522,16 @@ static int decode_create(struct xdr_stream *xdr, struct nfs4_change_info *cinfo) | |||
3341 | return status; | 3522 | return status; |
3342 | if ((status = decode_change_info(xdr, cinfo))) | 3523 | if ((status = decode_change_info(xdr, cinfo))) |
3343 | return status; | 3524 | return status; |
3344 | READ_BUF(4); | 3525 | p = xdr_inline_decode(xdr, 4); |
3526 | if (unlikely(!p)) | ||
3527 | goto out_overflow; | ||
3345 | bmlen = be32_to_cpup(p++); | 3528 | bmlen = be32_to_cpup(p++); |
3346 | READ_BUF(bmlen << 2); | 3529 | p = xdr_inline_decode(xdr, bmlen << 2); |
3347 | return 0; | 3530 | if (likely(p)) |
3531 | return 0; | ||
3532 | out_overflow: | ||
3533 | print_overflow_msg(__func__, xdr); | ||
3534 | return -EIO; | ||
3348 | } | 3535 | } |
3349 | 3536 | ||
3350 | static int decode_server_caps(struct xdr_stream *xdr, struct nfs4_server_caps_res *res) | 3537 | static int decode_server_caps(struct xdr_stream *xdr, struct nfs4_server_caps_res *res) |
@@ -3596,14 +3783,21 @@ static int decode_getfh(struct xdr_stream *xdr, struct nfs_fh *fh) | |||
3596 | if (status) | 3783 | if (status) |
3597 | return status; | 3784 | return status; |
3598 | 3785 | ||
3599 | READ_BUF(4); | 3786 | p = xdr_inline_decode(xdr, 4); |
3787 | if (unlikely(!p)) | ||
3788 | goto out_overflow; | ||
3600 | len = be32_to_cpup(p++); | 3789 | len = be32_to_cpup(p++); |
3601 | if (len > NFS4_FHSIZE) | 3790 | if (len > NFS4_FHSIZE) |
3602 | return -EIO; | 3791 | return -EIO; |
3603 | fh->size = len; | 3792 | fh->size = len; |
3604 | READ_BUF(len); | 3793 | p = xdr_inline_decode(xdr, len); |
3794 | if (unlikely(!p)) | ||
3795 | goto out_overflow; | ||
3605 | memcpy(fh->data, p, len); | 3796 | memcpy(fh->data, p, len); |
3606 | return 0; | 3797 | return 0; |
3798 | out_overflow: | ||
3799 | print_overflow_msg(__func__, xdr); | ||
3800 | return -EIO; | ||
3607 | } | 3801 | } |
3608 | 3802 | ||
3609 | static int decode_link(struct xdr_stream *xdr, struct nfs4_change_info *cinfo) | 3803 | static int decode_link(struct xdr_stream *xdr, struct nfs4_change_info *cinfo) |
@@ -3625,7 +3819,9 @@ static int decode_lock_denied (struct xdr_stream *xdr, struct file_lock *fl) | |||
3625 | __be32 *p; | 3819 | __be32 *p; |
3626 | uint32_t namelen, type; | 3820 | uint32_t namelen, type; |
3627 | 3821 | ||
3628 | READ_BUF(32); | 3822 | p = xdr_inline_decode(xdr, 32); |
3823 | if (unlikely(!p)) | ||
3824 | goto out_overflow; | ||
3629 | p = xdr_decode_hyper(p, &offset); | 3825 | p = xdr_decode_hyper(p, &offset); |
3630 | p = xdr_decode_hyper(p, &length); | 3826 | p = xdr_decode_hyper(p, &length); |
3631 | type = be32_to_cpup(p++); | 3827 | type = be32_to_cpup(p++); |
@@ -3641,8 +3837,12 @@ static int decode_lock_denied (struct xdr_stream *xdr, struct file_lock *fl) | |||
3641 | } | 3837 | } |
3642 | p = xdr_decode_hyper(p, &clientid); | 3838 | p = xdr_decode_hyper(p, &clientid); |
3643 | namelen = be32_to_cpup(p++); | 3839 | namelen = be32_to_cpup(p++); |
3644 | READ_BUF(namelen); | 3840 | p = xdr_inline_decode(xdr, namelen); |
3645 | return -NFS4ERR_DENIED; | 3841 | if (likely(p)) |
3842 | return -NFS4ERR_DENIED; | ||
3843 | out_overflow: | ||
3844 | print_overflow_msg(__func__, xdr); | ||
3845 | return -EIO; | ||
3646 | } | 3846 | } |
3647 | 3847 | ||
3648 | static int decode_lock(struct xdr_stream *xdr, struct nfs_lock_res *res) | 3848 | static int decode_lock(struct xdr_stream *xdr, struct nfs_lock_res *res) |
@@ -3697,7 +3897,9 @@ static int decode_space_limit(struct xdr_stream *xdr, u64 *maxsize) | |||
3697 | __be32 *p; | 3897 | __be32 *p; |
3698 | uint32_t limit_type, nblocks, blocksize; | 3898 | uint32_t limit_type, nblocks, blocksize; |
3699 | 3899 | ||
3700 | READ_BUF(12); | 3900 | p = xdr_inline_decode(xdr, 12); |
3901 | if (unlikely(!p)) | ||
3902 | goto out_overflow; | ||
3701 | limit_type = be32_to_cpup(p++); | 3903 | limit_type = be32_to_cpup(p++); |
3702 | switch (limit_type) { | 3904 | switch (limit_type) { |
3703 | case 1: | 3905 | case 1: |
@@ -3709,6 +3911,9 @@ static int decode_space_limit(struct xdr_stream *xdr, u64 *maxsize) | |||
3709 | *maxsize = (uint64_t)nblocks * (uint64_t)blocksize; | 3911 | *maxsize = (uint64_t)nblocks * (uint64_t)blocksize; |
3710 | } | 3912 | } |
3711 | return 0; | 3913 | return 0; |
3914 | out_overflow: | ||
3915 | print_overflow_msg(__func__, xdr); | ||
3916 | return -EIO; | ||
3712 | } | 3917 | } |
3713 | 3918 | ||
3714 | static int decode_delegation(struct xdr_stream *xdr, struct nfs_openres *res) | 3919 | static int decode_delegation(struct xdr_stream *xdr, struct nfs_openres *res) |
@@ -3717,7 +3922,9 @@ static int decode_delegation(struct xdr_stream *xdr, struct nfs_openres *res) | |||
3717 | uint32_t delegation_type; | 3922 | uint32_t delegation_type; |
3718 | int status; | 3923 | int status; |
3719 | 3924 | ||
3720 | READ_BUF(4); | 3925 | p = xdr_inline_decode(xdr, 4); |
3926 | if (unlikely(!p)) | ||
3927 | goto out_overflow; | ||
3721 | delegation_type = be32_to_cpup(p++); | 3928 | delegation_type = be32_to_cpup(p++); |
3722 | if (delegation_type == NFS4_OPEN_DELEGATE_NONE) { | 3929 | if (delegation_type == NFS4_OPEN_DELEGATE_NONE) { |
3723 | res->delegation_type = 0; | 3930 | res->delegation_type = 0; |
@@ -3726,7 +3933,9 @@ static int decode_delegation(struct xdr_stream *xdr, struct nfs_openres *res) | |||
3726 | status = decode_stateid(xdr, &res->delegation); | 3933 | status = decode_stateid(xdr, &res->delegation); |
3727 | if (unlikely(status)) | 3934 | if (unlikely(status)) |
3728 | return status; | 3935 | return status; |
3729 | READ_BUF(4); | 3936 | p = xdr_inline_decode(xdr, 4); |
3937 | if (unlikely(!p)) | ||
3938 | goto out_overflow; | ||
3730 | res->do_recall = be32_to_cpup(p++); | 3939 | res->do_recall = be32_to_cpup(p++); |
3731 | 3940 | ||
3732 | switch (delegation_type) { | 3941 | switch (delegation_type) { |
@@ -3739,6 +3948,9 @@ static int decode_delegation(struct xdr_stream *xdr, struct nfs_openres *res) | |||
3739 | return -EIO; | 3948 | return -EIO; |
3740 | } | 3949 | } |
3741 | return decode_ace(xdr, NULL, res->server->nfs_client); | 3950 | return decode_ace(xdr, NULL, res->server->nfs_client); |
3951 | out_overflow: | ||
3952 | print_overflow_msg(__func__, xdr); | ||
3953 | return -EIO; | ||
3742 | } | 3954 | } |
3743 | 3955 | ||
3744 | static int decode_open(struct xdr_stream *xdr, struct nfs_openres *res) | 3956 | static int decode_open(struct xdr_stream *xdr, struct nfs_openres *res) |
@@ -3757,13 +3969,17 @@ static int decode_open(struct xdr_stream *xdr, struct nfs_openres *res) | |||
3757 | 3969 | ||
3758 | decode_change_info(xdr, &res->cinfo); | 3970 | decode_change_info(xdr, &res->cinfo); |
3759 | 3971 | ||
3760 | READ_BUF(8); | 3972 | p = xdr_inline_decode(xdr, 8); |
3973 | if (unlikely(!p)) | ||
3974 | goto out_overflow; | ||
3761 | res->rflags = be32_to_cpup(p++); | 3975 | res->rflags = be32_to_cpup(p++); |
3762 | bmlen = be32_to_cpup(p++); | 3976 | bmlen = be32_to_cpup(p++); |
3763 | if (bmlen > 10) | 3977 | if (bmlen > 10) |
3764 | goto xdr_error; | 3978 | goto xdr_error; |
3765 | 3979 | ||
3766 | READ_BUF(bmlen << 2); | 3980 | p = xdr_inline_decode(xdr, bmlen << 2); |
3981 | if (unlikely(!p)) | ||
3982 | goto out_overflow; | ||
3767 | savewords = min_t(uint32_t, bmlen, NFS4_BITMAP_SIZE); | 3983 | savewords = min_t(uint32_t, bmlen, NFS4_BITMAP_SIZE); |
3768 | for (i = 0; i < savewords; ++i) | 3984 | for (i = 0; i < savewords; ++i) |
3769 | res->attrset[i] = be32_to_cpup(p++); | 3985 | res->attrset[i] = be32_to_cpup(p++); |
@@ -3774,6 +3990,9 @@ static int decode_open(struct xdr_stream *xdr, struct nfs_openres *res) | |||
3774 | xdr_error: | 3990 | xdr_error: |
3775 | dprintk("%s: Bitmap too large! Length = %u\n", __func__, bmlen); | 3991 | dprintk("%s: Bitmap too large! Length = %u\n", __func__, bmlen); |
3776 | return -EIO; | 3992 | return -EIO; |
3993 | out_overflow: | ||
3994 | print_overflow_msg(__func__, xdr); | ||
3995 | return -EIO; | ||
3777 | } | 3996 | } |
3778 | 3997 | ||
3779 | static int decode_open_confirm(struct xdr_stream *xdr, struct nfs_open_confirmres *res) | 3998 | static int decode_open_confirm(struct xdr_stream *xdr, struct nfs_open_confirmres *res) |
@@ -3820,7 +4039,9 @@ static int decode_read(struct xdr_stream *xdr, struct rpc_rqst *req, struct nfs_ | |||
3820 | status = decode_op_hdr(xdr, OP_READ); | 4039 | status = decode_op_hdr(xdr, OP_READ); |
3821 | if (status) | 4040 | if (status) |
3822 | return status; | 4041 | return status; |
3823 | READ_BUF(8); | 4042 | p = xdr_inline_decode(xdr, 8); |
4043 | if (unlikely(!p)) | ||
4044 | goto out_overflow; | ||
3824 | eof = be32_to_cpup(p++); | 4045 | eof = be32_to_cpup(p++); |
3825 | count = be32_to_cpup(p++); | 4046 | count = be32_to_cpup(p++); |
3826 | hdrlen = (u8 *) p - (u8 *) iov->iov_base; | 4047 | hdrlen = (u8 *) p - (u8 *) iov->iov_base; |
@@ -3835,6 +4056,9 @@ static int decode_read(struct xdr_stream *xdr, struct rpc_rqst *req, struct nfs_ | |||
3835 | res->eof = eof; | 4056 | res->eof = eof; |
3836 | res->count = count; | 4057 | res->count = count; |
3837 | return 0; | 4058 | return 0; |
4059 | out_overflow: | ||
4060 | print_overflow_msg(__func__, xdr); | ||
4061 | return -EIO; | ||
3838 | } | 4062 | } |
3839 | 4063 | ||
3840 | static int decode_readdir(struct xdr_stream *xdr, struct rpc_rqst *req, struct nfs4_readdir_res *readdir) | 4064 | static int decode_readdir(struct xdr_stream *xdr, struct rpc_rqst *req, struct nfs4_readdir_res *readdir) |
@@ -3947,7 +4171,9 @@ static int decode_readlink(struct xdr_stream *xdr, struct rpc_rqst *req) | |||
3947 | return status; | 4171 | return status; |
3948 | 4172 | ||
3949 | /* Convert length of symlink */ | 4173 | /* Convert length of symlink */ |
3950 | READ_BUF(4); | 4174 | p = xdr_inline_decode(xdr, 4); |
4175 | if (unlikely(!p)) | ||
4176 | goto out_overflow; | ||
3951 | len = be32_to_cpup(p++); | 4177 | len = be32_to_cpup(p++); |
3952 | if (len >= rcvbuf->page_len || len <= 0) { | 4178 | if (len >= rcvbuf->page_len || len <= 0) { |
3953 | dprintk("nfs: server returned giant symlink!\n"); | 4179 | dprintk("nfs: server returned giant symlink!\n"); |
@@ -3972,6 +4198,9 @@ static int decode_readlink(struct xdr_stream *xdr, struct rpc_rqst *req) | |||
3972 | kaddr[len+rcvbuf->page_base] = '\0'; | 4198 | kaddr[len+rcvbuf->page_base] = '\0'; |
3973 | kunmap_atomic(kaddr, KM_USER0); | 4199 | kunmap_atomic(kaddr, KM_USER0); |
3974 | return 0; | 4200 | return 0; |
4201 | out_overflow: | ||
4202 | print_overflow_msg(__func__, xdr); | ||
4203 | return -EIO; | ||
3975 | } | 4204 | } |
3976 | 4205 | ||
3977 | static int decode_remove(struct xdr_stream *xdr, struct nfs4_change_info *cinfo) | 4206 | static int decode_remove(struct xdr_stream *xdr, struct nfs4_change_info *cinfo) |
@@ -4069,10 +4298,16 @@ static int decode_setattr(struct xdr_stream *xdr) | |||
4069 | status = decode_op_hdr(xdr, OP_SETATTR); | 4298 | status = decode_op_hdr(xdr, OP_SETATTR); |
4070 | if (status) | 4299 | if (status) |
4071 | return status; | 4300 | return status; |
4072 | READ_BUF(4); | 4301 | p = xdr_inline_decode(xdr, 4); |
4302 | if (unlikely(!p)) | ||
4303 | goto out_overflow; | ||
4073 | bmlen = be32_to_cpup(p++); | 4304 | bmlen = be32_to_cpup(p++); |
4074 | READ_BUF(bmlen << 2); | 4305 | p = xdr_inline_decode(xdr, bmlen << 2); |
4075 | return 0; | 4306 | if (likely(p)) |
4307 | return 0; | ||
4308 | out_overflow: | ||
4309 | print_overflow_msg(__func__, xdr); | ||
4310 | return -EIO; | ||
4076 | } | 4311 | } |
4077 | 4312 | ||
4078 | static int decode_setclientid(struct xdr_stream *xdr, struct nfs_client *clp) | 4313 | static int decode_setclientid(struct xdr_stream *xdr, struct nfs_client *clp) |
@@ -4081,7 +4316,9 @@ static int decode_setclientid(struct xdr_stream *xdr, struct nfs_client *clp) | |||
4081 | uint32_t opnum; | 4316 | uint32_t opnum; |
4082 | int32_t nfserr; | 4317 | int32_t nfserr; |
4083 | 4318 | ||
4084 | READ_BUF(8); | 4319 | p = xdr_inline_decode(xdr, 8); |
4320 | if (unlikely(!p)) | ||
4321 | goto out_overflow; | ||
4085 | opnum = be32_to_cpup(p++); | 4322 | opnum = be32_to_cpup(p++); |
4086 | if (opnum != OP_SETCLIENTID) { | 4323 | if (opnum != OP_SETCLIENTID) { |
4087 | dprintk("nfs: decode_setclientid: Server returned operation" | 4324 | dprintk("nfs: decode_setclientid: Server returned operation" |
@@ -4090,26 +4327,39 @@ static int decode_setclientid(struct xdr_stream *xdr, struct nfs_client *clp) | |||
4090 | } | 4327 | } |
4091 | nfserr = be32_to_cpup(p++); | 4328 | nfserr = be32_to_cpup(p++); |
4092 | if (nfserr == NFS_OK) { | 4329 | if (nfserr == NFS_OK) { |
4093 | READ_BUF(8 + NFS4_VERIFIER_SIZE); | 4330 | p = xdr_inline_decode(xdr, 8 + NFS4_VERIFIER_SIZE); |
4331 | if (unlikely(!p)) | ||
4332 | goto out_overflow; | ||
4094 | p = xdr_decode_hyper(p, &clp->cl_clientid); | 4333 | p = xdr_decode_hyper(p, &clp->cl_clientid); |
4095 | memcpy(clp->cl_confirm.data, p, NFS4_VERIFIER_SIZE); | 4334 | memcpy(clp->cl_confirm.data, p, NFS4_VERIFIER_SIZE); |
4096 | } else if (nfserr == NFSERR_CLID_INUSE) { | 4335 | } else if (nfserr == NFSERR_CLID_INUSE) { |
4097 | uint32_t len; | 4336 | uint32_t len; |
4098 | 4337 | ||
4099 | /* skip netid string */ | 4338 | /* skip netid string */ |
4100 | READ_BUF(4); | 4339 | p = xdr_inline_decode(xdr, 4); |
4340 | if (unlikely(!p)) | ||
4341 | goto out_overflow; | ||
4101 | len = be32_to_cpup(p++); | 4342 | len = be32_to_cpup(p++); |
4102 | READ_BUF(len); | 4343 | p = xdr_inline_decode(xdr, len); |
4344 | if (unlikely(!p)) | ||
4345 | goto out_overflow; | ||
4103 | 4346 | ||
4104 | /* skip uaddr string */ | 4347 | /* skip uaddr string */ |
4105 | READ_BUF(4); | 4348 | p = xdr_inline_decode(xdr, 4); |
4349 | if (unlikely(!p)) | ||
4350 | goto out_overflow; | ||
4106 | len = be32_to_cpup(p++); | 4351 | len = be32_to_cpup(p++); |
4107 | READ_BUF(len); | 4352 | p = xdr_inline_decode(xdr, len); |
4353 | if (unlikely(!p)) | ||
4354 | goto out_overflow; | ||
4108 | return -NFSERR_CLID_INUSE; | 4355 | return -NFSERR_CLID_INUSE; |
4109 | } else | 4356 | } else |
4110 | return nfs4_stat_to_errno(nfserr); | 4357 | return nfs4_stat_to_errno(nfserr); |
4111 | 4358 | ||
4112 | return 0; | 4359 | return 0; |
4360 | out_overflow: | ||
4361 | print_overflow_msg(__func__, xdr); | ||
4362 | return -EIO; | ||
4113 | } | 4363 | } |
4114 | 4364 | ||
4115 | static int decode_setclientid_confirm(struct xdr_stream *xdr) | 4365 | static int decode_setclientid_confirm(struct xdr_stream *xdr) |
@@ -4126,11 +4376,16 @@ static int decode_write(struct xdr_stream *xdr, struct nfs_writeres *res) | |||
4126 | if (status) | 4376 | if (status) |
4127 | return status; | 4377 | return status; |
4128 | 4378 | ||
4129 | READ_BUF(16); | 4379 | p = xdr_inline_decode(xdr, 16); |
4380 | if (unlikely(!p)) | ||
4381 | goto out_overflow; | ||
4130 | res->count = be32_to_cpup(p++); | 4382 | res->count = be32_to_cpup(p++); |
4131 | res->verf->committed = be32_to_cpup(p++); | 4383 | res->verf->committed = be32_to_cpup(p++); |
4132 | memcpy(res->verf->verifier, p, 8); | 4384 | memcpy(res->verf->verifier, p, 8); |
4133 | return 0; | 4385 | return 0; |
4386 | out_overflow: | ||
4387 | print_overflow_msg(__func__, xdr); | ||
4388 | return -EIO; | ||
4134 | } | 4389 | } |
4135 | 4390 | ||
4136 | static int decode_delegreturn(struct xdr_stream *xdr) | 4391 | static int decode_delegreturn(struct xdr_stream *xdr) |
@@ -4152,9 +4407,13 @@ static int decode_exchange_id(struct xdr_stream *xdr, | |||
4152 | if (status) | 4407 | if (status) |
4153 | return status; | 4408 | return status; |
4154 | 4409 | ||
4155 | READ_BUF(8); | 4410 | p = xdr_inline_decode(xdr, 8); |
4411 | if (unlikely(!p)) | ||
4412 | goto out_overflow; | ||
4156 | p = xdr_decode_hyper(p, &clp->cl_ex_clid); | 4413 | p = xdr_decode_hyper(p, &clp->cl_ex_clid); |
4157 | READ_BUF(12); | 4414 | p = xdr_inline_decode(xdr, 12); |
4415 | if (unlikely(!p)) | ||
4416 | goto out_overflow; | ||
4158 | clp->cl_seqid = be32_to_cpup(p++); | 4417 | clp->cl_seqid = be32_to_cpup(p++); |
4159 | clp->cl_exchange_flags = be32_to_cpup(p++); | 4418 | clp->cl_exchange_flags = be32_to_cpup(p++); |
4160 | 4419 | ||
@@ -4164,7 +4423,9 @@ static int decode_exchange_id(struct xdr_stream *xdr, | |||
4164 | return -EIO; | 4423 | return -EIO; |
4165 | 4424 | ||
4166 | /* Throw away minor_id */ | 4425 | /* Throw away minor_id */ |
4167 | READ_BUF(8); | 4426 | p = xdr_inline_decode(xdr, 8); |
4427 | if (unlikely(!p)) | ||
4428 | goto out_overflow; | ||
4168 | 4429 | ||
4169 | /* Throw away Major id */ | 4430 | /* Throw away Major id */ |
4170 | status = decode_opaque_inline(xdr, &dummy, &dummy_str); | 4431 | status = decode_opaque_inline(xdr, &dummy, &dummy_str); |
@@ -4182,6 +4443,9 @@ static int decode_exchange_id(struct xdr_stream *xdr, | |||
4182 | return status; | 4443 | return status; |
4183 | 4444 | ||
4184 | return 0; | 4445 | return 0; |
4446 | out_overflow: | ||
4447 | print_overflow_msg(__func__, xdr); | ||
4448 | return -EIO; | ||
4185 | } | 4449 | } |
4186 | 4450 | ||
4187 | static int decode_chan_attrs(struct xdr_stream *xdr, | 4451 | static int decode_chan_attrs(struct xdr_stream *xdr, |
@@ -4190,7 +4454,9 @@ static int decode_chan_attrs(struct xdr_stream *xdr, | |||
4190 | __be32 *p; | 4454 | __be32 *p; |
4191 | u32 nr_attrs; | 4455 | u32 nr_attrs; |
4192 | 4456 | ||
4193 | READ_BUF(28); | 4457 | p = xdr_inline_decode(xdr, 28); |
4458 | if (unlikely(!p)) | ||
4459 | goto out_overflow; | ||
4194 | attrs->headerpadsz = be32_to_cpup(p++); | 4460 | attrs->headerpadsz = be32_to_cpup(p++); |
4195 | attrs->max_rqst_sz = be32_to_cpup(p++); | 4461 | attrs->max_rqst_sz = be32_to_cpup(p++); |
4196 | attrs->max_resp_sz = be32_to_cpup(p++); | 4462 | attrs->max_resp_sz = be32_to_cpup(p++); |
@@ -4203,9 +4469,15 @@ static int decode_chan_attrs(struct xdr_stream *xdr, | |||
4203 | __func__, nr_attrs); | 4469 | __func__, nr_attrs); |
4204 | return -EINVAL; | 4470 | return -EINVAL; |
4205 | } | 4471 | } |
4206 | if (nr_attrs == 1) | 4472 | if (nr_attrs == 1) { |
4207 | READ_BUF(4); /* skip rdma_attrs */ | 4473 | p = xdr_inline_decode(xdr, 4); /* skip rdma_attrs */ |
4474 | if (unlikely(!p)) | ||
4475 | goto out_overflow; | ||
4476 | } | ||
4208 | return 0; | 4477 | return 0; |
4478 | out_overflow: | ||
4479 | print_overflow_msg(__func__, xdr); | ||
4480 | return -EIO; | ||
4209 | } | 4481 | } |
4210 | 4482 | ||
4211 | static int decode_sessionid(struct xdr_stream *xdr, struct nfs4_sessionid *sid) | 4483 | static int decode_sessionid(struct xdr_stream *xdr, struct nfs4_sessionid *sid) |
@@ -4228,7 +4500,9 @@ static int decode_create_session(struct xdr_stream *xdr, | |||
4228 | return status; | 4500 | return status; |
4229 | 4501 | ||
4230 | /* seqid, flags */ | 4502 | /* seqid, flags */ |
4231 | READ_BUF(8); | 4503 | p = xdr_inline_decode(xdr, 8); |
4504 | if (unlikely(!p)) | ||
4505 | goto out_overflow; | ||
4232 | clp->cl_seqid = be32_to_cpup(p++); | 4506 | clp->cl_seqid = be32_to_cpup(p++); |
4233 | session->flags = be32_to_cpup(p++); | 4507 | session->flags = be32_to_cpup(p++); |
4234 | 4508 | ||
@@ -4237,6 +4511,9 @@ static int decode_create_session(struct xdr_stream *xdr, | |||
4237 | if (!status) | 4511 | if (!status) |
4238 | status = decode_chan_attrs(xdr, &session->bc_attrs); | 4512 | status = decode_chan_attrs(xdr, &session->bc_attrs); |
4239 | return status; | 4513 | return status; |
4514 | out_overflow: | ||
4515 | print_overflow_msg(__func__, xdr); | ||
4516 | return -EIO; | ||
4240 | } | 4517 | } |
4241 | 4518 | ||
4242 | static int decode_destroy_session(struct xdr_stream *xdr, void *dummy) | 4519 | static int decode_destroy_session(struct xdr_stream *xdr, void *dummy) |
@@ -4277,7 +4554,9 @@ static int decode_sequence(struct xdr_stream *xdr, | |||
4277 | goto out_err; | 4554 | goto out_err; |
4278 | } | 4555 | } |
4279 | 4556 | ||
4280 | READ_BUF(20); | 4557 | p = xdr_inline_decode(xdr, 20); |
4558 | if (unlikely(!p)) | ||
4559 | goto out_overflow; | ||
4281 | 4560 | ||
4282 | /* seqid */ | 4561 | /* seqid */ |
4283 | slot = &res->sr_session->fc_slot_table.slots[res->sr_slotid]; | 4562 | slot = &res->sr_session->fc_slot_table.slots[res->sr_slotid]; |
@@ -4302,6 +4581,10 @@ static int decode_sequence(struct xdr_stream *xdr, | |||
4302 | out_err: | 4581 | out_err: |
4303 | res->sr_status = status; | 4582 | res->sr_status = status; |
4304 | return status; | 4583 | return status; |
4584 | out_overflow: | ||
4585 | print_overflow_msg(__func__, xdr); | ||
4586 | status = -EIO; | ||
4587 | goto out_err; | ||
4305 | #else /* CONFIG_NFS_V4_1 */ | 4588 | #else /* CONFIG_NFS_V4_1 */ |
4306 | return 0; | 4589 | return 0; |
4307 | #endif /* CONFIG_NFS_V4_1 */ | 4590 | #endif /* CONFIG_NFS_V4_1 */ |