Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

NFSD: Fix callback decoder status codes

fs/nfsd/nfs4callback.c implements a callback client. Thus its XDR
decoders are decoding replies, not calls.

NFS4ERR_BAD_XDR is an on-the-wire status code that reports that the
client sent a corrupted RPC /call/. It's not used as the internal
error code when a /reply/ can't be decoded, since that kind of
failure is never reported to the sender of that RPC message.

Instead, a reply decoder should return -EIO, as the reply decoders
in the NFS client do.

Fixes: 6487a13b5c6b ("NFSD: add support for CB_GETATTR callback")
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>

+7 -7
+7 -7
fs/nfsd/nfs4callback.c
··· 101 101 102 102 if (bitmap[0] & FATTR4_WORD0_CHANGE) 103 103 if (xdr_stream_decode_u64(xdr, &fattr->ncf_cb_change) < 0) 104 - return -NFSERR_BAD_XDR; 104 + return -EIO; 105 105 if (bitmap[0] & FATTR4_WORD0_SIZE) 106 106 if (xdr_stream_decode_u64(xdr, &fattr->ncf_cb_fsize) < 0) 107 - return -NFSERR_BAD_XDR; 107 + return -EIO; 108 108 if (bitmap[2] & FATTR4_WORD2_TIME_DELEG_ACCESS) { 109 109 fattr4_time_deleg_access access; 110 110 111 111 if (!xdrgen_decode_fattr4_time_deleg_access(xdr, &access)) 112 - return -NFSERR_BAD_XDR; 112 + return -EIO; 113 113 fattr->ncf_cb_atime.tv_sec = access.seconds; 114 114 fattr->ncf_cb_atime.tv_nsec = access.nseconds; 115 115 ··· 118 118 fattr4_time_deleg_modify modify; 119 119 120 120 if (!xdrgen_decode_fattr4_time_deleg_modify(xdr, &modify)) 121 - return -NFSERR_BAD_XDR; 121 + return -EIO; 122 122 fattr->ncf_cb_mtime.tv_sec = modify.seconds; 123 123 fattr->ncf_cb_mtime.tv_nsec = modify.nseconds; 124 124 ··· 682 682 if (unlikely(status || cb->cb_status)) 683 683 return status; 684 684 if (xdr_stream_decode_uint32_array(xdr, bitmap, 3) < 0) 685 - return -NFSERR_BAD_XDR; 685 + return -EIO; 686 686 if (xdr_stream_decode_u32(xdr, &attrlen) < 0) 687 - return -NFSERR_BAD_XDR; 687 + return -EIO; 688 688 maxlen = sizeof(ncf->ncf_cb_change) + sizeof(ncf->ncf_cb_fsize); 689 689 if (bitmap[2] != 0) 690 690 maxlen += (sizeof(ncf->ncf_cb_mtime.tv_sec) + 691 691 sizeof(ncf->ncf_cb_mtime.tv_nsec)) * 2; 692 692 if (attrlen > maxlen) 693 - return -NFSERR_BAD_XDR; 693 + return -EIO; 694 694 status = decode_cb_fattr4(xdr, bitmap, ncf); 695 695 return status; 696 696 }