From f6e7e403947da48e91042f972b04d4906c8fe75d Mon Sep 17 00:00:00 2001 From: Ilya Dryomov Date: Thu, 16 Jun 2016 11:18:42 +0200 Subject: [PATCH] AsyncConnection: don't use state_buffer for connect authorizer state_buffer is 4096 bytes long, while connect authorizer can be arbitrarily big - an OSD service ticket with lots of per-pool or per-namespace caps is one example. We end up scribbling on invalid memory past the state_buffer and eventually crash. Move authorizer_bl up into connection and read directly into it. Signed-off-by: Ilya Dryomov --- src/msg/async/AsyncConnection.cc | 13 ++++++++----- src/msg/async/AsyncConnection.h | 1 + 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/msg/async/AsyncConnection.cc b/src/msg/async/AsyncConnection.cc index 6f7a38d0acc..39cc38984a8 100644 --- a/src/msg/async/AsyncConnection.cc +++ b/src/msg/async/AsyncConnection.cc @@ -994,6 +994,7 @@ ssize_t AsyncConnection::_process_connection() got_bad_auth = false; delete authorizer; authorizer = NULL; + authorizer_buf.clear(); memset(&connect_msg, 0, sizeof(connect_msg)); memset(&connect_reply, 0, sizeof(connect_reply)); @@ -1425,17 +1426,19 @@ ssize_t AsyncConnection::_process_connection() case STATE_ACCEPTING_WAIT_CONNECT_MSG_AUTH: { - bufferlist authorizer_bl, authorizer_reply; + bufferlist authorizer_reply; if (connect_msg.authorizer_len) { - r = read_until(connect_msg.authorizer_len, state_buffer); + if (!authorizer_buf.length()) + authorizer_buf.push_back(buffer::create(connect_msg.authorizer_len)); + + r = read_until(connect_msg.authorizer_len, authorizer_buf.c_str()); if (r < 0) { - ldout(async_msgr->cct, 1) << __func__ << " read connect msg failed" << dendl; + ldout(async_msgr->cct, 1) << __func__ << " read connect authorizer failed" << dendl; goto fail; } else if (r > 0) { break; } - authorizer_bl.append(state_buffer, connect_msg.authorizer_len); } ldout(async_msgr->cct, 20) << __func__ << " accept got peer connect_seq " @@ -1448,7 +1451,7 @@ ssize_t AsyncConnection::_process_connection() << policy.server << " policy.standby=" << policy.standby << " policy.resetcheck=" << policy.resetcheck << dendl; - r = handle_connect_msg(connect_msg, authorizer_bl, authorizer_reply); + r = handle_connect_msg(connect_msg, authorizer_buf, authorizer_reply); if (r < 0) goto fail; diff --git a/src/msg/async/AsyncConnection.h b/src/msg/async/AsyncConnection.h index 5769827b9d7..e9dbf076935 100644 --- a/src/msg/async/AsyncConnection.h +++ b/src/msg/async/AsyncConnection.h @@ -345,6 +345,7 @@ class AsyncConnection : public Connection { // Connecting state bool got_bad_auth; AuthAuthorizer *authorizer; + bufferlist authorizer_buf; ceph_msg_connect_reply connect_reply; // Accepting state entity_addr_t socket_addr; -- 2.47.3