Commit eb3d58c6 authored by Trond Myklebust's avatar Trond Myklebust
Browse files

NFSv4: Catch and trace server filehandle encoding errors



If the server returns a filehandle with an invalid length, then trace
that, and return an EREMOTEIO error.

Signed-off-by: default avatarTrond Myklebust <trond.myklebust@hammerspace.com>
parent 3d66bae1
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -433,7 +433,7 @@ static int decode_nfs_fh3(struct xdr_stream *xdr, struct nfs_fh *fh)
	if (unlikely(!p))
		return -EIO;
	length = be32_to_cpup(p++);
	if (unlikely(length > NFS3_FHSIZE))
	if (unlikely(length > NFS3_FHSIZE || length == 0))
		goto out_toobig;
	p = xdr_inline_decode(xdr, length);
	if (unlikely(!p))
@@ -442,7 +442,7 @@ static int decode_nfs_fh3(struct xdr_stream *xdr, struct nfs_fh *fh)
	memcpy(fh->data, p, length);
	return 0;
out_toobig:
	dprintk("NFS: file handle size (%u) too big\n", length);
	trace_nfs_xdr_bad_filehandle(xdr, NFSERR_BADHANDLE);
	return -E2BIG;
}

+1 −0
Original line number Diff line number Diff line
@@ -745,6 +745,7 @@ DECLARE_EVENT_CLASS(nfs4_xdr_event,
			), \
			TP_ARGS(xdr, op, error))
DEFINE_NFS4_XDR_EVENT(nfs4_xdr_status);
DEFINE_NFS4_XDR_EVENT(nfs4_xdr_bad_filehandle);

DECLARE_EVENT_CLASS(nfs4_cb_error_class,
		TP_PROTO(
+9 −4
Original line number Diff line number Diff line
@@ -3495,8 +3495,11 @@ static int decode_attr_filehandle(struct xdr_stream *xdr, uint32_t *bitmap, stru
		if (unlikely(!p))
			return -EIO;
		len = be32_to_cpup(p);
		if (len > NFS4_FHSIZE)
			return -EIO;
		if (len > NFS4_FHSIZE || len == 0) {
			trace_nfs4_xdr_bad_filehandle(xdr, OP_READDIR,
						      NFS4ERR_BADHANDLE);
			return -EREMOTEIO;
		}
		p = xdr_inline_decode(xdr, len);
		if (unlikely(!p))
			return -EIO;
@@ -4952,8 +4955,10 @@ static int decode_getfh(struct xdr_stream *xdr, struct nfs_fh *fh)
	if (unlikely(!p))
		return -EIO;
	len = be32_to_cpup(p);
	if (len > NFS4_FHSIZE)
		return -EIO;
	if (len > NFS4_FHSIZE || len == 0) {
		trace_nfs4_xdr_bad_filehandle(xdr, OP_GETFH, NFS4ERR_BADHANDLE);
		return -EREMOTEIO;
	}
	fh->size = len;
	p = xdr_inline_decode(xdr, len);
	if (unlikely(!p))
+1 −0
Original line number Diff line number Diff line
@@ -12,3 +12,4 @@
EXPORT_TRACEPOINT_SYMBOL_GPL(nfs_fsync_enter);
EXPORT_TRACEPOINT_SYMBOL_GPL(nfs_fsync_exit);
EXPORT_TRACEPOINT_SYMBOL_GPL(nfs_xdr_status);
EXPORT_TRACEPOINT_SYMBOL_GPL(nfs_xdr_bad_filehandle);
+1 −0
Original line number Diff line number Diff line
@@ -1451,6 +1451,7 @@ DECLARE_EVENT_CLASS(nfs_xdr_event,
			), \
			TP_ARGS(xdr, error))
DEFINE_NFS_XDR_EVENT(nfs_xdr_status);
DEFINE_NFS_XDR_EVENT(nfs_xdr_bad_filehandle);

#endif /* _TRACE_NFS_H */