diff options
author | Chuck Lever <chuck.lever@oracle.com> | 2017-10-16 15:01:06 -0400 |
---|---|---|
committer | Anna Schumaker <Anna.Schumaker@Netapp.com> | 2017-11-17 13:47:53 -0500 |
commit | 61433af56077f5fd8815281b44938d84feb04687 (patch) | |
tree | 3fc82e93f1cf8e68d39b4b02e1c563b024357d32 /net/sunrpc | |
parent | 2b4f8923ecaafc0c25ee56bc17ea9256d12b747c (diff) |
xprtrdma: Throw away reply when version is unrecognized
A reply with an unrecognized value in the version field means the
transport header is potentially garbled and therefore all the fields
are untrustworthy.
Fixes: 59aa1f9a3cce3 ("xprtrdma: Properly handle RDMA_ERROR ... ")
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
Diffstat (limited to 'net/sunrpc')
-rw-r--r-- | net/sunrpc/xprtrdma/rpc_rdma.c | 17 |
1 files changed, 8 insertions, 9 deletions
diff --git a/net/sunrpc/xprtrdma/rpc_rdma.c b/net/sunrpc/xprtrdma/rpc_rdma.c index f1889f4d4803..20c9e4cbaa73 100644 --- a/net/sunrpc/xprtrdma/rpc_rdma.c +++ b/net/sunrpc/xprtrdma/rpc_rdma.c | |||
@@ -1248,6 +1248,9 @@ rpcrdma_reply_handler(struct work_struct *work) | |||
1248 | p++; /* credits */ | 1248 | p++; /* credits */ |
1249 | proc = *p++; | 1249 | proc = *p++; |
1250 | 1250 | ||
1251 | if (vers != rpcrdma_version) | ||
1252 | goto out_badversion; | ||
1253 | |||
1251 | if (rpcrdma_is_bcall(r_xprt, rep, xid, proc)) | 1254 | if (rpcrdma_is_bcall(r_xprt, rep, xid, proc)) |
1252 | return; | 1255 | return; |
1253 | 1256 | ||
@@ -1280,8 +1283,6 @@ rpcrdma_reply_handler(struct work_struct *work) | |||
1280 | } | 1283 | } |
1281 | 1284 | ||
1282 | xprt->reestablish_timeout = 0; | 1285 | xprt->reestablish_timeout = 0; |
1283 | if (vers != rpcrdma_version) | ||
1284 | goto out_badversion; | ||
1285 | 1286 | ||
1286 | switch (proc) { | 1287 | switch (proc) { |
1287 | case rdma_msg: | 1288 | case rdma_msg: |
@@ -1321,17 +1322,15 @@ out_badstatus: | |||
1321 | } | 1322 | } |
1322 | return; | 1323 | return; |
1323 | 1324 | ||
1324 | /* If the incoming reply terminated a pending RPC, the next | ||
1325 | * RPC call will post a replacement receive buffer as it is | ||
1326 | * being marshaled. | ||
1327 | */ | ||
1328 | out_badversion: | 1325 | out_badversion: |
1329 | dprintk("RPC: %s: invalid version %d\n", | 1326 | dprintk("RPC: %s: invalid version %d\n", |
1330 | __func__, be32_to_cpu(vers)); | 1327 | __func__, be32_to_cpu(vers)); |
1331 | status = -EIO; | 1328 | goto repost; |
1332 | r_xprt->rx_stats.bad_reply_count++; | ||
1333 | goto out; | ||
1334 | 1329 | ||
1330 | /* If the incoming reply terminated a pending RPC, the next | ||
1331 | * RPC call will post a replacement receive buffer as it is | ||
1332 | * being marshaled. | ||
1333 | */ | ||
1335 | out_badheader: | 1334 | out_badheader: |
1336 | dprintk("RPC: %5u %s: invalid rpcrdma reply (type %u)\n", | 1335 | dprintk("RPC: %5u %s: invalid rpcrdma reply (type %u)\n", |
1337 | rqst->rq_task->tk_pid, __func__, be32_to_cpu(proc)); | 1336 | rqst->rq_task->tk_pid, __func__, be32_to_cpu(proc)); |