diff options
| -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 */ |
