diff options
| author | Chuck Lever <chuck.lever@oracle.com> | 2017-06-23 17:18:00 -0400 |
|---|---|---|
| committer | J. Bruce Fields <bfields@redhat.com> | 2017-06-28 14:21:44 -0400 |
| commit | ca5c76aba7502d52a6019358ec04bd4d734037d7 (patch) | |
| tree | 657fe7bdd07b1dcf53352f59133c19106c46d3d8 | |
| parent | 3c22f326074d2306041b0c5c9df516464349564d (diff) | |
svcrdma: Improve Reply chunk sanity checking
Identify malformed transport headers and unsupported chunk
combinations as early as possible.
- Ensure that segment lengths are not crazy.
- Ensure that the Reply chunk's segment count is not crazy.
With a 1KB inline threshold, the largest number of Write segments
that can be conveyed is about 60 (for a RDMA_NOMSG Reply message).
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
| -rw-r--r-- | net/sunrpc/xprtrdma/svc_rdma_recvfrom.c | 17 |
1 files changed, 11 insertions, 6 deletions
diff --git a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c index cf8be18f297a..b48089314f85 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c +++ b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c | |||
| @@ -217,15 +217,20 @@ static __be32 *xdr_check_write_list(__be32 *p, const __be32 *end) | |||
| 217 | return p; | 217 | return p; |
| 218 | } | 218 | } |
| 219 | 219 | ||
| 220 | static __be32 *xdr_check_reply_chunk(__be32 *p, __be32 *end) | 220 | /* Sanity check the Reply chunk. |
| 221 | * | ||
| 222 | * Sanity checks: | ||
| 223 | * - Reply chunk does not overflow buffer. | ||
| 224 | * - Segment size limited by largest NFS data payload. | ||
| 225 | * | ||
| 226 | * Returns pointer to the following RPC header. | ||
| 227 | */ | ||
| 228 | static __be32 *xdr_check_reply_chunk(__be32 *p, const __be32 *end) | ||
| 221 | { | 229 | { |
| 222 | __be32 *next; | ||
| 223 | |||
| 224 | if (*p++ != xdr_zero) { | 230 | if (*p++ != xdr_zero) { |
| 225 | next = p + 1 + be32_to_cpup(p) * rpcrdma_segment_maxsz; | 231 | p = xdr_check_write_chunk(p, end, MAX_BYTES_SPECIAL_SEG); |
| 226 | if (next > end) | 232 | if (!p) |
| 227 | return NULL; | 233 | return NULL; |
| 228 | p = next; | ||
| 229 | } | 234 | } |
| 230 | return p; | 235 | return p; |
| 231 | } | 236 | } |
