From: Ilya Dryomov Date: Thu, 16 Jun 2016 09:18:42 +0000 (+0200) Subject: AsyncConnection: don't use state_buffer for connect authorizer X-Git-Tag: ses5-milestone5~417^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=f6e7e403947da48e91042f972b04d4906c8fe75d;p=ceph.git 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 --- diff --git a/src/msg/async/AsyncConnection.cc b/src/msg/async/AsyncConnection.cc index 6f7a38d0acc1..39cc38984a84 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 5769827b9d72..e9dbf076935f 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;