Commit eb3d58c6 authored by Trond Myklebust's avatar Trond Myklebust

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
...@@ -433,7 +433,7 @@ static int decode_nfs_fh3(struct xdr_stream *xdr, struct nfs_fh *fh) ...@@ -433,7 +433,7 @@ static int decode_nfs_fh3(struct xdr_stream *xdr, struct nfs_fh *fh)
if (unlikely(!p)) if (unlikely(!p))
return -EIO; return -EIO;
length = be32_to_cpup(p++); length = be32_to_cpup(p++);
if (unlikely(length > NFS3_FHSIZE)) if (unlikely(length > NFS3_FHSIZE || length == 0))
goto out_toobig; goto out_toobig;
p = xdr_inline_decode(xdr, length); p = xdr_inline_decode(xdr, length);
if (unlikely(!p)) if (unlikely(!p))
...@@ -442,7 +442,7 @@ static int decode_nfs_fh3(struct xdr_stream *xdr, struct nfs_fh *fh) ...@@ -442,7 +442,7 @@ static int decode_nfs_fh3(struct xdr_stream *xdr, struct nfs_fh *fh)
memcpy(fh->data, p, length); memcpy(fh->data, p, length);
return 0; return 0;
out_toobig: out_toobig:
dprintk("NFS: file handle size (%u) too big\n", length); trace_nfs_xdr_bad_filehandle(xdr, NFSERR_BADHANDLE);
return -E2BIG; return -E2BIG;
} }
......
...@@ -745,6 +745,7 @@ DECLARE_EVENT_CLASS(nfs4_xdr_event, ...@@ -745,6 +745,7 @@ DECLARE_EVENT_CLASS(nfs4_xdr_event,
), \ ), \
TP_ARGS(xdr, op, error)) TP_ARGS(xdr, op, error))
DEFINE_NFS4_XDR_EVENT(nfs4_xdr_status); DEFINE_NFS4_XDR_EVENT(nfs4_xdr_status);
DEFINE_NFS4_XDR_EVENT(nfs4_xdr_bad_filehandle);
DECLARE_EVENT_CLASS(nfs4_cb_error_class, DECLARE_EVENT_CLASS(nfs4_cb_error_class,
TP_PROTO( TP_PROTO(
......
...@@ -3495,8 +3495,11 @@ static int decode_attr_filehandle(struct xdr_stream *xdr, uint32_t *bitmap, stru ...@@ -3495,8 +3495,11 @@ static int decode_attr_filehandle(struct xdr_stream *xdr, uint32_t *bitmap, stru
if (unlikely(!p)) if (unlikely(!p))
return -EIO; return -EIO;
len = be32_to_cpup(p); len = be32_to_cpup(p);
if (len > NFS4_FHSIZE) if (len > NFS4_FHSIZE || len == 0) {
return -EIO; trace_nfs4_xdr_bad_filehandle(xdr, OP_READDIR,
NFS4ERR_BADHANDLE);
return -EREMOTEIO;
}
p = xdr_inline_decode(xdr, len); p = xdr_inline_decode(xdr, len);
if (unlikely(!p)) if (unlikely(!p))
return -EIO; return -EIO;
...@@ -4952,8 +4955,10 @@ static int decode_getfh(struct xdr_stream *xdr, struct nfs_fh *fh) ...@@ -4952,8 +4955,10 @@ static int decode_getfh(struct xdr_stream *xdr, struct nfs_fh *fh)
if (unlikely(!p)) if (unlikely(!p))
return -EIO; return -EIO;
len = be32_to_cpup(p); len = be32_to_cpup(p);
if (len > NFS4_FHSIZE) if (len > NFS4_FHSIZE || len == 0) {
return -EIO; trace_nfs4_xdr_bad_filehandle(xdr, OP_GETFH, NFS4ERR_BADHANDLE);
return -EREMOTEIO;
}
fh->size = len; fh->size = len;
p = xdr_inline_decode(xdr, len); p = xdr_inline_decode(xdr, len);
if (unlikely(!p)) if (unlikely(!p))
......
...@@ -12,3 +12,4 @@ ...@@ -12,3 +12,4 @@
EXPORT_TRACEPOINT_SYMBOL_GPL(nfs_fsync_enter); EXPORT_TRACEPOINT_SYMBOL_GPL(nfs_fsync_enter);
EXPORT_TRACEPOINT_SYMBOL_GPL(nfs_fsync_exit); EXPORT_TRACEPOINT_SYMBOL_GPL(nfs_fsync_exit);
EXPORT_TRACEPOINT_SYMBOL_GPL(nfs_xdr_status); EXPORT_TRACEPOINT_SYMBOL_GPL(nfs_xdr_status);
EXPORT_TRACEPOINT_SYMBOL_GPL(nfs_xdr_bad_filehandle);
...@@ -1451,6 +1451,7 @@ DECLARE_EVENT_CLASS(nfs_xdr_event, ...@@ -1451,6 +1451,7 @@ DECLARE_EVENT_CLASS(nfs_xdr_event,
), \ ), \
TP_ARGS(xdr, error)) TP_ARGS(xdr, error))
DEFINE_NFS_XDR_EVENT(nfs_xdr_status); DEFINE_NFS_XDR_EVENT(nfs_xdr_status);
DEFINE_NFS_XDR_EVENT(nfs_xdr_bad_filehandle);
#endif /* _TRACE_NFS_H */ #endif /* _TRACE_NFS_H */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment